【问题标题】:How to call a JITed LLVM function with unknown type?如何调用未知类型的 JITed LLVM 函数?
【发布时间】:2013-04-07 17:05:19
【问题描述】:

我正在使用 LLVM 实现 JIT 编译器的前端。我从 LLVM 教程中的 Kaleidoscope 示例开始。我知道如何使用 LLVM C++ API 生成和 JIT LLVM IR。我也知道如何调用 JITed 函数,使用 llvm::ExecutionEngine 的“getPointerToFunction”方法。

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* 的函数指针类型。我的运行时需要能够调用这些函数(例如,对于 Read-Evaluate-Print 循环)。如何从我的 JIT 运行时处理此类任意函数?

谢谢

【问题讨论】:

    标签: llvm jit llvm-c++-api


    【解决方案1】:

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

    例如,如果我们从tutorial's section on JITting Kaleidoscope借用代码:

    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*,因此您可以执行以下操作:

    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 方法,该方法接收GenericValues 的向量并返回GenericValue。您仍然应该查询 Function 类型以查找每个 GenericValue 下的基础类型应该是什么。

    【讨论】:

    • 是的,你说得对,我确实知道运行时的函数签名。您提出的解决方案是有道理的。我看到 runFunction 与查询 GenericValue 的类型相结合,应该允许我 JIT 并执行具有任意值的任意函数。谢谢!
    猜你喜欢
    • 2015-10-13
    • 2016-08-20
    • 1970-01-01
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多