Get the order of the hext digits right!
[oota-llvm.git] / lib / VMCore / PassManager.cpp
index 253530824338b594a7a2dce819f1b7c2f46bd053..e590a6cc2a8eb8018267e84e189020bc58a1e7d2 100644 (file)
@@ -63,7 +63,9 @@ class VISIBILITY_HIDDEN BBPassManager : public PMDataManager,
                                         public FunctionPass {
 
 public:
-  BBPassManager(int Depth) : PMDataManager(Depth) { }
+  static char ID;
+  BBPassManager(int Depth) 
+    : PMDataManager(Depth), FunctionPass((intptr_t)&ID) {}
 
   /// Execute all of the passes scheduled for execution.  Keep track of
   /// whether any of the passes modifies the function, and if so, return true.
@@ -104,6 +106,7 @@ public:
   }
 };
 
+char BBPassManager::ID = 0;
 }
 
 namespace llvm {
@@ -116,9 +119,10 @@ class FunctionPassManagerImpl : public Pass,
                                 public PMDataManager,
                                 public PMTopLevelManager {
 public:
-
-  FunctionPassManagerImpl(int Depth) : PMDataManager(Depth),
-                                       PMTopLevelManager(TLM_Function) { }
+  static char ID;
+  FunctionPassManagerImpl(int Depth) : 
+    Pass((intptr_t)&ID), PMDataManager(Depth), 
+    PMTopLevelManager(TLM_Function) { }
 
   /// 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
@@ -167,9 +171,9 @@ public:
     FPPassManager *FP = static_cast<FPPassManager *>(PassManagers[N]);
     return FP;
   }
-
 };
 
+char FunctionPassManagerImpl::ID = 0;
 //===----------------------------------------------------------------------===//
 // MPPassManager
 //
@@ -179,8 +183,19 @@ public:
 class MPPassManager : public Pass, public PMDataManager {
  
 public:
-  MPPassManager(int Depth) : PMDataManager(Depth) { }
-  
+  static char ID;
+  MPPassManager(int Depth) : Pass((intptr_t)&ID), PMDataManager(Depth) { }
+
+  // Delete on the fly managers.
+  virtual ~MPPassManager() {
+    for (std::map<Pass *, FunctionPassManagerImpl *>::iterator 
+           I = OnTheFlyManagers.begin(), E = OnTheFlyManagers.end();
+         I != E; ++I) {
+      FunctionPassManagerImpl *FPP = I->second;
+      delete FPP;
+    }
+  }
+
   /// 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);
@@ -190,6 +205,16 @@ 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);
+
+  /// Return function pass corresponding to PassInfo PI, that is 
+  /// required by module pass MP. Instantiate analysis pass, by using
+  /// its runOnFunction() for function F.
+  virtual Pass* getOnTheFlyPass(Pass *MP, const PassInfo *PI, Function &F);
+
   virtual const char *getPassName() const {
     return "Module Pass Manager";
   }
@@ -200,6 +225,8 @@ public:
     for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
       ModulePass *MP = getContainedPass(Index);
       MP->dumpPassStructure(Offset + 1);
+      if (FunctionPassManagerImpl *FPP = OnTheFlyManagers[MP])
+        FPP->dumpPassStructure(Offset + 2);
       dumpLastUses(MP, Offset+1);
     }
   }
@@ -213,19 +240,26 @@ public:
   virtual PassManagerType getPassManagerType() const { 
     return PMT_ModulePassManager; 
   }
+
+ private:
+  /// Collection of on the fly FPPassManagers. These managers manage
+  /// function passes that are required by module passes.
+  std::map<Pass *, FunctionPassManagerImpl *> OnTheFlyManagers;
 };
 
+char MPPassManager::ID = 0;
 //===----------------------------------------------------------------------===//
 // PassManagerImpl
 //
+
 /// PassManagerImpl manages MPPassManagers
 class PassManagerImpl : public Pass,
                         public PMDataManager,
                         public PMTopLevelManager {
 
 public:
-
-  PassManagerImpl(int Depth) : PMDataManager(Depth),
+  static char ID;
+  PassManagerImpl(int Depth) : Pass((intptr_t)&ID), PMDataManager(Depth),
                                PMTopLevelManager(TLM_Pass) { }
 
   /// add - Add a pass to the queue of passes to run.  This passes ownership of
@@ -270,6 +304,7 @@ public:
 
 };
 
+char PassManagerImpl::ID = 0;
 } // End of llvm namespace
 
 namespace {
@@ -353,6 +388,10 @@ void PMTopLevelManager::setLastUser(std::vector<Pass *> &AnalysisPasses,
          E = AnalysisPasses.end(); I != E; ++I) {
     Pass *AP = *I;
     LastUser[AP] = P;
+    
+    if (P == AP)
+      continue;
+
     // 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(),
@@ -396,9 +435,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;
     }
   }
 
@@ -532,6 +576,29 @@ void PMDataManager::recordAvailableAnalysis(Pass *P) {
   }
 }
 
+// Return true if P preserves high level analysis used by other
+// passes managed by this manager
+bool PMDataManager::preserveHigherLevelAnalysis(Pass *P) {
+
+  AnalysisUsage AnUsage;
+  P->getAnalysisUsage(AnUsage);
+  
+  if (AnUsage.getPreservesAll())
+    return true;
+  
+  const std::vector<AnalysisID> &PreservedSet = AnUsage.getPreservedSet();
+  for (std::vector<Pass *>::iterator I = HigherLevelAnalysis.begin(),
+         E = HigherLevelAnalysis.end(); I  != E; ++I) {
+    Pass *P1 = *I;
+    if (!dynamic_cast<ImmutablePass*>(P1) 
+        && std::find(PreservedSet.begin(), PreservedSet.end(), P1->getPassInfo()) == 
+           PreservedSet.end())
+      return false;
+  }
+  
+  return true;
+}
+
 /// Remove Analyss not preserved by Pass P
 void PMDataManager::removeNotPreservedAnalysis(Pass *P) {
   AnalysisUsage AnUsage;
@@ -544,13 +611,32 @@ void PMDataManager::removeNotPreservedAnalysis(Pass *P) {
   for (std::map<AnalysisID, Pass*>::iterator I = AvailableAnalysis.begin(),
          E = AvailableAnalysis.end(); I != E; ) {
     std::map<AnalysisID, Pass*>::iterator Info = I++;
-    if (std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) == 
-        PreservedSet.end()) {
+    if (!dynamic_cast<ImmutablePass*>(Info->second)
+        && std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) == 
+           PreservedSet.end())
       // Remove this analysis
-      if (!dynamic_cast<ImmutablePass*>(Info->second))
-        AvailableAnalysis.erase(Info);
+      AvailableAnalysis.erase(Info);
+  }
+
+  // Check inherited analysis also. If P is not preserving analysis
+  // provided by parent manager then remove it here.
+  for (unsigned Index = 0; Index < PMT_Last; ++Index) {
+
+    if (!InheritedAnalysis[Index])
+      continue;
+
+    for (std::map<AnalysisID, Pass*>::iterator 
+           I = InheritedAnalysis[Index]->begin(),
+           E = InheritedAnalysis[Index]->end(); I != E; ) {
+      std::map<AnalysisID, Pass *>::iterator Info = I++;
+      if (!dynamic_cast<ImmutablePass*>(Info->second)
+          && std::find(PreservedSet.begin(), PreservedSet.end(), Info->first) == 
+             PreservedSet.end())
+        // Remove this analysis
+        InheritedAnalysis[Index]->erase(Info);
     }
   }
+
 }
 
 /// Remove analysis passes that are not used any longer
@@ -558,6 +644,11 @@ void PMDataManager::removeDeadPasses(Pass *P, std::string Msg,
                                      enum PassDebuggingString DBG_STR) {
 
   std::vector<Pass *> DeadPasses;
+
+  // If this is a on the fly manager then it does not have TPM.
+  if (!TPM)
+    return;
+
   TPM->collectLastUses(DeadPasses, P);
 
   for (std::vector<Pass *>::iterator I = DeadPasses.begin(),
@@ -596,11 +687,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;
@@ -613,11 +707,10 @@ void PMDataManager::add(Pass *P,
       else if (PDepth >  RDepth) {
         // Let the parent claim responsibility of last use
         TransferLastUses.push_back(PRequired);
-      } else {
-        // Note : This feature is not yet implemented
-        assert (0 && 
-                "Unable to handle Pass that requires lower level Analysis pass");
-      }
+        // Keep track of higher level analysis used by this manager.
+        HigherLevelAnalysis.push_back(PRequired);
+      } else 
+        assert (0 && "Unable to accomodate Required Pass");
     }
 
     // Set P as P's last user until someone starts using P.
@@ -633,6 +726,14 @@ void PMDataManager::add(Pass *P,
       TransferLastUses.clear();
     }
 
+    // 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);
+    }
+
     // Take a note of analysis required and made available by this pass.
     // Remove the analysis not preserved by this pass
     removeNotPreservedAnalysis(P);
@@ -643,27 +744,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);
   }
 }
 
@@ -681,7 +789,9 @@ void PMDataManager::initializeAnalysisImpl(Pass *P) {
          E = AnUsage.getRequiredSet().end(); I != E; ++I) {
     Pass *Impl = findAnalysisPass(*I, true);
     if (Impl == 0)
-      assert(0 && "Analysis used but not available!");
+      // This may be analysis pass that is initialized on the fly.
+      // If that is not the case then it will raise an assert when it is used.
+      continue;
     AnalysisResolver *AR = P->getResolver();
     AR->addAnalysisImplsPair(*I, Impl);
   }
@@ -708,8 +818,11 @@ Pass *PMDataManager::findAnalysisPass(AnalysisID AID, bool SearchParent) {
 void PMDataManager::dumpLastUses(Pass *P, unsigned Offset) const{
 
   std::vector<Pass *> LUses;
-  
-  assert (TPM && "Top Level Manager is missing");
+
+  // If this is a on the fly manager then it does not have TPM.
+  if (!TPM)
+    return;
+
   TPM->collectLastUses(LUses, P);
   
   for (std::vector<Pass *>::iterator I = LUses.begin(),
@@ -801,6 +914,11 @@ Pass *AnalysisResolver::getAnalysisToUpdate(AnalysisID ID, bool dir) const {
   return PM.findAnalysisPass(ID, dir);
 }
 
+Pass *AnalysisResolver::findImplPass(Pass *P, const PassInfo *AnalysisPI, 
+                                     Function &F) {
+  return PM.getOnTheFlyPass(P, AnalysisPI, F);
+}
+
 //===----------------------------------------------------------------------===//
 // BBPassManager implementation
 
@@ -990,6 +1108,7 @@ bool FunctionPassManagerImpl::run(Function &F) {
 //===----------------------------------------------------------------------===//
 // FPPassManager implementation
 
+char FPPassManager::ID = 0;
 /// Print passes managed by this manager
 void FPPassManager::dumpPassStructure(unsigned Offset) {
   llvm::cerr << std::string(Offset*2, ' ') << "FunctionPass Manager\n";
@@ -1106,6 +1225,47 @@ 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");
+
+  FunctionPassManagerImpl *FPP = OnTheFlyManagers[P];
+  if (!FPP) {
+    FPP = new FunctionPassManagerImpl(0);
+    // FPP is the top level manager.
+    FPP->setTopLevelManager(FPP);
+
+    OnTheFlyManagers[P] = FPP;
+  }
+  FPP->add(RequiredPass);
+
+  // Register P as the last user of RequiredPass.
+  std::vector<Pass *> LU; 
+  LU.push_back(RequiredPass);
+  FPP->setLastUser(LU,  P);
+}
+
+/// Return function pass corresponding to PassInfo PI, that is 
+/// required by module pass MP. Instantiate analysis pass, by using
+/// its runOnFunction() for function F.
+Pass* MPPassManager::getOnTheFlyPass(Pass *MP, const PassInfo *PI, 
+                                     Function &F) {
+   AnalysisID AID = PI;
+  FunctionPassManagerImpl *FPP = OnTheFlyManagers[MP];
+  assert (FPP && "Unable to find on the fly pass");
+  
+  FPP->run(F);
+  return (dynamic_cast<PMTopLevelManager *>(FPP))->findAnalysisPass(AID);
+}
+
+
 //===----------------------------------------------------------------------===//
 // PassManagerImpl implementation
 //
@@ -1245,7 +1405,7 @@ void PMStack::dump() {
 /// Find appropriate Module Pass Manager in the PM Stack and
 /// add self into that manager. 
 void ModulePass::assignPassManager(PMStack &PMS, 
-                                  PassManagerType PreferredType) {
+                                   PassManagerType PreferredType) {
 
   // Find Module Pass Manager
   while(!PMS.empty()) {
@@ -1264,7 +1424,7 @@ void ModulePass::assignPassManager(PMStack &PMS,
 /// Find appropriate Function Pass Manager or Call Graph Pass Manager
 /// in the PM Stack and add self into that manager. 
 void FunctionPass::assignPassManager(PMStack &PMS,
-                                    PassManagerType PreferredType) {
+                                     PassManagerType PreferredType) {
 
   // Find Module Pass Manager (TODO : Or Call Graph Pass Manager)
   while(!PMS.empty()) {
@@ -1309,7 +1469,7 @@ void FunctionPass::assignPassManager(PMStack &PMS,
 /// Find appropriate Basic Pass Manager or Call Graph Pass Manager
 /// in the PM Stack and add self into that manager. 
 void BasicBlockPass::assignPassManager(PMStack &PMS,
-                                      PassManagerType PreferredType) {
+                                       PassManagerType PreferredType) {
 
   BBPassManager *BBP = NULL;