Having a ModulePass that requires a FunctionPass that in turn requires another ModulePass results in an assertion being fired. Is this expected behavior (that seems to be undocumented), or a bug? Specifically, the following code will emit the assertion: [VMCore/PassManager.cpp:1597: virtual void llvm::ModulePass::assignPassManager(llvm::PMStack&, llvm::PassManagerType): Assertion `!PMS.empty() && "Unable to find appropriate Pass Manager"' failed] ****** struct ModPass1 : public ModulePass { static char ID; ModPass1() : ModulePass((intptr_t)&ID) {} virtual bool runOnModule(Module &M) { return false; } virtual void getAnalysisUsage(AnalysisUsage &AU) const {} }; struct FunPass1 : public FunctionPass { static char ID; FunPass1() : FunctionPass((intptr_t)&ID) {} virtual bool runOnFunction(Function &F) {return false; } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<ModPass1>(); } }; struct ModPass2 : public ModulePass { static char ID; ModPass2() : ModulePass((intptr_t)&ID) {} virtual bool runOnModule(Module &M) { return false; } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<FunPass1>(); } }; char ModPass1::ID = 0; char FunPass1::ID = 0; char ModPass2::ID = 0; RegisterPass<ModPass1> A("modpass1", ""); RegisterPass<FunPass1> B("funpass1", ""); RegisterPass<ModPass2> C("modpass2", ""); int main(int argc, char argv) { PassManager PM; PM.add(new ModPass2); } ****** Also of note, if the first module requires TargetData, then the code will fail earlier with the assertion [include/llvm/Target/TargetData.h:114: llvm::TargetData::TargetData(): Assertion `0 && "ERROR : Bad TargetData ctor used. " "Tool did not specify a TargetData to use?"' failed]. This occurs even when a valid TargetData object is added to the PassManager. Specifically, if ModPass1 above is changed to have addRequired<TargetData> then the first of the following code works, but the second fails with the TargetData assertion: ****** // Works! int main(int argc, char argv) { PassManager PM; Module TestMod = ...; PM.add(new TargetData(TestMod)); PM.add(new FunPass1); } ****** // Breaks with TargetData assertion rather than PMS.empty assertion int main(int argc, char argv) { PassManager PM; Module TestMod = ...; PM.add(new TargetData(TestMod)); PM.add(new ModPass2); } ******
Joseph, I had a similar problem a while back... Our solution was twofold: (1) To the degree possible, make everything a pass of the same level (e.g. all FunctionPasses, all ModulePasses, etc). (2) The order in which .addRequired<Foo>() are called within getAnalysisUsage() matters, try a different ordering. Beyond that, I don't know (no one responded to my post). Good luck, Nick On Thu, Apr 9, 2009 at 6:13 PM, Joseph Blomstedt <Joseph.Blomstedt at colorado.edu> wrote:> Having a ModulePass that requires a FunctionPass that in turn requires > another ModulePass results in an assertion being fired. Is this > expected behavior (that seems to be undocumented), or a bug? > > Specifically, the following code will emit the assertion: > [VMCore/PassManager.cpp:1597: virtual void > llvm::ModulePass::assignPassManager(llvm::PMStack&, > llvm::PassManagerType): Assertion `!PMS.empty() && "Unable to find > appropriate Pass Manager"' failed] > > ****** > struct ModPass1 : public ModulePass { > static char ID; > ModPass1() : ModulePass((intptr_t)&ID) {} > virtual bool runOnModule(Module &M) { return false; } > virtual void getAnalysisUsage(AnalysisUsage &AU) const {} > }; > > struct FunPass1 : public FunctionPass { > static char ID; > FunPass1() : FunctionPass((intptr_t)&ID) {} > virtual bool runOnFunction(Function &F) {return false; } > virtual void getAnalysisUsage(AnalysisUsage &AU) const { > AU.addRequired<ModPass1>(); > } > }; > > struct ModPass2 : public ModulePass { > static char ID; > ModPass2() : ModulePass((intptr_t)&ID) {} > virtual bool runOnModule(Module &M) { return false; } > virtual void getAnalysisUsage(AnalysisUsage &AU) const { > AU.addRequired<FunPass1>(); > } > }; > > char ModPass1::ID = 0; > char FunPass1::ID = 0; > char ModPass2::ID = 0; > > RegisterPass<ModPass1> A("modpass1", ""); > RegisterPass<FunPass1> B("funpass1", ""); > RegisterPass<ModPass2> C("modpass2", ""); > > int main(int argc, char argv) { > PassManager PM; > PM.add(new ModPass2); > } > ****** > > Also of note, if the first module requires TargetData, then the code > will fail earlier with the assertion > [include/llvm/Target/TargetData.h:114: llvm::TargetData::TargetData(): > Assertion `0 && "ERROR > : Bad TargetData ctor used. " "Tool did not specify a TargetData to > use?"' failed]. This occurs even when a valid TargetData object is > added to the PassManager. Specifically, if ModPass1 above is > changed to have addRequired<TargetData> then the first of the > following code works, but the second fails with the TargetData > assertion: > > ****** > // Works! > int main(int argc, char argv) { > PassManager PM; > Module TestMod = ...; > PM.add(new TargetData(TestMod)); > PM.add(new FunPass1); > } > ****** > // Breaks with TargetData assertion rather than PMS.empty assertion > int main(int argc, char argv) { > PassManager PM; > Module TestMod = ...; > PM.add(new TargetData(TestMod)); > PM.add(new ModPass2); > } > ****** > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-- Nick Johnson
"A module pass can use function level passes (e.g. dominators) using getAnalysis interfacegetAnalysis<DominatorTree>(Function), if the function pass does not require any module passes." http://llvm.org/docs/WritingAnLLVMPass.html In your case, A module pass (ModPass2) is trying tu use function level pass (FunPass1) which uses module level pass (ModPass1). This is not supported. - Devang On Apr 9, 2009, at 3:13 PM, Joseph Blomstedt wrote:> Having a ModulePass that requires a FunctionPass that in turn requires > another ModulePass results in an assertion being fired. Is this > expected behavior (that seems to be undocumented), or a bug? > > Specifically, the following code will emit the assertion: > [VMCore/PassManager.cpp:1597: virtual void > llvm::ModulePass::assignPassManager(llvm::PMStack&, > llvm::PassManagerType): Assertion `!PMS.empty() && "Unable to find > appropriate Pass Manager"' failed] > > ****** > struct ModPass1 : public ModulePass { > static char ID; > ModPass1() : ModulePass((intptr_t)&ID) {} > virtual bool runOnModule(Module &M) { return false; } > virtual void getAnalysisUsage(AnalysisUsage &AU) const {} > }; > > struct FunPass1 : public FunctionPass { > static char ID; > FunPass1() : FunctionPass((intptr_t)&ID) {} > virtual bool runOnFunction(Function &F) {return false; } > virtual void getAnalysisUsage(AnalysisUsage &AU) const { > AU.addRequired<ModPass1>(); > } > }; > > struct ModPass2 : public ModulePass { > static char ID; > ModPass2() : ModulePass((intptr_t)&ID) {} > virtual bool runOnModule(Module &M) { return false; } > virtual void getAnalysisUsage(AnalysisUsage &AU) const { > AU.addRequired<FunPass1>(); > } > }; > > char ModPass1::ID = 0; > char FunPass1::ID = 0; > char ModPass2::ID = 0; > > RegisterPass<ModPass1> A("modpass1", ""); > RegisterPass<FunPass1> B("funpass1", ""); > RegisterPass<ModPass2> C("modpass2", ""); > > int main(int argc, char argv) { > PassManager PM; > PM.add(new ModPass2); > } > ****** > > Also of note, if the first module requires TargetData, then the code > will fail earlier with the assertion > [include/llvm/Target/TargetData.h:114: llvm::TargetData::TargetData(): > Assertion `0 && "ERROR > : Bad TargetData ctor used. " "Tool did not specify a TargetData to > use?"' failed]. This occurs even when a valid TargetData object is > added to the PassManager. Specifically, if ModPass1 above is > changed to have addRequired<TargetData> then the first of the > following code works, but the second fails with the TargetData > assertion: > > ****** > // Works! > int main(int argc, char argv) { > PassManager PM; > Module TestMod = ...; > PM.add(new TargetData(TestMod)); > PM.add(new FunPass1); > } > ****** > // Breaks with TargetData assertion rather than PMS.empty assertion > int main(int argc, char argv) { > PassManager PM; > Module TestMod = ...; > PM.add(new TargetData(TestMod)); > PM.add(new ModPass2); > } > ****** > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Good to know. I was referencing a local copy of 2.3 docs which didn't include the "does not require any module passes" statement. It appears the docs were changed two days before 2.4 was released in November. I suppose I should update my docs more often. Are there any plans to change this restriction, or any best practices to get similar behavior? Since immutable pass is a subclass of module pass, this problem extends to immutable passes as well. In particular, any function pass that requires AliasAnalysis or MemoryDependenceAnalysis (which in turn requires AliasAnalysis) can no longer be used in a following module pass (even if the basic alias analysis is used, which is an immutable pass). This makes inter-procedural transformations/analysis that depends on memory dependence information difficult to achieve. I've worked around the problem by partitioning my passes into two sets which are run serially and share relevant information through an external structure on the heap, but that completely kills the benefit of the pass manager and having LLVM manage the lifetime of analysis information automatically. In short, I'm just surprised this type of chaining doesn't appear in the existing set of LLVM passes. Is there an obvious way to restructure passes that I'm missing? On Fri, Apr 10, 2009 at 12:53 PM, Devang Patel <dpatel at apple.com> wrote:> > "A module pass can use function level passes (e.g. dominators) using > getAnalysis interfacegetAnalysis<DominatorTree>(Function), if the > function pass does not require any module passes." > > http://llvm.org/docs/WritingAnLLVMPass.html > > In your case, A module pass (ModPass2) is trying tu use function level > pass (FunPass1) which uses module level pass (ModPass1). This is not > supported. > > - > Devang > > On Apr 9, 2009, at 3:13 PM, Joseph Blomstedt wrote: > >> Having a ModulePass that requires a FunctionPass that in turn requires >> another ModulePass results in an assertion being fired. Is this >> expected behavior (that seems to be undocumented), or a bug? >> >> Specifically, the following code will emit the assertion: >> [VMCore/PassManager.cpp:1597: virtual void >> llvm::ModulePass::assignPassManager(llvm::PMStack&, >> llvm::PassManagerType): Assertion `!PMS.empty() && "Unable to find >> appropriate Pass Manager"' failed] >> >> ****** >> struct ModPass1 : public ModulePass { >> static char ID; >> ModPass1() : ModulePass((intptr_t)&ID) {} >> virtual bool runOnModule(Module &M) { return false; } >> virtual void getAnalysisUsage(AnalysisUsage &AU) const {} >> }; >> >> struct FunPass1 : public FunctionPass { >> static char ID; >> FunPass1() : FunctionPass((intptr_t)&ID) {} >> virtual bool runOnFunction(Function &F) {return false; } >> virtual void getAnalysisUsage(AnalysisUsage &AU) const { >> AU.addRequired<ModPass1>(); >> } >> }; >> >> struct ModPass2 : public ModulePass { >> static char ID; >> ModPass2() : ModulePass((intptr_t)&ID) {} >> virtual bool runOnModule(Module &M) { return false; } >> virtual void getAnalysisUsage(AnalysisUsage &AU) const { >> AU.addRequired<FunPass1>(); >> } >> }; >> >> char ModPass1::ID = 0; >> char FunPass1::ID = 0; >> char ModPass2::ID = 0; >> >> RegisterPass<ModPass1> A("modpass1", ""); >> RegisterPass<FunPass1> B("funpass1", ""); >> RegisterPass<ModPass2> C("modpass2", ""); >> >> int main(int argc, char argv) { >> PassManager PM; >> PM.add(new ModPass2); >> } >> ****** >> >> Also of note, if the first module requires TargetData, then the code >> will fail earlier with the assertion >> [include/llvm/Target/TargetData.h:114: llvm::TargetData::TargetData(): >> Assertion `0 && "ERROR >> : Bad TargetData ctor used. " "Tool did not specify a TargetData to >> use?"' failed]. This occurs even when a valid TargetData object is >> added to the PassManager. Specifically, if ModPass1 above is >> changed to have addRequired<TargetData> then the first of the >> following code works, but the second fails with the TargetData >> assertion: >> >> ****** >> // Works! >> int main(int argc, char argv) { >> PassManager PM; >> Module TestMod = ...; >> PM.add(new TargetData(TestMod)); >> PM.add(new FunPass1); >> } >> ****** >> // Breaks with TargetData assertion rather than PMS.empty assertion >> int main(int argc, char argv) { >> PassManager PM; >> Module TestMod = ...; >> PM.add(new TargetData(TestMod)); >> PM.add(new ModPass2); >> } >> ****** >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >