Give each pass manager chance to manage lower level analysis pass, which is
authorDevang Patel <dpatel@apple.com>
Mon, 16 Apr 2007 20:12:57 +0000 (20:12 +0000)
committerDevang Patel <dpatel@apple.com>
Mon, 16 Apr 2007 20:12:57 +0000 (20:12 +0000)
pass required by one of pass managed by the manager.

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

include/llvm/PassManagers.h
lib/VMCore/PassManager.cpp

index c94a098a842f4032b1dbe909d2859310a2033f13..29912b140d764f74bdaced46a4a56b1aa015fdf8 100644 (file)
@@ -12,7 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/PassManager.h"
-
+#include "llvm/ADT/SmallVector.h"
 using namespace llvm;
 class llvm::PMDataManager;
 class llvm::PMStack;
@@ -221,6 +221,19 @@ public:
   /// AvailableAnalysis appropriately if ProcessAnalysis is true.
   void add(Pass *P, bool ProcessAnalysis = true);
 
+  /// Add RequiredPass into list of lower level passes required by pass P.
+  /// RequiredPass is run on the fly by Pass Manager when P requests it
+  /// through getAnalysis interface.
+  virtual void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) {
+    assert (0 && 
+            "Unable to handle Pass that requires lower level Analysis pass");
+  }
+
+  virtual Pass * getOnTheFlyPass(Pass *P, const PassInfo *PI, Function &F) {
+    assert (0 && "Unable to find on the fly pass");
+    return NULL;
+  }
+
   /// Initialize available analysis information.
   void initializeAnalysisInfo() { 
     AvailableAnalysis.clear();
@@ -233,10 +246,12 @@ public:
   bool preserveHigherLevelAnalysis(Pass *P);
 
 
-  /// Populate RequiredPasses with the analysis pass that are required by
-  /// pass P.
-  void collectRequiredAnalysisPasses(std::vector<Pass *> &RequiredPasses,
-                                     Pass *P);
+  /// Populate RequiredPasses with analysis pass that are required by
+  /// pass P and are available. Populate ReqPassNotAvailable with analysis
+  /// pass that are required by pass P but are not available.
+  void collectRequiredAnalysis(SmallVector<Pass *, 8> &RequiredPasses,
+                               SmallVector<AnalysisID, 8> &ReqPassNotAvailable,
+                               Pass *P);
 
   /// 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
index 37b8a5fbf3d70c1102620259ae1a3f60e16613c7..02a27c252732a7de8355e1227600fc49e2cd4dda 100644 (file)
@@ -190,6 +190,11 @@ public:
     Info.setPreservesAll();
   }
 
+  /// Add RequiredPass into list of lower level passes required by pass P.
+  /// RequiredPass is run on the fly by Pass Manager when P requests it
+  /// through getAnalysis interface.
+  virtual void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass);
+
   virtual const char *getPassName() const {
     return "Module Pass Manager";
   }
@@ -400,9 +405,14 @@ void PMTopLevelManager::schedulePass(Pass *P) {
 
     Pass *AnalysisPass = findAnalysisPass(*I);
     if (!AnalysisPass) {
-      // Schedule this analysis run first.
       AnalysisPass = (*I)->createPass();
-      schedulePass(AnalysisPass);
+      // Schedule this analysis run first only if it is not a lower level
+      // analysis pass. Lower level analsyis passes are run on the fly.
+      if (P->getPotentialPassManagerType () >=
+          AnalysisPass->getPotentialPassManagerType())
+        schedulePass(AnalysisPass);
+      else
+        delete AnalysisPass;
     }
   }
 
@@ -642,11 +652,14 @@ void PMDataManager::add(Pass *P,
 
     // At the moment, this pass is the last user of all required passes.
     std::vector<Pass *> LastUses;
-    std::vector<Pass *> RequiredPasses;
+    SmallVector<Pass *, 8> RequiredPasses;
+    SmallVector<AnalysisID, 8> ReqAnalysisNotAvailable;
+
     unsigned PDepth = this->getDepth();
 
-    collectRequiredAnalysisPasses(RequiredPasses, P);
-    for (std::vector<Pass *>::iterator I = RequiredPasses.begin(),
+    collectRequiredAnalysis(RequiredPasses, 
+                            ReqAnalysisNotAvailable, P);
+    for (SmallVector<Pass *, 8>::iterator I = RequiredPasses.begin(),
            E = RequiredPasses.end(); I != E; ++I) {
       Pass *PRequired = *I;
       unsigned RDepth = 0;
@@ -661,11 +674,16 @@ void PMDataManager::add(Pass *P,
         TransferLastUses.push_back(PRequired);
         // Keep track of higher level analysis used by this manager.
         HigherLevelAnalysis.push_back(PRequired);
-      } else {
-        // Note : This feature is not yet implemented
-        assert (0 && 
-                "Unable to handle Pass that requires lower level Analysis pass");
-      }
+      } else 
+        assert (0 && "Unable to accomodate Required Pass");
+    }
+
+    // Now, take care of required analysises that are not available.
+    for (SmallVector<AnalysisID, 8>::iterator 
+           I = ReqAnalysisNotAvailable.begin(), 
+           E = ReqAnalysisNotAvailable.end() ;I != E; ++I) {
+      Pass *AnalysisPass = (*I)->createPass();
+      this->addLowerLevelRequiredPass(P, AnalysisPass);
     }
 
     // Set P as P's last user until someone starts using P.
@@ -691,27 +709,34 @@ void PMDataManager::add(Pass *P,
   PassVector.push_back(P);
 }
 
-/// Populate RequiredPasses with the analysis pass that are required by
-/// pass P.
-void PMDataManager::collectRequiredAnalysisPasses(std::vector<Pass *> &RP,
-                                                  Pass *P) {
+
+/// Populate RP with analysis pass that are required by
+/// pass P and are available. Populate RP_NotAvail with analysis
+/// pass that are required by pass P but are not available.
+void PMDataManager::collectRequiredAnalysis(SmallVector<Pass *, 8>&RP,
+                                       SmallVector<AnalysisID, 8> &RP_NotAvail,
+                                            Pass *P) {
   AnalysisUsage AnUsage;
   P->getAnalysisUsage(AnUsage);
   const std::vector<AnalysisID> &RequiredSet = AnUsage.getRequiredSet();
   for (std::vector<AnalysisID>::const_iterator 
          I = RequiredSet.begin(), E = RequiredSet.end();
        I != E; ++I) {
-    Pass *AnalysisPass = findAnalysisPass(*I, true);
-    assert (AnalysisPass && "Analysis pass is not available");
-    RP.push_back(AnalysisPass);
+    AnalysisID AID = *I;
+    if (Pass *AnalysisPass = findAnalysisPass(*I, true))
+      RP.push_back(AnalysisPass);   
+    else
+      RP_NotAvail.push_back(AID);
   }
 
   const std::vector<AnalysisID> &IDs = AnUsage.getRequiredTransitiveSet();
   for (std::vector<AnalysisID>::const_iterator I = IDs.begin(),
          E = IDs.end(); I != E; ++I) {
-    Pass *AnalysisPass = findAnalysisPass(*I, true);
-    assert (AnalysisPass && "Analysis pass is not available");
-    RP.push_back(AnalysisPass);
+    AnalysisID AID = *I;
+    if (Pass *AnalysisPass = findAnalysisPass(*I, true))
+      RP.push_back(AnalysisPass);   
+    else
+      RP_NotAvail.push_back(AID);
   }
 }
 
@@ -1154,6 +1179,21 @@ MPPassManager::runOnModule(Module &M) {
   return Changed;
 }
 
+/// Add RequiredPass into list of lower level passes required by pass P.
+/// RequiredPass is run on the fly by Pass Manager when P requests it
+/// through getAnalysis interface.
+void MPPassManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) {
+
+  assert (P->getPotentialPassManagerType() == PMT_ModulePassManager
+          && "Unable to handle Pass that requires lower level Analysis pass");
+  assert ((P->getPotentialPassManagerType() < 
+           RequiredPass->getPotentialPassManagerType())
+          && "Unable to handle Pass that requires lower level Analysis pass");
+
+  assert (0 && 
+          "Unable to handle Pass that requires lower level Analysis pass");
+}
 //===----------------------------------------------------------------------===//
 // PassManagerImpl implementation
 //