Allocation insts always have one operand
[oota-llvm.git] / lib / VMCore / PassManagerT.h
index 3f2dc76f5140bb5d567afd6055f9910aac69bbc5..4a2ad8867146d875df239874481e2f44dfea4fda 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "llvm/Pass.h"
 #include "Support/CommandLine.h"
+#include "Support/LeakDetector.h"
 #include <algorithm>
 #include <iostream>
 class Annotable;
@@ -74,8 +75,24 @@ struct PMDebug {
 // amount of time each pass takes to execute.  This only happens when
 // -time-passes is enabled on the command line.
 //
+struct TimeRecord {      // TimeRecord - Data we collect and print for each pass
+  double Elapsed;        // Wall clock time elapsed in seconds
+  double UserTime;       // User time elapsed
+  double SystemTime;     // System time elapsed
+  unsigned long MaxRSS;  // Maximum resident set size (in bytes)
+  unsigned long RSSTemp; // Temp for calculating maxrss
+
+  TimeRecord() : Elapsed(0), UserTime(0), SystemTime(0), MaxRSS(0) {}
+  void passStart(const TimeRecord &T);
+  void passEnd(const TimeRecord &T);
+  void sum(const TimeRecord &TR);
+  bool operator<(const TimeRecord &TR) const;
+
+  void print(const char *PassName, const TimeRecord &TotalTime) const;
+};
+
 class TimingInfo {
-  std::map<Pass*, double> TimingData;
+  std::map<Pass*, TimeRecord> TimingData;
   TimingInfo() {}   // Private ctor, must use create member
 public:
   // Create method.  If Timing is enabled, this creates and returns a new timing
@@ -90,8 +107,6 @@ public:
   void passEnded(Pass *P);
 };
 
-
-
 //===----------------------------------------------------------------------===//
 // Declare the PassManagerTraits which will be specialized...
 //
@@ -174,14 +189,28 @@ public:
       PMDebug::PrintAnalysisSetInfo(getDepth(), "Required", P,
                                     AnUsage.getRequiredSet());
 
-#ifndef NDEBUG
-      // All Required analyses should be available to the pass as it runs!
-      for (std::vector<AnalysisID>::const_iterator
+      // All Required analyses should be available to the pass as it runs!  Here
+      // we fill in the AnalysisImpls member of the pass so that it can
+      // successfully use the getAnalysis() method to retrieve the
+      // implementations it needs.
+      //
+      P->AnalysisImpls.clear();
+      P->AnalysisImpls.reserve(AnUsage.getRequiredSet().size());
+      for (std::vector<const PassInfo *>::const_iterator
              I = AnUsage.getRequiredSet().begin(), 
              E = AnUsage.getRequiredSet().end(); I != E; ++I) {
-        assert(getAnalysisOrNullUp(*I) && "Analysis used but not available!");
+        Pass *Impl = getAnalysisOrNullUp(*I);
+        if (Impl == 0) {
+          std::cerr << "Analysis '" << (*I)->getPassName()
+                    << "' used but not available!";
+          assert(0 && "Analysis used but not available!");
+        } else if (PassDebugging == Details) {
+          if ((*I)->getPassName() != std::string(Impl->getPassName()))
+            std::cerr << "    Interface '" << (*I)->getPassName()
+                    << "' implemented by '" << Impl->getPassName() << "'\n";
+        }
+        P->AnalysisImpls.push_back(std::make_pair(*I, Impl));
       }
-#endif
 
       // Run the sub pass!
       startPass(P);
@@ -189,6 +218,10 @@ public:
       endPass(P);
       MadeChanges |= Changed;
 
+      // Check for memory leaks by the pass...
+      LeakDetector::checkForGarbage(std::string("after running pass '") +
+                                    P->getPassName() + "'");
+
       if (Changed)
         PMDebug::PrintPassInformation(getDepth()+1, "Made Modification", P,
                                       (Annotable*)M);
@@ -218,9 +251,17 @@ public:
       // Add the current pass to the set of passes that have been run, and are
       // thus available to users.
       //
-      if (const PassInfo *PI = P->getPassInfo())
+      if (const PassInfo *PI = P->getPassInfo()) {
         CurrentAnalyses[PI] = P;
 
+        // 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]] = P;
+      }
+
       // Free memory for any passes that we are the last use of...
       std::vector<Pass*> &DeadPass = LastUserOf[P];
       for (std::vector<Pass*>::iterator I = DeadPass.begin(),E = DeadPass.end();
@@ -253,24 +294,25 @@ public:
     }
   }
 
-  Pass *getAnalysisOrNullDown(AnalysisID ID) const {
+  Pass *getAnalysisOrNullDown(const PassInfo *ID) const {
     std::map<AnalysisID, Pass*>::const_iterator I = CurrentAnalyses.find(ID);
-    if (I == CurrentAnalyses.end()) {
-      if (Batcher)
-        return ((AnalysisResolver*)Batcher)->getAnalysisOrNullDown(ID);
-      return 0;
-    }
-    return I->second;
+
+    if (I != CurrentAnalyses.end())
+      return I->second;  // Found it.
+
+    if (Batcher)
+      return ((AnalysisResolver*)Batcher)->getAnalysisOrNullDown(ID);
+    return 0;
   }
 
-  Pass *getAnalysisOrNullUp(AnalysisID ID) const {
+  Pass *getAnalysisOrNullUp(const PassInfo *ID) const {
     std::map<AnalysisID, Pass*>::const_iterator I = CurrentAnalyses.find(ID);
-    if (I == CurrentAnalyses.end()) {
-      if (Parent)
-        return Parent->getAnalysisOrNullUp(ID);
-      return 0;
-    }
-    return I->second;
+    if (I != CurrentAnalyses.end())
+      return I->second;  // Found it.
+
+    if (Parent)          // Try scanning...
+      return Parent->getAnalysisOrNullUp(ID);
+    return 0;
   }
 
   // {start/end}Pass - Called when a pass is started, it just propogates
@@ -292,8 +334,9 @@ public:
   // make sure that analyses are not free'd before we have to use
   // them...
   //
-  void markPassUsed(AnalysisID P, Pass *User) {
-    std::map<AnalysisID, Pass*>::iterator I = CurrentAnalyses.find(P);
+  void markPassUsed(const PassInfo *P, Pass *User) {
+    std::map<AnalysisID, Pass*>::const_iterator I = CurrentAnalyses.find(P);
+
     if (I != CurrentAnalyses.end()) {
       LastUseOf[I->second] = User;    // Local pass, extend the lifetime
     } else {
@@ -302,8 +345,7 @@ 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! "
-             "Did your analysis pass 'Provide' itself?");
+      assert(Parent != 0 && "Pass available but not found!");
       Parent->markPassUsed(P, this);
     }
   }
@@ -320,7 +362,7 @@ public:
     return Passes[N];
   }
 
-  // add - Add a pass to the queue of passes to run.  This passes ownership of
+  // add - Add a pass to the queue of passes to run.  This gives ownership of
   // the Pass to the PassManager.  When the PassManager is destroyed, the pass
   // will be destroyed as well, so there is no need to delete the pass.  This
   // implies that all passes MUST be new'd.
@@ -401,9 +443,17 @@ private:
     }
 
     // Add this pass to the currently available set...
-    if (const PassInfo *PI = P->getPassInfo())
+    if (const PassInfo *PI = P->getPassInfo()) {
       CurrentAnalyses[PI] = P;
 
+      // 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]] = P;
+    }
+
     // For now assume that our results are never used...
     LastUseOf[P] = P;
   }