LLVM tornou-se um projeto guarda-chuva contendo múltiplos componentes.
Front endsEdit
LLVM foi originalmente escrito para ser um substituto do gerador de código existente na pilha GCC, e muitos dos front ends GCC foram modificados para funcionar com ele, resultando no agora extinto conjunto LLVM-GCC. As modificações geralmente envolvem uma etapa GIMPLE-to-LLVM IR para que otimizadores e codegen LLVM possam ser usados ao invés do sistema GIMPLE do GCC. A Apple foi um usuário significativo do LLVM-GCC através do Xcode 4.x (2013). Este uso do frontend GCC foi considerado principalmente uma medida temporária, mas com o advento do Clang e as vantagens da base de códigos moderna e modular de LLVM e Clang (assim como a velocidade de compilação), é na sua maioria obsoleto.
LLVM atualmente suporta a compilação de Ada, C, C++, D, Delphi, Fortran, Haskell, Julia, Objective-C, Rust, e Swift usando vários front-ends.
O interesse generalizado em LLVM levou a vários esforços para desenvolver novos front-ends para uma variedade de linguagens. A que tem recebido mais atenção é a Clang, um novo compilador que suporta C, C++, e Objective-C. Primariamente suportado pela Apple, o Clang visa substituir o compilador C/Objective-C no sistema GCC por um sistema que seja mais facilmente integrado com ambientes de desenvolvimento integrado (IDEs) e tenha um suporte mais amplo para multithreading. O suporte a diretrizes OpenMP foi incluído no Clang desde a versão 3.8.
O compilador Utrecht Haskell pode gerar código para LLVM. Embora o gerador esteja nos estágios iniciais de desenvolvimento, em muitos casos ele tem sido mais eficiente do que o gerador de código C. Existe um backend Glasgow Haskell Compiler (GHC) usando LLVM que atinge uma velocidade de 30% do código compilado em relação ao código nativo compilado via GHC ou geração de código C seguido de compilação, faltando apenas uma das muitas técnicas de otimização implementadas pelo GHC.
Muitos outros componentes estão em vários estágios de desenvolvimento, incluindo, mas não limitado a, o compilador Rust, um front end de bytecode Java, um front end de Common Intermediate Language (CIL), a implementação MacRuby do Ruby 1.9, vários front-ends para Standard ML, e um novo alocador de registros de cores gráficas.
Representação intermediáriaEdit
O núcleo da LLVM é a representação intermediária (IR), uma linguagem de programação de baixo nível semelhante à montagem. IR é um conjunto de instruções de computação reduzida (RISC) fortemente digitado, que abstrai a maioria dos detalhes do alvo. Por exemplo, a convenção de chamadas é abstraída através de instruções call e ret com argumentos explícitos. Além disso, ao invés de um conjunto fixo de registros, o IR usa um conjunto infinito de temporais da forma %0, %1, etc. LLVM suporta três formas equivalentes de IR: um formato de montagem legível por humanos, um formato in-memory adequado para frontends, e um formato denso de bitcode para serialização. Um simples programa “Olá, mundo!” no formato IR:
@.str = internal constant c"hello, world\0A\00"declare i32 @printf(i8*, ...)define i32 @main(i32 %argc, i8** %argv) nounwind {entry: %tmp1 = getelementptr , * @.str, i32 0, i32 0 %tmp2 = call i32 (i8*, ...) @printf( i8* %tmp1 ) nounwind ret i32 0}
As muitas convenções diferentes usadas e características fornecidas pelos diferentes alvos significam que LLVM não pode realmente produzir um IR independente do alvo e redirecioná-lo sem quebrar algumas regras estabelecidas. Exemplos de dependência de alvos além do que é explicitamente mencionado na documentação podem ser encontrados em uma proposta de 2011 para “código de palavras”, uma variante totalmente independente do alvo de LLVM IR destinada à distribuição online. Um exemplo mais prático é PNaCl.
Back endsEdit
Na versão 3.4, LLVM suporta muitos conjuntos de instruções, incluindo ARM, Qualcomm Hexagon, MIPS, Nvidia Parallel Thread Execution (PTX; chamada NVPTX na documentação LLVM), PowerPC, AMD TeraScale, AMD Graphics Core Next (GCN), SPARC, z/Architecture (chamada SystemZ na documentação LLVM), x86, x86-64 e XCore. Alguns recursos não estão disponíveis em algumas plataformas. A maioria dos recursos estão presentes para x86, x86-64, z/Arquitetura, ARM, e PowerPC. O RISC-V é suportado a partir da versão 7. No passado, LLVM também suportava total ou parcialmente outros backends, incluindo C backend, Cell SPU, mblaze (MicroBlaze), AMD R600, DEC/Compaq Alpha (Alpha AXP) e Nios2, mas a maior parte deste hardware é obsoleto, e o suporte e manutenção LLVM para ele não poderia ser justificado.
LLVM também suporta WebAssembly como um alvo, permitindo que programas compilados sejam executados em ambientes habilitados para WebAssembly como o Google Chrome / Chromium, Firefox, Microsoft Edge, Apple Safari ou WAVM. Os compiladores WebAssembly compatíveis com LLVM tipicamente suportam na sua maioria código fonte não modificado escrito em C, C++, D, Rust, Nim, Kotlin e vários outros idiomas.
O subprojecto código da máquina LLVM (MC) é a estrutura de LLVM para traduzir instruções de máquina entre formulários textuais e código da máquina. Anteriormente, LLVM contava com o assembler do sistema, ou um fornecido por uma cadeia de ferramentas, para traduzir a montagem em código de máquina. O assembler integrado da LLVM MC suporta a maioria dos alvos LLVM, incluindo x86, x86-64, ARM, e ARM64. Para alguns alvos, incluindo os vários conjuntos de instruções MIPS, o suporte a assembly integrado é utilizável, mas ainda no estágio beta.
LinkerEdit
O subprojeto lld é uma tentativa de desenvolver um linker embutido, independente de plataforma para LLVM. lld tem como objetivo remover a dependência de um linker de terceiros. Desde maio de 2017, o lld suporta ELF, PE/COFF, Mach-O, e WebAssembly em ordem decrescente de completude. O lld é mais rápido que ambos os sabores do GNU ld.
Não parecido com os linkers GNU, o lld tem suporte embutido para otimização link-time. Isto permite uma geração de código mais rápida, pois evita o uso de um plugin linker, mas por outro lado proíbe a interoperabilidade com outros sabores do LTO.
C++ Standard LibraryEdit
O projeto LLVM inclui uma implementação da biblioteca padrão C++ chamada libc++, com licença dupla sob a licença MIT e a licença UIUC.
Desde a v9.0.0, foi relicenciado para a Licença Apache 2.0 com exceções LLVM.
PollyEdit
Esta implementa um conjunto de otimizações de cache-localidade assim como auto-paralelelismo e vetorização usando um modelo poliédrico.