在运行时记录 LLVM 中分支指令的结果



我试图通过编写LLVM传递来获取分支指令的结果,以便我可以计算出CFG的边沿频率。

我已经阅读了多个教程文件和LLVM文档。我尝试的解决方案是识别分支指令,插入对显示分支源和目标的日志函数的调用。

我写了一个函数传递,看起来像这样:

for (auto &BB : F) {
for (auto &I: BB) {
if (auto* op = dyn_cast<BranchInst>(&I)) {
IRBuilder<> builder(op);
builder.SetInsertPoint(&BB, builder.GetInsertPoint());
Value* condition;
Value* false_dst;
Value* true_dst;
if (op->isConditional()) {
condition = op->getOperand(0);
false_dst = op->getOperand(1);
true_dst = op->getOperand(2);
} else {
condition = builder.getInt32(1);
false_dst = op->getOperand(0);
true_dst = op->getOperand(0);
}
Value* args[] = {condition, false_dst, true_dst};
builder.CreateCall(log_func, args);
}
}
}

我已经尝试了大约 10 个小时的多种解决方案,但没有一个奏效。我一直遇到此错误:

void llvm::CallInst::init(llvm::FunctionType*, llvm::Value*, llvm::ArrayRef<llvm::Value*>, llvm::ArrayRef<llvm::OperandBundleDefT<llvm::Value*> >, const llvm::Twine&): Assertion `(Args.size() == FTy->getNumParams() || (FTy->isVarArg() && Args.size() > FTy->getNumParams())) && "Calling a function with bad signature!"' failed.

它似乎只使用分支指令执行此操作,因为我已经使用二进制运算符进行了测试,并且它工作正常。

在调试器下运行代码并计算log_func->dump()表达式。这将使您了解此函数需要哪些类型的参数。

我怀疑,问题出在最后 2 个参数上。这些是基本的块标签,不能作为call指令的参数传递。您可能希望创建具有 BB 名称的字符串常量并传递它们。

最新更新