LLVM est devenu un projet parapluie contenant de multiples composants.
Front endsEdit
LLVM a été écrit à l’origine pour être un remplacement du générateur de code existant dans la pile GCC, et de nombreux front ends GCC ont été modifiés pour fonctionner avec lui, ce qui a donné la suite LLVM-GCC, aujourd’hui disparue. Les modifications impliquent généralement une étape d’IR GIMPLE vers LLVM afin que les optimiseurs et le générateur de code LLVM puissent être utilisés à la place du système GIMPLE de GCC. Apple a été un utilisateur important de LLVM-GCC jusqu’à Xcode 4.x (2013). Cette utilisation du front-end de GCC a été considérée surtout comme une mesure temporaire, mais avec l’avènement de Clang et les avantages de LLVM et de la base de code moderne et modulaire de Clang (ainsi que la vitesse de compilation), est en grande partie obsolète.
LLVM prend actuellement en charge la compilation d’Ada, C, C++, D, Delphi, Fortran, Haskell, Julia, Objective-C, Rust et Swift en utilisant divers frontaux.
L’intérêt généralisé pour LLVM a conduit à plusieurs efforts pour développer de nouveaux frontaux pour une variété de langages. Celui qui a reçu le plus d’attention est Clang, un nouveau compilateur supportant C, C++ et Objective-C. Principalement soutenu par Apple, Clang vise à remplacer le compilateur C/Objective-C du système GCC par un système plus facilement intégrable aux environnements de développement intégrés (IDE) et offrant un support plus large du multithreading. Le support des directives OpenMP est inclus dans Clang depuis la version 3.8.
Le compilateur Haskell d’Utrecht peut générer du code pour LLVM. Bien que le générateur soit dans les premiers stades de développement, dans de nombreux cas, il a été plus efficace que le générateur de code C. Il existe un backend Glasgow Haskell Compiler (GHC) utilisant LLVM qui atteint une accélération de 30% du code compilé par rapport à la compilation de code natif via GHC ou à la génération de code C suivie de la compilation, ne manquant qu’une des nombreuses techniques d’optimisation mises en œuvre par le GHC.
De nombreux autres composants sont à divers stades de développement, y compris, mais sans s’y limiter, le compilateur Rust, un frontal de bytecode Java, un frontal de langage intermédiaire commun (CIL), l’implémentation MacRuby de Ruby 1.9, divers frontaux pour Standard ML, et un nouvel allocateur de registre à coloration de graphe.
Représentation intermédiaireEdit
Le cœur de LLVM est la représentation intermédiaire (IR), un langage de programmation de bas niveau similaire à l’assemblage. L’IR est un jeu d’instructions RISC (reduced instruction set computing) fortement typé qui fait abstraction de la plupart des détails de la cible. Par exemple, la convention d’appel est abstraite grâce aux instructions call et ret avec des arguments explicites. De même, au lieu d’un ensemble fixe de registres, IR utilise un ensemble infini de temporaires de la forme %0, %1, etc. LLVM supporte trois formes équivalentes de IR : un format d’assemblage lisible par l’homme, un format en mémoire adapté aux frontends, et un format dense de code binaire pour la sérialisation. Un simple programme « Hello, world ! » au format 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}
Les nombreuses conventions utilisées et fonctionnalités fournies par les différentes cibles signifient que LLVM ne peut pas vraiment produire un IR indépendant de la cible et le recibler sans enfreindre certaines règles établies. Des exemples de dépendance à la cible au-delà de ce qui est explicitement mentionné dans la documentation peuvent être trouvés dans une proposition de 2011 pour « wordcode », une variante entièrement indépendante de la cible de LLVM IR destinée à la distribution en ligne. Un exemple plus pratique est PNaCl.
Retours en arrièreModification
À la version 3.4, LLVM supporte de nombreux jeux d’instructions, notamment ARM, Qualcomm Hexagon, MIPS, Nvidia Parallel Thread Execution (PTX ; appelé NVPTX dans la documentation LLVM), PowerPC, AMD TeraScale, AMD Graphics Core Next (GCN), SPARC, z/Architecture (appelé SystemZ dans la documentation LLVM), x86, x86-64 et XCore. Certaines fonctionnalités ne sont pas disponibles sur certaines plateformes. La plupart des fonctionnalités sont présentes pour x86, x86-64, z/Architecture, ARM, et PowerPC. RISC-V est supporté à partir de la version 7. Dans le passé, LLVM a également supporté entièrement ou partiellement d’autres backends, notamment C backend, Cell SPU, mblaze (MicroBlaze), AMD R600, DEC/Compaq Alpha (Alpha AXP) et Nios2, mais ce matériel est pour la plupart obsolète, et le support et la maintenance de LLVM pour celui-ci ne pourraient pas être justifiés.
LLVM prend également en charge WebAssembly comme cible, ce qui permet aux programmes compilés de s’exécuter dans des environnements compatibles avec WebAssembly, tels que Google Chrome / Chromium, Firefox, Microsoft Edge, Apple Safari ou WAVM. Les compilateurs WebAssembly conformes à LLVM prennent généralement en charge la plupart des codes sources non modifiés écrits en C, C++, D, Rust, Nim, Kotlin et plusieurs autres langages.
Le sous-projet LLVM machine code (MC) est le cadre de LLVM pour traduire les instructions machine entre les formes textuelles et le code machine. Auparavant, LLVM s’appuyait sur l’assembleur du système, ou sur celui fourni par une chaîne d’outils, pour traduire l’assemblage en code machine. L’assembleur intégré de LLVM MC supporte la plupart des cibles LLVM, y compris x86, x86-64, ARM, et ARM64. Pour certaines cibles, notamment les différents jeux d’instructions MIPS, le support de l’assembleur intégré est utilisable mais encore au stade bêta.
LinkerEdit
Le sous-projet lld est une tentative de développement d’un linker intégré, indépendant de la plateforme, pour LLVM. lld vise à supprimer la dépendance à un linker tiers. En mai 2017, lld supporte ELF, PE/COFF, Mach-O et WebAssembly par ordre décroissant d’exhaustivité. lld est plus rapide que les deux saveurs de GNU ld.
À la différence des linkers GNU, lld a un support intégré pour l’optimisation du temps de liaison. Cela permet une génération de code plus rapide car elle contourne l’utilisation d’un plugin d’éditeur de liens, mais interdit en revanche l’interopérabilité avec les autres saveurs de LTO.
La bibliothèque standard C++Edit
Le projet LLVM comprend une implémentation de la bibliothèque standard C++ appelée libc++, sous double licence MIT et UIUC.
Depuis la v9.0.0, elle a été ré-licenciée sous la licence Apache 2.0 avec LLVM Exceptions.
PollyEdit
Elle met en œuvre une suite d’optimisations de cache-localité ainsi que l’auto-parallélisme et la vectorisation en utilisant un modèle polyédrique.
DébogueurEdit
Laquelle ?