Я новичок в LLVM и пытаюсь написать пропуск LLVM. Мой проход довольно прост: он обнаруживает циклы и вызовы функций. Я хочу знать, находится ли вызов функции в цикле и обнаруживать подциклы.
Проблема, с которой я столкнулся, состоит в том, что мой пароль печатает вызовы функции дважды, когда вызов находится в цикле. Это мой код:
void BlocksInLoop(Loop *L,unsigned nlvl){
errs() <<"Loop level"<< nlvl << " {\n";
BasicBlock* h = L->getHeader();
ScalarEvolution *SE = &getAnalysis<ScalarEvolutionWrapperPass().getSE();
errs() <<"Loop trip count :"<< SE->getSmallConstantTripCount(L) << "\n";
std::vector<Loop*> subLoops = L-> getSubLoops();
Loop::iterator j,f;
for (j = subLoops.begin(), f = subLoops.end();j!=f ; ++j)
BlocksInLoop(*j ,nlvl+1);
unsigned numBlocks = 0;
Loop::block_iterator bb;
for(bb = L-> block_begin(); bb != L-> block_end();++bb){
BasicBlock* BB = *bb;
for(BasicBlock::iterator i = BB->begin() , e = BB->end(); i!=e; ++i){
if(isa<CallInst>(&(*i)) || isa<InvokeInst>(&(*i))){
errs()<<"Call "<< cast<CallInst((*i))->getCalledFunction()->getName() << "\n";
}
}
}
errs()<< "}\n";
}
virtual bool runOnFunction(Function &F){
LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
errs() << "Function " << F.getName () + "{\n";
for( Function::iterator b = F.begin() , be = F.end() ;b != be; ++b){
for(BasicBlock::iterator i = b->begin() , ie = b->end();i != ie; i ++){
if(isa<CallInst>(&(*i)) || isa<InvokeInst>(&(*i))){
errs()<<"Call "<< cast<CallInst>(&(*i))->getCalledFunction()->getName() << "\n";
}
}
}
for(LoopInfo::iterator i = LI.begin(), e = LI.end(); i!=e; ++i)
BlocksInLoop (*i,0);
errs()<< "}\n\n";
return(false);
}
Если ввод, например:
void foo(){
for(int i=0; i++; i<10)
foo();
}
Это вывод, который я получаю:
Function foo{
Call foo
Loop level0 {
Loop trip count :0
Call foo
}
}
Поэтому я ищу способ, чтобы определить, находится ли Call в цикле и, если да, игнорировать первый отпечаток. Возможно ли это, и если да, то как? (Счетчик поездок также неверен и всегда равен 0, но я постараюсь это исправить позже.)