LLVM

LLVM hat sich zu einem Dachprojekt entwickelt, das mehrere Komponenten enthält.

FrontendsBearbeiten

LLVM wurde ursprünglich als Ersatz für den bestehenden Codegenerator im GCC-Stack geschrieben, und viele der GCC-Frontends wurden so modifiziert, dass sie mit ihm zusammenarbeiten können, was zu der inzwischen eingestellten LLVM-GCC-Suite führte. Die Änderungen beinhalten im Allgemeinen einen GIMPLE-zu-LLVM-IR-Schritt, so dass LLVM-Optimierer und Codegen anstelle des GCC-GIMPLE-Systems verwendet werden können. Apple war ein bedeutender Nutzer von LLVM-GCC durch Xcode 4.x (2013). Diese Verwendung des GCC-Frontends wurde meist als vorübergehende Maßnahme betrachtet, ist aber mit dem Aufkommen von Clang und den Vorteilen von LLVM und der modernen und modularen Codebasis von Clang (sowie der Kompiliergeschwindigkeit) weitgehend obsolet.

LLVM unterstützt derzeit die Kompilierung von Ada, C, C++, D, Delphi, Fortran, Haskell, Julia, Objective-C, Rust und Swift unter Verwendung verschiedener Frontends.

Das weit verbreitete Interesse an LLVM hat zu mehreren Bemühungen geführt, neue Frontends für eine Vielzahl von Sprachen zu entwickeln. Die größte Aufmerksamkeit hat Clang erhalten, ein neuer Compiler, der C, C++ und Objective-C unterstützt. Clang wird in erster Linie von Apple unterstützt und soll den C/Objective-C-Compiler im GCC-System durch ein System ersetzen, das sich leichter in integrierte Entwicklungsumgebungen (IDEs) integrieren lässt und eine breitere Unterstützung für Multithreading bietet. Unterstützung für OpenMP-Direktiven ist in Clang seit Version 3.8 enthalten.

Der Utrecht Haskell Compiler kann Code für LLVM generieren. Obwohl sich der Generator noch in einem frühen Stadium der Entwicklung befindet, ist er in vielen Fällen effizienter als der C-Code-Generator. Es gibt ein Glasgow Haskell Compiler (GHC) Backend, das LLVM verwendet und eine 30%ige Beschleunigung des kompilierten Codes im Vergleich zur Kompilierung von nativem Code über GHC oder zur Generierung von C-Code mit anschließender Kompilierung erreicht, wobei nur eine der vielen vom GHC implementierten Optimierungstechniken fehlt.

Viele andere Komponenten befinden sich in verschiedenen Stadien der Entwicklung, einschließlich, aber nicht beschränkt auf, den Rust-Compiler, ein Java-Bytecode-Frontend, ein Common Intermediate Language (CIL)-Frontend, die MacRuby-Implementierung von Ruby 1.9, verschiedene Frontends für Standard ML und ein neuer Graph Coloring Register Allocator.

Intermediate representationEdit

LLVM IR wird z.B. verwendet, von radeonsi und von llvmpipe. Beide sind Teil von Mesa 3D.

Der Kern von LLVM ist die Intermediate Representation (IR), eine Low-Level-Programmiersprache ähnlich wie Assembler. IR ist ein stark typisierter RISC-Befehlssatz (Reduced Instruction Set Computing), der die meisten Details des Ziels abstrahiert. So wird zum Beispiel die Aufrufkonvention durch call- und ret-Anweisungen mit expliziten Argumenten abstrahiert. Außerdem verwendet IR anstelle eines festen Satzes von Registern einen unendlichen Satz von Temporären der Form %0, %1, usw. LLVM unterstützt drei äquivalente Formen von IR: ein für Menschen lesbares Assembler-Format, ein für Frontends geeignetes In-Memory-Format und ein dichtes Bitcode-Format zur Serialisierung. Ein einfaches „Hello, world!“-Programm im IR-Format:

@.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}

Die vielen unterschiedlichen Konventionen und Features, die von verschiedenen Targets bereitgestellt werden, bedeuten, dass LLVM keine wirklich zielunabhängige IR erzeugen und neu targeten kann, ohne einige etablierte Regeln zu brechen. Beispiele für eine Zielabhängigkeit, die über das hinausgeht, was in der Dokumentation explizit erwähnt wird, finden sich in einem Vorschlag aus dem Jahr 2011 für „Wordcode“, einer völlig zielunabhängigen Variante der LLVM-IR, die für die Online-Distribution gedacht ist. Ein praktischeres Beispiel ist PNaCl.

BackendsEdit

In der Version 3.4 unterstützt LLVM viele Befehlssätze, darunter ARM, Qualcomm Hexagon, MIPS, Nvidia Parallel Thread Execution (PTX; in der LLVM-Dokumentation NVPTX genannt), PowerPC, AMD TeraScale, AMD Graphics Core Next (GCN), SPARC, z/Architecture (in der LLVM-Dokumentation SystemZ genannt), x86, x86-64 und XCore. Einige Funktionen sind auf einigen Plattformen nicht verfügbar. Die meisten Funktionen sind für x86, x86-64, z/Architecture, ARM und PowerPC vorhanden. RISC-V wird ab der Version 7 unterstützt. In der Vergangenheit unterstützte LLVM auch ganz oder teilweise andere Backends, einschließlich C-Backend, Cell SPU, mblaze (MicroBlaze), AMD R600, DEC/Compaq Alpha (Alpha AXP) und Nios2, aber die meiste dieser Hardware ist größtenteils veraltet, und die LLVM-Unterstützung und -Wartung dafür war nicht zu rechtfertigen.

LLVM unterstützt auch WebAssembly als Ziel, so dass kompilierte Programme in WebAssembly-fähigen Umgebungen wie Google Chrome / Chromium, Firefox, Microsoft Edge, Apple Safari oder WAVM ausgeführt werden können. LLVM-konforme WebAssembly-Compiler unterstützen in der Regel unveränderten Quellcode, der in C, C++, D, Rust, Nim, Kotlin und einigen anderen Sprachen geschrieben wurde.

Das LLVM-Unterprojekt für Maschinencode (MC) ist das LLVM-Framework für die Übersetzung von Maschinenanweisungen zwischen textuellen Formen und Maschinencode. Früher war LLVM auf den Systemassembler oder einen von einer Toolchain bereitgestellten Assembler angewiesen, um Assembler in Maschinencode zu übersetzen. Der integrierte Assembler von LLVM MC unterstützt die meisten LLVM-Ziele, einschließlich x86, x86-64, ARM und ARM64. Für einige Ziele, einschließlich der verschiedenen MIPS-Befehlssätze, ist die integrierte Assembler-Unterstützung nutzbar, befindet sich aber noch im Beta-Stadium.

LinkerEdit

Das lld-Unterprojekt ist ein Versuch, einen eingebauten, plattformunabhängigen Linker für LLVM zu entwickeln. lld soll die Abhängigkeit von einem Linker eines Drittanbieters beseitigen. Mit Stand Mai 2017 unterstützt lld ELF, PE/COFF, Mach-O und WebAssembly in absteigender Reihenfolge der Vollständigkeit. lld ist schneller als beide Varianten von GNU ld.

Im Gegensatz zu den GNU-Linkern verfügt lld über eingebaute Unterstützung für Link-Time-Optimierung. Dies ermöglicht eine schnellere Codegenerierung, da es die Verwendung eines Linker-Plugins umgeht, verhindert aber andererseits die Interoperabilität mit anderen Varianten von LTO.

C++ Standard LibraryEdit

Das LLVM-Projekt umfasst eine Implementierung der C++ Standard Library namens libc++, die unter der MIT-Lizenz und der UIUC-Lizenz doppelt lizenziert ist.

Seit v9.0.0 wurde sie unter der Apache License 2.0 mit LLVM Exceptions neu lizenziert.

PollyEdit

Dies implementiert eine Reihe von Cache-Locality-Optimierungen sowie Autoparallelität und Vektorisierung unter Verwendung eines polyedrischen Modells.

DebuggerEdit

Hauptartikel: LLDB (Debugger)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.