I am trying to write a Simple pass on basic block and the code is as follows:
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;
}
}
}
and very strangely I get some output like this:
...
---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
......
It is easy to see that in both blocks above the actual number of instructions should be 5 and 7, however the visitInstrucion function sometimes do not visit the last instruction of a basic block, why does this happen? Is this supposed to happen?
In the first block:
Visiting every single instruction:call
Visiting every single instruction:load
Visiting every single instruction:add
Visiting every single instruction:store
Encountered an unconditional branch!
It is 5 though! The last line comes from your void visitBranchInst(BranchInst& I)
which takes precedence over visitInstruction
. More specific visitors take precedence over more generic ones. If you want visitInstruction
to be called anyway, you have to do it explicitly from more specific visitors - it won't happen automatically.
As for the next block, maybe it ends with a branch that is conditional? Then your visitBranchInst
doesn't print anything, and doesn't propagate to visitInstruction
.