Sebastian Hain via llvm-dev
2016-Apr-24 16:59 UTC
[llvm-dev] Cannot access module pass results from inside loop pass
Hello, I don't know wether this is the right place to ask, but I did not find any other appropriate place else so just ask: I'm writing several LLVM passes: the first one is a ModulePass that performs some analyzations tasks but does not change anything. It simply looks at some (named) metadata nodes and thats it. It neither changes them nor does it change anything else. This is the code to initialize the pass (MyModuleChecker.cpp): INITIALIZE_PASS_BEGIN(MyModuleChecker, "mmc", "Check module", false, true) INITIALIZE_PASS_END(MyModuleChecker, "mmc", "Check module", false, true) MyModuleChecker::MyModuleChecker(void) : ModulePass(ID) { initializeMyModuleCheckerPass(*PassRegistry::getPassRegistry()); } void MyModuleChecker::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); } bool MyModuleChecker::runOnModule(Module &M) { // ... return false; } And then there is a second pass. That pass is a LoopPass and basicly performs some loop unrolling tasks depending on some other criteria. For computing the unroll count the pass needs the results of the MyModuleChecker pass. So I put it in the dependencies like this: INITIALIZE_PASS_BEGIN(MyLoopUnroll, "myloopunroll", "Unroll loops", false, false) INITIALIZE_PASS_DEPENDENCY(LoopInfo) INITIALIZE_PASS_DEPENDENCY(ScalarEvolution) INITIALIZE_PASS_DEPENDENCY(MyModuleChecker) INITIALIZE_PASS_DEPENDENCY(DataLayoutPass) INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_END(MyLoopUnroll, "myloopunroll", "Unroll loops", false, false) MyLoopUnroll::MyLoopUnroll() : LoopPass(ID), MDK(nullptr), LI(nullptr), SE(nullptr), AC(nullptr), DL(nullptr) { initializeMyLoopUnrollPass(*PassRegistry::getPassRegistry()); } void HDLLoopUnroll::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<LoopInfo>(); AU.addRequired<ScalarEvolution>(); AU.addRequired<MyModuleChecker>(); AU.addPreserved<MyModuleChecker>(); AU.addRequired<DataLayoutPass>(); AU.addPreserved<DataLayoutPass>(); AU.addRequired<AssumptionCacheTracker>(); } bool MyLoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) { LI = &getAnalysis<LoopInfo>(); SE = &getAnalysis<ScalarEvolution>(); MDK = &getAnalysis<MyModuleChecker>(); DL = &getAnalysis<DataLayoutPass>().getDataLayout(); AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(*L->getHeader()->getParent()); bool Changed = handleLoop(L, LPM); return Changed; } The loop unrolling itself is carried out by the functions already existing in LLVM (and that are used by the LLVM loop unrolling pass). So my pass "only" computes the loop unroll count. Currently those passes are part of the Scalar-library so I adopted the corresponding files (include /llvm/Transforms/Scalar.h, LinkAllPasses.h, ...) accordingly. Now I want to run the passes using opt (I'm using LLVM 3.6): opt -stats -debug -debug-pass=Structure -mem2reg -loop-rotate -myloopunroll -simplifycfg And now I get an assertion error: LoopRotation: rotating Loop at depth 1 containing: %for.cond<header><exiting>,%for.body,%for.inc<latch> Inserted PHI: %i.01 = phi i32 [ 0, %entry ], [ %i.0, %for.cond ] LoopRotation: into Loop at depth 1 containing: %for.body<header>,%for.inc<latch><exiting> opt: ~/llvm-clang/source/include/llvm/PassAnalysisSupport.h:214: AnalysisType& llvm::Pass::getAnalysisID(llvm::AnalysisID) const [with AnalysisType = MyModuleChecker; llvm::AnalysisID = const void*]: Assertion `ResultPass && "getAnalysis*() called on an analysis that was not " "'required' by pass!"' failed. // ... #8 0x1685a99 MyModuleChecker& llvm::Pass::getAnalysisID<MyModuleChecker>(void const*) const (.../opt+0x1685a99) #9 0x16857f0 MyModuleChecker& llvm::Pass::getAnalysis<MyModuleChecker>() const (.../opt+0x16857f0) #10 0x16853cd MyLoopUnroll::runOnLoop(llvm::Loop*, llvm::LPPassManager&) (.../opt+0x16853cd) #11 0xd34aaa llvm::LPPassManager::runOnFunction(llvm::Function&) (.../opt+0xd34aaa) #12 0x11c6a34 llvm::FPPassManager::runOnFunction(llvm::Function&) (.../opt+0x11c6a34) #13 0x11c6ba4 llvm::FPPassManager::runOnModule(llvm::Module&) (.../opt+0x11c6ba4) #14 0x11c6ec2 (anonymous namespace)::MPPassManager::runOnModule(llvm::Module&) (.../opt+0x11c6ec2) #15 0x11c7568 llvm::legacy::PassManagerImpl::run(llvm::Module&) (.../opt+0x11c7568) #16 0x11c7787 llvm::legacy::PassManager::run(llvm::Module&) (.../opt+0x11c7787) // ... The following passes are run: Assumption Cache Tracker ModulePass Manager FunctionPass Manager Dominator Tree Construction Promote Memory to Register Natural Loop Information Canonicalize natural loops Loop-Closed SSA Form Pass Loop Pass Manager Rotate Loops Scalar Evolution Analysis Check module FunctionPass Manager Dominator Tree Construction Natural Loop Information Scalar Evolution Analysis Loop Pass Manager Unroll loops Simple constant propagation Module Verifier Debug Info Verifier Bitcode Writer And then the assertion error occurs and I don't know where that error comes from and why it occures (and yes, everything compiles without errors and warnings). It looks like the loop rotation pass is executed normally and then pass manager gets stuck in the loop unroll pass when calling the getAnalysis<MyModuleChecker> function in the LoopPass to get the analysis results. If I omit the -simplifycfg(when calling opt) and like this do not run the simplifycfg pass after my own loopunrolling pass, everything works fine and there is no assertion error. The assertion error also occurs if I replace the SimplifyCFG pass by - for example - the constprop pass. It also seems as if the error does not occur if the ModuleChecker pass is transformed into a FunctionPass. Could anyone tell my why this assertion error occures and (perhaps) how to solve that issue? Thanks Sebastian