diff --git a/clang/test/CodeGen/thinlto-distributed-newpm.ll b/clang/test/CodeGen/thinlto-distributed-newpm.ll index 7f478fb05f5059..e20f781915726c 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 c01704162e9623..8043cc7fc742e1 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>(); + PreservedAnalyses PA; PA.preserve(); AM.invalidate(*OldC, PA); diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp index 18aeb899172a81..9be28c6d29064f 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(C, CG).getManager(); - for (LazyCallGraph::Node &N : C) { Function &OldF = N.getFunction(); + FunctionAnalysisManager &FAM = + AM.getResult(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(); - for (auto *U : NewF->users()) { - auto *UserF = cast(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(); - PA.preserveSet>(); - return PA; + return PreservedAnalyses::none(); } namespace { diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp index 25b37c0a18163a..ca8660a98ded85 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 -static void addReadAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter, - SmallSetVector &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 &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(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 &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 &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 &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 &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 &Changed) { +bool AttributeInferer::run(const SCCNodeSet &SCCNodes) { SmallVector 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 &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 &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 &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 &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 &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 &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 Functions) { @@ -1570,33 +1582,32 @@ static SCCNodesResult createSCCNodeSet(ArrayRef Functions) { } template -static SmallSetVector -deriveAttrsInPostOrder(ArrayRef Functions, AARGetterT &&AARGetter) { +static bool deriveAttrsInPostOrder(ArrayRef 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 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 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(); + 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(); - for (Function *Changed : ChangedFunctions) - FAM.invalidate(*Changed, FuncPA); - - // We have not changed the call graph or removed/added functions. - PreservedAnalyses PA; - PA.preserve(); - PA.preserveSet>(); - 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 04bfd4d2d3db47..f0dbf3457c15c4 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(); - // We have already invalidated all analyses on modified functions. - PA.preserveSet>(); 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 fc41b96522c382..dbb04e04b9bf32 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 ff7b12fd6a3aba..00000000000000 --- 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 1eccaff9d2cc53..0b548f74e32c5f 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()