【问题标题】:LLVM - linking problemLLVM - 链接问题
【发布时间】:2009-09-13 23:44:32
【问题描述】:

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

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

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

【问题讨论】:

  • 您的意思是您尝试直接在 LLVM IR 中编写代码并且无法进行调用,还是您正在使用 LLVM 编译代码并且遇到问题?

标签: c linker llvm


【解决方案1】:

我假设您正在编写 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 方法。

【讨论】:

  • 这正是我想弄清楚的与 llvm 的关系,谢谢!
【解决方案2】:

使用 llvm-as 正常编译你的 LLVM 程序集文件:

llvm-as *.ll

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

llc *.bc

将它们与运行时库一起使用:

gcc *.s runtime.c -o executable

如有必要,请替换为真实的 makefile、共享库等。你明白了。

【讨论】:

    【解决方案3】:

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

    如 Jonathan Tang 所述,一种方法是将编译器的输出从 LLVM IR 转换为位码再到程序集,并让 vanilla gcc 将程序集与运行时源(或目标文件)链接起来。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-12
      • 2020-10-02
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多