From 70b4f3e05106761e99cc56919767155cad0e2d3a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 25 Sep 2002 21:59:11 +0000 Subject: [PATCH] Add support for ImmutablePasses, which are not run, and cannot be invalidated. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3921 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Pass.h | 19 +++++++ include/llvm/PassAnalysisSupport.h | 1 + lib/VMCore/Pass.cpp | 9 ++++ lib/VMCore/PassManagerT.h | 84 ++++++++++++++++++++++++------ 4 files changed, 96 insertions(+), 17 deletions(-) diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h index f237b1a791f..6242a4c81e9 100644 --- a/include/llvm/Pass.h +++ b/include/llvm/Pass.h @@ -32,6 +32,7 @@ class Function; class Module; class AnalysisUsage; class PassInfo; +class ImmutablePass; template class PassManagerT; struct AnalysisResolver; @@ -194,6 +195,24 @@ inline std::ostream &operator<<(std::ostream &OS, const Pass &P) { P.print(OS, 0); return OS; } + + +//===----------------------------------------------------------------------===// +/// ImmutablePass class - This class is used to provide information that does +/// not need to be run. This is useful for things like target information and +/// "basic" versions of AnalysisGroups. +/// +struct ImmutablePass : public Pass { + + // ImmutablePasses are never run. + virtual bool run(Module &M) { return false; } + +private: + friend class PassManagerT; + virtual void addToPassManager(PassManagerT *PM, AnalysisUsage &AU); +}; + + //===----------------------------------------------------------------------===// /// FunctionPass class - This class is used to implement most global /// optimizations. Optimizations should subclass this class if they meet the diff --git a/include/llvm/PassAnalysisSupport.h b/include/llvm/PassAnalysisSupport.h index 490c5bf12c6..82fc9cb1b2d 100644 --- a/include/llvm/PassAnalysisSupport.h +++ b/include/llvm/PassAnalysisSupport.h @@ -86,6 +86,7 @@ public: struct AnalysisResolver { virtual Pass *getAnalysisOrNullUp(AnalysisID ID) const = 0; virtual Pass *getAnalysisOrNullDown(AnalysisID ID) const = 0; + virtual void addPass(ImmutablePass *IP, AnalysisUsage &AU) = 0; Pass *getAnalysis(AnalysisID ID) const { Pass *Result = getAnalysisOrNullUp(ID); assert(Result && "Pass has an incorrect analysis uses set!"); diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp index 89b719c0dd8..85c4dec5fe7 100644 --- a/lib/VMCore/Pass.cpp +++ b/lib/VMCore/Pass.cpp @@ -298,6 +298,15 @@ void Pass::dump() const { print(std::cerr, 0); } +//===----------------------------------------------------------------------===// +// ImmutablePass Implementation +// +void ImmutablePass::addToPassManager(PassManagerT *PM, + AnalysisUsage &AU) { + PM->addPass(this, AU); +} + + //===----------------------------------------------------------------------===// // FunctionPass Implementation // diff --git a/lib/VMCore/PassManagerT.h b/lib/VMCore/PassManagerT.h index afff535391b..df54b06331f 100644 --- a/lib/VMCore/PassManagerT.h +++ b/lib/VMCore/PassManagerT.h @@ -129,8 +129,10 @@ class PassManagerT : public PassManagerTraits,public AnalysisResolver{ friend typename Traits::PassClass; friend typename Traits::SubPassClass; friend class Traits; + friend class ImmutablePass; std::vector Passes; // List of passes to run + std::vector ImmutablePasses; // List of immutable passes // The parent of this pass manager... ParentClass * const Parent; @@ -157,6 +159,10 @@ public: for (typename std::vector::iterator I = Passes.begin(), E = Passes.end(); I != E; ++I) delete *I; + + for (std::vector::iterator + I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I) + delete *I; } // run - Run all of the queued passes on the specified module in an optimal @@ -166,6 +172,17 @@ public: closeBatcher(); CurrentAnalyses.clear(); + // Add any immutable passes to the CurrentAnalyses set... + for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) + if (const PassInfo *PI = ImmutablePasses[i]->getPassInfo()) { + CurrentAnalyses[PI] = ImmutablePasses[i]; + + const std::vector &II = PI->getInterfacesImplemented(); + for (unsigned i = 0, e = II.size(); i != e; ++i) + CurrentAnalyses[II[i]] = ImmutablePasses[i]; + } + + // LastUserOf - This contains the inverted LastUseOfMap... std::map > LastUserOf; for (std::map::iterator I = LastUseOf.begin(), @@ -238,13 +255,17 @@ public: PreservedSet.end()) ++I; // This analysis is preserved, leave it in the available set... else { + if (!dynamic_cast(I->second)) { #if MAP_DOESNT_HAVE_BROKEN_ERASE_MEMBER - I = CurrentAnalyses.erase(I); // Analysis not preserved! + I = CurrentAnalyses.erase(I); // Analysis not preserved! #else - // GCC 2.95.3 STL doesn't have correct erase member! - CurrentAnalyses.erase(I); - I = CurrentAnalyses.begin(); + // GCC 2.95.3 STL doesn't have correct erase member! + CurrentAnalyses.erase(I); + I = CurrentAnalyses.begin(); #endif + } else { + ++I; + } } } @@ -345,11 +366,15 @@ public: // parent that we (the passmanager) are using the analysis so that it // frees the analysis AFTER this pass manager runs. // - assert(Parent != 0 && "Pass available but not found!"); - Parent->markPassUsed(P, this); + if (Parent) { + Parent->markPassUsed(P, this); + } else { + assert(0 && "Pass available but not found! " + "Perhaps this is a module pass requiring a function pass?"); + } } } - + // Return the number of parent PassManagers that exist virtual unsigned getDepth() const { if (Parent == 0) return 0; @@ -428,18 +453,15 @@ private: if (!AnUsage.preservesAll()) { const std::vector &PreservedSet = AnUsage.getPreservedSet(); for (std::map::iterator I = CurrentAnalyses.begin(), - E = CurrentAnalyses.end(); I != E; ) - if (std::find(PreservedSet.begin(), PreservedSet.end(), I->first) != - PreservedSet.end()) - ++I; // This analysis is preserved, leave it in the available set... - else { -#if MAP_DOESNT_HAVE_BROKEN_ERASE_MEMBER - I = CurrentAnalyses.erase(I); // Analysis not preserved! -#else - CurrentAnalyses.erase(I);// GCC 2.95.3 STL doesn't have correct erase! + E = CurrentAnalyses.end(); I != E; ) { + if (std::find(PreservedSet.begin(), PreservedSet.end(), I->first) == + PreservedSet.end()) { // Analysis not preserved! + CurrentAnalyses.erase(I); // Remove from available analyses I = CurrentAnalyses.begin(); -#endif + } else { + ++I; } + } } // Add this pass to the currently available set... @@ -476,6 +498,34 @@ private: Batcher = 0; } } + +public: + // When an ImmutablePass is added, it gets added to the top level pass + // manager. + void addPass(ImmutablePass *IP, AnalysisUsage &AU) { + if (Parent) { // Make sure this request goes to the top level passmanager... + Parent->addPass(IP, AU); + return; + } + + // Set the Resolver instance variable in the Pass so that it knows where to + // find this object... + // + setAnalysisResolver(IP, this); + ImmutablePasses.push_back(IP); + + // Add this pass to the currently available set... + if (const PassInfo *PI = IP->getPassInfo()) { + CurrentAnalyses[PI] = IP; + + // This pass is the current implementation of all of the interfaces it + // implements as well. + // + const std::vector &II = PI->getInterfacesImplemented(); + for (unsigned i = 0, e = II.size(); i != e; ++i) + CurrentAnalyses[II[i]] = IP; + } + } }; -- 2.34.1