以下代码段编译正常,但生成的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);
}
}
}
答案 0 :(得分:0)
如果你看一下从CallGraphSCCPass
传递开始的doc,你就会注意到一种用doInitialization()
方法表示的模式。
他们声明他们可以做大多数主要runOn
方法不允许做的事情。因此,由于ModulePass
几乎可以做任何事情,doInitialization
的使用仅限于用户特定的操作(例如用户数据分配等)。
此外,它只运行一次才能通过,所以如果您正在处理多个模块,它会跳过除第一个之外的所有模块,这没有任何意义(尽管,AFAIK,没有能力)在opt
中每次执行处理多个bitcode文件)。因此,甚至其文档也被省略(恕我直言)。
我知道您希望每个模块执行一次,因此我认为的最佳位置是 runOn
方法。如果你真的要求它与其他类型的处理分开,你可以将它自己留在一个通行证中,并通过你的其他通行证来要求它。