If you do not want to use the pass manager, you might need to call the Analyze method in the llvm::LoopInfoBase class on each function in the IR (assuming you are using LLVM-3.4). However, the Analyze method takes the DominatorTree of each function as input, which you have to generate at first. Following codes are what I tested with LLVM-3.4 (assuming you have read the IR file and converted it into a Module* named as module):
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());
}
Basically, with KLoop generated, you get all kinds of LOOP information in the IR level. You can refer APIs in the LoopInfoBase class for details. By the way, you might want to add following headers:
"llvm/Analysis/LoopInfo.h" "llvm/Analysis/Dominators.h".