LLVM LoopInfo in FunctionPass not compiling

I am starting to learn llvm api and I wrote my first pass. My goal is to print how functions call each other.

Recently, I wanted to add some loop information to the display to see if a function can be called several times or not. But when I try to use LoopInfo, I got this compilation error:

llvm[0]: Compiling cfg.cpp for Debug+Asserts build (PIC) In file included from cfg.cpp:19: In file included from /home/llvm-lab/llvm/include/llvm/Pass.h:378: /home/llvm-lab/llvm/include/llvm/PassAnalysisSupport.h:56:37: error: no member named 'ID' in 'llvm::LoopInfo' return addRequiredID(PassClass::ID); ^ cfg.cpp:33:10: note: in instantiation of function template specialization 'llvm::AnalysisUsage::addRequired<llvm::LoopInfo>' requested here AU.addRequired<LoopInfo>(); ^ 1 error generated. 

Here is my code:

 #include "llvm/ADT/Statistic.h" #include "llvm/IR/Function.h" #include "llvm/Support/raw_ostream.h" #include "iostream" #include "llvm/Pass.h" #include "llvm/IR/InstIterator.h" #include <llvm/IR/Instructions.h> #include <llvm/Analysis/LoopInfo.h> using namespace llvm; namespace { struct CFG : public FunctionPass { static char ID; // Pass identification, replacement for typeid CFG() : FunctionPass(ID) {} void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired<LoopInfo>(); } bool runOnFunction(Function &F) override { errs().write_escaped(F.getName()); errs() << " : "; for( Function::iterator b = F.begin() , be = F.end(); b != be; ++b){ errs() << "\n\t BB : "; LoopInfo *loop = new LoopInfo(); bool isLoop = loop->getLoopFor(b); if(isLoop){ errs() << "loop{"; } for(BasicBlock::iterator i = b->begin() , ie = b->end(); i!=ie; ++i){ if( isa<CallInst>(&(*i)) || isa<InvokeInst>(&(*i))){ errs() << cast<CallInst>(&(*i))->getCalledFunction()->getName() << "\t"; } } if(isLoop){ errs() << "}"; } } errs() << '\n'; return false; } }; } char CFG::ID = 0; static RegisterPass<CFG> X("CFG", "Gen CFG",true ,true); 

I can not find the link to "no member with the name" ID "in" llvm :: LoopInfo ", somewhere, can anyone understand what is wrong here?

+6
source share
1 answer

Why your code cannot be created

AU.addRequired<typename passclass>() needs the LLMV::Pass type, however what you are going through is LoopInfo , which is just an LLVM inner class for serving loop information. It does not have an ID field.

LoopInfoWrapperPass should be used instead

If you want to get information about the loop. Try changing it to AU.addRequired<LoopInfoWrapperPass> , as shown in LLVM. Write a new Pass document . LoopInfoWrapperPass used to generate LoopInfo .

LoopInfo should be obtained from the aisle

Your code also has a problem on how to get LoopInfo , you are trying to use new to create LoopInfo , what you get will be empty LoopInfo .

The code should work for your question

Below is a modified version of your code that can print the expected information.

 #include "llvm/ADT/Statistic.h" #include "llvm/IR/Function.h" #include "llvm/Support/raw_ostream.h" #include "iostream" #include "llvm/Pass.h" #include "llvm/IR/InstIterator.h" #include <llvm/IR/Instructions.h> #include <llvm/Analysis/LoopInfo.h> using namespace llvm; namespace { struct CFG : public FunctionPass { static char ID; // Pass identification, replacement for typeid CFG() : FunctionPass(ID) {} void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); AU.addRequired<LoopInfoWrapperPass>(); } bool runOnFunction(Function &F) override { LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); errs().write_escaped(F.getName()); errs() << " : "; for( Function::iterator b = F.begin() , be = F.end(); b != be; ++b){ errs() << "\n\t BB : "; bool isLoop = LI.getLoopFor(b); if(isLoop){ errs() << "loop{"; } for(BasicBlock::iterator i = b->begin() , ie = b->end(); i!=ie; ++i){ if( isa<CallInst>(&(*i)) || isa<InvokeInst>(&(*i))){ errs() << cast<CallInst>(&(*i))->getCalledFunction()->getName() << "\t"; } } if(isLoop){ errs() << "}"; } } errs() << '\n'; return false; } }; } char CFG::ID = 0; static RegisterPass<CFG> X("CFG", "Gen CFG",true ,true); 

For the following code in LLVM opt :

 #include <stdio.h> #define ARRAY_SIZE 100 int foo(int* a , int n) { int i; int sum = 0; for (; i < n; i++) { sum += a[i]; } return sum; } int main() { int a[ARRAY_SIZE] = {1}; int sum = foo(a, ARRAY_SIZE); printf("sum:0x%x\n", sum); return 0; } 

The output will be:

 foo : BB : BB : loop{} BB : loop{} BB : loop{} BB : main : BB : llvm.memset.p0i8.i64 foo printf 
+12
source

Source: https://habr.com/ru/post/987580/


All Articles