Writing LLVM Passを読んで、LLVMのPassの追加方法が少しわかったので、今度は別のPassを追加してみよう。
参考にしたのは以下のPDF資料。ここでは、BBinLoops
と呼ばれるPassを新たに作成している。
- Writing an LLVM Pass
https://www.inf.ed.ac.uk/teaching/courses/ct/19-20/slides/llvm-2-writing_pass.pdf
前回の実装では最外ループしか検出できていなかったので、再帰的呼び出しを使ってネストループを解析する。
void countBlocksInLoop (Loop *L, unsigned nesting) { unsigned numBlocks = 0; Loop::block_iterator bb; for (bb = L->block_begin(); bb != L->block_end(); ++bb) { numBlocks ++; } errs() << "Loop level " << nesting << " has " << numBlocks << " blocks\n"; std::vector <Loop *>subLoops = L->getSubLoops(); Loop::iterator j, f; for (j = subLoops.begin(), f = subLoops.end(); j != f; j++) { countBlocksInLoop(*j, nesting + 1); } } virtual bool runOnFunction (Function &F) { BBinLoopsCounter ++; LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); errs() << F.getName() + "\n"; for (LoopInfo::iterator i = LI.begin(), e = LI.end(); i != e; i++) { countBlocksInLoop (*i, 0); } return false; }
Loop
イテレータの中にさらにループが存在していると、countBlocksInLoop()
を再度呼び出してループ解析を行う。
これで再度ビルドし実行してみる。
$ clang -O0 -emit-llvm loop_sample.c -c -o loop_sample.bc $ ../bin/opt -enable-new-pm=0 -f -load ../lib/LLVMBBinLoops.so --bbinLoops < ./loop_sample.bc --disable-output
main Loop level 0 has 10 blocks Loop level 1 has 5 blocks
最初はループの回数と勘違いして最内ループが5ってどういうことだと思ったけど、これはループ内のブロックの数なので特に問題無いのか。