From 3dd8c9176be9515dc722b43d9ffb048b32ff5015 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 17 Aug 2021 21:31:35 +0200 Subject: [PATCH] [LICM] Remove AST-based implementation MSSA-based LICM has been enabled by default for a few years now. This drops the old AST-based implementation. Using loop(licm) will result in a fatal error, the use of loop-mssa(licm) is required (or just licm, which defaults to loop-mssa). Note that the core canSinkOrHoistInst() logic has to retain AST support for now, because it is shared with LoopSink. Differential Revision: https://reviews.llvm.org/D108244 --- llvm/include/llvm/Transforms/Utils/LoopUtils.h | 18 +- llvm/lib/Transforms/Scalar/LICM.cpp | 260 +++++++-------------- llvm/test/Analysis/BasicAA/store-promote.ll | 11 +- llvm/test/Analysis/GlobalsModRef/dead-uses.ll | 2 +- llvm/test/Analysis/MemorySSA/pr42294.ll | 1 - .../Other/optimization-remarks-invalidation.ll | 8 +- llvm/test/Other/time-passes.ll | 8 +- llvm/test/Transforms/ADCE/broken-loop-info.ll | 2 +- llvm/test/Transforms/LICM/assume.ll | 2 +- llvm/test/Transforms/LICM/atomics.ll | 9 +- llvm/test/Transforms/LICM/basictest.ll | 2 +- llvm/test/Transforms/LICM/call-hoisting.ll | 2 +- llvm/test/Transforms/LICM/constexpr.ll | 2 +- llvm/test/Transforms/LICM/crash.ll | 2 +- llvm/test/Transforms/LICM/debug-value.ll | 2 +- llvm/test/Transforms/LICM/explicit_guards.ll | 2 +- llvm/test/Transforms/LICM/extra-copies.ll | 2 +- llvm/test/Transforms/LICM/fence.ll | 2 +- llvm/test/Transforms/LICM/funclet.ll | 2 +- llvm/test/Transforms/LICM/guards.ll | 27 ++- llvm/test/Transforms/LICM/hoist-bitcast-load.ll | 2 +- llvm/test/Transforms/LICM/hoist-deref-load.ll | 1 - llvm/test/Transforms/LICM/hoist-mustexec.ll | 2 +- llvm/test/Transforms/LICM/hoist-nounwind.ll | 2 +- llvm/test/Transforms/LICM/hoist-phi.ll | 4 +- llvm/test/Transforms/LICM/hoist-round.ll | 2 +- llvm/test/Transforms/LICM/hoisting.ll | 2 +- llvm/test/Transforms/LICM/infinite_loops.ll | 2 +- llvm/test/Transforms/LICM/lcssa-ssa-promoter.ll | 2 +- llvm/test/Transforms/LICM/lnicm-sink.ll | 4 +- llvm/test/Transforms/LICM/lnicm.ll | 4 +- llvm/test/Transforms/LICM/no-preheader-test.ll | 2 +- .../LICM/opt-remarks-conditional-load.ll | 2 +- .../LICM/opt-remarks-intervening-store.ll | 2 +- llvm/test/Transforms/LICM/opt-remarks.ll | 2 +- llvm/test/Transforms/LICM/pr37323.ll | 2 +- llvm/test/Transforms/LICM/pr38513.ll | 2 +- llvm/test/Transforms/LICM/preheader-safe.ll | 2 +- llvm/test/Transforms/LICM/promote-order.ll | 8 +- llvm/test/Transforms/LICM/promote-tls.ll | 2 +- .../Transforms/LICM/scalar-promote-memmodel.ll | 2 +- llvm/test/Transforms/LICM/scalar-promote-unwind.ll | 2 +- llvm/test/Transforms/LICM/scalar-promote.ll | 2 +- llvm/test/Transforms/LICM/sink.ll | 2 +- llvm/test/Transforms/LICM/speculate.ll | 2 +- llvm/test/Transforms/LICM/store-hoisting.ll | 21 +- .../test/Transforms/LICM/unrolled-deeply-nested.ll | 2 +- llvm/test/Transforms/LICM/update-scev.ll | 2 +- llvm/test/Transforms/LICM/volatile-alias.ll | 2 +- .../LoopVersioningLICM/loopversioningLICM1.ll | 2 +- .../LoopVersioningLICM/loopversioningLICM2.ll | 2 +- .../test/Transforms/LoopVersioningLICM/metadata.ll | 2 +- llvm/unittests/Transforms/Scalar/LICMTest.cpp | 2 +- 53 files changed, 179 insertions(+), 283 deletions(-) diff --git a/llvm/include/llvm/Transforms/Utils/LoopUtils.h b/llvm/include/llvm/Transforms/Utils/LoopUtils.h index 9428e2d..a425aa2 100644 --- a/llvm/include/llvm/Transforms/Utils/LoopUtils.h +++ b/llvm/include/llvm/Transforms/Utils/LoopUtils.h @@ -151,18 +151,17 @@ protected: /// this function is called by \p sinkRegionForLoopNest. bool sinkRegion(DomTreeNode *, AAResults *, LoopInfo *, DominatorTree *, BlockFrequencyInfo *, TargetLibraryInfo *, - TargetTransformInfo *, Loop *CurLoop, AliasSetTracker *, - MemorySSAUpdater *, ICFLoopSafetyInfo *, - SinkAndHoistLICMFlags &, OptimizationRemarkEmitter *, - Loop *OutermostLoop = nullptr); + TargetTransformInfo *, Loop *CurLoop, MemorySSAUpdater *, + ICFLoopSafetyInfo *, SinkAndHoistLICMFlags &, + OptimizationRemarkEmitter *, Loop *OutermostLoop = nullptr); /// Call sinkRegion on loops contained within the specified loop /// in order from innermost to outermost. bool sinkRegionForLoopNest(DomTreeNode *, AAResults *, LoopInfo *, DominatorTree *, BlockFrequencyInfo *, TargetLibraryInfo *, TargetTransformInfo *, Loop *, - AliasSetTracker *, MemorySSAUpdater *, - ICFLoopSafetyInfo *, SinkAndHoistLICMFlags &, + MemorySSAUpdater *, ICFLoopSafetyInfo *, + SinkAndHoistLICMFlags &, OptimizationRemarkEmitter *); /// Walk the specified region of the CFG (defined by all blocks @@ -175,9 +174,8 @@ bool sinkRegionForLoopNest(DomTreeNode *, AAResults *, LoopInfo *, /// Diagnostics is emitted via \p ORE. It returns changed status. bool hoistRegion(DomTreeNode *, AAResults *, LoopInfo *, DominatorTree *, BlockFrequencyInfo *, TargetLibraryInfo *, Loop *, - AliasSetTracker *, MemorySSAUpdater *, ScalarEvolution *, - ICFLoopSafetyInfo *, SinkAndHoistLICMFlags &, - OptimizationRemarkEmitter *, bool); + MemorySSAUpdater *, ScalarEvolution *, ICFLoopSafetyInfo *, + SinkAndHoistLICMFlags &, OptimizationRemarkEmitter *, bool); /// This function deletes dead loops. The caller of this function needs to /// guarantee that the loop is infact dead. @@ -211,7 +209,7 @@ bool promoteLoopAccessesToScalars( const SmallSetVector &, SmallVectorImpl &, SmallVectorImpl &, SmallVectorImpl &, PredIteratorCache &, LoopInfo *, DominatorTree *, const TargetLibraryInfo *, - Loop *, AliasSetTracker *, MemorySSAUpdater *, ICFLoopSafetyInfo *, + Loop *, MemorySSAUpdater *, ICFLoopSafetyInfo *, OptimizationRemarkEmitter *); /// Does a BFS from a given node to all of its children inside a given loop. diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp index fa62703..963f73f 100644 --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/llvm/lib/Transforms/Scalar/LICM.cpp @@ -174,7 +174,7 @@ static Instruction *cloneInstructionInExitBlock( const LoopSafetyInfo *SafetyInfo, MemorySSAUpdater *MSSAU); static void eraseInstruction(Instruction &I, ICFLoopSafetyInfo &SafetyInfo, - AliasSetTracker *AST, MemorySSAUpdater *MSSAU); + MemorySSAUpdater *MSSAU); static void moveInstructionBefore(Instruction &I, Instruction &Dest, ICFLoopSafetyInfo &SafetyInfo, @@ -200,9 +200,6 @@ struct LoopInvariantCodeMotion { private: unsigned LicmMssaOptCap; unsigned LicmMssaNoAccForPromotionCap; - - std::unique_ptr - collectAliasInfoForLoop(Loop *L, LoopInfo *LI, AAResults *AA); }; struct LegacyLICMPass : public LoopPass { @@ -265,6 +262,9 @@ private: PreservedAnalyses LICMPass::run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &) { + if (!AR.MSSA) + report_fatal_error("LICM requires MemorySSA (loop-mssa)"); + // For the new PM, we also can't use OptimizationRemarkEmitter as an analysis // pass. Function analyses need to be preserved across loop transformations // but ORE cannot be preserved (see comment before the pass definition). @@ -279,8 +279,7 @@ PreservedAnalyses LICMPass::run(Loop &L, LoopAnalysisManager &AM, PA.preserve(); PA.preserve(); - if (AR.MSSA) - PA.preserve(); + PA.preserve(); return PA; } @@ -288,6 +287,9 @@ PreservedAnalyses LICMPass::run(Loop &L, LoopAnalysisManager &AM, PreservedAnalyses LNICMPass::run(LoopNest &LN, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &) { + if (!AR.MSSA) + report_fatal_error("LNICM requires MemorySSA (loop-mssa)"); + // For the new PM, we also can't use OptimizationRemarkEmitter as an analysis // pass. Function analyses need to be preserved across loop transformations // but ORE cannot be preserved (see comment before the pass definition). @@ -306,8 +308,7 @@ PreservedAnalyses LNICMPass::run(LoopNest &LN, LoopAnalysisManager &AM, PA.preserve(); PA.preserve(); - if (AR.MSSA) - PA.preserve(); + PA.preserve(); return PA; } @@ -376,10 +377,6 @@ bool LoopInvariantCodeMotion::runOnLoop( return false; } - std::unique_ptr CurAST; - std::unique_ptr MSSAU; - std::unique_ptr Flags; - // Don't sink stores from loops with coroutine suspend instructions. // LICM would sink instructions into the default destination of // the coroutine switch. The default destination of the switch is to @@ -396,17 +393,9 @@ bool LoopInvariantCodeMotion::runOnLoop( }); }); - if (!MSSA) { - LLVM_DEBUG(dbgs() << "LICM: Using Alias Set Tracker.\n"); - CurAST = collectAliasInfoForLoop(L, LI, AA); - Flags = std::make_unique( - LicmMssaOptCap, LicmMssaNoAccForPromotionCap, /*IsSink=*/true); - } else { - LLVM_DEBUG(dbgs() << "LICM: Using MemorySSA.\n"); - MSSAU = std::make_unique(MSSA); - Flags = std::make_unique( - LicmMssaOptCap, LicmMssaNoAccForPromotionCap, /*IsSink=*/true, L, MSSA); - } + MemorySSAUpdater MSSAU(MSSA); + SinkAndHoistLICMFlags Flags(LicmMssaOptCap, LicmMssaNoAccForPromotionCap, + /*IsSink=*/true, L, MSSA); // Get the preheader block to move instructions into... BasicBlock *Preheader = L->getLoopPreheader(); @@ -425,19 +414,16 @@ bool LoopInvariantCodeMotion::runOnLoop( // us to sink instructions in one pass, without iteration. After sinking // instructions, we perform another pass to hoist them out of the loop. if (L->hasDedicatedExits()) - Changed |= - LoopNestMode - ? sinkRegionForLoopNest(DT->getNode(L->getHeader()), AA, LI, DT, - BFI, TLI, TTI, L, CurAST.get(), MSSAU.get(), - &SafetyInfo, *Flags.get(), ORE) - : sinkRegion(DT->getNode(L->getHeader()), AA, LI, DT, BFI, TLI, TTI, - L, CurAST.get(), MSSAU.get(), &SafetyInfo, - *Flags.get(), ORE); - Flags->setIsSink(false); + Changed |= LoopNestMode + ? sinkRegionForLoopNest(DT->getNode(L->getHeader()), AA, LI, + DT, BFI, TLI, TTI, L, &MSSAU, + &SafetyInfo, Flags, ORE) + : sinkRegion(DT->getNode(L->getHeader()), AA, LI, DT, BFI, + TLI, TTI, L, &MSSAU, &SafetyInfo, Flags, ORE); + Flags.setIsSink(false); if (Preheader) Changed |= hoistRegion(DT->getNode(L->getHeader()), AA, LI, DT, BFI, TLI, L, - CurAST.get(), MSSAU.get(), SE, &SafetyInfo, - *Flags.get(), ORE, LoopNestMode); + &MSSAU, SE, &SafetyInfo, Flags, ORE, LoopNestMode); // Now that all loop invariants have been removed from the loop, promote any // memory references to scalars that we can. @@ -447,7 +433,7 @@ bool LoopInvariantCodeMotion::runOnLoop( // preheader for SSA updater, so also avoid sinking when no preheader // is available. if (!DisablePromotion && Preheader && L->hasDedicatedExits() && - !Flags->tooManyMemoryAccesses() && !HasCoroSuspendInst) { + !Flags.tooManyMemoryAccesses() && !HasCoroSuspendInst) { // Figure out the loop exits and their insertion points SmallVector ExitBlocks; L->getUniqueExitBlocks(ExitBlocks); @@ -461,55 +447,29 @@ bool LoopInvariantCodeMotion::runOnLoop( SmallVector InsertPts; SmallVector MSSAInsertPts; InsertPts.reserve(ExitBlocks.size()); - if (MSSAU) - MSSAInsertPts.reserve(ExitBlocks.size()); + MSSAInsertPts.reserve(ExitBlocks.size()); for (BasicBlock *ExitBlock : ExitBlocks) { InsertPts.push_back(&*ExitBlock->getFirstInsertionPt()); - if (MSSAU) - MSSAInsertPts.push_back(nullptr); + MSSAInsertPts.push_back(nullptr); } PredIteratorCache PIC; + // Promoting one set of accesses may make the pointers for another set + // loop invariant, so run this in a loop (with the MaybePromotable set + // decreasing in size over time). bool Promoted = false; - if (CurAST.get()) { - // Loop over all of the alias sets in the tracker object. - for (AliasSet &AS : *CurAST) { - // We can promote this alias set if it has a store, if it is a "Must" - // alias set, if the pointer is loop invariant, and if we are not - // eliminating any volatile loads or stores. - if (AS.isForwardingAliasSet() || !AS.isMod() || !AS.isMustAlias() || - !L->isLoopInvariant(AS.begin()->getValue())) - continue; - - assert( - !AS.empty() && - "Must alias set should have at least one pointer element in it!"); - - SmallSetVector PointerMustAliases; - for (const auto &ASI : AS) - PointerMustAliases.insert(ASI.getValue()); - - Promoted |= promoteLoopAccessesToScalars( - PointerMustAliases, ExitBlocks, InsertPts, MSSAInsertPts, PIC, LI, - DT, TLI, L, CurAST.get(), MSSAU.get(), &SafetyInfo, ORE); + bool LocalPromoted; + do { + LocalPromoted = false; + for (const SmallSetVector &PointerMustAliases : + collectPromotionCandidates(MSSA, AA, L)) { + LocalPromoted |= promoteLoopAccessesToScalars( + PointerMustAliases, ExitBlocks, InsertPts, MSSAInsertPts, PIC, + LI, DT, TLI, L, &MSSAU, &SafetyInfo, ORE); } - } else { - // Promoting one set of accesses may make the pointers for another set - // loop invariant, so run this in a loop (with the MaybePromotable set - // decreasing in size over time). - bool LocalPromoted; - do { - LocalPromoted = false; - for (const SmallSetVector &PointerMustAliases : - collectPromotionCandidates(MSSA, AA, L)) { - LocalPromoted |= promoteLoopAccessesToScalars( - PointerMustAliases, ExitBlocks, InsertPts, MSSAInsertPts, PIC, - LI, DT, TLI, L, /*AST*/nullptr, MSSAU.get(), &SafetyInfo, ORE); - } - Promoted |= LocalPromoted; - } while (LocalPromoted); - } + Promoted |= LocalPromoted; + } while (LocalPromoted); // Once we have promoted values across the loop body we have to // recursively reform LCSSA as any nested loop may now have values defined @@ -531,8 +491,8 @@ bool LoopInvariantCodeMotion::runOnLoop( assert((L->isOutermost() || L->getParentLoop()->isLCSSAForm(*DT)) && "Parent loop not left in LCSSA form after LICM!"); - if (MSSAU.get() && VerifyMemorySSA) - MSSAU->getMemorySSA()->verifyMemorySSA(); + if (VerifyMemorySSA) + MSSA->verifyMemorySSA(); if (Changed && SE) SE->forgetLoopDispositions(L); @@ -547,17 +507,15 @@ bool LoopInvariantCodeMotion::runOnLoop( bool llvm::sinkRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI, DominatorTree *DT, BlockFrequencyInfo *BFI, TargetLibraryInfo *TLI, TargetTransformInfo *TTI, - Loop *CurLoop, AliasSetTracker *CurAST, - MemorySSAUpdater *MSSAU, ICFLoopSafetyInfo *SafetyInfo, + Loop *CurLoop, MemorySSAUpdater *MSSAU, + ICFLoopSafetyInfo *SafetyInfo, SinkAndHoistLICMFlags &Flags, OptimizationRemarkEmitter *ORE, Loop *OutermostLoop) { // Verify inputs. assert(N != nullptr && AA != nullptr && LI != nullptr && DT != nullptr && - CurLoop != nullptr && SafetyInfo != nullptr && + CurLoop != nullptr && MSSAU != nullptr && SafetyInfo != nullptr && "Unexpected input to sinkRegion."); - assert(((CurAST != nullptr) ^ (MSSAU != nullptr)) && - "Either AliasSetTracker or MemorySSA should be initialized."); // We want to visit children before parents. We will enque all the parents // before their children in the worklist and process the worklist in reverse @@ -582,7 +540,7 @@ bool llvm::sinkRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI, salvageKnowledge(&I); salvageDebugInfo(I); ++II; - eraseInstruction(I, *SafetyInfo, CurAST, MSSAU); + eraseInstruction(I, *SafetyInfo, MSSAU); Changed = true; continue; } @@ -597,20 +555,20 @@ bool llvm::sinkRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI, if (!I.mayHaveSideEffects() && isNotUsedOrFreeInLoop(I, LoopNestMode ? OutermostLoop : CurLoop, SafetyInfo, TTI, FreeInLoop, LoopNestMode) && - canSinkOrHoistInst(I, AA, DT, CurLoop, CurAST, MSSAU, true, &Flags, - ORE)) { + canSinkOrHoistInst(I, AA, DT, CurLoop, /*CurAST*/nullptr, MSSAU, true, + &Flags, ORE)) { if (sink(I, LI, DT, BFI, CurLoop, SafetyInfo, MSSAU, ORE)) { if (!FreeInLoop) { ++II; salvageDebugInfo(I); - eraseInstruction(I, *SafetyInfo, CurAST, MSSAU); + eraseInstruction(I, *SafetyInfo, MSSAU); } Changed = true; } } } } - if (MSSAU && VerifyMemorySSA) + if (VerifyMemorySSA) MSSAU->getMemorySSA()->verifyMemorySSA(); return Changed; } @@ -618,9 +576,8 @@ bool llvm::sinkRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI, bool llvm::sinkRegionForLoopNest( DomTreeNode *N, AAResults *AA, LoopInfo *LI, DominatorTree *DT, BlockFrequencyInfo *BFI, TargetLibraryInfo *TLI, TargetTransformInfo *TTI, - Loop *CurLoop, AliasSetTracker *CurAST, MemorySSAUpdater *MSSAU, - ICFLoopSafetyInfo *SafetyInfo, SinkAndHoistLICMFlags &Flags, - OptimizationRemarkEmitter *ORE) { + Loop *CurLoop, MemorySSAUpdater *MSSAU, ICFLoopSafetyInfo *SafetyInfo, + SinkAndHoistLICMFlags &Flags, OptimizationRemarkEmitter *ORE) { bool Changed = false; SmallPriorityWorklist Worklist; @@ -628,9 +585,8 @@ bool llvm::sinkRegionForLoopNest( appendLoopsToWorklist(*CurLoop, Worklist); while (!Worklist.empty()) { Loop *L = Worklist.pop_back_val(); - Changed |= - sinkRegion(DT->getNode(L->getHeader()), AA, LI, DT, BFI, TLI, TTI, L, - CurAST, MSSAU, SafetyInfo, Flags, ORE, CurLoop); + Changed |= sinkRegion(DT->getNode(L->getHeader()), AA, LI, DT, BFI, TLI, + TTI, L, MSSAU, SafetyInfo, Flags, ORE, CurLoop); } return Changed; } @@ -837,9 +793,8 @@ public: if (HoistTarget == InitialPreheader) { // Phis in the loop header now need to use the new preheader. InitialPreheader->replaceSuccessorsPhiUsesWith(HoistCommonSucc); - if (MSSAU) - MSSAU->wireOldPredecessorsToNewImmediatePredecessor( - HoistTarget->getSingleSuccessor(), HoistCommonSucc, {HoistTarget}); + MSSAU->wireOldPredecessorsToNewImmediatePredecessor( + HoistTarget->getSingleSuccessor(), HoistCommonSucc, {HoistTarget}); // The new preheader dominates the loop header. DomTreeNode *PreheaderNode = DT->getNode(HoistCommonSucc); DomTreeNode *HeaderNode = DT->getNode(CurLoop->getHeader()); @@ -901,16 +856,14 @@ static bool worthSinkOrHoistInst(Instruction &I, BasicBlock *DstBlock, bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI, DominatorTree *DT, BlockFrequencyInfo *BFI, TargetLibraryInfo *TLI, Loop *CurLoop, - AliasSetTracker *CurAST, MemorySSAUpdater *MSSAU, - ScalarEvolution *SE, ICFLoopSafetyInfo *SafetyInfo, + MemorySSAUpdater *MSSAU, ScalarEvolution *SE, + ICFLoopSafetyInfo *SafetyInfo, SinkAndHoistLICMFlags &Flags, OptimizationRemarkEmitter *ORE, bool LoopNestMode) { // Verify inputs. assert(N != nullptr && AA != nullptr && LI != nullptr && DT != nullptr && - CurLoop != nullptr && SafetyInfo != nullptr && + CurLoop != nullptr && MSSAU != nullptr && SafetyInfo != nullptr && "Unexpected input to hoistRegion."); - assert(((CurAST != nullptr) ^ (MSSAU != nullptr)) && - "Either AliasSetTracker or MemorySSA should be initialized."); ControlFlowHoister CFH(LI, DT, CurLoop, MSSAU); @@ -939,12 +892,10 @@ bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI, &I, I.getModule()->getDataLayout(), TLI)) { LLVM_DEBUG(dbgs() << "LICM folding inst: " << I << " --> " << *C << '\n'); - if (CurAST) - CurAST->copyValue(&I, C); // FIXME MSSA: Such replacements may make accesses unoptimized (D51960). I.replaceAllUsesWith(C); if (isInstructionTriviallyDead(&I, TLI)) - eraseInstruction(I, *SafetyInfo, CurAST, MSSAU); + eraseInstruction(I, *SafetyInfo, MSSAU); Changed = true; continue; } @@ -957,8 +908,8 @@ bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI, // and we have accurately duplicated the control flow from the loop header // to that block. if (CurLoop->hasLoopInvariantOperands(&I) && - canSinkOrHoistInst(I, AA, DT, CurLoop, CurAST, MSSAU, true, &Flags, - ORE) && + canSinkOrHoistInst(I, AA, DT, CurLoop, /*CurAST*/ nullptr, MSSAU, + true, &Flags, ORE) && worthSinkOrHoistInst(I, CurLoop->getLoopPreheader(), ORE, BFI) && isSafeToExecuteUnconditionally( I, DT, TLI, CurLoop, SafetyInfo, ORE, @@ -987,7 +938,7 @@ bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI, SafetyInfo->insertInstructionTo(Product, I.getParent()); Product->insertAfter(&I); I.replaceAllUsesWith(Product); - eraseInstruction(I, *SafetyInfo, CurAST, MSSAU); + eraseInstruction(I, *SafetyInfo, MSSAU); hoist(*ReciprocalDivisor, DT, CurLoop, CFH.getOrCreateHoistedBlock(BB), SafetyInfo, MSSAU, SE, ORE); @@ -1066,7 +1017,7 @@ bool llvm::hoistRegion(DomTreeNode *N, AAResults *AA, LoopInfo *LI, } } } - if (MSSAU && VerifyMemorySSA) + if (VerifyMemorySSA) MSSAU->getMemorySSA()->verifyMemorySSA(); // Now that we've finished hoisting make sure that LI and DT are still @@ -1573,9 +1524,7 @@ static Instruction *cloneInstructionInExitBlock( } static void eraseInstruction(Instruction &I, ICFLoopSafetyInfo &SafetyInfo, - AliasSetTracker *AST, MemorySSAUpdater *MSSAU) { - if (AST) - AST->deleteValue(&I); + MemorySSAUpdater *MSSAU) { if (MSSAU) MSSAU->removeMemoryAccess(&I); SafetyInfo.removeInstruction(&I); @@ -1813,7 +1762,7 @@ static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT, Instruction *New = sinkThroughTriviallyReplaceablePHI( PN, &I, LI, SunkCopies, SafetyInfo, CurLoop, MSSAU); PN->replaceAllUsesWith(New); - eraseInstruction(*PN, *SafetyInfo, nullptr, nullptr); + eraseInstruction(*PN, *SafetyInfo, nullptr); Changed = true; } return Changed; @@ -1902,7 +1851,6 @@ class LoopPromoter : public LoadAndStorePromoter { SmallVectorImpl &LoopInsertPts; SmallVectorImpl &MSSAInsertPts; PredIteratorCache &PredCache; - AliasSetTracker *AST; MemorySSAUpdater *MSSAU; LoopInfo &LI; DebugLoc DL; @@ -1934,12 +1882,12 @@ public: SmallVectorImpl &LEB, SmallVectorImpl &LIP, SmallVectorImpl &MSSAIP, PredIteratorCache &PIC, - AliasSetTracker *ast, MemorySSAUpdater *MSSAU, LoopInfo &li, - DebugLoc dl, int alignment, bool UnorderedAtomic, - const AAMDNodes &AATags, ICFLoopSafetyInfo &SafetyInfo) + MemorySSAUpdater *MSSAU, LoopInfo &li, DebugLoc dl, + int alignment, bool UnorderedAtomic, const AAMDNodes &AATags, + ICFLoopSafetyInfo &SafetyInfo) : LoadAndStorePromoter(Insts, S), SomePtr(SP), PointerMustAliases(PMA), LoopExitBlocks(LEB), LoopInsertPts(LIP), MSSAInsertPts(MSSAIP), - PredCache(PIC), AST(ast), MSSAU(MSSAU), LI(li), DL(std::move(dl)), + PredCache(PIC), MSSAU(MSSAU), LI(li), DL(std::move(dl)), Alignment(alignment), UnorderedAtomic(UnorderedAtomic), AATags(AATags), SafetyInfo(SafetyInfo) {} @@ -1972,34 +1920,24 @@ public: if (AATags) NewSI->setAAMetadata(AATags); - if (MSSAU) { - MemoryAccess *MSSAInsertPoint = MSSAInsertPts[i]; - MemoryAccess *NewMemAcc; - if (!MSSAInsertPoint) { - NewMemAcc = MSSAU->createMemoryAccessInBB( - NewSI, nullptr, NewSI->getParent(), MemorySSA::Beginning); - } else { - NewMemAcc = - MSSAU->createMemoryAccessAfter(NewSI, nullptr, MSSAInsertPoint); - } - MSSAInsertPts[i] = NewMemAcc; - MSSAU->insertDef(cast(NewMemAcc), true); - // FIXME: true for safety, false may still be correct. + MemoryAccess *MSSAInsertPoint = MSSAInsertPts[i]; + MemoryAccess *NewMemAcc; + if (!MSSAInsertPoint) { + NewMemAcc = MSSAU->createMemoryAccessInBB( + NewSI, nullptr, NewSI->getParent(), MemorySSA::Beginning); + } else { + NewMemAcc = + MSSAU->createMemoryAccessAfter(NewSI, nullptr, MSSAInsertPoint); } + MSSAInsertPts[i] = NewMemAcc; + MSSAU->insertDef(cast(NewMemAcc), true); + // FIXME: true for safety, false may still be correct. } } - void replaceLoadWithValue(LoadInst *LI, Value *V) const override { - // Update alias analysis. - if (AST) - AST->copyValue(LI, V); - } void instructionDeleted(Instruction *I) const override { SafetyInfo.removeInstruction(I); - if (AST) - AST->deleteValue(I); - if (MSSAU) - MSSAU->removeMemoryAccess(I); + MSSAU->removeMemoryAccess(I); } }; @@ -2050,8 +1988,8 @@ bool llvm::promoteLoopAccessesToScalars( SmallVectorImpl &InsertPts, SmallVectorImpl &MSSAInsertPts, PredIteratorCache &PIC, LoopInfo *LI, DominatorTree *DT, const TargetLibraryInfo *TLI, - Loop *CurLoop, AliasSetTracker *CurAST, MemorySSAUpdater *MSSAU, - ICFLoopSafetyInfo *SafetyInfo, OptimizationRemarkEmitter *ORE) { + Loop *CurLoop, MemorySSAUpdater *MSSAU, ICFLoopSafetyInfo *SafetyInfo, + OptimizationRemarkEmitter *ORE) { // Verify inputs. assert(LI != nullptr && DT != nullptr && CurLoop != nullptr && SafetyInfo != nullptr && @@ -2283,7 +2221,7 @@ bool llvm::promoteLoopAccessesToScalars( SmallVector NewPHIs; SSAUpdater SSA(&NewPHIs); LoopPromoter Promoter(SomePtr, LoopUses, SSA, PointerMustAliases, ExitBlocks, - InsertPts, MSSAInsertPts, PIC, CurAST, MSSAU, *LI, DL, + InsertPts, MSSAInsertPts, PIC, MSSAU, *LI, DL, Alignment.value(), SawUnorderedAtomic, AATags, *SafetyInfo); @@ -2300,24 +2238,22 @@ bool llvm::promoteLoopAccessesToScalars( PreheaderLoad->setAAMetadata(AATags); SSA.AddAvailableValue(Preheader, PreheaderLoad); - if (MSSAU) { - MemoryAccess *PreheaderLoadMemoryAccess = MSSAU->createMemoryAccessInBB( - PreheaderLoad, nullptr, PreheaderLoad->getParent(), MemorySSA::End); - MemoryUse *NewMemUse = cast(PreheaderLoadMemoryAccess); - MSSAU->insertUse(NewMemUse, /*RenameUses=*/true); - } + MemoryAccess *PreheaderLoadMemoryAccess = MSSAU->createMemoryAccessInBB( + PreheaderLoad, nullptr, PreheaderLoad->getParent(), MemorySSA::End); + MemoryUse *NewMemUse = cast(PreheaderLoadMemoryAccess); + MSSAU->insertUse(NewMemUse, /*RenameUses=*/true); - if (MSSAU && VerifyMemorySSA) + if (VerifyMemorySSA) MSSAU->getMemorySSA()->verifyMemorySSA(); // Rewrite all the loads in the loop and remember all the definitions from // stores in the loop. Promoter.run(LoopUses); - if (MSSAU && VerifyMemorySSA) + if (VerifyMemorySSA) MSSAU->getMemorySSA()->verifyMemorySSA(); // If the SSAUpdater didn't use the load in the preheader, just zap it now. if (PreheaderLoad->use_empty()) - eraseInstruction(*PreheaderLoad, *SafetyInfo, CurAST, MSSAU); + eraseInstruction(*PreheaderLoad, *SafetyInfo, MSSAU); return true; } @@ -2383,26 +2319,6 @@ collectPromotionCandidates(MemorySSA *MSSA, AliasAnalysis *AA, Loop *L) { return Result; } -/// Returns an owning pointer to an alias set which incorporates aliasing info -/// from L and all subloops of L. -std::unique_ptr -LoopInvariantCodeMotion::collectAliasInfoForLoop(Loop *L, LoopInfo *LI, - AAResults *AA) { - auto CurAST = std::make_unique(*AA); - - // Add everything from all the sub loops. - for (Loop *InnerL : L->getSubLoops()) - for (BasicBlock *BB : InnerL->blocks()) - CurAST->add(*BB); - - // And merge in this loop (without anything from inner loops). - for (BasicBlock *BB : L->blocks()) - if (LI->getLoopFor(BB) == L) - CurAST->add(*BB); - - return CurAST; -} - static bool pointerInvalidatedByLoop(MemoryLocation MemLoc, AliasSetTracker *CurAST, Loop *CurLoop, AAResults *AA) { diff --git a/llvm/test/Analysis/BasicAA/store-promote.ll b/llvm/test/Analysis/BasicAA/store-promote.ll index 4ba44b6..dbf313b 100644 --- a/llvm/test/Analysis/BasicAA/store-promote.ll +++ b/llvm/test/Analysis/BasicAA/store-promote.ll @@ -2,9 +2,8 @@ ; disambiguating some obvious cases. If LICM is able to disambiguate the ; two pointers, then the load should be hoisted, and the store sunk. -; RUN: opt < %s -basic-aa -licm -enable-new-pm=0 -S | FileCheck %s -check-prefixes=CHECK,MSSA -; RUN: opt < %s -aa-pipeline=basic-aa -passes='loop(licm)' -S | FileCheck %s -check-prefixes=CHECK,AST -; RUN: opt < %s -aa-pipeline=basic-aa -passes='loop-mssa(licm)' -S | FileCheck %s -check-prefixes=CHECK,MSSA +; RUN: opt < %s -basic-aa -licm -enable-new-pm=0 -S | FileCheck %s +; RUN: opt < %s -aa-pipeline=basic-aa -passes='loop-mssa(licm)' -S | FileCheck %s target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128" @A = global i32 7 ; [#uses=3] @@ -27,13 +26,11 @@ Out: ; preds = %Loop ; The Loop block should be empty after the load/store are promoted. ; CHECK: @test1 ; CHECK: load i32, i32* @A -; MSSA: load i32, i32* @A -; MSSA: store i32 %Atmp, i32* @B +; CHECK: load i32, i32* @A +; CHECK: store i32 %Atmp, i32* @B ; CHECK: Loop: ; CHECK-NEXT: br i1 %c, label %Out, label %Loop ; CHECK: Out: -; AST: store i32 %Atmp, i32* @B -; AST: load i32, i32* @A } define i32 @test2(i1 %c) { diff --git a/llvm/test/Analysis/GlobalsModRef/dead-uses.ll b/llvm/test/Analysis/GlobalsModRef/dead-uses.ll index 3657e88..0f67de5 100644 --- a/llvm/test/Analysis/GlobalsModRef/dead-uses.ll +++ b/llvm/test/Analysis/GlobalsModRef/dead-uses.ll @@ -1,5 +1,5 @@ ; RUN: opt < %s -instcombine -globals-aa -licm -enable-new-pm=0 -S | FileCheck %s -; RUN: opt < %s -aa-pipeline=basic-aa,globals-aa -passes='function(instcombine),require,function(invalidate,loop(licm))' -S | FileCheck %s +; RUN: opt < %s -aa-pipeline=basic-aa,globals-aa -passes='function(instcombine),require,function(invalidate,loop-mssa(licm))' -S | FileCheck %s ; Make sure -globals-aa ignores dead uses of globals. diff --git a/llvm/test/Analysis/MemorySSA/pr42294.ll b/llvm/test/Analysis/MemorySSA/pr42294.ll index dbf996d..dc77b62 100644 --- a/llvm/test/Analysis/MemorySSA/pr42294.ll +++ b/llvm/test/Analysis/MemorySSA/pr42294.ll @@ -2,7 +2,6 @@ ; RUN: opt -loop-rotate -licm %s -disable-output -debug-only=licm 2>&1 | FileCheck %s -check-prefix=LICM ; RUN: opt -loop-rotate -licm %s -S | FileCheck %s -; LICM: Using ; LICM-NOT: LICM sinking instruction: %.pre = load i8, i8* %arrayidx.phi.trans.insert ; CHECK-LABEL: @fn1 diff --git a/llvm/test/Other/optimization-remarks-invalidation.ll b/llvm/test/Other/optimization-remarks-invalidation.ll index df2175d..49b36e3 100644 --- a/llvm/test/Other/optimization-remarks-invalidation.ll +++ b/llvm/test/Other/optimization-remarks-invalidation.ll @@ -4,26 +4,26 @@ ; ; First make sure we emit remarks on this test case. ; RUN: opt %s -disable-output -aa-pipeline=basic-aa 2>&1 \ -; RUN: -passes='require,loop(licm)' \ +; RUN: -passes='require,loop-mssa(licm)' \ ; RUN: -pass-remarks=licm -pass-remarks-with-hotness \ ; RUN: | FileCheck %s ; ; Check that passes which preserve BFI don't invalidate the emitter. ; RUN: opt %s -disable-output -aa-pipeline=basic-aa 2>&1 \ -; RUN: -passes='require,instcombine,require,loop(licm)' -debug-pass-manager \ +; RUN: -passes='require,instcombine,require,loop-mssa(licm)' -debug-pass-manager \ ; RUN: -pass-remarks=licm -pass-remarks-with-hotness \ ; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-PM-PRESERVE ; ; Check that invalidating BFI computes a fresh emitter. ; RUN: opt %s -disable-output -aa-pipeline=basic-aa 2>&1 \ -; RUN: -passes='require,invalidate,require,loop(licm)' -debug-pass-manager \ +; RUN: -passes='require,invalidate,require,loop-mssa(licm)' -debug-pass-manager \ ; RUN: -pass-remarks=licm -pass-remarks-with-hotness \ ; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-PM-INVALIDATE ; ; Check that invalidating BFI desn't compute a fresh emitter when we don't ; request hotness remarks. ; RUN: opt %s -disable-output -aa-pipeline=basic-aa 2>&1 \ -; RUN: -passes='require,invalidate,require,loop(licm)' -debug-pass-manager \ +; RUN: -passes='require,invalidate,require,loop-mssa(licm)' -debug-pass-manager \ ; RUN: -pass-remarks=licm \ ; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-PM-NO-INVALIDATE diff --git a/llvm/test/Other/time-passes.ll b/llvm/test/Other/time-passes.ll index b9c85b7..8032ce5 100644 --- a/llvm/test/Other/time-passes.ll +++ b/llvm/test/Other/time-passes.ll @@ -3,12 +3,12 @@ ; RUN: opt < %s -disable-output -passes='default' -time-passes 2>&1 | FileCheck %s --check-prefix=TIME ; ; For new pass manager, check that -time-passes-per-run emit one report for each pass run. -; RUN: opt < %s -disable-output -passes='instcombine,instcombine,loop(licm)' -time-passes-per-run 2>&1 | FileCheck %s --check-prefix=TIME --check-prefix=TIME-NEW -; RUN: opt < %s -disable-output -passes='instcombine,loop(licm),instcombine,loop(licm)' -time-passes-per-run 2>&1 | FileCheck %s --check-prefix=TIME --check-prefix=TIME-NEW -check-prefix=TIME-DOUBLE-LICM-NEW +; RUN: opt < %s -disable-output -passes='instcombine,instcombine,loop-mssa(licm)' -time-passes-per-run 2>&1 | FileCheck %s --check-prefix=TIME --check-prefix=TIME-NEW +; RUN: opt < %s -disable-output -passes='instcombine,loop-mssa(licm),instcombine,loop-mssa(licm)' -time-passes-per-run 2>&1 | FileCheck %s --check-prefix=TIME --check-prefix=TIME-NEW -check-prefix=TIME-DOUBLE-LICM-NEW ; ; For new pass manager, check that -time-passes emit one report for each pass. -; RUN: opt < %s -disable-output -passes='instcombine,instcombine,loop(licm)' -time-passes 2>&1 | FileCheck %s --check-prefixes=TIME,TIME-NEW-PER-PASS -; RUN: opt < %s -disable-output -passes='instcombine,loop(licm),instcombine,loop(licm)' -time-passes 2>&1 | FileCheck %s --check-prefixes=TIME,TIME-NEW-PER-PASS +; RUN: opt < %s -disable-output -passes='instcombine,instcombine,loop-mssa(licm)' -time-passes 2>&1 | FileCheck %s --check-prefixes=TIME,TIME-NEW-PER-PASS +; RUN: opt < %s -disable-output -passes='instcombine,loop-mssa(licm),instcombine,loop-mssa(licm)' -time-passes 2>&1 | FileCheck %s --check-prefixes=TIME,TIME-NEW-PER-PASS ; ; The following 4 test runs verify -info-output-file interaction (default goes to stderr, '-' goes to stdout). ; RUN: opt -enable-new-pm=0 < %s -disable-output -O2 -time-passes -info-output-file='-' 2>/dev/null | FileCheck %s --check-prefix=TIME diff --git a/llvm/test/Transforms/ADCE/broken-loop-info.ll b/llvm/test/Transforms/ADCE/broken-loop-info.ll index 8c9981f..70ef12b 100644 --- a/llvm/test/Transforms/ADCE/broken-loop-info.ll +++ b/llvm/test/Transforms/ADCE/broken-loop-info.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -licm -adce -licm -S < %s | FileCheck %s -; RUN: opt -passes='loop(licm),adce,loop(licm)' -S < %s | FileCheck %s +; RUN: opt -passes='loop-mssa(licm),adce,loop-mssa(licm)' -S < %s | FileCheck %s ; target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2" diff --git a/llvm/test/Transforms/LICM/assume.ll b/llvm/test/Transforms/LICM/assume.ll index 8c3abb5..187ffb8 100644 --- a/llvm/test/Transforms/LICM/assume.ll +++ b/llvm/test/Transforms/LICM/assume.ll @@ -1,5 +1,5 @@ ; RUN: opt -licm -basic-aa < %s -S | FileCheck %s -; RUN: opt -aa-pipeline=basic-aa -passes='require,require,require,require,loop(licm)' < %s -S | FileCheck %s +; RUN: opt -aa-pipeline=basic-aa -passes='require,require,require,require,loop-mssa(licm)' < %s -S | FileCheck %s define void @f_0(i1 %p) nounwind ssp { ; CHECK-LABEL: @f_0( diff --git a/llvm/test/Transforms/LICM/atomics.ll b/llvm/test/Transforms/LICM/atomics.ll index f5c2a08..526b441 100644 --- a/llvm/test/Transforms/LICM/atomics.ll +++ b/llvm/test/Transforms/LICM/atomics.ll @@ -1,6 +1,5 @@ -; RUN: opt < %s -S -basic-aa -licm -enable-new-pm=0 | FileCheck -check-prefixes=CHECK,MSSA %s -; RUN: opt -aa-pipeline=basic-aa -passes='require,loop(licm)' < %s -S | FileCheck -check-prefixes=CHECK,AST %s -; RUN: opt -aa-pipeline=basic-aa -passes='require,loop-mssa(licm)' < %s -S | FileCheck -check-prefixes=CHECK,MSSA %s +; RUN: opt < %s -S -basic-aa -licm -enable-new-pm=0 | FileCheck %s +; RUN: opt -aa-pipeline=basic-aa -passes='require,loop-mssa(licm)' < %s -S | FileCheck %s ; Check that we can hoist unordered loads define i32 @test1(i32* nocapture %y) nounwind uwtable ssp { @@ -174,12 +173,10 @@ loop: end: ret i32 %vala ; CHECK-LABEL: define i32 @test7b( -; AST-LABEL: entry: -; AST: store i32 5, i32* %x ; CHECK-LABEL: loop: ; CHECK: load atomic i32, i32* %y monotonic ; CHECK-LABEL: end: -; MSSA: store i32 5, i32* %x +; CHECK: store i32 5, i32* %x ; CHECK: store atomic i32 %{{.+}}, i32* %z unordered, align 4 } diff --git a/llvm/test/Transforms/LICM/basictest.ll b/llvm/test/Transforms/LICM/basictest.ll index 78c87ce..42a3a09 100644 --- a/llvm/test/Transforms/LICM/basictest.ll +++ b/llvm/test/Transforms/LICM/basictest.ll @@ -1,5 +1,5 @@ ; RUN: opt < %s -licm | llvm-dis -; RUN: opt -aa-pipeline=basic-aa -passes='require,require,require,require,loop(licm)' < %s | llvm-dis +; RUN: opt -aa-pipeline=basic-aa -passes='require,require,require,require,loop-mssa(licm)' < %s | llvm-dis define void @testfunc(i32 %i) { ;