1

我正在制作仪表通行证。pass 应该以特定的方式修改给定的 IR。所需的修改之一是在特定位置插入对函数的调用。这是被调用函数的签名:

void myclass::foo(Function *f, BasicBlock* b)

该函数的原型在include/llvmfoofile.h中的一个文件中, 而函数定义在MCJIT文件夹中的文件中。并在此文件夹中运行正常,并且编译时使用,并且同一文件中的另一个函数可以按预期正常工作。不回仪表通行证。如何在给定的 IR 中向 foo 函数插入 callinst?这是插入调用的片段:foofile.cppmakefoofile.cppMCJIT.cpp

Type* retTy = Type::getInt32Ty(C);
FunctionType* FuncTy = FunctionType::get(retTy, false);
PointerType* PtrToFuncTy = PointerType::get(FuncTy, 0);
Constant *fun = M->getOrInsertFunction("foo", Type::getVoidTy(C), PtrToFuncTy, Type::getLabelTy(C), nullptr);
Function *dofoo = cast<Function>(fun);
Instruction* dofooCall = CallInst::Create(fun, Args2, "", bb);

注意: Args2是一个包含 2 个指向函数和一个基本块的值指针的数组列表,bb是插入调用的基本块。

当我在给定的 IR 上使用 op 运行传递时,它会正确生成声明和调用,如下所示:

宣言:

declare void @foo(i32 ()*, label)

称呼:

call void @foo(i32 ()* @main, label %for.cond)

但是当我尝试使用 lli 运​​行生成的 .ll 文件时,一切都爆炸了!这是堆栈跟踪之前的前 2 行:

Can't get register for value!
UNREACHABLE executed at /home/marwayusuf/llvm-env/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:1158!

我得出的结论是,问题在于它找不到 foo 函数。如果这是问题所在,我该如何正确创建 callinst?

4

1 回答 1

0

如果函数是类 myclass 的成员,它将有一个 this 指针作为第一个参数。C++ 方法名称也有名称修饰,因此它不使用符号“foo”。使用 mcjit 时,它会将您的 IR 降低为机器代码,它实际上不会执行 IR,因此在运行时您不会传递 llvm::Function 或 llvm::BasicBlock 因此即使您像这样调用它,检测功能也不会工作那。

于 2015-08-23T15:27:28.200 回答