Index: llvm/include/llvm/Transforms/Utils/LoopUtils.h =================================================================== --- llvm/include/llvm/Transforms/Utils/LoopUtils.h +++ llvm/include/llvm/Transforms/Utils/LoopUtils.h @@ -151,18 +151,17 @@ /// 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 @@ /// 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 @@ 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. Index: llvm/lib/Transforms/Scalar/LICM.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LICM.cpp +++ llvm/lib/Transforms/Scalar/LICM.cpp @@ -174,7 +174,7 @@ 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 @@ private: unsigned LicmMssaOptCap; unsigned LicmMssaNoAccForPromotionCap; - - std::unique_ptr - collectAliasInfoForLoop(Loop *L, LoopInfo *LI, AAResults *AA); }; struct LegacyLICMPass : public LoopPass { @@ -265,6 +262,9 @@ 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 @@ PA.preserve(); PA.preserve(); - if (AR.MSSA) - PA.preserve(); + PA.preserve(); return PA; } @@ -288,6 +287,9 @@ 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 @@ PA.preserve(); PA.preserve(); - if (AR.MSSA) - PA.preserve(); + PA.preserve(); return PA; } @@ -376,10 +377,6 @@ 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 @@ }); }); - 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(); @@ -428,16 +417,14 @@ Changed |= LoopNestMode ? sinkRegionForLoopNest(DT->getNode(L->getHeader()), AA, LI, DT, - BFI, TLI, TTI, L, CurAST.get(), MSSAU.get(), - &SafetyInfo, *Flags.get(), ORE) + BFI, TLI, TTI, L, &MSSAU, &SafetyInfo, + Flags, ORE) : sinkRegion(DT->getNode(L->getHeader()), AA, LI, DT, BFI, TLI, TTI, - L, CurAST.get(), MSSAU.get(), &SafetyInfo, - *Flags.get(), ORE); - Flags->setIsSink(false); + 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 +434,7 @@ // 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 +448,29 @@ 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 +492,8 @@ 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 +508,15 @@ 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 +541,7 @@ salvageKnowledge(&I); salvageDebugInfo(I); ++II; - eraseInstruction(I, *SafetyInfo, CurAST, MSSAU); + eraseInstruction(I, *SafetyInfo, MSSAU); Changed = true; continue; } @@ -597,20 +556,20 @@ 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 +577,8 @@ 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; @@ -630,7 +588,7 @@ 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); + MSSAU, SafetyInfo, Flags, ORE, CurLoop); } return Changed; } @@ -837,9 +795,8 @@ 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 +858,14 @@ 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 +894,10 @@ &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 +910,8 @@ // 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 +940,7 @@ 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 +1019,7 @@ } } } - if (MSSAU && VerifyMemorySSA) + if (VerifyMemorySSA) MSSAU->getMemorySSA()->verifyMemorySSA(); // Now that we've finished hoisting make sure that LI and DT are still @@ -1573,9 +1526,7 @@ } 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 +1764,7 @@ 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 +1853,6 @@ SmallVectorImpl &LoopInsertPts; SmallVectorImpl &MSSAInsertPts; PredIteratorCache &PredCache; - AliasSetTracker *AST; MemorySSAUpdater *MSSAU; LoopInfo &LI; DebugLoc DL; @@ -1934,12 +1884,12 @@ 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 +1922,24 @@ 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 +1990,8 @@ 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 +2223,7 @@ 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 +2240,22 @@ 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 +2321,6 @@ 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) { Index: llvm/test/Analysis/BasicAA/store-promote.ll =================================================================== --- llvm/test/Analysis/BasicAA/store-promote.ll +++ 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 @@ ; 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) { Index: llvm/test/Analysis/GlobalsModRef/dead-uses.ll =================================================================== --- llvm/test/Analysis/GlobalsModRef/dead-uses.ll +++ 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. Index: llvm/test/Analysis/MemorySSA/pr42294.ll =================================================================== --- llvm/test/Analysis/MemorySSA/pr42294.ll +++ 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 Index: llvm/test/Other/optimization-remarks-invalidation.ll =================================================================== --- llvm/test/Other/optimization-remarks-invalidation.ll +++ 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 Index: llvm/test/Other/time-passes.ll =================================================================== --- llvm/test/Other/time-passes.ll +++ 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 Index: llvm/test/Transforms/ADCE/broken-loop-info.ll =================================================================== --- llvm/test/Transforms/ADCE/broken-loop-info.ll +++ 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" Index: llvm/test/Transforms/LICM/assume.ll =================================================================== --- llvm/test/Transforms/LICM/assume.ll +++ 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( Index: llvm/test/Transforms/LICM/atomics.ll =================================================================== --- llvm/test/Transforms/LICM/atomics.ll +++ 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 @@ 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 } Index: llvm/test/Transforms/LICM/basictest.ll =================================================================== --- llvm/test/Transforms/LICM/basictest.ll +++ 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) { ;