我正在爲語言Timber編寫LLVM代碼生成器,當前編譯器會發出C代碼。我的問題是我需要從生成的LLVM文件調用C函數,例如編譯器有一個實時垃圾回收器,我需要調用函數來通知何時在堆上分配新對象。我不知道如何將這些函數與我生成的LLVM文件鏈接起來。LLVM - 鏈接問題
代碼生成是由生成.ll文件,然後手動編譯這些。
我想從LLVM調用一個外部函數,但我沒有運氣。在我已經發現的例子中,只發現了像「puts」和「printf」這樣的C標準函數,但我想調用一個自制函數。我卡住了。
我正在爲語言Timber編寫LLVM代碼生成器,當前編譯器會發出C代碼。我的問題是我需要從生成的LLVM文件調用C函數,例如編譯器有一個實時垃圾回收器,我需要調用函數來通知何時在堆上分配新對象。我不知道如何將這些函數與我生成的LLVM文件鏈接起來。LLVM - 鏈接問題
代碼生成是由生成.ll文件,然後手動編譯這些。
我想從LLVM調用一個外部函數,但我沒有運氣。在我已經發現的例子中,只發現了像「puts」和「printf」這樣的C標準函數,但我想調用一個自制函數。我卡住了。
與LLVM,因爲通常編譯您的LLVM彙編文件:
llvm-as *.ll
編譯位碼文件.S彙編語言文件:
llc *.bc
GCC它們在運行時庫:
gcc *.s runtime.c -o executable
如果需要,在真正的makefile,共享庫等中替換。你明白了。
我假設你正在編寫一個LLVM轉換,並且你想將外部函數的調用添加到轉換後的代碼中。如果情況並非如此,請編輯您的問題並提供更多信息。
在您可以從LLVM代碼調用外部函數之前,您需要爲其插入一個聲明。例如:
virtual bool runOnModule(Module &m) {
Constant *log_func = m.getOrInsertFunction("log_func",
Type::VoidTy,
PointerType::getUnqual(Type::Int8Ty),
Type::Int32Ty,
Type::Int32Ty,
NULL);
...
}
上面的代碼聲明的函數log_func
返回空隙和三個參數:一個字節的指針(字符串),和兩個32位的整數。 getOrInsertFunction
是Module
的一種方法。
要真正調用函數,您必須插入一個CallInst
。有幾個靜態的Create
方法。
這就是我正在試圖找出llvm所做的,謝謝! – Dan 2009-11-28 23:29:40
我把你的問題解釋爲「如何在C或C++中爲編譯爲LLVM的語言實現運行時庫?」
由Jonathan Tang詳細介紹的一種方法是將編譯器的輸出從LLVM IR轉換爲位編碼,然後將程序集與運行時源(或對象文件)相鏈接。
另一種可能更靈活的方法是使用llvm-gcc
將運行時本身編譯爲LLVM位代碼,然後使用llvm-ld
將編譯器的位代碼與運行時的位代碼鏈接起來。然後這個位代碼可以用opt
重新優化,通過llvm-dis
轉換回IR,直接用lli
解釋(這樣做,afaik,只有在LLVM是根據libffi
構建的情況下才能工作),或者編譯爲與llc
(然後是本機二進制與香草gcc
)。
您的意思是說您要直接在LLVM IR中編寫代碼,而您無法撥打電話,或者您正在使用LLVM編譯代碼並遇到問題? – 2009-09-13 23:56:54