Update PassManagerImpl_New::analysisCurrentlyAvailable to check all
[oota-llvm.git] / lib / VMCore / PassManager.cpp
index c6130d8f5563babc41482e5a27834c199f9012d4..81753a11810c63127d4fe268fa7b0dc0c00801db 100644 (file)
@@ -33,7 +33,9 @@ public:
   bool manageablePass(Pass *P);
 
   /// Return true IFF AnalysisID AID is currently available.
-  bool analysisCurrentlyAvailable(AnalysisID AID);
+  bool isAnalysisAvailable(AnalysisID AID) {
+    return (AvailableAnalysis.count(AID) != 0);
+  }
 
   /// Augment RequiredAnalysis by adding analysis required by pass P.
   void noteDownRequiredAnalysis(Pass *P);
@@ -48,8 +50,8 @@ public:
   void removeDeadPasses() { /* TODO : Implement */ }
 
   /// Add pass P into the PassVector. Update RequiredAnalysis and
-  /// AvailableAnalysis appropriately
-  void addPassToManager (Pass *P);
+  /// AvailableAnalysis appropriately if ProcessAnalysis is true.
+  void addPassToManager (Pass *P, bool ProcessAnalysis = true);
 
   inline std::vector<Pass *>::iterator passVectorBegin() { 
     return PassVector.begin(); 
@@ -85,6 +87,9 @@ public:
   /// whether any of the passes modifies the function, and if so, return true.
   bool runOnFunction(Function &F);
 
+  /// Return true IFF AnalysisID AID is currently available.
+  bool analysisCurrentlyAvailable(AnalysisID AID);
+
 private:
 };
 
@@ -115,6 +120,9 @@ public:
   /// so, return true.
   bool runOnModule(Module &M);
 
+  /// Return true IFF AnalysisID AID is currently available.
+  bool analysisCurrentlyAvailable(AnalysisID AID);
+
 private:
   // Active Pass Managers
   BasicBlockPassManager_New *activeBBPassManager;
@@ -134,6 +142,9 @@ public:
   /// run - Execute all of the passes scheduled for execution.  Keep track of
   /// whether any of the passes modifies the module, and if so, return true.
   bool runOnModule(Module &M);
+
+  /// Return true IFF AnalysisID AID is currently available.
+  bool analysisCurrentlyAvailable(AnalysisID AID);
   
 private:
   // Active Pass Manager
@@ -155,11 +166,19 @@ public:
   /// whether any of the passes modifies the module, and if so, return true.
   bool run(Module &M);
 
+  /// Return true IFF AnalysisID AID is currently available.
+  bool analysisCurrentlyAvailable(AnalysisID AID);
+
 private:
 
   /// Add a pass into a passmanager queue. This is used by schedulePasses
   bool addPass(Pass *p);
 
+  /// 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 schedulePass(Pass *P);
+
   /// Schedule all passes collected in pass queue using add(). Add all the
   /// schedule passes into various manager's queue using addPass().
   void schedulePasses();
@@ -197,13 +216,6 @@ bool CommonPassManagerImpl::manageablePass(Pass *P) {
   return true;
 }
 
-/// Return true IFF AnalysisID AID is currently available.
-bool CommonPassManagerImpl::analysisCurrentlyAvailable(AnalysisID AID) {
-
-  // TODO
-  return false;
-}
-
 /// Augment RequiredAnalysis by adding analysis required by pass P.
 void CommonPassManagerImpl::noteDownRequiredAnalysis(Pass *P) {
   AnalysisUsage AnUsage;
@@ -248,18 +260,21 @@ void CommonPassManagerImpl::removeNotPreservedAnalysis(Pass *P) {
 }
 
 /// Add pass P into the PassVector. Update RequiredAnalysis and
-/// AvailableAnalysis appropriately
-void CommonPassManagerImpl::addPassToManager (Pass *P) {
+/// AvailableAnalysis appropriately if ProcessAnalysis is true.
+void CommonPassManagerImpl::addPassToManager (Pass *P, 
+                                              bool ProcessAnalysis) {
+
+  if (ProcessAnalysis) {
+    // Take a note of analysis required and made available by this pass
+    noteDownRequiredAnalysis(P);
+    noteDownAvailableAnalysis(P);
 
-  // Take a note of analysis required and made available by this pass
-  noteDownRequiredAnalysis(P);
-  noteDownAvailableAnalysis(P);
+    // Remove the analysis not preserved by this pass
+    removeNotPreservedAnalysis(P);
+  }
 
   // Add pass
   PassVector.push_back(P);
-
-  // Remove the analysis not preserved by this pass
-  removeNotPreservedAnalysis(P);
 }
 
 /// BasicBlockPassManager implementation
@@ -300,6 +315,11 @@ BasicBlockPassManager_New::runOnFunction(Function &F) {
   return Changed;
 }
 
+/// Return true IFF AnalysisID AID is currently available.
+bool BasicBlockPassManager_New::analysisCurrentlyAvailable(AnalysisID AID) {
+  return isAnalysisAvailable(AID);
+}
+
 // FunctionPassManager_New implementation
 /// Create new Function pass manager
 FunctionPassManager_New::FunctionPassManager_New() {
@@ -341,7 +361,7 @@ FunctionPassManagerImpl_New::addPass(Pass *P) {
         || !activeBBPassManager->addPass(BP)) {
 
       activeBBPassManager = new BasicBlockPassManager_New();
-      addPassToManager(activeBBPassManager);
+      addPassToManager(activeBBPassManager, false);
       if (!activeBBPassManager->addPass(BP))
         assert(0 && "Unable to add Pass");
     }
@@ -379,6 +399,19 @@ FunctionPassManagerImpl_New::runOnModule(Module &M) {
   return Changed;
 }
 
+/// Return true IFF AnalysisID AID is currently available.
+bool FunctionPassManagerImpl_New::analysisCurrentlyAvailable(AnalysisID AID) {
+
+  if (isAnalysisAvailable(AID))
+    return true;
+
+  if (activeBBPassManager && 
+      activeBBPassManager->isAnalysisAvailable(AID))
+    return true;
+
+  // TODO : Check inactive managers
+  return false;
+}
 
 // ModulePassManager implementation
 
@@ -397,7 +430,7 @@ ModulePassManager_New::addPass(Pass *P) {
         || !activeFunctionPassManager->addPass(P)) {
 
       activeFunctionPassManager = new FunctionPassManagerImpl_New();
-      addPassToManager(activeFunctionPassManager);
+      addPassToManager(activeFunctionPassManager, false);
       if (!activeFunctionPassManager->addPass(FP))
         assert(0 && "Unable to add pass");
     }
@@ -434,24 +467,73 @@ ModulePassManager_New::runOnModule(Module &M) {
   return Changed;
 }
 
+/// Return true IFF AnalysisID AID is currently available.
+bool ModulePassManager_New::analysisCurrentlyAvailable(AnalysisID AID) {
+
+  if (isAnalysisAvailable(AID))
+    return true;
+
+  if (activeFunctionPassManager && 
+      activeFunctionPassManager->isAnalysisAvailable(AID))
+    return true;
+
+  // TODO : Check inactive managers
+  return false;
+}
+
+/// Return true IFF AnalysisID AID is currently available.
+bool PassManagerImpl_New::analysisCurrentlyAvailable(AnalysisID AID) {
+
+  bool available = false;
+  for (std::vector<ModulePassManager_New *>::iterator itr = PassManagers.begin(),
+         e = PassManagers.end(); !available && itr != e; ++itr)
+    available  = (*itr)->analysisCurrentlyAvailable(AID);
+  return available;
+}
+
+/// 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 PassManagerImpl_New::schedulePass(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) {
+
+    if (!analysisCurrentlyAvailable(*I)) {
+      // Schedule this analysis run first.
+      Pass *AP = (*I)->createPass();
+      schedulePass(AP);
+    }
+  }
+    
+  addPass(P);
+
+  // TODO : Walk through all managers and remove not preserved analysis
+  // TODO : remove dead passes
+}
+
 /// Schedule all passes from the queue by adding them in their
 /// respective manager's queue. 
-void
-PassManagerImpl_New::schedulePasses() {
-  /* TODO */
+void PassManagerImpl_New::schedulePasses() {
+  for (std::vector<Pass *>::iterator I = passVectorBegin(),
+         E = passVectorEnd(); I != E; ++I)
+    schedulePass (*I);
 }
 
 /// Add pass P to the queue of passes to run.
-void
-PassManagerImpl_New::add(Pass *P) {
-  /* TODO */
+void PassManagerImpl_New::add(Pass *P) {
+  // Do not process Analysis now. Analysis is process while scheduling
+  // the pass vector.
+  addPassToManager(P, false);
 }
 
 // PassManager_New implementation
 /// Add P into active pass manager or use new module pass manager to
 /// manage it.
-bool
-PassManagerImpl_New::addPass(Pass *P) {
+bool PassManagerImpl_New::addPass(Pass *P) {
 
   if (!activeManager || !activeManager->addPass(P)) {
     activeManager = new ModulePassManager_New();
@@ -463,8 +545,7 @@ PassManagerImpl_New::addPass(Pass *P) {
 
 /// run - Execute all of the passes scheduled for execution.  Keep track of
 /// whether any of the passes modifies the module, and if so, return true.
-bool
-PassManagerImpl_New::run(Module &M) {
+bool PassManagerImpl_New::run(Module &M) {
 
   schedulePasses();
   bool Changed = false;