Kevin Fan
2009-Mar-09 22:49 UTC
[LLVMdev] Patch: PassManager should call add() instead of addLowerLevelRequiredPass()
Hello, LLVM asserts in the following scenario. Say there are three passes: A, B, C. C requires A and B; B requires A; and B does not preserve A. A valid pass ordering would be A B A C. However, opt gives the following assertion: $ opt -load libPassTest.so foo.bc -f -o /dev/null -c -debug-pass=Structure opt: /u/loc/kevin/llvm/llvm/lib/VMCore/PassManager.cpp:1424: virtual void llvm::MPPassManager::addLowerLevelRequiredPass(llvm::Pass*, llvm::Pass*): Assertion `(P->getPotentialPassManagerType() < RequiredPass->getPotentialPassManagerType()) && "Unable to handle Pass that requires lower level Analysis pass"' failed. even though all passes are ModulePasses and do not require lower level passes. The attached patch modifies PMDataManager::add() to check if the required pass is actually a lower level pass before calling addLowerLevelRequiredPass(); if not, it calls add() instead. Not sure if this is the best fix, but it works for me. I also attached a test case with the three passes A, B, C described above. Kevin -------------- next part -------------- A non-text attachment was scrubbed... Name: passmanager.diff Type: text/x-patch Size: 696 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090309/9ae8dfe5/attachment.bin> -------------- next part -------------- A non-text attachment was scrubbed... Name: PassTest1.cpp Type: text/x-c++src Size: 1130 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090309/9ae8dfe5/attachment.cpp>
Devang Patel
2009-Mar-10 17:08 UTC
[LLVMdev] Patch: PassManager should call add() instead of addLowerLevelRequiredPass()
Hi Kevin, On Mar 9, 2009, at 3:49 PM, Kevin Fan wrote:> Hello, > > LLVM asserts in the following scenario. Say there are three passes: > A, B, C. C requires A and B; B requires A; and B does not preserve A. > A valid pass ordering would be A B A C. However, opt gives the > following assertion: > > $ opt -load libPassTest.so foo.bc -f -o /dev/null -c -debug- > pass=Structure > opt: /u/loc/kevin/llvm/llvm/lib/VMCore/PassManager.cpp:1424: virtual > void llvm::MPPassManager::addLowerLevelRequiredPass(llvm::Pass*, > llvm::Pass*): Assertion `(P->getPotentialPassManagerType() < > RequiredPass->getPotentialPassManagerType()) && "Unable to handle Pass > that requires lower level Analysis pass"' failed. > > even though all passes are ModulePasses and do not require lower > level passes. > > The attached patch modifies PMDataManager::add() to check if the > required pass is actually a lower level pass before calling > addLowerLevelRequiredPass(); if not, it calls add() instead. Not sure > if this is the best fix, but it works for me. > > I also attached a test case with the three passes A, B, C described > above. > > Kevin > <passmanager.diff><PassTest1.cpp>This patch is not appropriate. At this point, the pass manager expects that all required passes at the same level (module pass, requiring module pass) are handled. The pass manager uses simplistic approach and does not handle cases where required passes cancels each other. And that's what happens in your example. Pass B cancels, already schedule Pass A. You've two alternatives: 1) Require pass B before requiring pass A. In other words, replace virtual void getAnalysisUsage(AnalysisUsage &use) const { use.addRequired<A>(); use.addRequired<B>(); } with virtual void getAnalysisUsage(AnalysisUsage &use) const { use.addRequired<B>(); use.addRequired<A>(); } 2) do $ opt -load libPassTest.so foo.bc -f -o /dev/null -b -c -debug- pass=Structure - Devang