[英]Logging the outcome of branch instructions in LLVM during runtime
我试图通过编写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()
表达式。 这将使您了解此函数需要什么类型的参数。
我怀疑,问题出在最后两个参数上。 这些是基本的块标签,不能作为call
指令的参数传递。 您可能要使用BB名称创建字符串常量,然后将其传递。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.