Index: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp =================================================================== --- lib/Transforms/Scalar/SimpleLoopUnswitch.cpp +++ lib/Transforms/Scalar/SimpleLoopUnswitch.cpp @@ -24,6 +24,8 @@ #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopIterator.h" #include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/MemorySSA.h" +#include "llvm/Analysis/MemorySSAUpdater.h" #include "llvm/Analysis/Utils/Local.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constant.h" @@ -179,7 +181,8 @@ /// terminator. static void rewritePHINodesForUnswitchedExitBlock(BasicBlock &UnswitchedBB, BasicBlock &OldExitingBB, - BasicBlock &OldPH) { + BasicBlock &OldPH, + MemorySSA *MSSA) { for (PHINode &PN : UnswitchedBB.phis()) { // When the loop exit is directly unswitched we just need to update the // incoming basic block. We loop to handle weird cases with repeated @@ -190,6 +193,13 @@ PN.setIncomingBlock(i, &OldPH); } } + + if (MSSA) + if (MemoryPhi *MPhi = MSSA->getMemoryAccess(&UnswitchedBB)) { + // Only updates incoming block. Incoming value will be replaced in all + // blocks no longer dominated by OldExitingBB, after DT is updated. + MPhi->setIncomingBlock(MPhi->getBasicBlockIndex(&UnswitchedBB), &OldPH); + } } /// Rewrite the PHI nodes in the loop exit basic block and the split off @@ -199,11 +209,10 @@ /// LCSSA PHI nodes in it to remove the unswitched edge and introduces PHI /// nodes into the unswitched basic block to select between the value in the /// old preheader and the loop exit. -static void rewritePHINodesForExitAndUnswitchedBlocks(BasicBlock &ExitBB, - BasicBlock &UnswitchedBB, - BasicBlock &OldExitingBB, - BasicBlock &OldPH, - bool FullUnswitch) { +static void rewritePHINodesForExitAndUnswitchedBlocks( + BasicBlock &ExitBB, BasicBlock &UnswitchedBB, BasicBlock &OldExitingBB, + BasicBlock &OldPH, MemorySSA *MSSA, MemorySSAUpdater *MSSAUpdater, + bool FullUnswitch) { assert(&ExitBB != &UnswitchedBB && "Must have different loop exit and unswitched blocks!"); Instruction *InsertPt = &*UnswitchedBB.begin(); @@ -237,6 +246,13 @@ PN.replaceAllUsesWith(NewPN); NewPN->addIncoming(&PN, &ExitBB); } + + if (MSSA) { + // Only updates incoming block. Incoming value will be replaced in all + // blocks no longer dominated by OldExitingBB, after DT is updated. + MSSAUpdater->wireOldPhiIntoNewPhiAfterUnswitch( + &ExitBB, &UnswitchedBB, &OldExitingBB, &OldPH, FullUnswitch); + } } /// Unswitch a trivial branch if the condition is loop invariant. @@ -254,7 +270,8 @@ /// the loop to an unconditional branch but doesn't remove it entirely. Further /// cleanup can be done with some simplify-cfg like pass. static bool unswitchTrivialBranch(Loop &L, BranchInst &BI, DominatorTree &DT, - LoopInfo &LI) { + LoopInfo &LI, MemorySSA *MSSA, + MemorySSAUpdater *MSSAUpdater) { assert(BI.isConditional() && "Can only unswitch a conditional branch!"); LLVM_DEBUG(dbgs() << " Trying to unswitch branch: " << BI << "\n"); @@ -318,11 +335,24 @@ } }); + if (MSSA) { + /* + dbgs()<<"Start unswitchTrivialBranch..."; + if (FullUnswitch) + dbgs()<<"FullUnswitch\n"; + else + dbgs()<<"PartialUnswitch\n"; + MSSA->dump(); + */ + MSSA->verifyMemorySSA(); + } + // Split the preheader, so that we know that there is a safe place to insert // the conditional branch. We will change the preheader to have a conditional // branch on LoopCond. BasicBlock *OldPH = L.getLoopPreheader(); - BasicBlock *NewPH = SplitEdge(OldPH, L.getHeader(), &DT, &LI); + BasicBlock *NewPH = + SplitEdge(OldPH, L.getHeader(), &DT, &LI, MSSA, MSSAUpdater); // Now that we have a place to insert the conditional branch, create a place // to branch to: this is the exit block out of the loop that we are @@ -334,7 +364,8 @@ "A branch's parent isn't a predecessor!"); UnswitchedBB = LoopExitBB; } else { - UnswitchedBB = SplitBlock(LoopExitBB, &LoopExitBB->front(), &DT, &LI); + UnswitchedBB = SplitBlock(LoopExitBB, &LoopExitBB->front(), &DT, &LI, MSSA, + MSSAUpdater); } // Actually move the invariant uses into the unswitched position. If possible, @@ -370,10 +401,12 @@ // Rewrite the relevant PHI nodes. if (UnswitchedBB == LoopExitBB) - rewritePHINodesForUnswitchedExitBlock(*UnswitchedBB, *ParentBB, *OldPH); + rewritePHINodesForUnswitchedExitBlock(*UnswitchedBB, *ParentBB, *OldPH, + MSSA); else rewritePHINodesForExitAndUnswitchedBlocks(*LoopExitBB, *UnswitchedBB, - *ParentBB, *OldPH, FullUnswitch); + *ParentBB, *OldPH, MSSA, + MSSAUpdater, FullUnswitch); // Now we need to update the dominator tree. DT.insertEdge(OldPH, UnswitchedBB); @@ -392,6 +425,14 @@ for (Value *Invariant : Invariants) replaceLoopInvariantUses(L, Invariant, *Replacement); + // After the dominator tree was updated, update values in phis no longer + // dominated by ParentBB, to use value incoming from NewPh (incoming BB was + // already set to OldPh for those value in the rewritePhi calls above). + if (MSSA) { + MSSAUpdater->updateHeaderPhisUsesAfterLoopUnswitch(ParentBB, NewPH, &DT); + MSSA->verifyMemorySSA(); + } + ++NumTrivial; ++NumBranches; return true; @@ -421,7 +462,8 @@ /// in-loop successor, the switch is further simplified to an unconditional /// branch. Still more cleanup can be done with some simplify-cfg like pass. static bool unswitchTrivialSwitch(Loop &L, SwitchInst &SI, DominatorTree &DT, - LoopInfo &LI) { + LoopInfo &LI, MemorySSA *MSSA, + MemorySSAUpdater *MSSAUpdater) { LLVM_DEBUG(dbgs() << " Trying to unswitch switch: " << SI << "\n"); Value *LoopCond = SI.getCondition(); @@ -448,6 +490,11 @@ LLVM_DEBUG(dbgs() << " unswitching trivial cases...\n"); + if (MSSA) { + dbgs() << "Start unswitchTrivialSwitch\n"; + MSSA->verifyMemorySSA(); + } + SmallVector, 4> ExitCases; ExitCases.reserve(ExitCaseIndices.size()); // We walk the case indices backwards so that we remove the last case first @@ -499,7 +546,8 @@ // Split the preheader, so that we know that there is a safe place to insert // the switch. BasicBlock *OldPH = L.getLoopPreheader(); - BasicBlock *NewPH = SplitEdge(OldPH, L.getHeader(), &DT, &LI); + BasicBlock *NewPH = + SplitEdge(OldPH, L.getHeader(), &DT, &LI, MSSA, MSSAUpdater); OldPH->getTerminator()->eraseFromParent(); // Now add the unswitched switch. @@ -519,12 +567,14 @@ if (DefaultExitBB) { if (pred_empty(DefaultExitBB)) { UnswitchedExitBBs.insert(DefaultExitBB); - rewritePHINodesForUnswitchedExitBlock(*DefaultExitBB, *ParentBB, *OldPH); + rewritePHINodesForUnswitchedExitBlock(*DefaultExitBB, *ParentBB, *OldPH, + MSSA); } else { - auto *SplitBB = - SplitBlock(DefaultExitBB, &DefaultExitBB->front(), &DT, &LI); + auto *SplitBB = SplitBlock(DefaultExitBB, &DefaultExitBB->front(), &DT, + &LI, MSSA, MSSAUpdater); rewritePHINodesForExitAndUnswitchedBlocks( - *DefaultExitBB, *SplitBB, *ParentBB, *OldPH, /*FullUnswitch*/ true); + *DefaultExitBB, *SplitBB, *ParentBB, *OldPH, MSSA, MSSAUpdater, + /*FullUnswitch*/ true); DefaultExitBB = SplitExitBBMap[DefaultExitBB] = SplitBB; } } @@ -539,7 +589,7 @@ if (pred_empty(ExitBB)) { // Only rewrite once. if (UnswitchedExitBBs.insert(ExitBB).second) - rewritePHINodesForUnswitchedExitBlock(*ExitBB, *ParentBB, *OldPH); + rewritePHINodesForUnswitchedExitBlock(*ExitBB, *ParentBB, *OldPH, MSSA); continue; } @@ -548,9 +598,11 @@ BasicBlock *&SplitExitBB = SplitExitBBMap[ExitBB]; if (!SplitExitBB) { // If this is the first time we see this, do the split and remember it. - SplitExitBB = SplitBlock(ExitBB, &ExitBB->front(), &DT, &LI); + SplitExitBB = + SplitBlock(ExitBB, &ExitBB->front(), &DT, &LI, MSSA, MSSAUpdater); rewritePHINodesForExitAndUnswitchedBlocks( - *ExitBB, *SplitExitBB, *ParentBB, *OldPH, /*FullUnswitch*/ true); + *ExitBB, *SplitExitBB, *ParentBB, *OldPH, MSSA, MSSAUpdater, + /*FullUnswitch*/ true); } // Update the case pair to point to the split block. CasePair.second = SplitExitBB; @@ -602,6 +654,13 @@ } DT.applyUpdates(DTUpdates); + // Update MemorySSA only after the dominator tree was updated. + if (MSSA) { + MSSAUpdater->updateHeaderPhisUsesAfterLoopUnswitch(ParentBB, NewPH, &DT); + dbgs() << "End unswitchTrivialSwitch\n"; + MSSA->verifyMemorySSA(); + } + assert(DT.verify(DominatorTree::VerificationLevel::Fast)); ++NumTrivial; ++NumSwitches; @@ -618,9 +677,11 @@ /// The return value indicates whether anything was unswitched (and therefore /// changed). static bool unswitchAllTrivialConditions(Loop &L, DominatorTree &DT, - LoopInfo &LI) { + LoopInfo &LI, MemorySSA *MSSA, + MemorySSAUpdater *MSSAUpdater) { bool Changed = false; + // dbgs() << "Start unswitchAllTrivialConditions\n"; // If loop header has only one reachable successor we should keep looking for // trivial condition candidates in the successor as well. An alternative is // to constant fold conditions and merge successors into loop header (then we @@ -652,7 +713,7 @@ if (isa(SI->getCondition())) return Changed; - if (!unswitchTrivialSwitch(L, *SI, DT, LI)) + if (!unswitchTrivialSwitch(L, *SI, DT, LI, MSSA, MSSAUpdater)) // Couldn't unswitch this one so we're done. return Changed; @@ -684,7 +745,7 @@ // Found a trivial condition candidate: non-foldable conditional branch. If // we fail to unswitch this, we can't do anything else that is trivial. - if (!unswitchTrivialBranch(L, *BI, DT, LI)) + if (!unswitchTrivialBranch(L, *BI, DT, LI, MSSA, MSSAUpdater)) return Changed; // Mark that we managed to unswitch something. @@ -737,7 +798,8 @@ const SmallDenseMap &DominatingSucc, ValueToValueMapTy &VMap, SmallVectorImpl &DTUpdates, AssumptionCache &AC, - DominatorTree &DT, LoopInfo &LI) { + DominatorTree &DT, LoopInfo &LI, MemorySSA *MSSA, + MemorySSAUpdater *MSSAUpdater) { SmallVector NewBlocks; NewBlocks.reserve(L.getNumBlocks() + ExitBlocks.size()); @@ -782,7 +844,8 @@ // place to merge the CFG, so split the exit first. This is always safe to // do because there cannot be any non-loop predecessors of a loop exit in // loop simplified form. - auto *MergeBB = SplitBlock(ExitBB, &ExitBB->front(), &DT, &LI); + auto *MergeBB = + SplitBlock(ExitBB, &ExitBB->front(), &DT, &LI, MSSA, MSSAUpdater); // Rearrange the names to make it easier to write test cases by having the // exit block carry the suffix rather than the merge block carrying the @@ -1188,7 +1251,7 @@ static void deleteDeadClonedBlocks(Loop &L, ArrayRef ExitBlocks, ArrayRef> VMaps, - DominatorTree &DT) { + DominatorTree &DT, MemorySSAUpdater *MSSAUpdater) { // Find all the dead clones, and remove them from their successors. SmallVector DeadBlocks; for (BasicBlock *BB : llvm::concat(L.blocks(), ExitBlocks)) @@ -1200,6 +1263,13 @@ DeadBlocks.push_back(ClonedBB); } + // Remove all MemorySSA in the dead blocks + if (MSSAUpdater) { + SmallPtrSet DeadBlockSet(DeadBlocks.begin(), + DeadBlocks.end()); + MSSAUpdater->removeBlocks(DeadBlockSet); + } + // Drop any remaining references to break cycles. for (BasicBlock *BB : DeadBlocks) BB->dropAllReferences(); @@ -1208,10 +1278,10 @@ BB->eraseFromParent(); } -static void -deleteDeadBlocksFromLoop(Loop &L, - SmallVectorImpl &ExitBlocks, - DominatorTree &DT, LoopInfo &LI) { +static void deleteDeadBlocksFromLoop(Loop &L, + SmallVectorImpl &ExitBlocks, + DominatorTree &DT, LoopInfo &LI, + MemorySSAUpdater *MSSAUpdater) { // Find all the dead blocks, and remove them from their successors. SmallVector DeadBlocks; for (BasicBlock *BB : llvm::concat(L.blocks(), ExitBlocks)) @@ -1224,6 +1294,10 @@ SmallPtrSet DeadBlockSet(DeadBlocks.begin(), DeadBlocks.end()); + // Remove all MemorySSA in the dead blocks + if (MSSAUpdater) + MSSAUpdater->removeBlocks(DeadBlockSet); + // Filter out the dead blocks from the exit blocks list so that it can be // used in the caller. llvm::erase_if(ExitBlocks, @@ -1621,7 +1695,8 @@ static bool unswitchNontrivialInvariants( Loop &L, TerminatorInst &TI, ArrayRef Invariants, - DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC, + DominatorTree &DT, LoopInfo &LI, MemorySSA *MSSA, + MemorySSAUpdater *MSSAUpdater, AssumptionCache &AC, function_ref)> UnswitchCB) { auto *ParentBB = TI.getParent(); BranchInst *BI = dyn_cast(&TI); @@ -1639,6 +1714,11 @@ assert(isa(BI->getCondition()) && "Partial unswitching requires an instruction as the condition!"); + if (MSSA) { + // dbgs() << "Start unswitchInvariantBranch, is full? "<verifyMemorySSA(); + } + // Constant and BBs tracking the cloned and continuing successor. When we are // unswitching the entire condition, this can just be trivially chosen to // unswitch towards `true`. However, when we are unswitching a set of @@ -1689,6 +1769,10 @@ // Compute the parent loop now before we start hacking on things. Loop *ParentL = L.getParentLoop(); + // Get blocks in RPO order for MSSA update, also before changing CFG. + LoopBlocksRPO LBRPO(&L); + if (MSSA) + LBRPO.perform(&LI); // Compute the outer-most loop containing one of our exit blocks. This is the // furthest up our loopnest which can be mutated, which we will use below to @@ -1728,7 +1812,8 @@ // between the unswitched versions, and we will have a new preheader for the // original loop. BasicBlock *SplitBB = L.getLoopPreheader(); - BasicBlock *LoopPH = SplitEdge(SplitBB, L.getHeader(), &DT, &LI); + BasicBlock *LoopPH = + SplitEdge(SplitBB, L.getHeader(), &DT, &LI, MSSA, MSSAUpdater); // Keep track of the dominator tree updates needed. SmallVector DTUpdates; @@ -1739,9 +1824,10 @@ SmallDenseMap ClonedPHs; for (auto *SuccBB : UnswitchedSuccBBs) { VMaps.emplace_back(new ValueToValueMapTy()); - ClonedPHs[SuccBB] = buildClonedLoopBlocks( - L, LoopPH, SplitBB, ExitBlocks, ParentBB, SuccBB, RetainedSuccBB, - DominatingSucc, *VMaps.back(), DTUpdates, AC, DT, LI); + ClonedPHs[SuccBB] = + buildClonedLoopBlocks(L, LoopPH, SplitBB, ExitBlocks, ParentBB, SuccBB, + RetainedSuccBB, DominatingSucc, *VMaps.back(), + DTUpdates, AC, DT, LI, MSSA, MSSAUpdater); } // The stitching of the branched code back together depends on whether we're @@ -1749,16 +1835,16 @@ // nuke the initial terminator placed in the split block. SplitBB->getTerminator()->eraseFromParent(); if (FullUnswitch) { - for (BasicBlock *SuccBB : UnswitchedSuccBBs) { - // Remove the parent as a predecessor of the unswitched successor. - SuccBB->removePredecessor(ParentBB, - /*DontDeleteUselessPHIs*/ true); - DTUpdates.push_back({DominatorTree::Delete, ParentBB, SuccBB}); - } - - // Now splice the terminator from the original loop and rewrite its + // Splice the terminator from the original loop and rewrite its // successors. SplitBB->getInstList().splice(SplitBB->end(), ParentBB->getInstList(), TI); + + // Keep a clone of the terminator for now. + Instruction *NewTI = TI.clone(); + if (TI.hasName()) + NewTI->setName(TI.getName() + ".us"); + ParentBB->getInstList().push_back(NewTI); + if (BI) { assert(UnswitchedSuccBBs.size() == 1 && "Only one possible unswitched block for a branch!"); @@ -1782,6 +1868,24 @@ SI->setDefaultDest(LoopPH); } + if (MSSA) { + DT.applyUpdates(DTUpdates); + DTUpdates.clear(); + for (auto &VMap : VMaps) + MSSAUpdater->updateForClonedLoop(LBRPO, ExitBlocks, *VMap, + /*IgnoreIncomingWithNoClones=*/true); + MSSAUpdater->updateExitBlocksForClonedLoop(ExitBlocks, VMaps, &DT); + for (BasicBlock *SuccBB : UnswitchedSuccBBs) + MSSAUpdater->removeEdge(ParentBB, SuccBB); + } + + for (BasicBlock *SuccBB : UnswitchedSuccBBs) { + // Remove the parent as a predecessor of the unswitched successor. + SuccBB->removePredecessor(ParentBB, + /*DontDeleteUselessPHIs*/ true); + DTUpdates.push_back({DominatorTree::Delete, ParentBB, SuccBB}); + } + ParentBB->getTerminator()->eraseFromParent(); // Create a new unconditional branch to the continuing block (as opposed to // the one cloned). BranchInst::Create(RetainedSuccBB, ParentBB); @@ -1804,7 +1908,7 @@ // blocks so that we can accurately build any cloned loops. It is important to // not delete the blocks from the original loop yet because we still want to // reference the original loop to understand the cloned loop's structure. - deleteDeadClonedBlocks(L, ExitBlocks, VMaps, DT); + deleteDeadClonedBlocks(L, ExitBlocks, VMaps, DT, MSSAUpdater); // Build the cloned loop structure itself. This may be substantially // different from the original structure due to the simplified CFG. This also @@ -1816,10 +1920,23 @@ // Now that our cloned loops have been built, we can update the original loop. // First we delete the dead blocks from it and then we rebuild the loop // structure taking these deletions into account. - deleteDeadBlocksFromLoop(L, ExitBlocks, DT, LI); + deleteDeadBlocksFromLoop(L, ExitBlocks, DT, LI, MSSAUpdater); + + if (MSSA) { + // dbgs()<<"After deleting dead blocks\n"; + // MSSA->dump(); + MSSA->verifyMemorySSA(); + } + SmallVector HoistedLoops; bool IsStillLoop = rebuildLoopAfterUnswitch(L, ExitBlocks, LI, HoistedLoops); + if (MSSA) { + // dbgs()<<"After rebuilding loop\n"; + // MSSA->dump(); + MSSA->verifyMemorySSA(); + } + // This transformation has a high risk of corrupting the dominator tree, and // the below steps to rebuild loop structures will result in hard to debug // errors in that case so verify that the dominator tree is sane first. @@ -1931,6 +2048,10 @@ SibLoops.push_back(UpdatedL); UnswitchCB(IsStillLoop, SibLoops); + if (MSSA) { + MSSA->verifyMemorySSA(); + } + ++NumBranches; return true; } @@ -1968,10 +2089,11 @@ return Cost; } -static bool unswitchBestCondition( - Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC, - TargetTransformInfo &TTI, - function_ref)> UnswitchCB) { +static bool +unswitchBestCondition(Loop &L, DominatorTree &DT, LoopInfo &LI, MemorySSA *MSSA, + MemorySSAUpdater *MSSAUpdater, AssumptionCache &AC, + TargetTransformInfo &TTI, + function_ref)> UnswitchCB) { // Collect all invariant conditions within this loop (as opposed to an inner // loop which would be handled when visiting that inner loop). SmallVector>, 4> @@ -2163,8 +2285,9 @@ LLVM_DEBUG(dbgs() << " Trying to unswitch non-trivial (cost = " << BestUnswitchCost << ") terminator: " << *BestUnswitchTI << "\n"); - return unswitchNontrivialInvariants( - L, *BestUnswitchTI, BestUnswitchInvariants, DT, LI, AC, UnswitchCB); + return unswitchNontrivialInvariants(L, *BestUnswitchTI, + BestUnswitchInvariants, DT, LI, MSSA, + MSSAUpdater, AC, UnswitchCB); } /// Unswitch control flow predicated on loop invariant conditions. @@ -2175,7 +2298,8 @@ /// well by cloning the loop if the result is small enough. static bool unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC, - TargetTransformInfo &TTI, bool NonTrivial, + TargetTransformInfo &TTI, MemorySSA *MSSA, + MemorySSAUpdater *MSSAUpdater, bool NonTrivial, function_ref)> UnswitchCB) { assert(L.isRecursivelyLCSSAForm(DT, LI) && "Loops must be in LCSSA form before unswitching."); @@ -2186,7 +2310,7 @@ return false; // Try trivial unswitch first before loop over other basic blocks in the loop. - if (unswitchAllTrivialConditions(L, DT, LI)) { + if (unswitchAllTrivialConditions(L, DT, LI, MSSA, MSSAUpdater)) { // If we unswitched successfully we will want to clean up the loop before // processing it further so just mark it as unswitched and return. UnswitchCB(/*CurrentLoopValid*/ true, {}); @@ -2207,7 +2331,7 @@ // Try to unswitch the best invariant condition. We prefer this full unswitch to // a partial unswitch when possible below the threshold. - if (unswitchBestCondition(L, DT, LI, AC, TTI, UnswitchCB)) + if (unswitchBestCondition(L, DT, LI, MSSA, MSSAUpdater, AC, TTI, UnswitchCB)) return true; // No other opportunities to unswitch. @@ -2241,10 +2365,23 @@ U.markLoopAsDeleted(L, LoopName); }; - if (!unswitchLoop(L, AR.DT, AR.LI, AR.AC, AR.TTI, NonTrivial, - UnswitchCB)) + std::unique_ptr MSSAUpdater; + if (AR.MSSA) { + MSSAUpdater = make_unique(AR.MSSA); + // dbgs()<<"[SimpleLoopUnswitch]=====Before unswitchLoop call\n"; + // AR.MSSA->dump(); + AR.MSSA->verifyMemorySSA(); + } + if (!unswitchLoop(L, AR.DT, AR.LI, AR.AC, AR.TTI, AR.MSSA, MSSAUpdater.get(), + NonTrivial, UnswitchCB)) return PreservedAnalyses::all(); + if (AR.MSSA) { + // dbgs()<<"[SimpleLoopUnswitch]=====After unswitchLoop call\n"; + // AR.MSSA->dump(); + AR.MSSA->verifyMemorySSA(); + } + // Historically this pass has had issues with the dominator tree so verify it // in asserts builds. assert(AR.DT.verify(DominatorTree::VerificationLevel::Fast)); @@ -2270,6 +2407,8 @@ void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); AU.addRequired(); + if (EnableMSSALoopDependency) + AU.addRequired(); getLoopAnalysisUsage(AU); } }; @@ -2289,6 +2428,12 @@ auto &LI = getAnalysis().getLoopInfo(); auto &AC = getAnalysis().getAssumptionCache(F); auto &TTI = getAnalysis().getTTI(F); + MemorySSA *MSSA = nullptr; + std::unique_ptr MSSAUpdater; + if (EnableMSSALoopDependency) { + MSSA = &getAnalysis().getMSSA(); + MSSAUpdater = make_unique(MSSA); + } auto UnswitchCB = [&L, &LPM](bool CurrentLoopValid, ArrayRef NewLoops) { @@ -2305,8 +2450,23 @@ LPM.markLoopAsDeleted(*L); }; - bool Changed = - unswitchLoop(*L, DT, LI, AC, TTI, NonTrivial, UnswitchCB); + if (MSSA) { + // dbgs()<<"Before unswitchLoop call\n"; + MSSA->verifyMemorySSA(); + } + + bool Changed = unswitchLoop(*L, DT, LI, AC, TTI, MSSA, MSSAUpdater.get(), + NonTrivial, UnswitchCB); + + if (MSSA) { + // TODO: Compare performance of update vs rebuild MSSA. Hack: + // auto &AA = getAnalysis().getAAResults(); + // MSSA->~MemorySSA(); + // new (MSSA) MemorySSA(*F, &AA, DT); + + // dbgs()<<"After unswitchLoop call\n"; + MSSA->verifyMemorySSA(); + } // If anything was unswitched, also clear any cached information about this // loop. @@ -2326,6 +2486,7 @@ INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(LoopPass) +INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) INITIALIZE_PASS_END(SimpleLoopUnswitchLegacyPass, "simple-loop-unswitch", "Simple unswitch loops", false, false)