Clang - LLVM Wie geht das?

Frank

Anfänger
Hallo,

in Zukunft soll ja clang den gcc unter FreeBSD ersetzen.
Das ist ein weiterer Grund für mich, llvm und clang mal auszuprobieren.

Leider verstehe ich die Sache nicht so richtig.
Ich lese, dass llvm eine Low Level Virtual Machine ist und eine modulare Compiler Architektur.

Was ich dabei nicht verstehe:
Wo kommt die Virtual-Machine zum Einsatz?
Nur beim Linken (Binden) nach dem Kompilieren.
Also läuft der Code beim Linken in der VM und wird dort nochmal optimiert.

Und liegt der Quellcode dann in "normaler" Maschinensprache vor wie auch beim gcc, oder läuft der Code immer in einer VM wie bei Java?

Wie arbeiten llvm und clang zusammen?
 
LLVM.ORG erklärts doch ganz nett: "The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. Despite its name, LLVM has little to do with traditional virtual machines, though it does provide helpful libraries that can be used to build them."
 
LLVM ist ein Framework mit dem man Compiler und VMs bauen kann.

Die Kurzfassung ist, clang ist auf kompatibilität (Kommandozeilenparameter usw.) mit gcc ausgelegt, dem wurde viel von dem Potential in LLVM geopfert.

Ein konsequent mit LLVM gemachtes System könnte Object-Code mit in Binaries packen um damit zur Laufzeit Code zu optimieren, zum Beispiel Derivate von Funktionen mit häufig vorkommenden Parametern anlegen. Binaries könnten auch so ohne zusätzlichen Compiliervorgang neu verlinkt werden.

Wahrscheinleich wäre das dann sogar Plattvormunabhängig. Wenn der Linker mit LLVM Unterstützung liefe könnte er aus dem beigelegten Objektcode die Binaries für die aktuelle Platform neu übersetzen. Zumindest so lange der C-Code keine Plattformspezifischen ifdefs enthielt.
 
FreeBSD kann derzeit nicht einmal relativ simple Funktionen der LLVM nutzen, da es an der umgebenden Software fehlt. Ein gutes Beispiel ist -O4, was "Link Time Optimizations" einschalten würde. Da FreeBSD keinen entsprechenden Linker besitzt (Googles "Gold" könnte es, aber der ist meiner Erfahrung nach selbst unter Linux noch nicht so weit, dass man ihn einsetzen möchte. Zudem ist er unter GPL3 lizensiert.), kann man die Funktion nicht nutzen... Vom praktischen Standpunkt her würde ich Clang daher eher als langfristig angelegtes Projekt betrachten. Kurzfristig wird es uns von der GPL wegbringen und erlauben den uralten und verbuggten GCC 4.2 zu ersetzen, die wirklichen Vorteile wird man aber erst in der Zukunft ernten können.

Von Clang werden so oder so alle profitieren, auch diejenigen, die es nicht nutzen werden. Bricht Clang doch das seit ~20 Jahren bestehende Monopol der "politischen Waffe" GCC auf und forciert endlich sowas wie Wettbewerb im bereich der Opensource-Compiler.
 
LLVM ist quasi ein Backend zur Codegenerierung. Es definiert dazu einen "virtuellen Prozessor" mit (afaik) unendlich Registern und Instruktionen für Interger, Floatingpoint und Vektor Berechnungen.

Ein Frontend (wie Clang für die C-Sprachen, oder pypy für Python) übersetzt nun den Code in das Format für den "virtuellen Prozessor" von LLVM und LLVM macht daraus, für den gewählten Prozessor, echten Code. Entweder zur Laufzeit per JiTC oder es wird in nativen Code übersetzt (klassisches Binary).

Das Gute ist, seit LLVM 3.0 bleibt "die Sprache" (das Bytecodeformat) des "virtuellen Prozessors" vorwärtskompatibel, d.h. ein mal vom Frontend übersetzte Software ist auch in zukünftigen Versionen von LLVM übersetzbar (auch ohne das Frontend). Das ermöglicht nachträgliche Optimierungen.

Im Prinzip ist der Hauptvorteil von LLVM, dass die ganze Codegenerierung vereinheitlicht wird und sich das Frontend somit nur um die Erstellung von LLVM-Code kümmern muss. Er braucht somit nicht mehr wissen, für was einen Prozessor er kompiliert (OK, bei Clang mit C ist das etwas unmöglich, aber das liegt nunmal an C).

Portierst du also nun LLVM auf eine andere Prozessorarchitektur, dann können somit alle Frontends ebenso auf diesem Prozessor compilieren.

Das ist natürlich alles ziemlich naiv ausgedrückt und es gibt zig Fallstricke die die schöne heile Welt kaputt machen, aber das Konzept bleibt natürlich und funktioniert auch ziemlich gut, sofern bestimmte Voraussetzungen erfüllt sind.

Mal als weiteres Beispiel. Jeder Prozessor hat ja eine SIMD-Einheit zur parallelen Berechnung. Und jeder hat dazu eine andere API. Sei es nun SSE1/2/3/4 AVX, Altivec oder NEON. Alle haben ihre eigene Syntax und ein Entwickler dafür muss, wenn er alle Prozessoren nutzen will, einen Algorithmus mehrfach schreiben.

LLVM bietet hier aber eine verdammt simple Syntax:

< <# elements> x <elementtype> >

also z.B.:
<4 x i32>.
<8 x float>

und auf diesen Datentypen funktionieren nun auch die "normalen" add/sub/mult-Befehle.

LLVM weiß nun, dass hier SIMD-Berechnungen gewünscht sind und generiert, sofern der Prozessor es kann, auch den SIMD Code. Sollte der Prozessor es nicht können, wird einfach die normale FPU oder IU benutzt.
 
Danke für die Erklärungen

Vielen Dank für die Erklärungen!

Werde das WE mal nutzen, um mit clang mal herum zu spielen.
Die Fehlermeldungen für c++ und vor allem c++0x sollen ja netter sein.
Und es werden ja schon einige c++0x-Features (leider keine lambdas) unterstützt.

Gruß Frank
 
Back
Top