Pular para o conteúdo

O backend, e o que ele não é

Não há LLVM, não há código de máquina e não há target triple. O que existe no lugar, e por que a troca é essa.

Esta página existe porque a pergunta aparece, e porque a resposta certa é um não com o motivo — não um silêncio.

O que não existe#

PedidoResposta
emitir LLVM IRnão existe. Emitir texto de IR é fácil; o que vem depois não é — seria preciso llc ou clang instalado, e aí a linguagem passaria a depender de um compilador C para rodar
llvmlite, cffi, qualquer backend em pacoterecusado por regra: dataforge/ não tem dependência externa, e é isso que faz pip install dataforge-lang bastar
passes LLVM em C++não se aplica: não há IR para um passe transformar
target triple, cross compiler, RISC-V, WebAssembly, bare-metalnão existe. Não há código de máquina a produzir para alvo nenhum
debug info (DWARF), intrinsicsnão se aplica. A informação de depuração existe, mas é a da linguagem: linha, coluna e o DAP

O que existe no lugar#

Em vez deO DataForge tem
backend de código de máquinacompilador.py — a árvore vira fechamentos Python, uma vez, com a cobertura medida pelo LIR
passes customizados em C++plugins do `check` escritos em DataForge, que agora veem o MIR e o SSA por Arcane.Compilador
calling convention e ABI loweringexistem, e são de verdade — mas só na fronteira com o C: `Arcane.C` declara a assinatura e o ctypes aplica a ABI da plataforma
cross compilationo release constrói nas quatro plataformas (Linux, macOS Intel, macOS ARM, Windows), com .deb, PKGBUILD e instalador do Windows; e dataforge devops gera Dockerfile e manifesto para outra arquitetura
instrumentaçãoo MIR e o SSA como dado, e Arcane.Macro para reescrever corpo de ação

Um passe próprio, escrito na linguagem#

É o análogo honesto de "custom pass": não um .so carregado no otimizador, mas uma regra que lê as mesmas representações e devolve diagnóstico.

dataforge
adopt Arcane.Compilador as K

// A regra: acusar ramo que nunca roda, com o corpo e a linha.
action verificar(fonte):
    achados := []
    cycle morto in K.ramos_mortos(fonte):
        achados.append($"{morto["corpo"]}:{morto["linha"]} ramo {morto["rotulo"]} nao roda")
    yield achados

suspeito := "x := 1\ngiven x bigger 5:\n    out 1\notherwise:\n    out 2\n"
assert len(verificar(suspeito)) bigger 0
assert len(verificar("given entrada:\n    out 1\n")) is 0

A diferença entre isso e um passe do LLVM é real e vale dizer: um passe do LLVM transforma o IR que vai gerar código; isto relata. Transformar a árvore também é possível — é o que os passes de otimização fazem —, mas o ganho medido ali é 1,01×, e essa é a razão pela qual a instrumentação é o uso que paga.