检测 BasicBlock 是否在循环中

Detect if BasicBlock is in a Loop

我是 LLVM 的初学者,我正在尝试编写 LLVM pass。我的传递非常简单:它检测循环和函数调用。我想知道函数调用是否在循环中并检测子循环。

我遇到的问题是,当调用处于循环中时,我的传递会打印函数调用两次。这是我的代码:

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,但我稍后会尝试修复它。)

这是实现您的 objective 的一种方法,跳过那些属于循环的基本块。

virtual bool runOnFunction(Function &F){
LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();

for(LoopInfo::iterator i = LI.begin(), e = LI.end(); i!=e; ++i)
  BlocksInLoop (*i,0);

errs() << "Function " << F.getName () + "{\n";
for( Function::iterator b = F.begin() , be = F.end() ;b != be; ++b){
  for(LoopInfo::iterator L = LI.begin(), e = LI.end(); L!=e; ++L) {
    if(L->contains(&*b)){
      break; // Skip those BB that belong to a loop.
    }       
  }  
  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"; 
    }
  }
}
return(false);

}

注意:我没有运行这段代码,它可能有语法问题,但这是总体思路。