LLVM | |
---|---|
Type | compiler |
Udvikler | Vikram Adwe [d] og Chris Lattner [d] |
Skrevet i | C++ [3] , C [4] og assemblersprog [4] |
Operativ system | på tværs af platforme |
Første udgave | 24. oktober 2003 [1] |
nyeste version |
|
Licens | University of Illinois åben licens [d] [5]ogApache License 2.0[6] |
Internet side | llvm.org _ |
Mediefiler på Wikimedia Commons |
LLVM (tidligere Low Level Virtual Machine [7] ) er et software-infrastrukturprojekt til at skabe compilere og relaterede hjælpeprogrammer . Det består af et sæt kompilatorer fra sprog på højt niveau (de såkaldte "frontends"), et system til optimering, fortolkning og kompilering til maskinkode. Infrastrukturen er baseret på et RISC -lignende platform-uafhængigt maskininstruktionskodningssystem ( LLVM IR bytecode ), som er en højniveau assembler, som forskellige transformationer fungerer med.
Skrevet i C++ giver det optimeringer på stadierne af kompilering, linkning og udførelse. Oprindeligt blev compilere til C- og C++- sprog implementeret i projektet ved hjælp af Clang -frontend , senere dukkede front-ends op for mange sprog, herunder: 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 kan producere indbygget kode til en række forskellige arkitekturer, herunder ARM , x86 , x86-64 , PowerPC , MIPS , SPARC , RISC-V og mere (inklusive GPU'er fra Nvidia og AMD ).
Nogle projekter har deres egne LLVM-kompilere (f.eks. LLVM-versionen af GCC), andre bruger LLVM-rammeværket [9] , såsom Glasgow Haskell Compiler .
Udvikling startede i 2000 ved University of Illinois . I midten af 2010'erne var LLVM blevet udbredt i branchen: det blev blandt andet brugt af Adobe , Apple og Google . Især OpenGL- undersystemet i Mac OS X 10.5 er baseret på LLVM, og iPhone SDK bruger GCC -forprocessoren (frontend) med en LLVM-backend. Apple og Google er en af hovedsponsorerne for projektet, og en af hovedudviklerne, Chris Lattner, har arbejdet hos Apple i 11 år (siden 2017 - hos Tesla Motors [10] , siden 2020 - i udvikleren af processorer og mikrocontrollere baseret på RISC-V- arkitekturen SiFive [11] ).
LLVM er baseret på en mellemkoderepræsentation ( Intermediate Representation, IR ), som kan transformeres under kompilering, sammenkædning og eksekvering. Ud fra denne repræsentation genereres optimeret maskinkode til en række platforme, både statisk og dynamisk ( JIT-kompilering ). LLVM 9.0.0 understøtter statisk kodegenerering til x86 , x86-64 , ARM , PowerPC , SPARC , MIPS , RISC-V , Qualcomm Hexagon , NVPTX, SystemZ, Xcore. JIT-kompilering (generering af maskinkode ved kørsel) understøttes for x86, x86_64, PowerPC, MIPS, SystemZ og delvist ARM [12] arkitekturer .
LLVM er skrevet i C++ og er blevet overført til de fleste Unix-lignende systemer og Windows . Systemet har en modulær opbygning, dets individuelle moduler kan indbygges i forskellige softwaresystemer, det kan udvides med yderligere transformationsalgoritmer og kodegeneratorer til nye hardwareplatforme.
LLVM inkluderer en API -indpakning til OCaml .
LLVM understøtter følgende platforme:
Operativ system | Arkitektur | Kompiler |
---|---|---|
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 har delvis understøttelse af følgende platforme:
Operativ system | Arkitektur | Kompiler |
---|---|---|
AIX | PowerPC | GCC |
linux | PowerPC | GCC |
Amiga OS | m68k , PowerPC | GCC |
Windows | x86 | MSVC |
Heltal af vilkårlig bithed | jeg lidt dybde |
|
| ||
Flydende kommatal | float , double , platformspecifikke typer (f.eks. x86_fp80 ) | |
tom værdi | ugyldig |
Pointer | type* | i32* - pointer til 32-bit heltal |
Arrays | [antal elementer x type] |
|
strukturer | { i32, i32, dobbelt } | |
En vektor er en speciel type til at forenkle SIMD - operationer.
Vektoren består af 2 n værdier af en primitiv type - heltal eller flydende komma. |
<antal elementer x type> | < 4 x float > - XMM vektor |
Funktioner |
|
Typesystemet understøtter superposition/nesting, dvs. du kan bruge multidimensionelle arrays, arrays af strukturer, pointere til strukturer og funktioner osv.
De fleste instruktioner i LLVM tager to argumenter (operand) og returnerer én værdi (tre adressekoder). Værdier er defineret af en tekstidentifikator. Lokale værdier er præfiks %med , og globale værdier er præfiks med @. Lokale værdier kaldes også registre, og LLVM kaldes også en virtuel maskine med et uendeligt antal registre. Eksempel:
%sum = tilføj i32 %n, 5 %diff = subdobbelt %a, %b %z = add <4 x float> %v1, %v2 ; elementvis tilføjelse %cond = icmp eq %x, %y; Heltals sammenligning. Resultatet er af type i1. %success = kald i32 @puts(i8* %str)Typen af operanderne er altid specificeret eksplicit og entydigt bestemmer typen af resultatet. Aritmetiske instruktioners operander skal være af samme type, men selve instruktionerne er "overbelastet" for alle numeriske typer og vektorer.
LLVM understøtter et komplet sæt af aritmetiske operationer, bitvise logiske operationer og shift-operationer samt specielle instruktioner til at arbejde med vektorer.
LLVM IR er stærkt skrevet, så der er cast-operationer, der er eksplicit kodet med specielle instruktioner. Et sæt på 9 instruktioner dækker over alle mulige kast mellem forskellige numeriske typer: heltal og flydende komma, fortegn og uden fortegn, forskellig bitlængde osv. Derudover er der instruktioner til konvertering mellem heltal og pointere, samt en universel instruktion for type casting bitcast(ansvarlig for rigtigheden af sådanne transformationer ligger hos programmøren).
Udover registerværdier har LLVM også hukommelseshåndtering. Værdier i hukommelsen adresseres af indtastede pointere . Du kan få adgang til hukommelsen ved at bruge to instruktioner: loadog store. For eksempel:
%x = load i32* %x.ptr ; indlæs i32 type værdi ved %x.ptr pointer %tmp = tilføj i32 %x, 5 ; tilføje 5 gem i32 %tmp, i32* %x.ptr ; og læg tilbageInstruktionen mallocoversættes til et opkald af systemfunktionen af samme navn og tildeler hukommelse på heapen , hvilket returnerer en værdi - en pointer af en bestemt type. Den kommer med instruktioner free.
%struct.ptr = malloc { dobbelt, dobbelt } %streng = malloc i8, i32 %længde %array = malloc [16 x i32] gratis i8* %strengInstruktionen allocatildeler hukommelse på stakken.
%x.ptr = alloca double ; %x.ptr er af typen double* %array = alloca float, i32 8 ; %array er af typen float*, ikke [8 x float]!Den tildelte hukommelse allocafrigøres automatisk, når funktionen afsluttes ved hjælp af instruktionerne reteller unwind.
For at beregne adresserne på elementer af arrays, strukturer osv. med den korrekte indtastning, bruges instruktionen getelementptr.
%array = alloca i32, i32 %størrelse %ptr = getelementptr i32* %array, i32 %index ; værdi af type i32*getelementptrberegner kun adressen, men får ikke adgang til hukommelsen. Instruktionen accepterer et vilkårligt antal indekser og kan afvige fra strukturer for enhver indlejring.
Der er også instruktioner extractvalueog insertvalue. De adskiller sig fra getelementptrdet faktum, at de ikke tager en pointer til en samlet datatype (array eller struktur), men selve værdien af denne type. extractvaluereturnerer den tilsvarende værdi af underelementet, men insertvaluegenererer en ny værdi af den samlede type.
%n = udtræksværdi { i32, [4 x i8*] } %s, 0 %tmp = tilføj i32 %n, 1 %s.1 = indsæt værdi { i32, [4 x i8*] } %s, i32 %tmp, 0Gratis og open source software | |
---|---|
Det vigtigste |
|
Fællesskab |
|
Organisationer | |
Licenser | |
Problemer | |
Andet |
|
|