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

Llvm 如何将函数插入模块传递转换为内部到内联,llvm,inline-assembly,llvm-clang,llvm-ir,Llvm,Inline Assembly,Llvm Clang,Llvm Ir,问题: 我目前有一个传统的模块检测通过 根据某些逻辑将新函数调用插入到给定的IR中 插入的函数来自稍后链接的小库的外部 到给定的程序。运行实验,我的开销来自 对库函数执行函数调用的成本 我想做的是: 我想将这些函数体内联到 给定的程序可以摆脱这个瓶颈。我假设一个内在的 这是一种干净的方法,因为内在函数 请在降到ASM时扩展到其功能体 如果我的理解不正确,请纠正我,这是我的第一次 使用intrinsics/LTO的时间 当前状态: 我的原始库调用定义: void register_my_mem(v

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

我想做的是: 我想将这些函数体内联到 给定的程序可以摆脱这个瓶颈。我假设一个内在的 这是一种干净的方法,因为内在函数 请在降到ASM时扩展到其功能体 如果我的理解不正确,请纠正我,这是我的第一次 使用intrinsics/LTO的时间

当前状态:

我的原始库调用定义:

void register_my_mem(void *user_vaddr){
  ... C code ...
}
到目前为止:

我已经在:llvm project/llvm/include/llvm/IR/IntrinsicsX86.td中创建了一个def

让TargetPrefix=x86输入{ def int_x86_register_mem:GCCBuiltin, 固有的 }

在中添加了另一个def: otwm/llvm项目/clang/include/clang/Basic/BuiltinsX86.def

目标内置寄存器我的内存,vv*

将我的库源代码*.c、*.h添加到编译器rt/lib/test\u lib中 并添加到CMakeLists.txt

将函数插入替换为尝试插入内部函数 改为:llvm/lib/Transforms/Instrumentation/myModulePass.cpp 是:

新的:

问题:

如果我插入内在函数的逻辑不应该是 模块通行证,我应该放在哪里? 我是不是把LTO和本质混淆了? 我是否将库函数定义放入以下文件中,如中所述 例如emitRegisterymem? clang/lib/CodeGen/CodeGenFunction.cpp-define llvm::Instrinsic::ID clang/lib/CodeGen/CodeGenFunction.h-declare llvm::infrant::ID 我的LLVM是编译的,所以它在语义上是正确的,但当前
尝试插入此函数调用时,LLVM segfaults表示函数参数的类型无效

我在这里看到了多个问题

事实上,你把LTO和本质混淆了。intrinsic是一种特殊函数,通过后端扩展为特殊指令,或者降低为库函数调用。这肯定不是你要达到的目标。你根本不需要一个内在的,你只需要内联有问题的函数调用:通过你的模块传递或者通过LTO,实际上

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

如果要求声明类型无效的变量内在函数,我会假定您的func_类型是非整数类型 传递指针参数 希望这能把问题弄清楚


另请参见:

感谢您澄清了这个问题@Anton Kornikov


在阅读了你的解释之后,我也相信我必须使用LTO来完成我试图做的事情。我特别发现这个链接非常有用:。看来我现在走上了正确的道路。

这看起来像是一条评论,是对现有答案的回复。如果你没有回答问题,请不要发布答案。即使在其他情况下你没有足够的代表发表评论,你也可以对别人对你自己问题的答案发表评论。谢谢你的建议。经过考虑,我仍然坚信我的回答也是答案的一部分,因为我分享了一个解决我问题的有用链接。其他遇到类似问题的人可以从中受益@PeterCordesOk,那么问题是这只是一个链接的答案。听起来,安东的答案中包含该链接是一个很好的评论或编辑建议,但链接本身并没有给出答案。你回答的大部分文字是对安东的回复和对你进步的评论,而不是对未来读者有帮助的任何东西。
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);