LLVM没有在doInitialization()方法中插入函数调用

时间:2017-04-28 04:01:30

标签: llvm

以下代码段编译正常,但生成的bitcode没有插入instrument_global_variable的任何调用。但是,我正在运行的代码中列出了全局变量。在这种情况下,为什么LLVM传递不插入任何检测?

bool doInitialization(Module &M) override {
    for (auto &global : M.getGlobalList()) {
        if (isa<GlobalVariable>(global)) {
            errs() << "[G]: " << global << '\n';
            auto &Ctx = M.getContext();
            IRBuilder<> builder(Ctx);
            Constant *instrument_func = M.getOrInsertFunction("instrument_global_variable", Type::getVoidTy(Ctx), Type::getInt64Ty(Ctx), NULL);
            Value* args[] = {global.getOperand(0)};
            builder.CreateCall(instrument_func, args);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

如果你看一下从CallGraphSCCPass传递开始的doc,你就会注意到一种用doInitialization()方法表示的模式。

他们声明他们可以做大多数主要runOn方法不允许做的事情。因此,由于ModulePass几乎可以做任何事情,doInitialization的使用仅限于用户特定的操作(例如用户数据分配等)。

此外,它只运行一次才能通过,所以如果您正在处理多个模块,它会跳过除第一个之外的所有模块,这没有任何意义(尽管,AFAIK,没有能力)在opt中每次执行处理多个bitcode文件)。因此,甚至其文档也被省略(恕我直言)。

我知道您希望每个模块执行一次,因此我认为的最佳位置是 runOn方法。如果你真的要求它与其他类型的处理分开,你可以将它自己留在一个通行证中,并通过你的其他通行证来要求它。