如何将函数插入模块传递转换为内联到内联

How to convert function insertion module pass to intrinsic to inline

问题: 我目前有一个传统的模块检测传递 根据某种逻辑将新的函数调用插入给定的 IR (插入的函数是一个小库的外部,稍后链接 给定的程序)。 运行实验,我的开销来自 执行对库函数的函数调用的成本。

我想做什么: 我想将这些函数体内联到 IR 中 给定的程序来摆脱这个瓶颈。我假设一个内在的 将是一种干净的方式来做到这一点,因为一个内在的功能会 降为ASM时展开为它的函数体(请 如果我的理解不正确,请纠正我,这是我的第一次 与 intrinsics/LTO).

一起工作的时间

当前状态:

我原来的库调用定义:

void register_my_mem(void *user_vaddr){
  ... C code ...
}

到目前为止:

是:

FunctionCallee sm_func =
curr_inst->getModule()->getOrInsertFunction("register_my_mem",
func_type);
ArrayRef<Value*> args = {
      builder.CreatePointerCast(sm_arg_val, currType->getPointerTo())
};
builder.CreateCall(sm_func, args);

新:

Intrinsic::ID aREGISTER(Intrinsic::x86_register_my_mem);
Function *sm_func = Intrinsic::getDeclaration(currFunc->getParent(),
aREGISTER, func_type);
ArrayRef<Value*> args = {
      builder.CreatePointerCast(sm_arg_val, currType->getPointerTo())
};
builder.CreateCall(sm_func, args);

问题:

  1. 如果我插入内部函数的逻辑不应该是 模块通行证,我应该把它放在哪里?
  2. 我是否将 LTO 与内在函数混淆了?
  3. 我是否将我的库函数定义放入以下文件中,如 http://lists.llvm.org/pipermail/llvm-dev/2017-June/114322.html 例如 EmitRegisterMyMem()?
    • clang/lib/CodeGen/CodeGenFunction.cpp - 定义 llvm::Instrinsic::ID
    • clang/lib/CodeGen/CodeGenFunction.h - 声明 llvm::Intrinsic::ID

我的 LLVM 可以编译,所以它在语义上是正确的,但是目前 试图插入这个函数调用,LLVM 段错误说 "Not a valid type for function argument!"

我在这里看到多个问题。

确实,您将 LTO 与内在函数混淆了。内在函数是特殊的 "functions" ,它们要么被后端扩展为特殊指令,要么被降低为库函数调用。这当然不是你要实现的目标。您根本不需要内在函数,您只需要内联有问题的函数调用:实际上是手动(从您的模块传递)或通过 LTO。

出现特定错误是因为您将内在函数声明为接收整数参数(这就是声明的样子),但是:

  • 询问具有无效类型的 variadic intrinsic 的声明(我假设你的 func_type 是非整数类型)
  • 传递指针参数

希望这能说明问题。


另请参阅:https://llvm.org/docs/LinkTimeOptimization.html

感谢您解决问题@Anton Korobeynikov。

看完你的解释,我也相信我必须使用LTO来完成我想做的事情。我特别发现这个 link 非常有用:https://llvm.org/docs/LinkTimeOptimization.html。看来我现在的路是对的。