I'm trying to get loop information from IR by writing a function pass. So I followed some examples and wrote like following. I'm not very familiar with writing passes and pass managers.
#include <iostream>
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Function.h"
#include "llvm/BasicBlock.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Support/IRReader.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
using namespace llvm;
namespace {
class DetectLoop: public FunctionPass {
public:
DetectLoop() : FunctionPass(ID) {}
static char ID;
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<LoopInfo>();//I'm not sure if it's correct here *****1*****
}
virtual bool runOnFunction(Function &F) {
if (!F.isDeclaration())
LoopInfo &li = getAnalysis<LoopInfo>(F);//*****2*****
for (Function::iterator I = F.begin(); I != F.end(); I++) {
BasicBlock *BB = I;
for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
Instruction &I = *BI++;
//did noting inside
}
}
return false;
}
};
}
char DetectLoop::ID = 0;
int main(int argc, char** argv)
{
if (argc < 2) {
errs() << "Expected an argument - IR file name\n";
exit(1);
}
SMDiagnostic Err;
std::cout<<argv[1]<<std::endl;
Module *Mod = ParseIRFile(argv[1], Err, getGlobalContext());
Err.Print(argv[0], errs());
if (Mod) {
PassManager PM;
PM.add(new DetectLoop());
PM.add(new LoopInfo());//*****3*****
PM.run(*Mod);
}
else {
std::cout << "Mod is null" << std::endl;
}
return 0;
}
While I was running this program, it just showed me segmentation error(core dumped)
,
but when I commented out addRequired the error msg I got was
IRparser: PassManager.cpp:1200: virtual llvm::Pass* llvm::PMDataManager::getOnTheFlyPass
(llvm::Pass*, llvm::AnalysisID, llvm::Function&): Assertion `0 && "Unable to find on the fly pass"' failed.
Stack dump:
0. Running pass 'Function Pass Manager' on module '../../testcase/forloop1.ll'.
1. Running pass 'Unnamed pass: implement Pass::getPassName()' on function '@main'
Aborted (core dumped)
I have marked 3 places I'm not sure which is correct or not. Can anyone help me with that?
If you use it in a Module:
If you use it in a function:
I had this question before. After searching several answers, I found the solution. You should change the location of the two statements below:
Because LoopInfo Pass must be registed before your own pass.