我想在LLVM字节码中找到简单的循环,并提取基本的 循环信息。
例如:
for (i=0; i<1000; i++)
sum += i;
我想提取绑定[0,1000],循环变量“i”和
循环体(sum + = i)。
我该怎么办?
我阅读了LLVM API文档,找到了一些有用的类,比如“Loop”,
“LoopInfo”。
但我不知道如何详细使用它们。
答案 0 :(得分:6)
如果您不想使用传递管理器,则可能需要在IR中的每个函数的 llvm :: LoopInfoBase 类中调用Analyze方法(假设您使用的是LLVM-3.4 )。但是,Analyze方法将每个函数的DominatorTree作为输入,您必须首先生成它。以下代码是我用 LLVM-3.4 测试的(假设您已经读取了IR文件并将其转换为名为模块的模块*):
for(llvm::Module::iterator func = module->begin(), y=module->end(); func!=y; func++){
//get the dominatortree of the current function
llvm::DominatorTree* DT = new llvm::DominatorTree();
DT->DT->recalculate(*func);
//generate the LoopInfoBase for the current function
llvm::LoopInfoBase<llvm::BasicBlock, llvm::Loop>* KLoop = new llvm::LoopInfoBase<llvm::BasicBlock, llvm::Loop>();
KLoop->releaseMemory();
KLoop->Analyze(DT->getBase());
}
基本上,通过生成KLoop,您可以获得IR级别的各种LOOP信息。您可以在LoopInfoBase类中引用API以获取详细信息。顺便说一下,您可能想要添加以下标头: 的&#34; LLVM /分析/ LoopInfo.h&#34; &#34; LLVM /分析/ Dominators.h&#34; 强>
答案 1 :(得分:2)
一旦达到LLVM IR级别,您请求的信息可能不再准确。例如,clang可能已经转换了你的代码,所以我从-1000变为0。或者它可能完全优化了“i”,因此没有明确的归纳变量。如果你真的需要完全按照C代码中的面值提取信息,那么你需要查看clang,而不是LLVM IR。否则,你可以做的最好的事情是计算一个循环行程计数,在这种情况下,看看ScalarEvolution传递。
检查PowerPC硬件循环转换过程,它可以很好地演示行程计数:http://llvm.org/docs/doxygen/html/PPCCTRLoops_8cpp_source.html
代码相当繁重,但应该可以使用。有趣的功能是PPCCTRLoops :: convertToCTRLoop。如果您对此有任何疑问,我可以尝试回答。
答案 2 :(得分:1)
答案 3 :(得分:1)
就像Matteo说的那样,为了让LLVM能够识别循环变量和条件,文件需要在LLVM IR中。问题是你在LLVM字节码中有它,但由于LLVM IR是以SSA形式编写的,所以谈论&#34;循环变量&#34;并非真的是真实的。我确定你是否描述了你想要做的事情,以及你期望我们可以获得进一步帮助的结果类型。
一些帮助您入门的代码:
virtual void getAnalysisUsage(AnalysisUsage &AU) const{
AU.addRequired<LoopInfo>();
}
bool runOnLoop(Loop* L, LPPassManager&){
BasicBlock* h = L->getHeader();
if (BranchInst *bi = dyn_cast<BranchInst>(h->getTerminator())) {
Value *loopCond = bi->getCondition();
}
return false;
}
此代码段来自常规LLVM传递。
答案 4 :(得分:1)
只是Junxzm答案的更新, LLVM 3.5 中的一些参考,指针和方法已经改变。
for(llvm::Module::iterator f = m->begin(), fe=m->end(); f!=fe; ++f){
llvm::DominatorTree DT = llvm::DominatorTree();
DT.recalculate(*f);
llvm::LoopInfoBase<llvm::BasicBlock, llvm::Loop>* LoopInfo = new llvm::LoopInfoBase<llvm::BasicBlock, llvm::Loop>();
LoopInfo->releaseMemory();
LoopInfo->Analyze(DT);
}