[llvm] r245409 - [LPM] Teach the legacy pass manager to support *using* an analysis

Chandler Carruth via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 20:02:13 PDT 2015


Author: chandlerc
Date: Tue Aug 18 22:02:12 2015
New Revision: 245409

URL: http://llvm.org/viewvc/llvm-project?rev=245409&view=rev
Log:
[LPM] Teach the legacy pass manager to support *using* an analysis
without *requiring* it.

This allows a pass indicate that it will use an analysis if available
(through getAnalysisIfAvailable). When the pass manager knows this, it
will refrain from deleting that analysis if it can. Naturally, it will
still get invalidated at the correct time. These passes are not
considered when scheduling the pass pipeline, so typically they will
require manual scheduling, but this may also allow passes with
getAnalysisIfAvailable to find the analysis more often if nothing after
them requires that analysis and it wasn't invalidated.

I don't have a particular use case with the current passes, but with my
new structure for alias analyses, this will be very useful. We want to
allow people to customize the set of AAs available by scheduling
additional passes. These's aren't ever *required* for obvious reasons.
So we need some way to mark in the legacy pass manager that they will
still be used if available.

This is essentially how analysis groups already work. But this makes the
feature generally available and more explicit. It should allow the AA
change to not impact how people trigger a custom alias analysis being
available at a certain point in compilation.

Differential Revision: http://reviews.llvm.org/D12114

Modified:
    llvm/trunk/include/llvm/IR/LegacyPassManagers.h
    llvm/trunk/include/llvm/PassAnalysisSupport.h
    llvm/trunk/lib/IR/LegacyPassManager.cpp

Modified: llvm/trunk/include/llvm/IR/LegacyPassManagers.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/LegacyPassManagers.h?rev=245409&r1=245408&r2=245409&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/LegacyPassManagers.h (original)
+++ llvm/trunk/include/llvm/IR/LegacyPassManagers.h Tue Aug 18 22:02:12 2015
@@ -320,12 +320,12 @@ public:
   bool preserveHigherLevelAnalysis(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(SmallVectorImpl<Pass *> &RequiredPasses,
-                               SmallVectorImpl<AnalysisID> &ReqPassNotAvailable,
-                               Pass *P);
+  /// Populate UsedPasses with analysis pass that are used or required by pass
+  /// P and are available. Populate ReqPassNotAvailable with analysis pass that
+  /// are required by pass P but are not available.
+  void collectRequiredAndUsedAnalyses(
+      SmallVectorImpl<Pass *> &UsedPasses,
+      SmallVectorImpl<AnalysisID> &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
@@ -351,6 +351,7 @@ public:
                     enum PassDebuggingString S2, StringRef Msg);
   void dumpRequiredSet(const Pass *P) const;
   void dumpPreservedSet(const Pass *P) const;
+  void dumpUsedSet(const Pass *P) const;
 
   unsigned getNumContainedPasses() const {
     return (unsigned)PassVector.size();

Modified: llvm/trunk/include/llvm/PassAnalysisSupport.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/PassAnalysisSupport.h?rev=245409&r1=245408&r2=245409&view=diff
==============================================================================
--- llvm/trunk/include/llvm/PassAnalysisSupport.h (original)
+++ llvm/trunk/include/llvm/PassAnalysisSupport.h Tue Aug 18 22:02:12 2015
@@ -40,7 +40,7 @@ public:
 
 private:
   /// Sets of analyses required and preserved by a pass
-  VectorType Required, RequiredTransitive, Preserved;
+  VectorType Required, RequiredTransitive, Preserved, Used;
   bool PreservesAll;
 
 public:
@@ -80,6 +80,25 @@ public:
   }
   ///@}
 
+  ///@{
+  /// Add the specified ID to the set of analyses used by this pass if they are
+  /// available..
+  AnalysisUsage &addUsedIfAvailableID(const void *ID) {
+    Used.push_back(ID);
+    return *this;
+  }
+  AnalysisUsage &addUsedIfAvailableID(char &ID) {
+    Used.push_back(&ID);
+    return *this;
+  }
+  /// Add the specified Pass class to the set of analyses used by this pass.
+  template<class PassClass>
+  AnalysisUsage &addUsedIfAvailable() {
+    Used.push_back(&PassClass::ID);
+    return *this;
+  }
+  ///@}
+
   /// Add the Pass with the specified argument string to the set of analyses
   /// preserved by this pass. If no such Pass exists, do nothing. This can be
   /// useful when a pass is trivially preserved, but may not be linked in. Be
@@ -107,6 +126,7 @@ public:
     return RequiredTransitive;
   }
   const VectorType &getPreservedSet() const { return Preserved; }
+  const VectorType &getUsedSet() const { return Used; }
 };
 
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/IR/LegacyPassManager.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LegacyPassManager.cpp?rev=245409&r1=245408&r2=245409&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LegacyPassManager.cpp (original)
+++ llvm/trunk/lib/IR/LegacyPassManager.cpp Tue Aug 18 22:02:12 2015
@@ -989,29 +989,28 @@ void PMDataManager::add(Pass *P, bool Pr
 
   // At the moment, this pass is the last user of all required passes.
   SmallVector<Pass *, 12> LastUses;
-  SmallVector<Pass *, 8> RequiredPasses;
+  SmallVector<Pass *, 8> UsedPasses;
   SmallVector<AnalysisID, 8> ReqAnalysisNotAvailable;
 
   unsigned PDepth = this->getDepth();
 
-  collectRequiredAnalysis(RequiredPasses,
-                          ReqAnalysisNotAvailable, P);
-  for (Pass *PRequired : RequiredPasses) {
+  collectRequiredAndUsedAnalyses(UsedPasses, ReqAnalysisNotAvailable, P);
+  for (Pass *PUsed : UsedPasses) {
     unsigned RDepth = 0;
 
-    assert(PRequired->getResolver() && "Analysis Resolver is not set");
-    PMDataManager &DM = PRequired->getResolver()->getPMDataManager();
+    assert(PUsed->getResolver() && "Analysis Resolver is not set");
+    PMDataManager &DM = PUsed->getResolver()->getPMDataManager();
     RDepth = DM.getDepth();
 
     if (PDepth == RDepth)
-      LastUses.push_back(PRequired);
+      LastUses.push_back(PUsed);
     else if (PDepth > RDepth) {
       // Let the parent claim responsibility of last use
-      TransferLastUses.push_back(PRequired);
+      TransferLastUses.push_back(PUsed);
       // Keep track of higher level analysis used by this manager.
-      HigherLevelAnalysis.push_back(PRequired);
+      HigherLevelAnalysis.push_back(PUsed);
     } else
-      llvm_unreachable("Unable to accommodate Required Pass");
+      llvm_unreachable("Unable to accommodate Used Pass");
   }
 
   // Set P as P's last user until someone starts using P.
@@ -1044,22 +1043,27 @@ void PMDataManager::add(Pass *P, bool Pr
 }
 
 
-/// Populate RP with analysis pass that are required by
+/// Populate UP with analysis pass that are used or 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(SmallVectorImpl<Pass *> &RP,
-                                       SmallVectorImpl<AnalysisID> &RP_NotAvail,
-                                            Pass *P) {
+void PMDataManager::collectRequiredAndUsedAnalyses(
+    SmallVectorImpl<Pass *> &UP, SmallVectorImpl<AnalysisID> &RP_NotAvail,
+    Pass *P) {
   AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P);
+
+  for (const auto &UsedID : AnUsage->getUsedSet())
+    if (Pass *AnalysisPass = findAnalysisPass(UsedID, true))
+      UP.push_back(AnalysisPass);
+
   for (const auto &RequiredID : AnUsage->getRequiredSet())
     if (Pass *AnalysisPass = findAnalysisPass(RequiredID, true))
-      RP.push_back(AnalysisPass);
+      UP.push_back(AnalysisPass);
     else
       RP_NotAvail.push_back(RequiredID);
 
   for (const auto &RequiredID : AnUsage->getRequiredTransitiveSet())
     if (Pass *AnalysisPass = findAnalysisPass(RequiredID, true))
-      RP.push_back(AnalysisPass);
+      UP.push_back(AnalysisPass);
     else
       RP_NotAvail.push_back(RequiredID);
 }
@@ -1196,6 +1200,15 @@ void PMDataManager::dumpPreservedSet(con
   dumpAnalysisUsage("Preserved", P, analysisUsage.getPreservedSet());
 }
 
+void PMDataManager::dumpUsedSet(const Pass *P) const {
+  if (PassDebugging < Details)
+    return;
+
+  AnalysisUsage analysisUsage;
+  P->getAnalysisUsage(analysisUsage);
+  dumpAnalysisUsage("Used", P, analysisUsage.getUsedSet());
+}
+
 void PMDataManager::dumpAnalysisUsage(StringRef Msg, const Pass *P,
                                    const AnalysisUsage::VectorType &Set) const {
   assert(PassDebugging >= Details);
@@ -1300,6 +1313,7 @@ bool BBPassManager::runOnFunction(Functi
         dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG,
                      I->getName());
       dumpPreservedSet(BP);
+      dumpUsedSet(BP);
 
       verifyPreservedAnalysis(BP);
       removeNotPreservedAnalysis(BP);
@@ -1514,6 +1528,7 @@ bool FPPassManager::runOnFunction(Functi
     if (LocalChanged)
       dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getName());
     dumpPreservedSet(FP);
+    dumpUsedSet(FP);
 
     verifyPreservedAnalysis(FP);
     removeNotPreservedAnalysis(FP);
@@ -1591,6 +1606,7 @@ MPPassManager::runOnModule(Module &M) {
       dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG,
                    M.getModuleIdentifier());
     dumpPreservedSet(MP);
+    dumpUsedSet(MP);
 
     verifyPreservedAnalysis(MP);
     removeNotPreservedAnalysis(MP);




More information about the llvm-commits mailing list