LLVM - 链接问题

时间:2009-09-13 23:44:33

标签: c linker llvm

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

代码生成是通过生成.ll文件然后手动编译它们来完成的。

  

我正在尝试从LLVM调用外部函数,但我没有运气。在示例中,我发现只有“put”和“printf”等C标准函数被调用,但我想调用一个>自制函数。我被卡住了。

3 个答案:

答案 0 :(得分: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,它返回void并接受三个参数:一个字节指针(字符串)和两个32位整数。 getOrInsertFunctionModule的一种方法。

要实际调用该函数,您必须插入CallInst。有几种静态Create方法。

答案 1 :(得分:5)

使用llvm-as:

正常编译LLVM程序集文件
llvm-as *.ll

将bitcode文件编译为.s汇编语言文件:

llc *.bc

使用运行时库GCC它们:

gcc *.s runtime.c -o executable

必要时替换真实的makefile,共享库等。你明白了。

答案 2 :(得分:3)

我正在将您的问题解释为“我如何使用C或C ++为我的语言实现运行时库,并将其编译为LLVM?”

正如Jonathan Tang所详述的,一种方法是将编译器的输出从LLVM IR转换为bitcode转换为汇编,并使vanilla gcc将程序集链接到运行时源(或目标文件)。 / p>

另一种可能更灵活的方法是使用llvm-gcc将运行时本身编译为LLVM bitcode,然后使用llvm-ld将编译器中的bitcode与运行时的bitcode链接起来。然后可以使用opt重新优化此bitcode,使用llvm-dis转换回IR,直接使用lli进行解释(这将是afaik,仅当LLVM针对{{1}构建时才有效}},或者使用libffi编译成程序集(然后编译为带有vanilla llc的本机二进制文件)。