[clang] f7788e1 - Revert "[NewPM] Only invalidate modified functions' analyses in CGSCC passes"

Arthur Eubanks via cfe-commits cfe-commits at lists.llvm.org
Fri May 21 16:39:00 PDT 2021


Author: Arthur Eubanks
Date: 2021-05-21T16:38:03-07:00
New Revision: f7788e1bff223a58292b8b1d0818dac63b713ead

URL: https://github.com/llvm/llvm-project/commit/f7788e1bff223a58292b8b1d0818dac63b713ead
DIFF: https://github.com/llvm/llvm-project/commit/f7788e1bff223a58292b8b1d0818dac63b713ead.diff

LOG: Revert "[NewPM] Only invalidate modified functions' analyses in CGSCC passes"

This reverts commit d14d84af2f5ebb8ae2188ce6884a29a586dc0a40.

Causes unacceptable memory regressions.

Added: 
    

Modified: 
    clang/test/CodeGen/thinlto-distributed-newpm.ll
    llvm/lib/Analysis/CGSCCPassManager.cpp
    llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
    llvm/lib/Transforms/IPO/FunctionAttrs.cpp
    llvm/lib/Transforms/IPO/Inliner.cpp
    llvm/test/Other/opt-O3-pipeline-enable-matrix.ll
    llvm/test/Transforms/Inline/cgscc-incremental-invalidate.ll

Removed: 
    llvm/test/Transforms/Inline/analysis-invalidation.ll


################################################################################
diff  --git a/clang/test/CodeGen/thinlto-distributed-newpm.ll b/clang/test/CodeGen/thinlto-distributed-newpm.ll
index 7f478fb05f50..e20f78191572 100644
--- a/clang/test/CodeGen/thinlto-distributed-newpm.ll
+++ b/clang/test/CodeGen/thinlto-distributed-newpm.ll
@@ -64,10 +64,18 @@
 ; CHECK-O: Running analysis: OuterAnalysisManagerProxy
 ; CHECK-O: Running pass: InlinerPass on (main)
 ; CHECK-O: Running pass: PostOrderFunctionAttrsPass on (main)
+; CHECK-O: Invalidating analysis: DominatorTreeAnalysis on main
+; CHECK-O: Invalidating analysis: BasicAA on main
+; CHECK-O: Invalidating analysis: AAManager on main
 ; CHECK-O3: Running pass: ArgumentPromotionPass on (main)
 ; CHECK-O: Running pass: SROA on main
+; These next two can appear in any order since they are accessed as parameters
+; on the same call to SROA::runImpl
+; CHECK-O-DAG: Running analysis: DominatorTreeAnalysis on main
 ; CHECK-O: Running pass: EarlyCSEPass on main
 ; CHECK-O: Running analysis: MemorySSAAnalysis on main
+; CHECK-O: Running analysis: AAManager on main
+; CHECK-O: Running analysis: BasicAA on main
 ; CHECK-O: Running pass: SpeculativeExecutionPass on main
 ; CHECK-O: Running pass: JumpThreadingPass on main
 ; CHECK-O: Running analysis: LazyValueAnalysis on main
@@ -105,6 +113,16 @@
 ; CHECK-O: Running pass: LCSSAPass on main
 ; CHECK-O: Running pass: SimplifyCFGPass on main
 ; CHECK-O: Running pass: InstCombinePass on main
+; CHECK-O: Invalidating analysis: DominatorTreeAnalysis on main
+; CHECK-O: Invalidating analysis: BasicAA on main
+; CHECK-O: Invalidating analysis: AAManager on main
+; CHECK-O: Invalidating analysis: MemorySSAAnalysis on main
+; CHECK-O: Invalidating analysis: LoopAnalysis on main
+; CHECK-O: Invalidating analysis: PhiValuesAnalysis on main
+; CHECK-O: Invalidating analysis: MemoryDependenceAnalysis on main
+; CHECK-O: Invalidating analysis: DemandedBitsAnalysis on main
+; CHECK-O: Invalidating analysis: PostDominatorTreeAnalysis on main
+; CHECK-O: Invalidating analysis: CallGraphAnalysis
 ; CHECK-O: Running pass: GlobalOptPass
 ; CHECK-O: Running pass: GlobalDCEPass
 ; CHECK-O: Running pass: EliminateAvailableExternallyPass
@@ -114,13 +132,21 @@
 ; CHECK-O: Running pass: Float2IntPass on main
 ; CHECK-O: Running pass: LowerConstantIntrinsicsPass on main
 ; CHECK-O: Running pass: LoopSimplifyPass on main
+; CHECK-O: Running analysis: LoopAnalysis on main
 ; CHECK-O: Running pass: LCSSAPass on main
+; CHECK-O: Running analysis: MemorySSAAnalysis on main
+; CHECK-O: Running analysis: AAManager on main
+; CHECK-O: Running analysis: BasicAA on main
+; CHECK-O: Running analysis: ScalarEvolutionAnalysis on main
+; CHECK-O: Running analysis: InnerAnalysisManagerProxy
 ; CHECK-O: Running pass: LoopRotatePass on Loop at depth 1 containing: %b
 ; CHECK-O: Running pass: LoopDistributePass on main
 ; CHECK-O: Running pass: InjectTLIMappings on main
 ; CHECK-O: Running pass: LoopVectorizePass on main
 ; CHECK-O: Running analysis: BlockFrequencyAnalysis on main
 ; CHECK-O: Running analysis: BranchProbabilityAnalysis on main
+; CHECK-O: Running analysis: PostDominatorTreeAnalysis on main
+; CHECK-O: Running analysis: DemandedBitsAnalysis on main
 ; CHECK-O: Running pass: LoopLoadEliminationPass on main
 ; CHECK-O: Running pass: InstCombinePass on main
 ; CHECK-O: Running pass: SimplifyCFGPass on main

diff  --git a/llvm/lib/Analysis/CGSCCPassManager.cpp b/llvm/lib/Analysis/CGSCCPassManager.cpp
index c01704162e96..8043cc7fc742 100644
--- a/llvm/lib/Analysis/CGSCCPassManager.cpp
+++ b/llvm/lib/Analysis/CGSCCPassManager.cpp
@@ -858,7 +858,7 @@ incorporateNewSCCRange(const SCCRangeT &NewSCCRange, LazyCallGraph &G,
   // split-off SCCs.
   // We know however that this will preserve any FAM proxy so go ahead and mark
   // that.
-  auto PA = PreservedAnalyses::allInSet<AllAnalysesOn<Function>>();
+  PreservedAnalyses PA;
   PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
   AM.invalidate(*OldC, PA);
 

diff  --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
index 18aeb899172a..9be28c6d2906 100644
--- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -1019,12 +1019,11 @@ PreservedAnalyses ArgumentPromotionPass::run(LazyCallGraph::SCC &C,
   do {
     LocalChange = false;
 
-    FunctionAnalysisManager &FAM =
-        AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
-
     for (LazyCallGraph::Node &N : C) {
       Function &OldF = N.getFunction();
 
+      FunctionAnalysisManager &FAM =
+          AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
       // FIXME: This lambda must only be used with this function. We should
       // skip the lambda and just get the AA results directly.
       auto AARGetter = [&](Function &F) -> AAResults & {
@@ -1047,13 +1046,6 @@ PreservedAnalyses ArgumentPromotionPass::run(LazyCallGraph::SCC &C,
       C.getOuterRefSCC().replaceNodeFunction(N, *NewF);
       FAM.clear(OldF, OldF.getName());
       OldF.eraseFromParent();
-
-      PreservedAnalyses FuncPA;
-      FuncPA.preserveSet<CFGAnalyses>();
-      for (auto *U : NewF->users()) {
-        auto *UserF = cast<CallBase>(U)->getParent()->getParent();
-        FAM.invalidate(*UserF, FuncPA);
-      }
     }
 
     Changed |= LocalChange;
@@ -1062,10 +1054,7 @@ PreservedAnalyses ArgumentPromotionPass::run(LazyCallGraph::SCC &C,
   if (!Changed)
     return PreservedAnalyses::all();
 
-  PreservedAnalyses PA;
-  PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
-  PA.preserveSet<AllAnalysesOn<Function>>();
-  return PA;
+  return PreservedAnalyses::none();
 }
 
 namespace {

diff  --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index 25b37c0a1816..ca8660a98ded 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -240,8 +240,7 @@ MemoryAccessKind llvm::computeFunctionBodyMemoryAccess(Function &F,
 
 /// Deduce readonly/readnone attributes for the SCC.
 template <typename AARGetterT>
-static void addReadAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter,
-                         SmallSetVector<Function *, 8> &Changed) {
+static bool addReadAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter) {
   // Check if any of the functions in the SCC read or write memory.  If they
   // write memory then they can't be marked readnone or readonly.
   bool ReadsMemory = false;
@@ -256,7 +255,7 @@ static void addReadAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter,
     switch (checkFunctionMemoryAccess(*F, F->hasExactDefinition(),
                                       AAR, SCCNodes)) {
     case MAK_MayWrite:
-      return;
+      return false;
     case MAK_ReadOnly:
       ReadsMemory = true;
       break;
@@ -272,10 +271,11 @@ static void addReadAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter,
   // If the SCC contains both functions that read and functions that write, then
   // we cannot add readonly attributes.
   if (ReadsMemory && WritesMemory)
-    return;
+    return false;
 
   // Success!  Functions in this SCC do not access memory, or only read memory.
   // Give them the appropriate attribute.
+  bool MadeChange = false;
 
   for (Function *F : SCCNodes) {
     if (F->doesNotAccessMemory())
@@ -289,7 +289,7 @@ static void addReadAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter,
     if (F->doesNotReadMemory() && WritesMemory)
       continue;
 
-    Changed.insert(F);
+    MadeChange = true;
 
     // Clear out any existing attributes.
     AttrBuilder AttrsToRemove;
@@ -318,6 +318,8 @@ static void addReadAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter,
     else
       ++NumReadNone;
   }
+
+  return MadeChange;
 }
 
 namespace {
@@ -579,8 +581,9 @@ determinePointerReadAttrs(Argument *A,
 }
 
 /// Deduce returned attributes for the SCC.
-static void addArgumentReturnedAttrs(const SCCNodeSet &SCCNodes,
-                                     SmallSetVector<Function *, 8> &Changed) {
+static bool addArgumentReturnedAttrs(const SCCNodeSet &SCCNodes) {
+  bool Changed = false;
+
   // Check each function in turn, determining if an argument is always returned.
   for (Function *F : SCCNodes) {
     // We can infer and propagate function attributes only when we know that the
@@ -620,9 +623,11 @@ static void addArgumentReturnedAttrs(const SCCNodeSet &SCCNodes,
       auto *A = cast<Argument>(RetArg);
       A->addAttr(Attribute::Returned);
       ++NumReturned;
-      Changed.insert(F);
+      Changed = true;
     }
   }
+
+  return Changed;
 }
 
 /// If a callsite has arguments that are also arguments to the parent function,
@@ -688,8 +693,9 @@ static bool addReadAttr(Argument *A, Attribute::AttrKind R) {
 }
 
 /// Deduce nocapture attributes for the SCC.
-static void addArgumentAttrs(const SCCNodeSet &SCCNodes,
-                             SmallSetVector<Function *, 8> &Changed) {
+static bool addArgumentAttrs(const SCCNodeSet &SCCNodes) {
+  bool Changed = false;
+
   ArgumentGraph AG;
 
   // Check each function in turn, determining which pointer arguments are not
@@ -701,8 +707,7 @@ static void addArgumentAttrs(const SCCNodeSet &SCCNodes,
     if (!F->hasExactDefinition())
       continue;
 
-    if (addArgumentAttrsFromCallsites(*F))
-      Changed.insert(F);
+    Changed |= addArgumentAttrsFromCallsites(*F);
 
     // Functions that are readonly (or readnone) and nounwind and don't return
     // a value can't capture arguments. Don't analyze them.
@@ -713,7 +718,7 @@ static void addArgumentAttrs(const SCCNodeSet &SCCNodes,
         if (A->getType()->isPointerTy() && !A->hasNoCaptureAttr()) {
           A->addAttr(Attribute::NoCapture);
           ++NumNoCapture;
-          Changed.insert(F);
+          Changed = true;
         }
       }
       continue;
@@ -732,7 +737,7 @@ static void addArgumentAttrs(const SCCNodeSet &SCCNodes,
             // If it's trivially not captured, mark it nocapture now.
             A->addAttr(Attribute::NoCapture);
             ++NumNoCapture;
-            Changed.insert(F);
+            Changed = true;
           } else {
             // If it's not trivially captured and not trivially not captured,
             // then it must be calling into another function in our SCC. Save
@@ -756,8 +761,7 @@ static void addArgumentAttrs(const SCCNodeSet &SCCNodes,
         Self.insert(&*A);
         Attribute::AttrKind R = determinePointerReadAttrs(&*A, Self);
         if (R != Attribute::None)
-          if (addReadAttr(A, R))
-            Changed.insert(F);
+          Changed = addReadAttr(A, R);
       }
     }
   }
@@ -781,7 +785,7 @@ static void addArgumentAttrs(const SCCNodeSet &SCCNodes,
         Argument *A = ArgumentSCC[0]->Definition;
         A->addAttr(Attribute::NoCapture);
         ++NumNoCapture;
-        Changed.insert(A->getParent());
+        Changed = true;
       }
       continue;
     }
@@ -823,7 +827,7 @@ static void addArgumentAttrs(const SCCNodeSet &SCCNodes,
       Argument *A = ArgumentSCC[i]->Definition;
       A->addAttr(Attribute::NoCapture);
       ++NumNoCapture;
-      Changed.insert(A->getParent());
+      Changed = true;
     }
 
     // We also want to compute readonly/readnone. With a small number of false
@@ -854,11 +858,12 @@ static void addArgumentAttrs(const SCCNodeSet &SCCNodes,
     if (ReadAttr != Attribute::None) {
       for (unsigned i = 0, e = ArgumentSCC.size(); i != e; ++i) {
         Argument *A = ArgumentSCC[i]->Definition;
-        if (addReadAttr(A, ReadAttr))
-          Changed.insert(A->getParent());
+        Changed = addReadAttr(A, ReadAttr);
       }
     }
   }
+
+  return Changed;
 }
 
 /// Tests whether a function is "malloc-like".
@@ -929,8 +934,7 @@ static bool isFunctionMallocLike(Function *F, const SCCNodeSet &SCCNodes) {
 }
 
 /// Deduce noalias attributes for the SCC.
-static void addNoAliasAttrs(const SCCNodeSet &SCCNodes,
-                            SmallSetVector<Function *, 8> &Changed) {
+static bool addNoAliasAttrs(const SCCNodeSet &SCCNodes) {
   // Check each function in turn, determining which functions return noalias
   // pointers.
   for (Function *F : SCCNodes) {
@@ -942,7 +946,7 @@ static void addNoAliasAttrs(const SCCNodeSet &SCCNodes,
     // definition we'll get at link time is *exactly* the definition we see now.
     // For more details, see GlobalValue::mayBeDerefined.
     if (!F->hasExactDefinition())
-      return;
+      return false;
 
     // We annotate noalias return values, which are only applicable to
     // pointer types.
@@ -950,9 +954,10 @@ static void addNoAliasAttrs(const SCCNodeSet &SCCNodes,
       continue;
 
     if (!isFunctionMallocLike(F, SCCNodes))
-      return;
+      return false;
   }
 
+  bool MadeChange = false;
   for (Function *F : SCCNodes) {
     if (F->returnDoesNotAlias() ||
         !F->getReturnType()->isPointerTy())
@@ -960,8 +965,10 @@ static void addNoAliasAttrs(const SCCNodeSet &SCCNodes,
 
     F->setReturnDoesNotAlias();
     ++NumNoAlias;
-    Changed.insert(F);
+    MadeChange = true;
   }
+
+  return MadeChange;
 }
 
 /// Tests whether this function is known to not return null.
@@ -1037,12 +1044,13 @@ static bool isReturnNonNull(Function *F, const SCCNodeSet &SCCNodes,
 }
 
 /// Deduce nonnull attributes for the SCC.
-static void addNonNullAttrs(const SCCNodeSet &SCCNodes,
-                            SmallSetVector<Function *, 8> &Changed) {
+static bool addNonNullAttrs(const SCCNodeSet &SCCNodes) {
   // Speculative that all functions in the SCC return only nonnull
   // pointers.  We may refute this as we analyze functions.
   bool SCCReturnsNonNull = true;
 
+  bool MadeChange = false;
+
   // Check each function in turn, determining which functions return nonnull
   // pointers.
   for (Function *F : SCCNodes) {
@@ -1055,7 +1063,7 @@ static void addNonNullAttrs(const SCCNodeSet &SCCNodes,
     // definition we'll get at link time is *exactly* the definition we see now.
     // For more details, see GlobalValue::mayBeDerefined.
     if (!F->hasExactDefinition())
-      return;
+      return false;
 
     // We annotate nonnull return values, which are only applicable to
     // pointer types.
@@ -1071,7 +1079,7 @@ static void addNonNullAttrs(const SCCNodeSet &SCCNodes,
                           << " as nonnull\n");
         F->addAttribute(AttributeList::ReturnIndex, Attribute::NonNull);
         ++NumNonNullReturn;
-        Changed.insert(F);
+        MadeChange = true;
       }
       continue;
     }
@@ -1090,9 +1098,11 @@ static void addNonNullAttrs(const SCCNodeSet &SCCNodes,
       LLVM_DEBUG(dbgs() << "SCC marking " << F->getName() << " as nonnull\n");
       F->addAttribute(AttributeList::ReturnIndex, Attribute::NonNull);
       ++NumNonNullReturn;
-      Changed.insert(F);
+      MadeChange = true;
     }
   }
+
+  return MadeChange;
 }
 
 namespace {
@@ -1145,13 +1155,12 @@ class AttributeInferer {
     InferenceDescriptors.push_back(AttrInference);
   }
 
-  void run(const SCCNodeSet &SCCNodes, SmallSetVector<Function *, 8> &Changed);
+  bool run(const SCCNodeSet &SCCNodes);
 };
 
 /// Perform all the requested attribute inference actions according to the
 /// attribute predicates stored before.
-void AttributeInferer::run(const SCCNodeSet &SCCNodes,
-                           SmallSetVector<Function *, 8> &Changed) {
+bool AttributeInferer::run(const SCCNodeSet &SCCNodes) {
   SmallVector<InferenceDescriptor, 4> InferInSCC = InferenceDescriptors;
   // Go through all the functions in SCC and check corresponding attribute
   // assumptions for each of them. Attributes that are invalid for this SCC
@@ -1160,7 +1169,7 @@ void AttributeInferer::run(const SCCNodeSet &SCCNodes,
 
     // No attributes whose assumptions are still valid - done.
     if (InferInSCC.empty())
-      return;
+      return false;
 
     // Check if our attributes ever need scanning/can be scanned.
     llvm::erase_if(InferInSCC, [F](const InferenceDescriptor &ID) {
@@ -1203,8 +1212,9 @@ void AttributeInferer::run(const SCCNodeSet &SCCNodes,
   }
 
   if (InferInSCC.empty())
-    return;
+    return false;
 
+  bool Changed = false;
   for (Function *F : SCCNodes)
     // At this point InferInSCC contains only functions that were either:
     //   - explicitly skipped from scan/inference, or
@@ -1213,9 +1223,10 @@ void AttributeInferer::run(const SCCNodeSet &SCCNodes,
     for (auto &ID : InferInSCC) {
       if (ID.SkipFunction(*F))
         continue;
-      Changed.insert(F);
+      Changed = true;
       ID.SetAttribute(*F);
     }
+  return Changed;
 }
 
 struct SCCNodesResult {
@@ -1271,8 +1282,7 @@ static bool InstrBreaksNoFree(Instruction &I, const SCCNodeSet &SCCNodes) {
 /// Attempt to remove convergent function attribute when possible.
 ///
 /// Returns true if any changes to function attributes were made.
-static void inferConvergent(const SCCNodeSet &SCCNodes,
-                            SmallSetVector<Function *, 8> &Changed) {
+static bool inferConvergent(const SCCNodeSet &SCCNodes) {
   AttributeInferer AI;
 
   // Request to remove the convergent attribute from all functions in the SCC
@@ -1295,7 +1305,7 @@ static void inferConvergent(const SCCNodeSet &SCCNodes,
       },
       /* RequiresExactDefinition= */ false});
   // Perform all the requested attribute inference actions.
-  AI.run(SCCNodes, Changed);
+  return AI.run(SCCNodes);
 }
 
 /// Infer attributes from all functions in the SCC by scanning every
@@ -1304,9 +1314,7 @@ static void inferConvergent(const SCCNodeSet &SCCNodes,
 ///   - addition of NoUnwind attribute
 ///
 /// Returns true if any changes to function attributes were made.
-static void
-inferAttrsFromFunctionBodies(const SCCNodeSet &SCCNodes,
-                             SmallSetVector<Function *, 8> &Changed) {
+static bool inferAttrsFromFunctionBodies(const SCCNodeSet &SCCNodes) {
   AttributeInferer AI;
 
   if (!DisableNoUnwindInference)
@@ -1355,20 +1363,19 @@ inferAttrsFromFunctionBodies(const SCCNodeSet &SCCNodes,
         /* RequiresExactDefinition= */ true});
 
   // Perform all the requested attribute inference actions.
-  AI.run(SCCNodes, Changed);
+  return AI.run(SCCNodes);
 }
 
-static void addNoRecurseAttrs(const SCCNodeSet &SCCNodes,
-                              SmallSetVector<Function *, 8> &Changed) {
+static bool addNoRecurseAttrs(const SCCNodeSet &SCCNodes) {
   // Try and identify functions that do not recurse.
 
   // If the SCC contains multiple nodes we know for sure there is recursion.
   if (SCCNodes.size() != 1)
-    return;
+    return false;
 
   Function *F = *SCCNodes.begin();
   if (!F || !F->hasExactDefinition() || F->doesNotRecurse())
-    return;
+    return false;
 
   // If all of the calls in F are identifiable and are to norecurse functions, F
   // is norecurse. This check also detects self-recursion as F is not currently
@@ -1379,7 +1386,7 @@ static void addNoRecurseAttrs(const SCCNodeSet &SCCNodes,
         Function *Callee = CB->getCalledFunction();
         if (!Callee || Callee == F || !Callee->doesNotRecurse())
           // Function calls a potentially recursive function.
-          return;
+          return false;
       }
 
   // Every call was to a non-recursive function other than this function, and
@@ -1387,7 +1394,7 @@ static void addNoRecurseAttrs(const SCCNodeSet &SCCNodes,
   // recurse.
   F->setDoesNotRecurse();
   ++NumNoRecurse;
-  Changed.insert(F);
+  return true;
 }
 
 static bool instructionDoesNotReturn(Instruction &I) {
@@ -1405,8 +1412,9 @@ static bool basicBlockCanReturn(BasicBlock &BB) {
 }
 
 // Set the noreturn function attribute if possible.
-static void addNoReturnAttrs(const SCCNodeSet &SCCNodes,
-                             SmallSetVector<Function *, 8> &Changed) {
+static bool addNoReturnAttrs(const SCCNodeSet &SCCNodes) {
+  bool Changed = false;
+
   for (Function *F : SCCNodes) {
     if (!F || !F->hasExactDefinition() || F->hasFnAttribute(Attribute::Naked) ||
         F->doesNotReturn())
@@ -1416,9 +1424,11 @@ static void addNoReturnAttrs(const SCCNodeSet &SCCNodes,
     // FIXME: this doesn't handle recursion or unreachable blocks.
     if (none_of(*F, basicBlockCanReturn)) {
       F->setDoesNotReturn();
-      Changed.insert(F);
+      Changed = true;
     }
   }
+
+  return Changed;
 }
 
 static bool functionWillReturn(const Function &F) {
@@ -1451,16 +1461,19 @@ static bool functionWillReturn(const Function &F) {
 }
 
 // Set the willreturn function attribute if possible.
-static void addWillReturn(const SCCNodeSet &SCCNodes,
-                          SmallSetVector<Function *, 8> &Changed) {
+static bool addWillReturn(const SCCNodeSet &SCCNodes) {
+  bool Changed = false;
+
   for (Function *F : SCCNodes) {
     if (!F || F->willReturn() || !functionWillReturn(*F))
       continue;
 
     F->setWillReturn();
     NumWillReturn++;
-    Changed.insert(F);
+    Changed = true;
   }
+
+  return Changed;
 }
 
 // Return true if this is an atomic which has an ordering stronger than
@@ -1519,8 +1532,7 @@ static bool InstrBreaksNoSync(Instruction &I, const SCCNodeSet &SCCNodes) {
 }
 
 // Infer the nosync attribute.
-static void addNoSyncAttr(const SCCNodeSet &SCCNodes,
-                          SmallSetVector<Function *, 8> &Changed) {
+static bool addNoSyncAttr(const SCCNodeSet &SCCNodes) {
   AttributeInferer AI;
   AI.registerAttrInference(AttributeInferer::InferenceDescriptor{
       Attribute::NoSync,
@@ -1537,7 +1549,7 @@ static void addNoSyncAttr(const SCCNodeSet &SCCNodes,
         ++NumNoSync;
       },
       /* RequiresExactDefinition= */ true});
-  AI.run(SCCNodes, Changed);
+  return AI.run(SCCNodes);
 }
 
 static SCCNodesResult createSCCNodeSet(ArrayRef<Function *> Functions) {
@@ -1570,33 +1582,32 @@ static SCCNodesResult createSCCNodeSet(ArrayRef<Function *> Functions) {
 }
 
 template <typename AARGetterT>
-static SmallSetVector<Function *, 8>
-deriveAttrsInPostOrder(ArrayRef<Function *> Functions, AARGetterT &&AARGetter) {
+static bool deriveAttrsInPostOrder(ArrayRef<Function *> Functions,
+                                   AARGetterT &&AARGetter) {
   SCCNodesResult Nodes = createSCCNodeSet(Functions);
+  bool Changed = false;
 
   // Bail if the SCC only contains optnone functions.
   if (Nodes.SCCNodes.empty())
-    return {};
+    return Changed;
 
-  SmallSetVector<Function *, 8> Changed;
-
-  addArgumentReturnedAttrs(Nodes.SCCNodes, Changed);
-  addReadAttrs(Nodes.SCCNodes, AARGetter, Changed);
-  addArgumentAttrs(Nodes.SCCNodes, Changed);
-  inferConvergent(Nodes.SCCNodes, Changed);
-  addNoReturnAttrs(Nodes.SCCNodes, Changed);
-  addWillReturn(Nodes.SCCNodes, Changed);
+  Changed |= addArgumentReturnedAttrs(Nodes.SCCNodes);
+  Changed |= addReadAttrs(Nodes.SCCNodes, AARGetter);
+  Changed |= addArgumentAttrs(Nodes.SCCNodes);
+  Changed |= inferConvergent(Nodes.SCCNodes);
+  Changed |= addNoReturnAttrs(Nodes.SCCNodes);
+  Changed |= addWillReturn(Nodes.SCCNodes);
 
   // If we have no external nodes participating in the SCC, we can deduce some
   // more precise attributes as well.
   if (!Nodes.HasUnknownCall) {
-    addNoAliasAttrs(Nodes.SCCNodes, Changed);
-    addNonNullAttrs(Nodes.SCCNodes, Changed);
-    inferAttrsFromFunctionBodies(Nodes.SCCNodes, Changed);
-    addNoRecurseAttrs(Nodes.SCCNodes, Changed);
+    Changed |= addNoAliasAttrs(Nodes.SCCNodes);
+    Changed |= addNonNullAttrs(Nodes.SCCNodes);
+    Changed |= inferAttrsFromFunctionBodies(Nodes.SCCNodes);
+    Changed |= addNoRecurseAttrs(Nodes.SCCNodes);
   }
 
-  addNoSyncAttr(Nodes.SCCNodes, Changed);
+  Changed |= addNoSyncAttr(Nodes.SCCNodes);
 
   // Finally, infer the maximal set of attributes from the ones we've inferred
   // above.  This is handling the cases where one attribute on a signature
@@ -1604,8 +1615,7 @@ deriveAttrsInPostOrder(ArrayRef<Function *> Functions, AARGetterT &&AARGetter) {
   // the later is missing (or simply less sophisticated).
   for (Function *F : Nodes.SCCNodes)
     if (F)
-      if (inferAttributesFromOthers(*F))
-        Changed.insert(F);
+      Changed |= inferAttributesFromOthers(*F);
 
   return Changed;
 }
@@ -1628,24 +1638,14 @@ PreservedAnalyses PostOrderFunctionAttrsPass::run(LazyCallGraph::SCC &C,
     Functions.push_back(&N.getFunction());
   }
 
-  auto ChangedFunctions = deriveAttrsInPostOrder(Functions, AARGetter);
-  if (ChangedFunctions.empty()) {
-    return PreservedAnalyses::all();
+  if (deriveAttrsInPostOrder(Functions, AARGetter)) {
+    // We have not changed the call graph or removed/added functions.
+    PreservedAnalyses PA;
+    PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
+    return PA;
   }
 
-  // Invalidate analyses for modified functions so that we don't have to
-  // invalidate all analyses for all functions in this SCC.
-  PreservedAnalyses FuncPA;
-  // We haven't changed the CFG for modified functions.
-  FuncPA.preserveSet<CFGAnalyses>();
-  for (Function *Changed : ChangedFunctions)
-    FAM.invalidate(*Changed, FuncPA);
-
-  // We have not changed the call graph or removed/added functions.
-  PreservedAnalyses PA;
-  PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
-  PA.preserveSet<AllAnalysesOn<Function>>();
-  return PA;
+  return PreservedAnalyses::all();
 }
 
 namespace {
@@ -1690,7 +1690,7 @@ static bool runImpl(CallGraphSCC &SCC, AARGetterT AARGetter) {
     Functions.push_back(I->getFunction());
   }
 
-  return !deriveAttrsInPostOrder(Functions, AARGetter).empty();
+  return deriveAttrsInPostOrder(Functions, AARGetter);
 }
 
 bool PostOrderFunctionAttrsLegacyPass::runOnSCC(CallGraphSCC &SCC) {

diff  --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp
index 04bfd4d2d3db..f0dbf3457c15 100644
--- a/llvm/lib/Transforms/IPO/Inliner.cpp
+++ b/llvm/lib/Transforms/IPO/Inliner.cpp
@@ -951,10 +951,6 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
       UR.InlinedInternalEdges.insert({&N, OldC});
     }
     InlinedCallees.clear();
-
-    // Invalidate analyses for this function now so that we don't have to
-    // invalidate analyses for all functions in this SCC later.
-    FAM.invalidate(F, PreservedAnalyses::none());
   }
 
   // Now that we've finished inlining all of the calls across this SCC, delete
@@ -994,12 +990,10 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
   if (!Changed)
     return PreservedAnalyses::all();
 
-  PreservedAnalyses PA;
   // Even if we change the IR, we update the core CGSCC data structures and so
   // can preserve the proxy to the function analysis manager.
+  PreservedAnalyses PA;
   PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
-  // We have already invalidated all analyses on modified functions.
-  PA.preserveSet<AllAnalysesOn<Function>>();
   return PA;
 }
 

diff  --git a/llvm/test/Other/opt-O3-pipeline-enable-matrix.ll b/llvm/test/Other/opt-O3-pipeline-enable-matrix.ll
index fc41b96522c3..dbb04e04b9bf 100644
--- a/llvm/test/Other/opt-O3-pipeline-enable-matrix.ll
+++ b/llvm/test/Other/opt-O3-pipeline-enable-matrix.ll
@@ -398,11 +398,19 @@
 ; NEWPM-NEXT: Running pass: InlinerPass on (f)
 ; NEWPM-NEXT: Running pass: PostOrderFunctionAttrsPass on (f)
 ; NEWPM-NEXT: Running analysis: AAManager on f
+; NEWPM-NEXT: Invalidating analysis: PreservedCFGCheckerAnalysis on f
+; NEWPM-NEXT: Invalidating analysis: DominatorTreeAnalysis on f
+; NEWPM-NEXT: Invalidating analysis: BasicAA on f
+; NEWPM-NEXT: Invalidating analysis: AAManager on f
 ; NEWPM-NEXT: Running pass: ArgumentPromotionPass on (f)
 ; NEWPM-NEXT: Running pass: OpenMPOptCGSCCPass on (f)
+; NEWPM-NEXT: Running analysis: PreservedCFGCheckerAnalysis on f
 ; NEWPM-NEXT: Running pass: SROA on f
+; NEWPM-NEXT: Running analysis: DominatorTreeAnalysis on f
 ; NEWPM-NEXT: Running pass: EarlyCSEPass on f
 ; NEWPM-NEXT: Running analysis: MemorySSAAnalysis on f
+; NEWPM-NEXT: Running analysis: AAManager on f
+; NEWPM-NEXT: Running analysis: BasicAA on f
 ; NEWPM-NEXT: Running pass: SpeculativeExecutionPass on f
 ; NEWPM-NEXT: Running pass: JumpThreadingPass on f
 ; NEWPM-NEXT: Running analysis: LazyValueAnalysis on f
@@ -444,6 +452,16 @@
 ; NEWPM-NEXT: Running pass: LCSSAPass on f
 ; NEWPM-NEXT: Running pass: SimplifyCFGPass on f
 ; NEWPM-NEXT: Running pass: InstCombinePass on f
+; NEWPM-NEXT: Invalidating analysis: PreservedCFGCheckerAnalysis on f
+; NEWPM-NEXT: Invalidating analysis: DominatorTreeAnalysis on f
+; NEWPM-NEXT: Invalidating analysis: BasicAA on f
+; NEWPM-NEXT: Invalidating analysis: AAManager on f
+; NEWPM-NEXT: Invalidating analysis: MemorySSAAnalysis on f
+; NEWPM-NEXT: Invalidating analysis: LoopAnalysis on f
+; NEWPM-NEXT: Invalidating analysis: PhiValuesAnalysis on f
+; NEWPM-NEXT: Invalidating analysis: MemoryDependenceAnalysis on f
+; NEWPM-NEXT: Invalidating analysis: DemandedBitsAnalysis on f
+; NEWPM-NEXT: Invalidating analysis: PostDominatorTreeAnalysis on f
 ; NEWPM-NEXT: Invalidating analysis: CallGraphAnalysis on
 ; NEWPM-NEXT: Running pass: GlobalOptPass on
 ; NEWPM-NEXT: Running pass: GlobalDCEPass on
@@ -451,9 +469,14 @@
 ; NEWPM-NEXT: Running pass: ReversePostOrderFunctionAttrsPass on
 ; NEWPM-NEXT: Running analysis: CallGraphAnalysis on
 ; NEWPM-NEXT: Running pass: RequireAnalysisPass<{{.*}}GlobalsAA
+; NEWPM-NEXT: Running analysis: PreservedCFGCheckerAnalysis on f
 ; NEWPM-NEXT: Running pass: Float2IntPass on f
+; NEWPM-NEXT: Running analysis: DominatorTreeAnalysis on f
 ; NEWPM-NEXT: Running pass: LowerConstantIntrinsicsPass on f
 ; NEWPM-NEXT: Running pass: LowerMatrixIntrinsicsPass on f
+; NEWPM-NEXT: Running analysis: AAManager on f
+; NEWPM-NEXT: Running analysis: BasicAA on f
+; NEWPM-NEXT: Running analysis: LoopAnalysis on f
 ; NEWPM-NEXT: Running pass: EarlyCSEPass on f
 ; NEWPM-NEXT: Running pass: LoopSimplifyPass on f
 ; NEWPM-NEXT: Running pass: LCSSAPass on f
@@ -464,6 +487,9 @@
 ; NEWPM-NEXT: Running pass: LoopVectorizePass on f
 ; NEWPM-NEXT: Running analysis: BlockFrequencyAnalysis on f
 ; NEWPM-NEXT: Running analysis: BranchProbabilityAnalysis on f
+; NEWPM-NEXT: Running analysis: PostDominatorTreeAnalysis on f
+; NEWPM-NEXT: Running analysis: DemandedBitsAnalysis on f
+; NEWPM-NEXT: Running analysis: MemorySSAAnalysis on f
 ; NEWPM-NEXT: Running pass: LoopLoadEliminationPass on f
 ; NEWPM-NEXT: Running pass: InstCombinePass on f
 ; NEWPM-NEXT: Running pass: SimplifyCFGPass on f

diff  --git a/llvm/test/Transforms/Inline/analysis-invalidation.ll b/llvm/test/Transforms/Inline/analysis-invalidation.ll
deleted file mode 100644
index ff7b12fd6a3a..000000000000
--- a/llvm/test/Transforms/Inline/analysis-invalidation.ll
+++ /dev/null
@@ -1,17 +0,0 @@
-; RUN: opt -passes=inliner-wrapper < %s -disable-output -debug-pass-manager 2>&1 | FileCheck %s
-
-; We shouldn't invalidate any function analyses on g since it's never modified.
-
-; CHECK-NOT: Invalidating{{.*}} on g
-; CHECK: Invalidating{{.*}} on f
-; CHECK-NOT: Invalidating{{.*}} on g
-
-define void @f() {
-  call void @g()
-  ret void
-}
-
-define void @g() alwaysinline {
-  call void @f()
-  ret void
-}

diff  --git a/llvm/test/Transforms/Inline/cgscc-incremental-invalidate.ll b/llvm/test/Transforms/Inline/cgscc-incremental-invalidate.ll
index 1eccaff9d2cc..0b548f74e32c 100644
--- a/llvm/test/Transforms/Inline/cgscc-incremental-invalidate.ll
+++ b/llvm/test/Transforms/Inline/cgscc-incremental-invalidate.ll
@@ -8,11 +8,11 @@
 ;
 ; CHECK: Running pass: InlinerPass on (test1_f, test1_g, test1_h)
 ; CHECK: Running analysis: DominatorTreeAnalysis on test1_f
+; CHECK: Running analysis: DominatorTreeAnalysis on test1_g
 ; CHECK: Invalidating analysis: DominatorTreeAnalysis on test1_f
 ; CHECK: Invalidating analysis: LoopAnalysis on test1_f
 ; CHECK: Invalidating analysis: BranchProbabilityAnalysis on test1_f
 ; CHECK: Invalidating analysis: BlockFrequencyAnalysis on test1_f
-; CHECK: Running analysis: DominatorTreeAnalysis on test1_g
 ; CHECK: Invalidating analysis: DominatorTreeAnalysis on test1_g
 ; CHECK: Invalidating analysis: LoopAnalysis on test1_g
 ; CHECK: Invalidating analysis: BranchProbabilityAnalysis on test1_g
@@ -29,6 +29,7 @@
 ; CHECK-NEXT: Running analysis: DominatorTreeAnalysis on test1_h
 ; CHECK-NOT: Invalidating analysis:
 ; CHECK: Running pass: DominatorTreeVerifierPass on test1_f
+; CHECK-NEXT: Running analysis: DominatorTreeAnalysis on test1_f
 
 ; An external function used to control branches.
 declare i1 @flag()


        


More information about the cfe-commits mailing list