LLVM

LLVM
Típusú fordítóprogram
Fejlesztő Vikram Adwe [d] és Chris Lattner [d]
Beírva C++ [3] , C [4] és assembly nyelv [4]
Operációs rendszer platformközi
Első kiadás 2003. október 24. [1]
legújabb verzió
Engedély University of Illinois nyílt licenc [d] [5]ésApache License 2.0[6]
Weboldal llvm.org
 Médiafájlok a Wikimedia Commons oldalon

Az LLVM (korábban Low Level Virtual Machine [7] ) egy szoftver infrastruktúra projekt fordítók és kapcsolódó segédprogramok létrehozására . Magas szintű nyelvekből származó fordítókészletből áll (az úgynevezett "frontendek"), egy rendszer az optimalizáláshoz, az értelmezéshez és a gépi kódba fordításhoz. Az infrastruktúra egy RISC -szerű platformfüggetlen gépi utasítás kódoló rendszerre ( LLVM IR bytecode ) épül, amely egy magas szintű assembler, amellyel különféle átalakítások működnek.

A C++ nyelven írva optimalizálást biztosít a fordítás, az összekapcsolás és a végrehajtás szakaszában. Kezdetben a C és C++ nyelvekhez való fordítóprogramokat a Clang front-end segítségével valósították meg a projektben , később számos nyelvhez jelentek meg a front-endek, többek között: ActionScript , Ada , C # [8] , Common Lisp , Crystal , CUDA , D , Delphi , Dylan, Fortran , Grafikus G programozási nyelv, Halide , Haskell , Java (bytecode), JavaScript , Julia , Kotlin , Lua , Objective-C , OpenGL árnyékoló nyelv , Ruby , Rust , Scala , Swift , Xojo .

Az LLVM különféle architektúrákhoz képes natív kódot készíteni, beleértve az ARM , x86 , x86-64 , PowerPC , MIPS , SPARC , RISC-V és egyéb architektúrákat (beleértve az Nvidia és az AMD GPU -it is ).

Egyes projektek saját LLVM fordítókkal rendelkeznek (pl. a GCC LLVM verziója), mások az LLVM keretrendszert [9] használják , mint például a Glasgow Haskell Compiler .

A fejlesztés 2000 - ben kezdődött az Illinoisi Egyetemen . A 2010-es évek közepére az LLVM széles körben elterjedt az iparágban: használta többek között az Adobe , az Apple és a Google . Különösen a Mac OS X 10.5 OpenGL alrendszere LLVM-en alapul, az iPhone SDK pedig a GCC előfeldolgozót (frontend) használja LLVM háttérrendszerrel. Az Apple és a Google a projekt egyik fő támogatója, az egyik fő fejlesztő, Chris Lattner pedig 11 éve dolgozik az Apple -nél (2017-től - a Tesla Motorsnál [10] , 2020-tól - a processzorok, ill. a RISC-V SiFive architektúrán alapuló mikrokontrollerek [11] ).

Jellemzők

Az LLVM egy köztes kódreprezentáción ( Intermediate Representation, IR ) alapul, amely fordítás, összekapcsolás és végrehajtás során átalakítható. Ebből az ábrázolásból optimalizált gépi kód generálódik számos platformhoz, mind statikusan, mind dinamikusan ( JIT-összeállítás ). Az LLVM 9.0.0 támogatja az x86 , x86-64 , ARM , PowerPC , SPARC , MIPS , RISC-V , Qualcomm Hexagon , NVPTX, SystemZ, Xcore statikus kódgenerálást. A JIT-fordítás (gépi kódgenerálás futás közben) támogatott x86, x86_64, PowerPC, MIPS, SystemZ és részben ARM [12] architektúrákon .

Az LLVM C++ nyelven íródott, és a legtöbb Unix-szerű rendszerre és Windowsra portolták . A rendszer moduláris felépítésű, egyes moduljai különféle szoftverrendszerekbe építhetők, további transzformációs algoritmusokkal, kódgenerátorokkal bővíthető új hardverplatformokhoz.

Az LLVM tartalmaz egy API -burkolót az OCaml számára .

Platformok

Az LLVM a következő platformokat támogatja:

Operációs rendszer Építészet Fordítóprogram
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

Az LLVM részben támogatja a következő platformokat:

Operációs rendszer Építészet Fordítóprogram
AIX PowerPC GCC
Linux PowerPC GCC
Amiga OS m68k , PowerPC GCC
ablakok x86 MSVC

Adattípusok

Egyszerű típusok

Tetszőleges bitességű egész számok mélységet haraptam
  • i1 - logikai érték - 0 vagy 1
  • i32 - 32 bites egész szám
  • i17
  • i256
  • A nagyon nagy bittípusok natív kódgenerálása nem támogatott. De a köztes képviseletre nincsenek korlátozások.
  • A számokat a kettő komplementerében ábrázoltnak tekintjük. Típusszinten nincs különbség az előjeles és előjel nélküli egészek között: ahol ez számít, ott más utasítások kezelik őket.
Lebegőpontos számok float , double , platformspecifikus típusok (pl. x86_fp80 )
üres érték üres

Származtatott típusok

Mutatók típusú* i32* - mutató 32 bites egész számra
Tömbök [elemek száma x típus]
  • [10 x i32]
  • [8 x dupla]
szerkezetek { i32, i32, dupla }
A vektor egy speciális típus a SIMD műveletek egyszerűsítésére.

A vektor 2 n primitív típusú értékből áll - egész vagy lebegőpontos.

<elemek száma x típus> < 4 x float > - XMM vektor
Funkciók
  • i32 (i32, i32)
  • lebegés ({ float, float }, { float, float })

A típusrendszer támogatja a szuperpozíciót/beágyazást, azaz használhatunk többdimenziós tömböket, struktúratömböket, struktúrákra és függvényekre mutató mutatókat stb.

Műveletek

Az LLVM-ben a legtöbb utasítás két argumentumot (operandust) vesz fel, és egy értéket ad vissza (három címkód). Az értékeket egy szöveges azonosító határozza meg. A helyi értékek előtagjaként %szerepel, a globális értékek előtt pedig @. A helyi értékeket regisztereknek is nevezik, az LLVM-et pedig virtuális gépnek is nevezik végtelen számú regiszterrel. Példa:

%összeg = összeadjuk i32 %n, 5 %diff = aldupla %a, %b %z = add <4 x float> %v1, %v2 ; elemenkénti összeadás %cond = icmp eq %x, %y ; Egész számok összehasonlítása. Az eredmény i1 típusú. %siker = i32 hívása @puts(i8* %str)

Az operandusok típusa mindig kifejezetten meg van adva, és egyértelműen meghatározza az eredmény típusát. Az aritmetikai utasítások operandusainak azonos típusúaknak kell lenniük, de maguk az utasítások „túlterheltek” bármilyen numerikus típus és vektor esetén.

Az LLVM az aritmetikai műveletek, a bitenkénti logikai műveletek és az eltolási műveletek teljes készletét támogatja , valamint speciális utasításokat a vektorokkal való munkához.

Az LLVM IR erősen típusos, ezért vannak olyan cast műveletek, amelyek kifejezetten speciális utasításokkal vannak kódolva. A 9 utasításból álló készlet lefedi a különböző numerikus típusok közötti összes lehetséges castot: egész és lebegőpontos, előjeles és előjel nélküli, eltérő bithosszúság stb. Ezen kívül vannak utasítások az egész számok és mutatók közötti konvertáláshoz, valamint egy univerzális utasítás a típushoz öntés bitcast(az ilyen átalakítások helyességéért a programozó a felelős).

Memória

A regiszterértékeken kívül az LLVM memóriakezeléssel is rendelkezik. A memóriában lévő értékeket begépelt mutatók címzik . A memóriát két utasítással érheti el: loadés store. Például:

%x = i32 terhelés* %x.ptr ; töltse be az i32 típusú értéket a %x.ptr mutatóba %tmp = i32 hozzáadása %x, 5 ; adjunk hozzá 5-öt store i32 %tmp, i32* %x.ptr ; és tedd vissza

Az utasítás mallocaz azonos nevű rendszerfüggvény hívására fordítódik, és memóriát foglal le a kupacban , visszaadva egy értéket - egy bizonyos típusú mutatót . Utasításokkal jár free.

%struct.ptr = malloc { double, double } %string = malloc i8, i32 %hossz %array = malloc [16 x i32] ingyenes i8* %string

Az utasítás allocalefoglalja a memóriát a veremben.

%x.ptr = alloca double ; A %x.ptr dupla* típusú %array = alloca float, i32 8 ; A %tömb float* típusú, nem [8 x float]!

A lefoglalt memória allocaautomatikusan felszabadul, amikor a funkció a retvagy utasításokkal kilép unwind.

Műveletek mutatókkal

A tömbök, struktúrák stb. elemeinek címének kiszámításához megfelelő gépeléssel a következő utasítást kell használni: getelementptr.

%array = alloca i32, i32 %size %ptr = getelementptr i32* %tömb, i32 %index ; i32* típusú érték

getelementptrcsak a címet számítja ki, de nem fér hozzá a memóriához. Az utasítás tetszőleges számú indexet fogad el, és bármilyen beágyazás struktúráira hivatkozhat.

Vannak még utasítások extractvalueés insertvalue. Abban különböznek getelementptr, hogy nem egy összesített adattípusra (tömbre vagy struktúrára) visznek mutatót, hanem magának ennek a típusnak az értékét. extractvalueaz alelem megfelelő értékét adja vissza, de insertvalueaz összesített típusú új értéket generálja.

%n = kivonatérték { i32, [4 x i8*] } %s, 0 %tmp = add i32 %n, 1 %s.1 = beillesztési érték { i32, [4 x i8*] } %s, i32 %tmp, 0

Jegyzetek

  1. Lattner K. Végre elérhető az LLVM 1.0 kiadás!
  2. LLVM 15.0.4 Megjelent – ​​2022.
  3. Az llvm nyílt forráskódú projekt az Open Hubon: Nyelvek oldala - 2006.
  4. 1 2 Az llvm nyílt forráskódú projekt az Open Hubon: Nyelvek  oldal
  5. Licenc  _
  6. http://releases.llvm.org/9.0.0/LICENSE.TXT – 2019.
  7. LLVMdev: Az LLVM neve archiválva 2016. november 3-án a Wayback Machine -nél , Chris Lattner (Apple), 2011-12-21 Az "LLVM" hivatalosan már nem egy mozaikszó. Az egykor kibővített rövidítés is zavaró volt, és szinte az első naptól kezdve alkalmatlan volt.”
  8. LLILC . Letöltve: 2015. április 14. Az eredetiből archiválva : 2019. május 19.
  9. LLVM-mel épített  projektek . llvm. Letöltve: 2018. május 24. Az eredetiből archiválva : 2018. május 24.
  10. Üdvözöljük Chris Lattner | Tesla . Letöltve: 2017. január 11. Az eredetiből archiválva : 2017. január 11..
  11. Az LLVM alapítója csatlakozik a SiFive-hoz . Letöltve: 2020. január 28. Az eredetiből archiválva : 2020. január 28.
  12. Az LLVM Target-Independent Code Generator archiválva 2021. május 1-én a Wayback Machine Target Feature Matrix szekcióban 

Irodalom

Linkek