Add support for ImmutablePasses, which are not run, and cannot be
authorChris Lattner <sabre@nondot.org>
Wed, 25 Sep 2002 21:59:11 +0000 (21:59 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 25 Sep 2002 21:59:11 +0000 (21:59 +0000)
invalidated.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3921 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Pass.h
include/llvm/PassAnalysisSupport.h
lib/VMCore/Pass.cpp
lib/VMCore/PassManagerT.h

index f237b1a791f02cdaf19c22d330720f7c5c6b4e1f..6242a4c81e955b46688ba651446b8ff1d3ab4b58 100644 (file)
@@ -32,6 +32,7 @@ class Function;
 class Module;
 class AnalysisUsage;
 class PassInfo;
+class ImmutablePass;
 template<class UnitType> 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<Module>;
+  virtual void addToPassManager(PassManagerT<Module> *PM, AnalysisUsage &AU);
+};
+
+
 //===----------------------------------------------------------------------===//
 /// FunctionPass class - This class is used to implement most global
 /// optimizations.  Optimizations should subclass this class if they meet the
index 490c5bf12c64637068b886669f937d38d29ef9a8..82fc9cb1b2d15142c40f42f35b727c2fd7d18e3a 100644 (file)
@@ -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!");
index 89b719c0dd89c5c24ee0dcbf737d52857fb250a6..85c4dec5fe722876aba27eb79f1a533512f219e2 100644 (file)
@@ -298,6 +298,15 @@ void Pass::dump() const {
   print(std::cerr, 0);
 }
 
+//===----------------------------------------------------------------------===//
+// ImmutablePass Implementation
+//
+void ImmutablePass::addToPassManager(PassManagerT<Module> *PM,
+                                     AnalysisUsage &AU) {
+  PM->addPass(this, AU);
+}
+
+
 //===----------------------------------------------------------------------===//
 // FunctionPass Implementation
 //
index afff535391b952ffd17a08ca9c037833896eab13..df54b06331ff1d3960f3a6f202a36f4815c4775b 100644 (file)
@@ -129,8 +129,10 @@ class PassManagerT : public PassManagerTraits<UnitType>,public AnalysisResolver{
   friend typename Traits::PassClass;
   friend typename Traits::SubPassClass;  
   friend class Traits;
+  friend class ImmutablePass;
 
   std::vector<PassClass*> Passes;    // List of passes to run
+  std::vector<ImmutablePass*> ImmutablePasses;  // List of immutable passes
 
   // The parent of this pass manager...
   ParentClass * const Parent;
@@ -157,6 +159,10 @@ public:
     for (typename std::vector<PassClass*>::iterator
            I = Passes.begin(), E = Passes.end(); I != E; ++I)
       delete *I;
+
+    for (std::vector<ImmutablePass*>::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<const PassInfo*> &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<Pass *, std::vector<Pass*> > LastUserOf;
     for (std::map<Pass*, Pass*>::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<ImmutablePass*>(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<AnalysisID> &PreservedSet = AnUsage.getPreservedSet();
       for (std::map<AnalysisID, Pass*>::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<const PassInfo*> &II = PI->getInterfacesImplemented();
+      for (unsigned i = 0, e = II.size(); i != e; ++i)
+        CurrentAnalyses[II[i]] = IP;
+    }
+  }
 };