我正在为语言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