llvm: VisitInstruction не посещает каждую инструкцию в базовом блоке?

Я пытаюсь написать простой проход в базовом блоке, и код выглядит следующим образом:

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 иногда не посещает последнюю инструкцию базового блока, почему это происходит? Это должно произойти?


person Boyu Fang    schedule 24.10.2014    source источник
comment
Вы уверены, что последняя инструкция в блоке не является инструкцией TerminatorInst? (т.е. это не представляет собой фактический код)   -  person Joachim Isaksson    schedule 24.10.2014
comment
@JoachimIsaksson ага, я не знал этого раньше, спасибо, думаю, теперь я решил проблему :)   -  person Boyu Fang    schedule 24.10.2014


Ответы (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.

person Eli Bendersky    schedule 24.10.2014