Michael McCracken
2004-Aug-05 23:51 UTC
[LLVMdev] How to get LoopInfo within Pass subclass?
Hi, I have a hopefully quick question. I'm writing a Pass that needs to see a whole module at a time and keep some state, so I subclassed Pass. However, I want to be able to see the Loops in each Function. Roughly, here's what I want: virtual bool run(Module &M){ // do stuff... for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I){ if(! I->isExternal()) visitFunction(*I); } // ... return false; } virtual void visitFunction(Function &F){ LoopInfo *LI = &getAnalysis<LoopInfo>(); std::vector<Loop*> SubLoops(LI->begin(), LI->end()); for(unsigned i = 0, e = SubLoops.size(); i != e; ++i){ // visit SubLoops[i]; } } So, I add LoopInfo as a required analysis: virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired<LoopInfo>(); }; However, when running I'm informed that: PassManagerT.h:421: failed assertion `getAnalysisOrNullUp(P) && dynamic_cast<ImmutablePass*>(getAnalysisOrNullUp(P)) && "Pass available but not found! " "Perhaps this is a module pass requiring a function pass?"' I couldn't find a clear explanation of which passes can require which other ones, and I'm a little confused as to whether what I want is even possible. How can I say that I want LoopInfo for each Function in my Module? PS, if I'm not just missing it, and this is a gap in the docs, I'd be glad to try writing something to fill the gap. It'd probably be a good way to learn more about LLVM. Thanks, -mike -- Michael O. McCracken UCSD CSE Ph.D. Student mike at cs.ucsd.edu
On Thu, 5 Aug 2004, Michael McCracken wrote:> Hi, I have a hopefully quick question. I'm writing a Pass that needs to > see a whole module at a time and keep some state, so I subclassed Pass. > However, I want to be able to see the Loops in each Function. Roughly,ok.> However, when running I'm informed that: > > PassManagerT.h:421: failed assertion `getAnalysisOrNullUp(P) && > dynamic_cast<ImmutablePass*>(getAnalysisOrNullUp(P)) && "Pass available > but not found! " "Perhaps this is a module pass requiring a function > pass?"' > > I couldn't find a clear explanation of which passes can require which > other ones, and I'm a little confused as to whether what I want is even > possible. How can I say that I want LoopInfo for each Function in my > Module?Unfortunately this is a big missing feature in the pass management system. In particular, as the assertion says, a "Pass" cannot yet require a "FunctionPass". The reason this is tricky is that each (e.g.) LoopInfo instance contains loop information for one function. When we allow Pass objects to require FunctionPass objects, the PassManager will have to instantiate one FunctionPass for each function in the module. This is clearly something that we want to do, but unfortunately we can't do it yet. This is actually mentioned here, though I'm not suprised you missed it: :) http://llvm.org/docs/WritingAnLLVMPass.html#PassFunctionPass As a work-around you can make your "Pass" object work as a FunctionPass. I don't know what this will do to the logic in the pass, but if this is an option, it would be the best way to go. You're right that FunctionPass's are not supposed to have state (something that many people overlook :) ), however, for now, nothing will break if it does have state, and this is really the only way around this. However, if you want to work on the PassManager, please let us know! :) -Chris -- http://llvm.cs.uiuc.edu/ http://nondot.org/sabre/
Michael McCracken
2004-Aug-06 01:09 UTC
[LLVMdev] How to get LoopInfo within Pass subclass?
On Aug 5, 2004, at 5:30 PM, Chris Lattner wrote:> On Thu, 5 Aug 2004, Michael McCracken wrote: > >> Hi, I have a hopefully quick question. I'm writing a Pass that needs >> to >> see a whole module at a time and keep some state, so I subclassed >> Pass. >> However, I want to be able to see the Loops in each Function. Roughly, > > ok. > >> However, when running I'm informed that: >> >> PassManagerT.h:421: failed assertion `getAnalysisOrNullUp(P) && >> dynamic_cast<ImmutablePass*>(getAnalysisOrNullUp(P)) && "Pass >> available >> but not found! " "Perhaps this is a module pass requiring a function >> pass?"' >> >> I couldn't find a clear explanation of which passes can require which >> other ones, and I'm a little confused as to whether what I want is >> even >> possible. How can I say that I want LoopInfo for each Function in my >> Module? > > Unfortunately this is a big missing feature in the pass management > system. > In particular, as the assertion says, a "Pass" cannot yet require a > "FunctionPass". The reason this is tricky is that each (e.g.) LoopInfo > instance contains loop information for one function. When we allow > Pass > objects to require FunctionPass objects, the PassManager will have to > instantiate one FunctionPass for each function in the module. > > This is clearly something that we want to do, but unfortunately we > can't > do it yet. This is actually mentioned here, though I'm not suprised > you > missed it: :) > http://llvm.org/docs/WritingAnLLVMPass.html#PassFunctionPassOK. Yeah, I stopped reading after I saw the first 'future extension'. Woops.> As a work-around you can make your "Pass" object work as a > FunctionPass. > I don't know what this will do to the logic in the pass, but if this > is an > option, it would be the best way to go.> You're right that FunctionPass's are not supposed to have state > (something > that many people overlook :) ), however, for now, nothing will break > if it > does have state, and this is really the only way around this.I'm not sure if I can do this. The pass I'm writing is writing info about the module and its parts to a file, so I need to see the module, if only to print its moduleIdentifier. I'm not sure if there's a way to get the Module that a Function belongs to from within a FunctionPass. If I could do that, and cheat by keeping some state, I could do what I want as a FunctionPass. Am I missing something, or is that not possible? Also, out of curiosity, why the stateless restriction - is it because passes may someday be run in parallel?> However, if you want to work on the PassManager, please let us know! :)This depends. If it's really in my way, I may have little choice. I would like to make a contribution, though, and it didn't actually sound too bad. Any guess what amount of work that'd be? Assume I have a passing familiarity with the LLVM architecture, slightly rusty average C++ skills, and little shame in asking questions. :) -mike -- Michael O. McCracken UCSD CSE Ph.D. Student mike at cs.ucsd.edu