【问题标题】:How to call a JITed LLVM function with known type?如何调用已知类型的 JITed LLVM 函数?
【发布时间】:2015-10-13 03:38:56
【问题描述】:

我可以从 JITed LLVM 函数调用 C++ 函数:我使用 clang 将 C++ 函数编译为 LLVM IR,然后查看它的 LLVM 类型。例如,C++ 中的 std::array<uint64_t, 2>(*)() 类型变成了在 LLVM IR 中返回 {i64, i64} 的函数。然后,我可以创建一个合适的 FunctionType,并调用我想要的函数。

但是在相反的方向上,如果我有一个返回[i64 x 3] 的 LLVM 函数,我如何从 C++ 代码中调用这个函数?我尝试将返回的函数指针转换为(std::array<uint64_t, 3>(*)()),然后调用它,但很明显这不起作用,因为当我尝试打印返回值时不会显示它们。理想情况下,我希望我的 C++ 代码能够调用任何返回 [i64 x N] 的函数,对于任意 N >= 2。

/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp 在处理函数返回类型方面做了一个温和的尝试,但它在我感兴趣的情况下有所保留。(它说,“还不支持全功能的参数传递!” )

【问题讨论】:

  • (我当前的解决方法是创建并 JIT 一个蹦床 LLVM 函数,该函数调用所需的 LLVM 函数。蹦床函数 malloc 内存,然后将值存储在那里,然后返回指向该内存的指针。这行得通因为 LLVM IR 函数很容易调用其他 LLVM IR 函数。但是这种解决方法的开销很大,大约占程序总运行时间的 30%。)
  • (我能想到的第二种可能的解决方法是改变原来LLVM IR函数的函数类型,强制它匹配对应C++函数的ABI。这意味着让LLVM IR函数接受一个指向内存的指针作为它的第一个参数。)

标签: llvm jit llvm-ir


【解决方案1】:

使用纯 C++ 是不可能的。根据Returning structs in registers - ARM ABI in GCC 的说法,ABI 的事情没有组装就无法处理。根据经验,我看到在 Linux x64 上,LLVM IR 约定是在 eax、edx、ecx 寄存器中返回最多三个返回整数,然后在内存中返回 4 个或更多。在 C++ 中,只能在寄存器中返回单个对象;较大的对象必须放在结构中,然后必须在内存中返回。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-20
    • 2020-08-23
    • 2015-01-08
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多