繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM