diff --git a/llvm/include/llvm/Analysis/LoopPass.h b/llvm/include/llvm/Analysis/LoopPass.h index 4f449952d944..d04287d1ba1e 100644 --- a/llvm/include/llvm/Analysis/LoopPass.h +++ b/llvm/include/llvm/Analysis/LoopPass.h @@ -44,7 +44,15 @@ class LoopPass : public Pass { // Finalization hook does not supply Loop because at this time // loop nest is completely different. virtual bool doFinalization() { return false; } - + + // Check if this pass is suitable for the current LPPassManager, if + // available. This pass P is not suitable for a LPPassManager if P + // is not preserving higher level analysis info used by other + // LPPassManager passes. In such case, pop LPPassManager from the + // stack. This will force assignPassManager() to create new + // LPPassManger as expected. + void preparePassManager(PMStack &PMS); + /// Assign pass manager to manager this pass virtual void assignPassManager(PMStack &PMS, PassManagerType PMT = PMT_LoopPassManager); diff --git a/llvm/lib/Analysis/LoopPass.cpp b/llvm/lib/Analysis/LoopPass.cpp index 8d613b09f423..de062baec8ef 100644 --- a/llvm/lib/Analysis/LoopPass.cpp +++ b/llvm/lib/Analysis/LoopPass.cpp @@ -129,6 +129,31 @@ bool LPPassManager::runOnFunction(Function &F) { //===----------------------------------------------------------------------===// // LoopPass +// Check if this pass is suitable for the current LPPassManager, if +// available. This pass P is not suitable for a LPPassManager if P +// is not preserving higher level analysis info used by other +// LPPassManager passes. In such case, pop LPPassManager from the +// stack. This will force assignPassManager() to create new +// LPPassManger as expected. +void LoopPass::preparePassManager(PMStack &PMS) { + + // Find LPPassManager + while (!PMS.empty()) { + if (PMS.top()->getPassManagerType() > PMT_LoopPassManager) + PMS.pop(); + else; + break; + } + + LPPassManager *LPPM = dynamic_cast(PMS.top()); + + // If this pass is destroying high level information that is used + // by other passes that are managed by LPM then do not insert + // this pass in current LPM. Use new LPPassManager. + if (LPPM && !LPPM->preserveHigherLevelAnalysis(this)) + PMS.pop(); +} + /// Assign pass manager to manage this pass. void LoopPass::assignPassManager(PMStack &PMS, PassManagerType PreferredType) {