LLVM is een overkoepelend project geworden dat meerdere componenten bevat.
Front endsEdit
LVM is oorspronkelijk geschreven als vervanging voor de bestaande code generator in de GCC stack, en veel van de GCC front ends zijn aangepast om ermee te werken, wat resulteerde in de nu ter ziele gegane LLVM-GCC suite. De aanpassingen omvatten meestal een GIMPLE-naar-LLVM IR stap, zodat LLVM optimizers en codegen gebruikt kunnen worden in plaats van GCC’s GIMPLE systeem. Apple was een belangrijke gebruiker van LLVM-GCC via Xcode 4.x (2013). Dit gebruik van de GCC frontend werd meestal beschouwd als een tijdelijke maatregel, maar met de komst van Clang en de voordelen van LLVM en Clang’s moderne en modulaire codebase (evenals compilatiesnelheid), is grotendeels achterhaald.
LLVM ondersteunt momenteel het compileren van Ada, C, C++, D, Delphi, Fortran, Haskell, Julia, Objective-C, Rust, en Swift met behulp van verschillende front-ends.
Wijdverbreide belangstelling voor LLVM heeft geleid tot verschillende pogingen om nieuwe front-ends te ontwikkelen voor een verscheidenheid aan talen. Degene die de meeste aandacht heeft gekregen is Clang, een nieuwe compiler die C, C++, en Objective-C ondersteunt. Clang, dat voornamelijk door Apple wordt ondersteund, is bedoeld om de C/Objective-C compiler in het GCC systeem te vervangen door een systeem dat eenvoudiger te integreren is met geïntegreerde ontwikkelomgevingen (IDE’s) en bredere ondersteuning voor multithreading heeft. Ondersteuning voor OpenMP directives is opgenomen in Clang sinds versie 3.8.
De Utrechtse Haskell compiler kan code genereren voor LLVM. Hoewel de generator zich nog in het beginstadium van ontwikkeling bevindt, is hij in veel gevallen efficiënter dan de C-code generator. Er is een Glasgow Haskell Compiler (GHC) backend die LLVM gebruikt en die een versnelling van 30% bereikt van de gecompileerde code ten opzichte van native code compileren via GHC of C code generatie gevolgd door compileren, waarbij slechts een van de vele optimalisatietechnieken wordt gemist die door de GHC worden geïmplementeerd.
Vele andere componenten bevinden zich in verschillende stadia van ontwikkeling, waaronder, maar niet beperkt tot, de Rust compiler, een Java bytecode front end, een Common Intermediate Language (CIL) front end, de MacRuby implementatie van Ruby 1.9, diverse front-ends voor Standard ML, en een nieuwe graph coloring register allocator.
Intermediate representationEdit
De kern van LLVM is de intermediaire representatie (IR), een programmeertaal op laag niveau die lijkt op assemblage. IR is een sterk getypeerde reduced instruction set computing (RISC) instructieset die de meeste details van het doel weg abstraheert. Zo wordt bijvoorbeeld de aanroepconventie geabstraheerd door call en ret instructies met expliciete argumenten. Ook, in plaats van een vaste set van registers, gebruikt IR een oneindige set van temporaries van de vorm %0, %1, etc. LLVM ondersteunt drie equivalente vormen van IR: een menselijk leesbaar assemblage formaat, een in-memory formaat geschikt voor frontends, en een dicht bitcode formaat voor serialisatie. Een eenvoudig “Hallo, wereld!”-programma in het IR-formaat:
@.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}
De vele verschillende conventies die worden gebruikt en functies die worden geleverd door verschillende targets betekenen dat LLVM niet echt een target-onafhankelijke IR kan produceren en retargeten zonder enkele gevestigde regels te breken. Voorbeelden van doelafhankelijkheid die verder gaan dan wat expliciet in de documentatie wordt vermeld, zijn te vinden in een voorstel uit 2011 voor “wordcode”, een volledig doel-onafhankelijke variant van LLVM IR bedoeld voor online distributie. Een praktischer voorbeeld is PNaCl.
AchteraankantenEdit
In versie 3.4, LLVM ondersteunt vele instructiesets, waaronder ARM, Qualcomm Hexagon, MIPS, Nvidia Parallel Thread Execution (PTX; NVPTX genoemd in LLVM documentatie), PowerPC, AMD TeraScale, AMD Graphics Core Next (GCN), SPARC, z/Architecture (SystemZ genoemd in LLVM documentatie), x86, x86-64, en XCore. Sommige functies zijn niet beschikbaar op sommige platformen. De meeste functies zijn aanwezig voor x86, x86-64, z/Architecture, ARM, en PowerPC. RISC-V wordt ondersteund vanaf versie 7. In het verleden ondersteunde LLVM ook geheel of gedeeltelijk andere backends, waaronder C backend, Cell SPU, mblaze (MicroBlaze), AMD R600, DEC/Compaq Alpha (Alpha AXP) en Nios2, maar de meeste van deze hardware is grotendeels verouderd, en de LLVM ondersteuning en onderhoud ervoor kon niet worden gerechtvaardigd.
LLVM ondersteunt ook WebAssembly als target, waardoor gecompileerde programma’s kunnen worden uitgevoerd in omgevingen die WebAssembly ondersteunen, zoals Google Chrome / Chromium, Firefox, Microsoft Edge, Apple Safari of WAVM. LLVM-compatibele WebAssembly compilers ondersteunen meestal ongewijzigde broncode geschreven in C, C++, D, Rust, Nim, Kotlin en verschillende andere talen.
Het LLVM machine code (MC) subproject is LLVM’s raamwerk voor het vertalen van machine-instructies tussen tekstuele vormen en machinecode. Voorheen was LLVM afhankelijk van de systeemassembler, of een assembler geleverd door een toolchain, om assemblage te vertalen naar machinecode. LLVM MC’s geïntegreerde assembler ondersteunt de meeste LLVM targets, waaronder x86, x86-64, ARM, en ARM64. Voor sommige targets, waaronder de verschillende MIPS-instructiesets, is geïntegreerde assemblerondersteuning bruikbaar, maar nog in de bètafase.
LinkerEdit
Het lld-subproject is een poging om een ingebouwde, platformonafhankelijke linker voor LLVM te ontwikkelen. lld heeft als doel om de afhankelijkheid van een third-party linker te verwijderen. Vanaf mei 2017 ondersteunt lld ELF, PE/COFF, Mach-O, en WebAssembly in aflopende volgorde van volledigheid. lld is sneller dan beide smaken van GNU ld.
In tegenstelling tot de GNU linkers, heeft lld ingebouwde ondersteuning voor link-time optimalisatie. Dit maakt snellere code generatie mogelijk omdat het het gebruik van een linker plugin omzeilt, maar aan de andere kant verbiedt het interoperabiliteit met andere smaken van LTO.
C++ Standard LibraryEdit
Het LLVM project bevat een implementatie van de C++ Standard Library, libc++ genaamd, met een dubbele licentie onder de MIT Licentie en de UIUC licentie.
Sinds v9.0.0 is het opnieuw gelicenseerd onder de Apache Licentie 2.0 met LLVM Exceptions.
PollyEdit
Dit implementeert een suite van cache-locality optimalisaties, alsmede auto-parallelisme en vectorisatie met behulp van een polyhedral model.