LLVM
| LLVM | |
|---|---|
| Tipo di | compilatore |
| Sviluppatore | Vikram Adwe [d] e Chris Lattner [d] |
| Scritto in | C++ [3] , C [4] e linguaggio assembly [4] |
| Sistema operativo | multipiattaforma |
| Prima edizione | 24 ottobre 2003 [1] |
| ultima versione |
|
| Licenza | Licenza aperta dell'Università dell'Illinois [d] [5]eLicenza Apache 2.0[6] |
| Sito web | llvm.org _ |
| File multimediali su Wikimedia Commons | |
LLVM (precedentemente Low Level Virtual Machine [7] ) è un progetto di infrastruttura software per la creazione di compilatori e utilità correlate . Consiste in un insieme di compilatori da linguaggi di alto livello (i cosiddetti "frontend"), un sistema per l'ottimizzazione, l'interpretazione e la compilazione in codice macchina. L'infrastruttura si basa su un sistema di codifica delle istruzioni macchina indipendente dalla piattaforma simile a RISC ( LLVM IR bytecode ), che è un assemblatore di alto livello con cui funzionano varie trasformazioni.
Scritto in C++, fornisce ottimizzazioni nelle fasi di compilazione, collegamento ed esecuzione. Inizialmente, i compilatori per i linguaggi C e C++ sono stati implementati nel progetto utilizzando il front-end Clang , successivamente sono apparsi front-end per molti linguaggi, tra cui: ActionScript , Ada , C# [8] , Common Lisp , Crystal , CUDA , D , Delphi , Dylan, Fortran , Graphical G Programming Language, Halide , Haskell , Java (bytecode), JavaScript , Julia , Kotlin , Lua , Objective-C , OpenGL Shading Language , Ruby , Rust , Scala , Swift , Xojo .
LLVM può produrre codice nativo per una varietà di architetture, tra cui ARM , x86 , x86-64 , PowerPC , MIPS , SPARC , RISC-V e altre (comprese GPU di Nvidia e AMD ).
Alcuni progetti hanno i propri compilatori LLVM (ad esempio la versione LLVM di GCC), altri usano il framework LLVM [9] , come Glasgow Haskell Compiler .
Lo sviluppo è iniziato nel 2000 presso l' Università dell'Illinois . Entro la metà degli anni 2010, LLVM si era diffuso nel settore: veniva utilizzato, tra gli altri, da Adobe , Apple e Google . In particolare, il sottosistema OpenGL in Mac OS X 10.5 è basato su LLVM e iPhone SDK utilizza il preprocessore GCC (frontend) con un backend LLVM. Apple e Google sono uno dei principali sponsor del progetto, e uno dei principali sviluppatori, Chris Lattner, lavora in Apple da 11 anni (dal 2017 - presso Tesla Motors [10] , dal 2020 - nello sviluppo di processori e microcontrollori basati sull'architettura RISC-V SiFive [11] ).
Caratteristiche
LLVM si basa su una rappresentazione di codice intermedia ( Rappresentazione intermedia, IR ), che può essere trasformata durante la compilazione, il collegamento e l'esecuzione. Da questa rappresentazione, viene generato un codice macchina ottimizzato per una gamma di piattaforme, sia staticamente che dinamicamente ( compilazione JIT ). LLVM 9.0.0 supporta la generazione di codice statico per x86 , x86-64 , ARM , PowerPC , SPARC , MIPS , RISC-V , Qualcomm Hexagon , NVPTX, SystemZ, Xcore. La compilazione JIT (generazione di codice macchina in fase di esecuzione) è supportata per le architetture x86, x86_64, PowerPC, MIPS, SystemZ e parzialmente ARM [12] .
LLVM è scritto in C++ ed è stato portato sulla maggior parte dei sistemi simili a Unix e Windows . Il sistema ha una struttura modulare, i suoi singoli moduli possono essere integrati in vari sistemi software, può essere ampliato con ulteriori algoritmi di trasformazione e generatori di codice per nuove piattaforme hardware.
LLVM include un wrapper API per OCaml .
Piattaforme
LLVM supporta le seguenti piattaforme:
| Sistema operativo | Architettura | compilatore |
|---|---|---|
| linux | x86 / AMD64 | GCC , Clang |
| FreeBSD | x86 / AMD64 | GCC , Clang |
| OpenBSD | x86 / AMD64 | GCC , Clang |
| MacOS X | PowerPC | GCC |
| MacOS X | x86 / AMD64 | GCC , Clang |
| Solaris | UltraSPARC | GCC |
| Cygwin / Win32 | x86 | GCC 3.4.X, Binutils 2.15 |
| MinGW / Win32 | x86 | GCC 3.4.X, Binutils 2.15 |
LLVM ha un supporto parziale per le seguenti piattaforme:
| Sistema operativo | Architettura | compilatore |
|---|---|---|
| AIX | PowerPC | GCC |
| linux | PowerPC | GCC |
| Sistema operativo Amiga | m68k , PowerPC | GCC |
| finestre | x86 | MSVC |
Tipi di dati
Tipi semplici
| Interi di bit arbitrario | ho bit di profondità |
|
| ||
| Numeri in virgola mobile | float , double , tipi specifici della piattaforma (ad es. x86_fp80 ) | |
| valore vuoto | vuoto | |
Tipi derivati
| Puntatori | tipo di* | i32* - puntatore a numero intero a 32 bit |
| Matrici | [numero di elementi x tipo] |
|
| strutture | { i32, i32, doppio } | |
| Un vettore è un tipo speciale per semplificare le operazioni SIMD .
Il vettore è costituito da 2 n valori di tipo primitivo: intero o virgola mobile. |
<numero di elementi x tipo> | < 4 x float > - vettore XMM |
| Funzioni |
|
Il sistema di tipi supporta la sovrapposizione/nidificazione, ovvero è possibile utilizzare array multidimensionali, array di strutture, puntatori a strutture e funzioni, ecc.
Operazioni
La maggior parte delle istruzioni in LLVM accetta due argomenti (operando) e restituisce un valore (tre codici di indirizzo). I valori sono definiti da un identificatore di testo. I valori locali sono preceduti %da e i valori globali sono preceduti da @. I valori locali sono anche chiamati registri e LLVM è anche chiamato macchina virtuale con un numero infinito di registri. Esempio:
%somma = aggiungi i32 %n, 5 %diff = subdoppio %a, %b %z = aggiungi <4 x float> %v1, %v2 ; addizione per elementi %cond = icmp eq %x, %y ; Confronto intero. Il risultato è di tipo i1. %successo = chiama i32 @puts(i8* %str)
Il tipo degli operandi è sempre specificato in modo esplicito e determina inequivocabilmente il tipo del risultato. Gli operandi delle istruzioni aritmetiche devono essere dello stesso tipo, ma le istruzioni stesse sono "sovraccariche" per qualsiasi tipo numerico e vettore.
LLVM supporta un set completo di operazioni aritmetiche, operazioni logiche bit per bit e operazioni di spostamento, nonché istruzioni speciali per lavorare con i vettori.
LLVM IR è fortemente tipizzato, quindi ci sono operazioni di cast che sono codificate in modo esplicito con istruzioni speciali. Un set di 9 istruzioni copre tutti i possibili cast tra diversi tipi numerici: intero e virgola mobile, con segno e senza segno, lunghezza di bit diversa, ecc. Inoltre, ci sono istruzioni per la conversione tra numeri interi e puntatori, nonché un'istruzione universale per il tipo il casting bitcast(responsabile della correttezza di tali trasformazioni spetta al programmatore).
Memoria
Oltre ai valori di registro, LLVM ha anche la gestione della memoria. I valori in memoria sono indirizzati da puntatori digitati . È possibile accedere alla memoria utilizzando due istruzioni: loade store. Per esempio:
%x = carica i32* %x.ptr ; caricare il valore del tipo i32 al puntatore %x.ptr %tmp = aggiungi i32 %x, 5 ; aggiungi 5 memorizzare i32 %tmp, i32* %x.ptr ; e rimetti
L'istruzione mallocviene tradotta in una chiamata della funzione di sistema con lo stesso nome e alloca memoria sull'heap , restituendo un valore, un puntatore di un certo tipo. Viene fornito con le istruzioni free.
%struct.ptr = malloc { double, double }
%stringa = malloc i8, i32 %lunghezza
%array = malloc [16 x i32]
libero i8* %stringa
L'istruzione allocaalloca memoria nello stack.
%x.ptr = allocazione doppia; %x.ptr è di tipo double* %array = alloca float, i32 8 ; %array è di tipo float*, non [8 x float]!
La memoria allocata allocaviene liberata automaticamente quando la funzione esce utilizzando le istruzioni reto unwind.
Operazioni con i puntatori
Per calcolare gli indirizzi di elementi di array, strutture, ecc. con la digitazione corretta, viene utilizzata l'istruzione getelementptr.
%array = alloca i32, i32 %dimensione %ptr = getelementptr i32* %array, i32 %indice ; valore di tipo i32*
getelementptrcalcola solo l'indirizzo, ma non accede alla memoria. L'istruzione accetta un numero arbitrario di indici e può dereferenziare strutture di qualsiasi annidamento.
Ci sono anche istruzioni extractvaluee insertvalue. Differiscono dal getelementptrfatto che non prendono un puntatore a un tipo di dati aggregato (array o struttura), ma il valore di questo tipo stesso. extractvaluerestituisce il valore corrispondente del sottoelemento, ma insertvaluegenera un nuovo valore di tipo aggregato.
%n = valore di estrazione { i32, [4 x i8*] } %s, 0
%tmp = aggiungi i32 %n, 1
%s.1 = valore di inserimento { i32, [4 x i8*] } %s, i32 %tmp, 0
Note
- ↑ Lattner K. La versione LLVM 1.0 è finalmente disponibile!
- ^ Rilasciato LLVM 15.0.4 - 2022.
- ↑ Il progetto llvm Open Source su Open Hub: Pagina delle lingue - 2006.
- ↑ 1 2 Il progetto llvm Open Source su Open Hub: pagina delle lingue
- ↑ Licenza _
- ^ http://releases.llvm.org/9.0.0/LICENSE.TXT - 2019.
- ^ LLVMdev: Il nome di LLVM Archiviato il 3 novembre 2016 su Wayback Machine , Chris Lattner (Apple), 21-12-2011 "'LLVM' ufficialmente non è più un acronimo. Anche l'acronimo che era stato ampliato una volta era confuso e inappropriato quasi dal primo giorno".
- ^ LLILC . Estratto il 14 aprile 2015 . Archiviato dall'originale il 19 maggio 2019.
- ↑ Progetti realizzati con LLVM . lvm. Estratto il 24 maggio 2018 . Archiviato dall'originale il 24 maggio 2018.
- ↑ Benvenuto Chris Lattner | Tesla . Estratto l'11 gennaio 2017 . Archiviato dall'originale l'11 gennaio 2017.
- ↑ Il fondatore di LLVM si unisce a SiFive . Estratto il 28 gennaio 2020 . Archiviato dall'originale il 28 gennaio 2020.
- ^ Il generatore di codice indipendente dal target LLVM Archiviato il 1 maggio 2021 nella sezione Wayback Machine Target Feature Matrix
Letteratura
- Andrei Borovsky. LLVM: Generatore di codice rapido // Formato Linux . - Problema. 2010 , n. 2 (128) . -S.76-79 . _
- Amy Brown e Greg Wilson (a cura di). Capitolo 11. LLVM (Chris Lattner) // L'architettura delle applicazioni open source . - 2011. - P. 155-170. — 432 pag. - ISBN 978-1-257-63801-7 . ( traduzione )
- Arpan sen. Creazione di un compilatore funzionante utilizzando il framework LLVM. Parte 1 . Sviluppatore IBMWorks (12/11/2012). Estratto il 15 maggio 2015 ,parte 2
- Chris Lattner. Il design di LLVM . Dott. Diario di Dobb (29 maggio 2012). Estratto: 15 maggio 2015.
- Giovanni Siracusa. Mac OS X 10.6 Snow Leopard: la recensione di Ars Technica → LLVM e Clang . Ars Technica (1 settembre 2009). Estratto: 15 maggio 2015.
Collegamenti
- llvm.org - sito ufficiale di LLVM
- Codice SAFE
- libJIT Allocatore di registri a scansione lineare