我正在尝试在基本块上编写一个简单传递,代码如下:
struct SimplePass : BasicBlockPass, InstVisitor<SimplePass>
{
... some initialisation and some finalization code
virtual bool runOnBasicBlock(BasicBlock& B) {
std::cout << "---This is a block divider---" << B.size() << std::endl;
visit(B);
return false;
}
void visitInstruction(Instruction& I){
std::cout << "Visiting every single instruction:" << I.getOpcodeName(I.getOpcode()) << std::endl;
}
void visitBranchInst(BranchInst& I) {
if(I.isUnconditional()) {
std::cout << "Encountered an unconditional branch!" << std::endl;
}
}
}
非常奇怪的是我得到了这样的输出:
...
---This is a block divider---5
Visiting every single instruction:call
Visiting every single instruction:load
Visiting every single instruction:add
Visiting every single instruction:store
Encountered an unconditional branch!
---This is a block divider---7
Visiting every single instruction:phi
Visiting every single instruction:load
Visiting every single instruction:sub
Visiting every single instruction:call
Visiting every single instruction:load
Visiting every single instruction:icmp
---This is a block divider---3
......
很容易看出,在上面的两个块中,实际的指令数应该是5和7,但 visitInstrucion 函数有时不会访问基本块的最后一条指令,为什么这样做发生?这应该发生吗?
答案 0 :(得分:1)
在第一个区块中:
Visiting every single instruction:call
Visiting every single instruction:load
Visiting every single instruction:add
Visiting every single instruction:store
Encountered an unconditional branch!
它是 5!最后一行来自您的void visitBranchInst(BranchInst& I)
,其优先于visitInstruction
。更具体的访问者优先于更通用的访问者。如果你想要调用visitInstruction
,你必须明确地从更具体的访问者那里做到 - 它不会自动发生。
至于下一个块,也许它以一个有条件的分支结束?那么您的visitBranchInst
不会打印任何内容,也不会传播到visitInstruction
。