Keeping a std::vector<Loop*> in a ModulePass

To whom it may concern,

I’m writing a LLVM ModulePass as a part of my undergraduate dissertation and I need to keep a list of pointers to all Loops within a Module.
I’ve tried the following bit of code (inside a runOnModule() method in my ModulePass, I also have getAnalysisUsage setup properly with LoopInfo added as required)

std::vector<Loop*> loops;

for (Module::iterator F = M.begin(), FEND = M.end(); F != FEND; ++F){
if (!(*F).isDeclaration()){
LoopInfo& LI = getAnalysis(*F);
for(LoopInfo::iterator l = LI.begin(), lend = LI.end(); l != lend; ++l){
loops.push_back(*l);
}
}
}

However, if I try to print out the loops with

for(auto l: loops){
errs() << *l << “\n”;
}

I get runtime errors. Now, I understand why this is happening - the LoopInfo object is not living between iterations of the outermost loop and thus all pointers are invalidated. I tried keep a pair std::pair<Function*, int> of a function pointer and the corresponding position of the loop in the list from LI.begin() to LI.end() but this causes runtime exceptions as well. The code for that looks like this:

std::vector<std::pair<Function*,int>> loops;
for (Module::iterator F = M.begin(), FEND = M.end(); F != FEND; ++F){
if (!(*F).isDeclaration()){
LoopInfo& LI = getAnalysis(*F);
int count = 0;
for(LoopInfo::iterator l = LI.begin(), lend = LI.end(); l != lend; ++l){
if ((*l)->getLoopDepth() == 0) errs() << **l <<“\n”;
loops.push_back(std::make_pair(F,count));
++count;
}
}
}
for(auto l: loops){
LoopInfo& LI = getAnalysis(*l.first);
errs() << ((LI.begin()) + l.second) << “\n”;
}

However, no luck again. Is there any way to keep pointers to all loops in a Module Pass?

Thanks,

Bilyan

Hi Bilyan,

I believe there is no easy way to do this.

Please check this thread in which they discuss this exact problem:
http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-March/048138.html

Regards,
Victor.