LLVM | |
---|---|
Tip de | compilator |
Dezvoltator | Vikram Adwe [d] și Chris Lattner [d] |
Scris in | C++ [3] , C [4] și limbaj de asamblare [4] |
Sistem de operare | multiplatformă |
Prima editie | 24 octombrie 2003 [1] |
ultima versiune |
|
Licență | Licența deschisă a Universității din Illinois [d] [5]șilicența Apache 2.0[6] |
Site-ul web | llvm.org _ |
Fișiere media la Wikimedia Commons |
LLVM (fosta Low Level Virtual Machine [7] ) este un proiect de infrastructură software pentru crearea de compilatoare și utilități aferente . Este format dintr-un set de compilatoare din limbaje de nivel înalt (așa-numitele „frontend”), un sistem de optimizare, interpretare și compilare în codul mașinii. Infrastructura se bazează pe un sistem de codare a instrucțiunilor de mașină, independent de platformă, asemănător RISC ( LLVM IR bytecode ), care este un asamblator de nivel înalt cu care funcționează diferite transformări.
Scris în C++, oferă optimizări în etapele de compilare, legare și execuție. Inițial, compilatoarele pentru limbajele C și C++ au fost implementate în proiect folosind front-end-ul Clang , ulterior au apărut front-end-uri pentru multe limbi, inclusiv: ActionScript , Ada , C# [8] , Common Lisp , Crystal , CUDA , D , Delphi , Dylan, Fortran , Limbaj de programare G grafic, Halide , Haskell , Java (bytecode), JavaScript , Julia , Kotlin , Lua , Objective-C , OpenGL Shading Language , Ruby , Rust , Scala , Swift , Xojo .
LLVM poate produce cod nativ pentru o varietate de arhitecturi, inclusiv ARM , x86 , x86-64 , PowerPC , MIPS , SPARC , RISC-V și multe altele (inclusiv GPU -uri de la Nvidia și AMD ).
Unele proiecte au propriile lor compilatoare LLVM (de exemplu, versiunea LLVM a GCC), altele folosesc cadrul LLVM [9] , cum ar fi Glasgow Haskell Compiler .
Dezvoltarea a început în 2000 la Universitatea din Illinois . La mijlocul anilor 2010, LLVM a devenit larg răspândit în industrie: a fost folosit, printre altele, de Adobe , Apple și Google . În special, subsistemul OpenGL din Mac OS X 10.5 se bazează pe LLVM, iar iPhone SDK utilizează preprocesorul GCC (frontend) cu un backend LLVM. Apple și Google sunt unul dintre principalii sponsori ai proiectului, iar unul dintre principalii dezvoltatori, Chris Lattner, a lucrat la Apple timp de 11 ani (din 2017 - la Tesla Motors [10] , din 2020 - în dezvoltator de procesoare și microcontrolere bazate pe arhitectura RISC-V SiFive [11] ).
LLVM se bazează pe o reprezentare intermediară de cod ( Reprezentare intermediară, IR ), care poate fi transformată în timpul compilării, conectării și execuției. Din această reprezentare, codul mașină optimizat este generat pentru o serie de platforme, atât static, cât și dinamic ( compilare JIT ). LLVM 9.0.0 acceptă generarea de cod static pentru x86 , x86-64 , ARM , PowerPC , SPARC , MIPS , RISC-V , Qualcomm Hexagon , NVPTX, SystemZ, Xcore. Compilarea JIT (generarea codului de mașină în timpul execuției) este acceptată pentru arhitecturile x86, x86_64, PowerPC, MIPS, SystemZ și parțial ARM [12] .
LLVM este scris în C++ și a fost portat pe majoritatea sistemelor de tip Unix și Windows . Sistemul are o structură modulară, modulele sale individuale pot fi construite în diverse sisteme software, poate fi extins cu algoritmi de transformare suplimentari și generatoare de cod pentru noi platforme hardware.
LLVM include un wrapper API pentru OCaml .
LLVM acceptă următoarele platforme:
Sistem de operare | Arhitectură | Compilator |
---|---|---|
linux | x86 / AMD64 | GCC , Clang |
FreeBSD | x86 / AMD64 | GCC , Clang |
OpenBSD | x86 / AMD64 | GCC , Clang |
Mac OS X | PowerPC | GCC |
Mac OS 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 are suport parțial pentru următoarele platforme:
Sistem de operare | Arhitectură | Compilator |
---|---|---|
AIX | PowerPC | GCC |
linux | PowerPC | GCC |
Amiga OS | m68k , PowerPC | GCC |
Windows | x86 | MSVC |
Numerele întregi de bitness arbitrar | am bit adâncime |
|
| ||
Numere în virgulă mobilă | float , double , tipuri specifice platformei (de ex. x86_fp80 ) | |
valoare goală | gol |
Indicatori | tip de* | i32* - indicator către un întreg pe 32 de biți |
Matrice | [număr de elemente x tip] |
|
structurilor | { i32, i32, dublu } | |
Un vector este un tip special pentru simplificarea operațiunilor SIMD .
Vectorul este format din 2 n valori de tip primitiv - întreg sau virgulă mobilă. |
<număr de elemente x tip> | < 4 x float > - vector XMM |
Funcții |
|
Sistemul de tipuri acceptă suprapunerea/imbricarea, adică puteți utiliza matrice multidimensionale, matrice de structuri, pointeri către structuri și funcții etc.
Majoritatea instrucțiunilor din LLVM iau două argumente (operand) și returnează o valoare (codul cu trei adrese). Valorile sunt definite printr-un identificator text. Valorile locale sunt prefixate %cu , iar valorile globale sunt prefixate cu @. Valorile locale se mai numesc și registre, iar LLVM se mai numește și o mașină virtuală cu un număr infinit de registre. Exemplu:
%sum = adăugați i32 %n, 5 %diff = sub dublu %a, %b %z = adăugați <4 x float> %v1, %v2 ; adăugarea elementară %cond = icmp eq %x, %y ; Comparație între numere întregi. Rezultatul este de tip i1. %success = apel i32 @puts(i8* %str)Tipul operanzilor este întotdeauna specificat explicit și determină fără ambiguitate tipul rezultatului. Operanzii instrucțiunilor aritmetice trebuie să fie de același tip, dar instrucțiunile în sine sunt „supraîncărcate” pentru orice tip numeric și vector.
LLVM acceptă un set complet de operații aritmetice, operații logice pe biți și operații de deplasare, precum și instrucțiuni speciale pentru lucrul cu vectori.
LLVM IR este puternic tipizat, deci există operații de turnare care sunt codificate explicit cu instrucțiuni speciale. Un set de 9 instrucțiuni acoperă toate variantele posibile între diferite tipuri numerice: întreg și virgulă mobilă, cu semn și fără semn, lungime diferită de biți etc. În plus, există instrucțiuni pentru conversia între numere întregi și pointeri, precum și o instrucțiune universală pentru tip turnare bitcast(responsabilul pentru corectitudinea unor astfel de transformări revine programatorului).
Pe lângă valorile înregistrate, LLVM are și gestionarea memoriei. Valorile din memorie sunt adresate prin pointeri tastate . Puteți accesa memoria utilizând două instrucțiuni: loadși store. De exemplu:
%x = încărcare i32* %x.ptr ; încărcați valoarea tipului i32 la pointerul %x.ptr %tmp = adaugă i32 %x, 5 ; adauga 5 stocați i32 %tmp, i32* %x.ptr ; și pune înapoiInstrucțiunea malloceste tradusă într-un apel al funcției de sistem cu același nume și alocă memorie pe heap , returnând o valoare - un pointer de un anumit tip. Vine cu instructiuni free.
%struct.ptr = malloc { dublu, dublu } %string = malloc i8, i32 %lungime %array = malloc [16 x i32] gratuit i8* %stringInstrucțiunea allocaalocă memorie pe stivă.
%x.ptr = alloca double ; %x.ptr este de tip double* %array = alloca float, i32 8 ; %array este de tip float*, nu [8 x float]!Memoria alocată allocaeste eliberată automat când funcția se iese utilizând instrucțiunile retsau unwind.
Pentru a calcula adresele elementelor de matrice, structuri etc. cu tastarea corectă, se folosește instrucțiunea getelementptr.
%array = alloca i32, i32 %size %ptr = getelementptr i32* %array, i32 %index ; valoarea de tip i32*getelementptrcalculează doar adresa, dar nu accesează memoria. Instrucțiunea acceptă un număr arbitrar de indici și poate dereferința structuri ale oricărei imbricare.
Există, de asemenea, instrucțiuni extractvalueși insertvalue. Ele diferă de getelementptrfaptul că nu iau un pointer către un tip de date agregate (matrice sau structură), ci valoarea acestui tip în sine. extractvaluereturnează valoarea corespunzătoare a subelementului, dar insertvaluegenerează o nouă valoare de tip agregat.
%n = extrage valoare { i32, [4 x i8*] } %s, 0 %tmp = adăugați i32 %n, 1 %s.1 = inserare valoare { i32, [4 x i8*] } %s, i32 %tmp, 0Software gratuit și open source | |
---|---|
Lucrul principal |
|
Comunitate |
|
Organizații | |
Licențe | |
Probleme | |
Alte |
|
|