2009-09-13 16 views
10

Sto scrivendo un generatore di codice LLVM per la lingua Timber, il compilatore corrente emette il codice C. Il mio problema è che ho bisogno di chiamare le funzioni C dai file LLVM generati, ad esempio il compilatore ha un garbage collector in tempo reale e ho bisogno di chiamare le funzioni per notificare quando i nuovi oggetti sono allocati nell'heap. Non ho idea di come collegare queste funzioni con i miei file LLVM generati.LLVM - problema di collegamento

La generazione del codice viene creata generando tutti i file .ll e quindi li compila manualmente.

Sto provando a chiamare una funzione esterna da LLVM ma non ho fortuna. Negli esempi che ho trovato solo le funzioni standard di C come "puts" e "printf" vengono chiamate, ma voglio chiamare una> funzione fatta in casa. Sono bloccato.

+0

Vuoi dire che stai provando a scrivere codice direttamente in IR LLVM e non sei in grado di effettuare una chiamata, o che stai compilando codice usando LLVM e riscontrando problemi? –

risposta

5

compilare il file di assieme LLVM normalmente con LLVM-come:

llvm-as *.ll 

compilare i file codice binario che per .s file in linguaggio assembly:

llc *.bc 

GCC loro con la libreria di runtime:

gcc *.s runtime.c -o executable 

Sostituire in makefile reali, librerie condivise, ecc. Se necessario. Hai un'idea.

12

Suppongo che si stia scrivendo una trasformazione LLVM e si desidera aggiungere chiamate a funzioni esterne in codice trasformato. Se questo non è il tuo caso, modifica la tua domanda e includi più informazioni.

Prima di poter chiamare una funzione esterna dal codice LLVM, è necessario inserire una dichiarazione per questo. Ad esempio:

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

Il codice dichiara sopra una funzione che restituisce log_func vuoto e accetta tre parametri: un puntatore byte (stringa), e due interi a 32 bit. getOrInsertFunction è un metodo di Module.

Per chiamare effettivamente la funzione, è necessario inserire uno CallInst. Esistono diversi metodi statici Create per questo.

+0

Questo è esattamente quello che stavo cercando di capire con llvm, grazie! – Dan

3

Sto interpretando la tua domanda come "come faccio a implementare una libreria di runtime in C o C++ per la mia lingua che viene compilata su LLVM?"

Un approccio è, come dettagliato da Jonathan Tang, per trasformare l'output del compilatore da LLVM IR in bitcode in assembly e disporre di vaniglia gcc per collegare l'assembly all'origine di runtime (o ai file oggetto).

Un'alternativa, approccio forse più flessibile è quello di utilizzare llvm-gcc per compilare il runtime stesso in codice binario che LLVM, e quindi utilizzare llvm-ld per collegare il codice binario che dal compilatore con il codice binario che del runtime. Questo bitcode può quindi essere nuovamente ottimizzato con, riconvertito in IR con llvm-dis, interpretato direttamente con lli (questo, a priori, funzionerà solo se LLVM è stato creato rispetto a libffi), o compilato per l'assembly con llc (e quindi a un nativo binario con vaniglia gcc).