如何调用未知类型的 JITed LLVM 函数?

2024-01-23

我正在使用 LLVM 实现 JIT 编译器的前端。我首先遵循 LLVM 教程中的 Kaleidscope 示例。我知道如何使用 LLVM C++ API 生成和 JIT LLVM IR。我还知道如何使用 llvm::ExecutionEngine 的“getPointerToFunction”方法调用 JITed 函数。

getPointerToFunction 返回一个 void*,然后我必须将其转换为正确的函数类型。例如,在我的编译器中,我有如下所示的单元测试:

void* compiled_func = compiler.get_function("f");   
auto f = reinterpret_cast<int32_t(*)(int32_t)>(compiled_func);
int32_t result = f(10);

问题是我必须事先知道函数签名。在上面的示例中,我有一个函数“f”,它接受一个 32 位整数并返回一个 32 位整数。由于我自己创建了“f”,所以我知道函数类型是什么,因此我能够调用 JIT 函数。但是,一般来说,我不知道用户输入的函数签名是什么(或者结构类型是什么)。用户可以使用任意参数和返回类型创建任意函数,因此我不知道从 LLVM 的 getPointerToFunction 中转换 void* 的函数指针类型。我的运行时需要能够调用这些函数(例如,对于读取-评估-打印循环)。如何从 JIT 运行时处理此类任意函数?

Thanks


您无法从中获得太多信息compiled_func- 正如你所写,这只是一个void*。但是当你写“一般来说,我不知道函数签名是什么”时,这是不准确的 - 你刚刚编译了该函数,所以你应该有权访问 LLVMFunction对象,可以查询其类型。确实,它是 LLVM IR 类型而不是 C++ 类型,但您通常可以知道哪个类型转换为哪个类型。

例如,如果我们借用代码教程中有关 JITting 万花筒的部分 http://llvm.org/docs/tutorial/LangImpl4.html#adding-a-jit-compiler:

if (Function *LF = F->Codegen()) {
  LF->dump();  // Dump the function for exposition purposes.

  // JIT the function, returning a function pointer.
  void *FPtr = TheExecutionEngine->getPointerToFunction(LF);

  // Cast it to the right type (takes no arguments, returns a double) so we
  // can call it as a native function.
  double (*FP)() = (double (*)())(intptr_t)FPtr;
  fprintf(stderr, "Evaluated to %f\n", FP());
}

好的,FPtr被“假定”为类型double (),但也有LF类型的Function*在这里,所以你could做过类似的事情:

Type* RetTy = LF->getReturnType();
if (RetTy->isDoubleTy()) {
  double (*FP)() = (double (*)())(intptr_t)FPtr;
  fprintf(stderr, "Evaluated to %f\n", FP());
} else if (RetTy->isIntegerTy(32)) {
  int (*FP)() = (int (*)())(intptr_t)FPtr;
  fprintf(stderr, "Evaluated to %d\n", FP());
} else ...

以大致相同的方式,您可以查询函数的参数类型。

有点麻烦?您可以使用执行引擎通过其方便的方式调用该函数runFunction http://llvm.org/docs/doxygen/html/classllvm_1_1ExecutionEngine.html#a83ac805ce571233b79802b8210332039方法,它接收一个向量GenericValue http://llvm.org/docs/doxygen/html/structllvm_1_1GenericValue.htmls 并返回 aGenericValue。您仍然应该查询Functiontype 来查找每个下的基础类型GenericValue应该。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何调用未知类型的 JITed LLVM 函数? 的相关文章

  • 如何嵌入LLVM?

    LLVM 核心项目包括 编译器 将源代码转换为 LLVM IR VM 执行编译后的IR代码 如何将 VM 嵌入到 C 应用程序中 LLVM 实际上是一个可以链接到的库的集合 因此嵌入起来非常容易 更多时候 LLVM 会获取您生成的 IR 并
  • 未优化的 clang++ 代码在简单的 main() 中生成不需要的“movl $0, -4(%rbp)”

    我创建了一个最小的 C 程序 int main return 1234 并使用 clang 5 0 禁用优化 默认 O0 得到的汇编代码是 https gcc godbolt org z OYLghAFBqd5QCxAYwPYBMCmBRd
  • 是否有像 pygccxml 一样的 Python Clang 包装器来包装 GCC-XML?

    很长一段时间以来 我一直在使用 pygccxml 来解析和内省我的 C 源代码 它帮助我在构建过程中进行一些巧妙的代码生成 最近我读了很多关于 LLVM 堆栈的好处 特别是 LLVM Clang 解析器给 C 编译带来的好处 我现在想知道
  • 运行JDK代码时Java JIT会作弊吗?

    我正在对一些代码进行基准测试 但我无法让它运行得像java math BigInteger https docs oracle com javase 7 docs api java math BigInteger html 即使使用完全相同
  • 有谁能够在 iOS 上使用 Address-Sanitizer(称为 asan 或 -fsanitize=address)吗?

    地址消毒剂https code google com p address sanitizer wiki AddressSanitizer https code google com p address sanitizer wiki Addr
  • 防止运行测试时优化掉未使用的静态函数

    我正在编写一个将利用 LLVM 的库 通过inkwell https github com TheDan64 inkwell 来 JIT 编译一些函数 这些函数需要能够回调我的代码中的一些 Rust 函数 我让它工作 但我的单元测试不起作用
  • PyPy 明显慢于 CPython

    我一直在测试我制作的缓存系统 其目的是加速 Django Web 应用程序 它将所有内容存储在内存中 根据 cProfile 我的测试中的大部分时间都花在 QuerySet clone 内 结果证明效率非常低 考虑到实现 这实际上并不奇怪
  • 如何在 Mac 上使用 Emscripten emcc 和 make 时包含 ncurses

    我正在尝试构建一个项目 即 Angband 的源代码 http rephial org downloads 3 3 angband v3 3 2 tar gz http rephial org downloads 3 3 angband v
  • ld:警告:__DATA/__objc_imageinfo__DATA 节的大小意外地大

    有谁知道这个警告是什么意思 接下来是错误 Command Developer Platforms iPhoneSimulator platform Developer usr bin llvm gcc 4 2 failed with exi
  • 玩框架。无需编译

    我被介绍到 Play 框架 我发现它的令人惊奇的事情之一是不需要编译项目 您只需保存编辑的文件并重新加载网页即可 我听说 Java 源代码被编译为字节码 然后使用 JIT 编译器进行编译 那么 Play 框架内部到底有什么魔力呢 在 DEV
  • 如何编译LLVM Kaleidscope教程?

    我之前一直在 C 中使用 LLVM 其中包含一个 Nuget LLVM 库 我转向 C 并尝试遵循万花筒教程 https llvm org docs tutorial LangImpl03 html 不幸的是我不知道如何编译它 我保存了第三
  • 找不到“Attributes.inc”文件

    我一直在使用中提供的标题include llvm and include llvm c尝试制作我自己的编译器 但是 每当我尝试编译时 都会收到此错误 没有llvm IR Attributes inc在我的文件或我见过的任何 LLVM 项目中
  • 静态方法是否会立即编译(JIT)?

    根据我的理解 CLR 编译器对实例方法和静态方法的处理方式相同 并且每当首次调用该方法时 IL 代码都会进行 JIT 编译 今天我和同事讨论了 他告诉我静态方法与实例方法的处理方式不同 即 静态方法在程序集加载到应用程序域后立即进行 JIT
  • 通过 cmake 链接 libc++ 时 libc++abi 的链接问题

    我正在尝试构建一个简单的 hello world C 使用 LLVM Clang 3 7 0 的程序 根据工具链的源代码构建libc 使用命令行 clang std c 14 stdlib libc fno exceptions hello
  • 如何让 clangd 转向 c++20

    当没有其他信息时 如何让 clangd 回退到 c 20 例如 在第一次构建之前 cmake 可以生成一个 这是在带有最新 LLVM 的 Arch Linux 上 这是通过 Emacs LSP 运行的 但这应该没有什么区别 你可以加 Com
  • 从什么时候起 Xcode 不再需要前向方法声明,为什么?

    我注意到 Xcode 或更准确地说是 Apple LLVM 编译器 不再需要前向方法声明 换句话说 构建以下代码时不会发出警告 implementation Foo void foo self bar void bar end 这曾经发出警
  • gcc 与 clang:符号剥离

    gcc 和 AMD Open64 opencc 都有一个 s选项 剥离符号表和重定位信息 到目前为止我还没能在 Clang LLVM 中找到相同的选项 它存在吗 您可以使用stripbinutils 中的实用程序 实际上 llvm ld 有
  • llvm 中 CloneFunction 的 vmap 参数传递什么?

    我正在尝试克隆另一个函数的精确副本 我在互联网上找不到任何 CloneFunction 使用的示例 事实证明 您可以只创建一个 ValueToValueMapTy 变量并在不初始化的情况下传递它
  • 如何确定特定的 LLVM 指令是否依赖于另一个指令?

    我正在尝试编写 LLVM 优化过程 我需要一种方法来确定一个 LLVM 指令是否影响另一个指令 或依赖于另一个指令 这些依赖关系可以具有不同的性质 第一条指令创建一个值 另一条指令将其用作操作数 第一条指令写入内存位置 另一条指令从该位置读
  • 一个单元在哪一级测试无锁代码?

    Can LLVM https packages debian org stretch llvm QEMU https packages debian org stretch qemu kvm GDB https packages debia

随机推荐