Frage

Ich bin ein LLVM-Code-Generator für die Sprache Timber schreiben, gibt der aktuelle Compiler C-Code. Mein Problem ist, dass ich C-Funktionen aus den generierten LLVM-Dateien aufrufen, zum Beispiel der Compiler eine Echtzeit-Garbage Collector hat und ich brauche Funktionen aufrufen zu benachrichtigen, wenn neue Objekte auf dem Heap zugewiesen werden. Ich habe keine Ahnung, wie diese Funktionen mit meinen generierten LLVM-Dateien zu verknüpfen.

Die Codegenerierung erfolgt durch generieren .ll-Dateien und diese dann manuell kompilieren.

  

Ich versuche, eine externe Funktion von LLVM zu nennen, aber ich habe kein Glück. In den Beispielen Ich habe> eine> hausgemachte Funktion nur C-Standardfunktionen wie „Puts“ und „printf“ genannt werden, aber ich mag rufen gefunden. Ich bin fest.

War es hilfreich?

Lösung

Stellen Sie sich Ihre LLVM Baugruppendateien normalerweise mit llvm-as:

llvm-as *.ll

Stellen Sie die Bitcode Dateien Assembler-Sprache-Dateien · s:

llc *.bc

GCC sie mit der Laufzeitbibliothek in:

gcc *.s runtime.c -o executable

Ersatz in Echtmakefiles, gemeinsam genutzte Bibliotheken usw., falls erforderlich. Sie erhalten die Idee.

Andere Tipps

Ich gehe davon aus Sie eine LLVM Transformation schreiben, und Sie möchten Anrufe auf externe Funktionen in transformierte Code hinzuzufügen. Ist dies nicht der Fall ist, bearbeiten Sie Ihre Frage und weitere Informationen enthalten.

Bevor Sie eine externe Funktion von LLVM-Code aufrufen können, müssen Sie dafür eine Erklärung einzufügen. Zum Beispiel:

virtual bool runOnModule(Module &m) {
    Constant *log_func = m.getOrInsertFunction("log_func",
                                               Type::VoidTy,
                                               PointerType::getUnqual(Type::Int8Ty),
                                               Type::Int32Ty,
                                               Type::Int32Ty,
                                               NULL);
    ...
}

Der obige Code deklariert eine Funktion log_func, die void zurückgibt und hat drei Argumente: ein Byte-Zeiger (string) und zwei 32-Bit-Integer. getOrInsertFunction ist ein Verfahren zur Module .

So rufen Sie tatsächlich die Funktion, müssen Sie einen CallInst . Es gibt mehrere statische Create Methoden.

Ich bin zu interpretieren Ihre Frage als „Wie implementiere ich eine Laufzeitbibliothek in C oder C ++ für meine Sprache, der LLVM kompiliert wird?“

Ein Ansatz ist es, wie von Jonathan Tang detailliert, die Ausgabe des Compilers von LLVM IR zu transformieren, um Montag zu Bitcode und Vanille gcc Link, um die Baugruppe gegen die Laufzeitquelle (oder Objektdateien).

Eine Alternative, möglicherweise flexiblerer Ansatz ist llvm-gcc zu verwenden, um die Laufzeit selbst in LLVM Bitcode zu kompilieren und dann llvm-ld verwenden, um die Bitcode von Ihrem Compiler mit dem Bitcode Ihrer Laufzeit zu verknüpfen. Diese Bitcode kann dann mit opt neu optimiert werden, umgewandelt mit llvm-dis wieder auf IR, interpretierte direkt mit lli (dies wird, afaik nur funktionieren, wenn LLVM gegen libffi gebaut wurde), oder dem Zusammenbau mit llc zusammengestellt (und dann zu einem nativen binär mit Vanille gcc).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top