2009-09-13 153 views
10

我正在为语言Timber编写LLVM代码生成器,当前编译器会发出C代码。我的问题是我需要从生成的LLVM文件调用C函数,例如编译器有一个实时垃圾回收器,我需要调用函数来通知何时在堆上分配新对象。我不知道如何将这些函数与我生成的LLVM文件链接起来。LLVM - 链接问题

代码生成是由生成.ll文件,然后手动编译这些。

我想从LLVM调用一个外部函数,但我没有运气。在我已经发现的例子中,只发现了像“puts”和“printf”这样的C标准函数,但我想调用一个自制函数。我卡住了。

+0

您的意思是说您要直接在LLVM IR中编写代码,而您无法拨打电话,或者您正在使用LLVM编译代码并遇到问题? – 2009-09-13 23:56:54

回答

5

与LLVM,因为通常编译您的LLVM汇编文件:

llvm-as *.ll 

编译位码文件.S汇编语言文件:

llc *.bc 

GCC它们在运行时库:

gcc *.s runtime.c -o executable 

如果需要,在真正的makefile,共享库等中替换。你明白了。

12

我假设你正在编写一个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位的整数。 getOrInsertFunctionModule的一种方法。

要真正调用函数,您必须插入一个CallInst。有几个静态的Create方法。

+0

这就是我正在试图找出llvm所做的,谢谢! – Dan 2009-11-28 23:29:40

3

我把你的问题解释为“如何在C或C++中为编译为LLVM的语言实现运行时库?”

由Jonathan Tang详细介绍的一种方法是将编译器的输出从LLVM IR转换为位编码,然后将程序集与运行时源(或对象文件)相链接。

另一种可能更灵活的方法是使用llvm-gcc将运行时本身编译为LLVM位代码,然后使用llvm-ld将编译器的位代码与运行时的位代码链接起来。然后这个位代码可以用opt重新优化,通过llvm-dis转换回IR,直接用lli解释(这样做,afaik,只有在LLVM是根据libffi构建的情况下才能工作),或者编译为与llc(然后是本机二进制与香草gcc)。