Initialize AnalysisImpls for each pass before executing the pass.
[oota-llvm.git] / lib / VMCore / PassManager.cpp
index 1141c6a32918198d8051ffd004a6bb1f8ab98ad1..06f7af86bba05c8c6668ae9b9e345b9d1437fbd6 100644 (file)
@@ -86,6 +86,8 @@ using namespace llvm;
 
 namespace llvm {
 
+class PMDataManager;
+
 //===----------------------------------------------------------------------===//
 // PMTopLevelManager
 //
@@ -137,11 +139,25 @@ public:
     return ImmutablePasses;
   }
 
+  void addPassManager(Pass *Manager) {
+    PassManagers.push_back(Manager);
+  }
+
+  // Add Manager into the list of managers that are not directly
+  // maintained by this top level pass manager
+  inline void addIndirectPassManager(PMDataManager *Manager) {
+    IndirectPassManagers.push_back(Manager);
+  }
+
 private:
   
   /// Collection of pass managers
   std::vector<Pass *> PassManagers;
 
+  /// Collection of pass managers that are not directly maintained
+  /// by this pass manager
+  std::vector<PMDataManager *> IndirectPassManagers;
+
   // Map to keep track of last user of the analysis pass.
   // LastUser->second is the last user of Lastuser->first.
   std::map<Pass *, Pass *> LastUser;
@@ -150,94 +166,6 @@ private:
   std::vector<ImmutablePass *> ImmutablePasses;
 };
   
-/// Set pass P as the last user of the given analysis passes.
-void PMTopLevelManager::setLastUser(std::vector<Pass *> &AnalysisPasses, 
-                                    Pass *P) {
-
-  for (std::vector<Pass *>::iterator I = AnalysisPasses.begin(),
-         E = AnalysisPasses.end(); I != E; ++I) {
-    Pass *AP = *I;
-    LastUser[AP] = P;
-    // If AP is the last user of other passes then make P last user of
-    // such passes.
-    for (std::map<Pass *, Pass *>::iterator LUI = LastUser.begin(),
-           LUE = LastUser.end(); LUI != LUE; ++LUI) {
-      if (LUI->second == AP)
-        LastUser[LUI->first] = P;
-    }
-  }
-
-}
-
-/// Collect passes whose last user is P
-void PMTopLevelManager::collectLastUses(std::vector<Pass *> &LastUses,
-                                            Pass *P) {
-   for (std::map<Pass *, Pass *>::iterator LUI = LastUser.begin(),
-          LUE = LastUser.end(); LUI != LUE; ++LUI)
-      if (LUI->second == P)
-        LastUses.push_back(LUI->first);
-}
-
-/// Schedule pass P for execution. Make sure that passes required by
-/// P are run before P is run. Update analysis info maintained by
-/// the manager. Remove dead passes. This is a recursive function.
-void PMTopLevelManager::schedulePass(Pass *P) {
-
-  // TODO : Allocate function manager for this pass, other wise required set
-  // may be inserted into previous function manager
-
-  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);
-    if (!AnalysisPass) {
-      // Schedule this analysis run first.
-      AnalysisPass = (*I)->createPass();
-      schedulePass(AnalysisPass);
-    }
-  }
-
-  // Now all required passes are available.
-  addTopLevelPass(P);
-}
-
-/// Find the pass that implements Analysis AID. Search immutable
-/// passes and all pass managers. If desired pass is not found
-/// then return NULL.
-Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) {
-
-  Pass *P = NULL;
-  for (std::vector<ImmutablePass *>::iterator I = ImmutablePasses.begin(),
-         E = ImmutablePasses.end(); P == NULL && I != E; ++I) {
-    const PassInfo *PI = (*I)->getPassInfo();
-    if (PI == AID)
-      P = *I;
-
-    // If Pass not found then check the interfaces implemented by Immutable Pass
-    if (!P) {
-      const std::vector<const PassInfo*> &ImmPI = 
-        PI->getInterfacesImplemented();
-      for (unsigned Index = 0, End = ImmPI.size(); 
-           P == NULL && Index != End; ++Index)
-        if (ImmPI[Index] == AID)
-          P = *I;
-    }
-  }
-
-  if (P)
-    return P;
-
-  // Check pass managers;
-  for (std::vector<Pass *>::iterator I = PassManagers.begin(),
-         E = PassManagers.end(); P == NULL && I != E; ++I) 
-    P = NULL; // FIXME: (*I)->findAnalysisPass(AID, false /* Search downward */);
-
-  return P;
-}
-
 //===----------------------------------------------------------------------===//
 // PMDataManager
 
@@ -272,12 +200,6 @@ public:
   void initializeAnalysisInfo() { 
     ForcedLastUses.clear();
     AvailableAnalysis.clear();
-
-    // Include immutable passes into AvailableAnalysis vector.
-    std::vector<ImmutablePass *> &ImmutablePasses =  TPM->getImmutablePasses();
-    for (std::vector<ImmutablePass *>::iterator I = ImmutablePasses.begin(),
-           E = ImmutablePasses.end(); I != E; ++I) 
-      recordAvailableAnalysis(*I);
   }
 
   /// Populate RequiredPasses with the analysis pass that are required by
@@ -317,7 +239,6 @@ protected:
   std::vector<Pass *> ForcedLastUses;
 
   // Top level manager.
-  // TODO : Make it a reference.
   PMTopLevelManager *TPM;
 
 private:
@@ -333,6 +254,9 @@ private:
   unsigned Depth;
 };
 
+//===----------------------------------------------------------------------===//
+// BasicBlockPassManager_New
+//
 /// BasicBlockPassManager_New manages BasicBlockPass. It batches all the
 /// pass together and sequence them to process one basic block before
 /// processing next basic block.
@@ -361,6 +285,9 @@ public:
 
 };
 
+//===----------------------------------------------------------------------===//
+// FunctionPassManagerImpl_New
+//
 /// FunctionPassManagerImpl_New manages FunctionPasses and BasicBlockPassManagers.
 /// It batches all function passes and basic block pass managers together and
 /// sequence them to process one function at a time before processing next
@@ -369,15 +296,25 @@ class FunctionPassManagerImpl_New : public ModulePass,
                                     public PMDataManager,
                                     public PMTopLevelManager {
 public:
-  FunctionPassManagerImpl_New(ModuleProvider *P, int D) :
-    PMDataManager(D) { /* TODO */ }
   FunctionPassManagerImpl_New(int D) : PMDataManager(D) { 
     activeBBPassManager = NULL;
   }
   ~FunctionPassManagerImpl_New() { /* TODO */ };
  
   inline void addTopLevelPass(Pass *P) { 
-    addPass(P);
+
+    if (ImmutablePass *IP = dynamic_cast<ImmutablePass *> (P)) {
+
+      // P is a immutable pass then it will be managed by this
+      // top level manager. Set up analysis resolver to connect them.
+      AnalysisResolver_New *AR = new AnalysisResolver_New(*this);
+      P->setResolver(AR);
+      initializeAnalysisImpl(P);
+      addImmutablePass(IP);
+      recordAvailableAnalysis(IP);
+    } 
+    else 
+      addPass(P);
   }
 
   /// add - Add a pass to the queue of passes to run.  This passes
@@ -397,6 +334,7 @@ public:
   /// so, return true.
   bool runOnModule(Module &M);
   bool runOnFunction(Function &F);
+  bool run(Function &F);
 
   /// doInitialization - Run all of the initializers for the function passes.
   ///
@@ -416,6 +354,9 @@ private:
   BasicBlockPassManager_New *activeBBPassManager;
 };
 
+//===----------------------------------------------------------------------===//
+// ModulePassManager_New
+//
 /// ModulePassManager_New manages ModulePasses and function pass managers.
 /// It batches all Module passes  passes and function pass managers together and
 /// sequence them to process one module.
@@ -444,14 +385,19 @@ private:
   FunctionPassManagerImpl_New *activeFunctionPassManager;
 };
 
-/// PassManager_New manages ModulePassManagers
+//===----------------------------------------------------------------------===//
+// PassManagerImpl_New
+//
+/// PassManagerImpl_New manages ModulePassManagers
 class PassManagerImpl_New : public Pass,
                             public PMDataManager,
                             public PMTopLevelManager {
 
 public:
 
-  PassManagerImpl_New(int D) : PMDataManager(D) {}
+  PassManagerImpl_New(int D) : PMDataManager(D) {
+    activeManager = NULL;
+  }
 
   /// add - Add a pass to the queue of passes to run.  This passes ownership of
   /// the Pass to the PassManager.  When the PassManager is destroyed, the pass
@@ -471,7 +417,19 @@ public:
   }
 
   inline void addTopLevelPass(Pass *P) {
-    addPass(P);
+
+    if (ImmutablePass *IP = dynamic_cast<ImmutablePass *> (P)) {
+      
+      // P is a immutable pass and it will be managed by this
+      // top level manager. Set up analysis resolver to connect them.
+      AnalysisResolver_New *AR = new AnalysisResolver_New(*this);
+      P->setResolver(AR);
+      initializeAnalysisImpl(P);
+      addImmutablePass(IP);
+      recordAvailableAnalysis(IP);
+    }
+    else 
+      addPass(P);
   }
 
 private:
@@ -479,15 +437,108 @@ private:
   /// Add a pass into a passmanager queue.
   bool addPass(Pass *p);
 
-  // Collection of pass managers
-  std::vector<ModulePassManager_New *> PassManagers;
-
   // Active Pass Manager
   ModulePassManager_New *activeManager;
 };
 
 } // End of llvm namespace
 
+//===----------------------------------------------------------------------===//
+// PMTopLevelManager implementation
+
+/// Set pass P as the last user of the given analysis passes.
+void PMTopLevelManager::setLastUser(std::vector<Pass *> &AnalysisPasses, 
+                                    Pass *P) {
+
+  for (std::vector<Pass *>::iterator I = AnalysisPasses.begin(),
+         E = AnalysisPasses.end(); I != E; ++I) {
+    Pass *AP = *I;
+    LastUser[AP] = P;
+    // If AP is the last user of other passes then make P last user of
+    // such passes.
+    for (std::map<Pass *, Pass *>::iterator LUI = LastUser.begin(),
+           LUE = LastUser.end(); LUI != LUE; ++LUI) {
+      if (LUI->second == AP)
+        LastUser[LUI->first] = P;
+    }
+  }
+
+}
+
+/// Collect passes whose last user is P
+void PMTopLevelManager::collectLastUses(std::vector<Pass *> &LastUses,
+                                            Pass *P) {
+   for (std::map<Pass *, Pass *>::iterator LUI = LastUser.begin(),
+          LUE = LastUser.end(); LUI != LUE; ++LUI)
+      if (LUI->second == P)
+        LastUses.push_back(LUI->first);
+}
+
+/// Schedule pass P for execution. Make sure that passes required by
+/// P are run before P is run. Update analysis info maintained by
+/// the manager. Remove dead passes. This is a recursive function.
+void PMTopLevelManager::schedulePass(Pass *P) {
+
+  // TODO : Allocate function manager for this pass, other wise required set
+  // may be inserted into previous function manager
+
+  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);
+    if (!AnalysisPass) {
+      // Schedule this analysis run first.
+      AnalysisPass = (*I)->createPass();
+      schedulePass(AnalysisPass);
+    }
+  }
+
+  // Now all required passes are available.
+  addTopLevelPass(P);
+}
+
+/// Find the pass that implements Analysis AID. Search immutable
+/// passes and all pass managers. If desired pass is not found
+/// then return NULL.
+Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) {
+
+  Pass *P = NULL;
+  // Check pass managers
+  for (std::vector<Pass *>::iterator I = PassManagers.begin(),
+         E = PassManagers.end(); P == NULL && I != E; ++I) {
+    PMDataManager *PMD = dynamic_cast<PMDataManager *>(*I);
+    assert(PMD && "This is not a PassManager");
+    P = PMD->findAnalysisPass(AID, false);
+  }
+
+  // Check other pass managers
+  for (std::vector<PMDataManager *>::iterator I = IndirectPassManagers.begin(),
+         E = IndirectPassManagers.end(); P == NULL && I != E; ++I)
+    P = (*I)->findAnalysisPass(AID, false);
+
+  for (std::vector<ImmutablePass *>::iterator I = ImmutablePasses.begin(),
+         E = ImmutablePasses.end(); P == NULL && I != E; ++I) {
+    const PassInfo *PI = (*I)->getPassInfo();
+    if (PI == AID)
+      P = *I;
+
+    // If Pass not found then check the interfaces implemented by Immutable Pass
+    if (!P) {
+      const std::vector<const PassInfo*> &ImmPI = 
+        PI->getInterfacesImplemented();
+      for (unsigned Index = 0, End = ImmPI.size(); 
+           P == NULL && Index != End; ++Index)
+        if (ImmPI[Index] == AID)
+          P = *I;
+    }
+  }
+
+  return P;
+}
+
 //===----------------------------------------------------------------------===//
 // PMDataManager implementation
 
@@ -529,13 +580,17 @@ void PMDataManager::removeNotPreservedAnalysis(Pass *P) {
 
   const std::vector<AnalysisID> &PreservedSet = AnUsage.getPreservedSet();
   for (std::map<AnalysisID, Pass*>::iterator I = AvailableAnalysis.begin(),
-         E = AvailableAnalysis.end(); I != E; ++I ) {
+         E = AvailableAnalysis.end(); I != E; ) {
     if (std::find(PreservedSet.begin(), PreservedSet.end(), I->first) == 
         PreservedSet.end()) {
       // Remove this analysis
-      std::map<AnalysisID, Pass*>::iterator J = I++;
-      AvailableAnalysis.erase(J);
-    }
+      if (!dynamic_cast<ImmutablePass*>(I->second)) {
+        std::map<AnalysisID, Pass*>::iterator J = I++;
+        AvailableAnalysis.erase(J);
+      } else
+        ++I;
+    } else
+      ++I;
   }
 }
 
@@ -563,6 +618,11 @@ void PMDataManager::removeDeadPasses(Pass *P) {
 void PMDataManager::addPassToManager(Pass *P, 
                                      bool ProcessAnalysis) {
 
+  // This manager is going to manage pass P. Set up analysis resolver
+  // to connect them.
+  AnalysisResolver_New *AR = new AnalysisResolver_New(*this);
+  P->setResolver(AR);
+
   if (ProcessAnalysis) {
 
     // At the moment, this pass is the last user of all required passes.
@@ -575,7 +635,10 @@ void PMDataManager::addPassToManager(Pass *P,
            E = RequiredPasses.end(); I != E; ++I) {
       Pass *PRequired = *I;
       unsigned RDepth = 0;
-      //FIXME: RDepth = PRequired->getResolver()->getDepth();
+
+      PMDataManager &DM = PRequired->getResolver()->getPMDataManager();
+      RDepth = DM.getDepth();
+
       if (PDepth == RDepth)
         LastUses.push_back(PRequired);
       else if (PDepth >  RDepth) {
@@ -593,7 +656,6 @@ void PMDataManager::addPassToManager(Pass *P,
 
     // Take a note of analysis required and made available by this pass.
     // Remove the analysis not preserved by this pass
-    initializeAnalysisImpl(P);
     removeNotPreservedAnalysis(P);
     recordAvailableAnalysis(P);
   }
@@ -616,6 +678,14 @@ void PMDataManager::collectRequiredAnalysisPasses(std::vector<Pass *> &RP,
     assert (AnalysisPass && "Analysis pass is not available");
     RP.push_back(AnalysisPass);
   }
+
+  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);
+  }
 }
 
 // All Required analyses should be available to the pass as it runs!  Here
@@ -633,7 +703,8 @@ void PMDataManager::initializeAnalysisImpl(Pass *P) {
     Pass *Impl = findAnalysisPass(*I, true);
     if (Impl == 0)
       assert(0 && "Analysis used but not available!");
-    // TODO:  P->AnalysisImpls.push_back(std::make_pair(*I, Impl));
+    AnalysisResolver_New *AR = P->getResolver();
+    AR->addAnalysisImplsPair(*I, Impl);
   }
 }
 
@@ -651,14 +722,15 @@ Pass *PMDataManager::findAnalysisPass(AnalysisID AID, bool SearchParent) {
   if (SearchParent)
     return TPM->findAnalysisPass(AID);
   
-  // FIXME : This is expensive and requires. Need to check only managers not all passes.
-  // One solution is to collect managers in advance at TPM level.
-  Pass *P = NULL;
-  for(std::vector<Pass *>::iterator I = passVectorBegin(),
-        E = passVectorEnd(); P == NULL && I!= E; ++I )
-    P = NULL; // FIXME : P = (*I)->getResolver()->getAnalysisToUpdate(AID, false /* Do not search parents again */);
+  return NULL;
+}
 
-  return P;
+
+//===----------------------------------------------------------------------===//
+// NOTE: Is this the right place to define this method ?
+// getAnalysisToUpdate - Return an analysis result or null if it doesn't exist
+Pass *AnalysisResolver_New::getAnalysisToUpdate(AnalysisID ID, bool dir) const {
+  return PM.findAnalysisPass(ID, dir);
 }
 
 //===----------------------------------------------------------------------===//
@@ -696,7 +768,7 @@ BasicBlockPassManager_New::runOnFunction(Function &F) {
     for (std::vector<Pass *>::iterator itr = passVectorBegin(),
            e = passVectorEnd(); itr != e; ++itr) {
       Pass *P = *itr;
-      
+      initializeAnalysisImpl(P);
       BasicBlockPass *BP = dynamic_cast<BasicBlockPass*>(P);
       Changed |= BP->runOnBasicBlock(*I);
       removeNotPreservedAnalysis(P);
@@ -770,6 +842,8 @@ FunctionPassManager_New::FunctionPassManager_New() {
 
 FunctionPassManager_New::FunctionPassManager_New(ModuleProvider *P) {
   FPM = new FunctionPassManagerImpl_New(0);
+  // FPM is the top level manager.
+  FPM->setTopLevelManager(FPM);
   MP = P;
 }
 
@@ -799,7 +873,7 @@ bool FunctionPassManager_New::run(Function &F) {
     cerr << "Error reading bytecode file: " << errstr << "\n";
     abort();
   }
-  return FPM->runOnFunction(F);
+  return FPM->run(F);
 }
 
 
@@ -836,8 +910,17 @@ FunctionPassManagerImpl_New::addPass(Pass *P) {
       // Create and add new manager
       activeBBPassManager = 
         new BasicBlockPassManager_New(getDepth() + 1);
+      // Inherit top level manager
+      activeBBPassManager->setTopLevelManager(this->getTopLevelManager());
+
+      // Add new manager into current manager's list.
       addPassToManager(activeBBPassManager, false);
 
+      // Add new manager into top level manager's indirect passes list
+      PMDataManager *PMD = dynamic_cast<PMDataManager *>(activeBBPassManager);
+      assert (PMD && "Manager is not Pass Manager");
+      TPM->addIndirectPassManager(PMD);
+
       // Add pass into new manager. This time it must succeed.
       if (!activeBBPassManager->addPass(BP))
         assert(0 && "Unable to add Pass");
@@ -894,7 +977,7 @@ bool FunctionPassManagerImpl_New::runOnFunction(Function &F) {
   for (std::vector<Pass *>::iterator itr = passVectorBegin(),
          e = passVectorEnd(); itr != e; ++itr) {
     Pass *P = *itr;
-    
+    initializeAnalysisImpl(P);    
     FunctionPass *FP = dynamic_cast<FunctionPass*>(P);
     Changed |= FP->runOnFunction(F);
     removeNotPreservedAnalysis(P);
@@ -933,6 +1016,19 @@ inline bool FunctionPassManagerImpl_New::doFinalization(Module &M) {
   return Changed;
 }
 
+// Execute all the passes managed by this top level manager.
+// Return true if any function is modified by a pass.
+bool FunctionPassManagerImpl_New::run(Function &F) {
+
+  bool Changed = false;
+  for (std::vector<Pass *>::iterator I = passManagersBegin(),
+         E = passManagersEnd(); I != E; ++I) {
+    FunctionPass *FP = dynamic_cast<FunctionPass *>(*I);
+    Changed |= FP->runOnFunction(F);
+  }
+  return Changed;
+}
+
 //===----------------------------------------------------------------------===//
 // ModulePassManager implementation
 
@@ -954,8 +1050,18 @@ ModulePassManager_New::addPass(Pass *P) {
       // Create and add new manager
       activeFunctionPassManager = 
         new FunctionPassManagerImpl_New(getDepth() + 1);
+      
+      // Add new manager into current manager's list
       addPassToManager(activeFunctionPassManager, false);
 
+      // Inherit top level manager
+      activeFunctionPassManager->setTopLevelManager(this->getTopLevelManager());
+
+      // Add new manager into top level manager's indirect passes list
+      PMDataManager *PMD = dynamic_cast<PMDataManager *>(activeFunctionPassManager);
+      assert (PMD && "Manager is not Pass Manager");
+      TPM->addIndirectPassManager(PMD);
+      
       // Add pass into new manager. This time it must succeed.
       if (!activeFunctionPassManager->addPass(FP))
         assert(0 && "Unable to add pass");
@@ -998,7 +1104,7 @@ ModulePassManager_New::runOnModule(Module &M) {
   for (std::vector<Pass *>::iterator itr = passVectorBegin(),
          e = passVectorEnd(); itr != e; ++itr) {
     Pass *P = *itr;
-
+    initializeAnalysisImpl(P);
     ModulePass *MP = dynamic_cast<ModulePass*>(P);
     Changed |= MP->runOnModule(M);
     removeNotPreservedAnalysis(P);
@@ -1018,7 +1124,15 @@ bool PassManagerImpl_New::addPass(Pass *P) {
 
   if (!activeManager || !activeManager->addPass(P)) {
     activeManager = new ModulePassManager_New(getDepth() + 1);
-    PassManagers.push_back(activeManager);
+    // Inherit top level manager
+    activeManager->setTopLevelManager(this->getTopLevelManager());
+
+    // This top level manager is going to manage activeManager. 
+    // Set up analysis resolver to connect them.
+    AnalysisResolver_New *AR = new AnalysisResolver_New(*this);
+    activeManager->setResolver(AR);
+
+    addPassManager(activeManager);
     return activeManager->addPass(P);
   }
   return true;
@@ -1029,10 +1143,10 @@ bool PassManagerImpl_New::addPass(Pass *P) {
 bool PassManagerImpl_New::run(Module &M) {
 
   bool Changed = false;
-  for (std::vector<ModulePassManager_New *>::iterator itr = PassManagers.begin(),
-         e = PassManagers.end(); itr != e; ++itr) {
-    ModulePassManager_New *pm = *itr;
-    Changed |= pm->runOnModule(M);
+  for (std::vector<Pass *>::iterator I = passManagersBegin(),
+         E = passManagersEnd(); I != E; ++I) {
+    ModulePassManager_New *MP = dynamic_cast<ModulePassManager_New *>(*I);
+    Changed |= MP->runOnModule(M);
   }
   return Changed;
 }
@@ -1043,6 +1157,8 @@ bool PassManagerImpl_New::run(Module &M) {
 /// Create new pass manager
 PassManager_New::PassManager_New() {
   PM = new PassManagerImpl_New(0);
+  // PM is the top level manager
+  PM->setTopLevelManager(PM);
 }
 
 /// add - Add a pass to the queue of passes to run.  This passes ownership of