Index: lib/Transforms/Scalar/LoopInstSimplify.cpp =================================================================== --- lib/Transforms/Scalar/LoopInstSimplify.cpp +++ lib/Transforms/Scalar/LoopInstSimplify.cpp @@ -22,8 +22,9 @@ #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/TargetLibraryInfo.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CFG.h" #include "llvm/IR/DataLayout.h" @@ -36,6 +37,7 @@ #include "llvm/Pass.h" #include "llvm/Support/Casting.h" #include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/LoopUtils.h" #include #include @@ -47,8 +49,8 @@ STATISTIC(NumSimplified, "Number of redundant instructions simplified"); static bool simplifyLoopInst(Loop &L, DominatorTree &DT, LoopInfo &LI, - AssumptionCache &AC, - const TargetLibraryInfo &TLI) { + AssumptionCache &AC, const TargetLibraryInfo &TLI, + MemorySSAUpdater *MSSAU) { const DataLayout &DL = L.getHeader()->getModule()->getDataLayout(); SimplifyQuery SQ(DL, &TLI, &DT, &AC); @@ -75,9 +77,12 @@ // iterate. LoopBlocksRPO RPOT(&L); RPOT.perform(&LI); + MemorySSA *MSSA = MSSAU ? MSSAU->getMemorySSA() : nullptr; bool Changed = false; for (;;) { + if (MSSAU && VerifyMemorySSA) + MSSA->verifyMemorySSA(); for (BasicBlock *BB : RPOT) { for (Instruction &I : *BB) { if (auto *PI = dyn_cast(&I)) @@ -129,6 +134,12 @@ ToSimplify->insert(UserI); } + if (MSSAU) + if (Instruction *SimpleI = dyn_cast_or_null(V)) + if (MemoryAccess *MA = MSSA->getMemoryAccess(&I)) + if (MemoryAccess *ReplacementMA = MSSA->getMemoryAccess(SimpleI)) + MA->replaceAllUsesWith(ReplacementMA); + assert(I.use_empty() && "Should always have replaced all uses!"); if (isInstructionTriviallyDead(&I, &TLI)) DeadInsts.push_back(&I); @@ -141,9 +152,12 @@ // iteration over all instructions in all the loop blocks. if (!DeadInsts.empty()) { Changed = true; - RecursivelyDeleteTriviallyDeadInstructions(DeadInsts, &TLI); + RecursivelyDeleteTriviallyDeadInstructions(DeadInsts, &TLI, MSSAU); } + if (MSSAU && VerifyMemorySSA) + MSSA->verifyMemorySSA(); + // If we never found a PHI that needs to be simplified in the next // iteration, we're done. if (Next->empty()) @@ -180,8 +194,15 @@ *L->getHeader()->getParent()); const TargetLibraryInfo &TLI = getAnalysis().getTLI(); + MemorySSA *MSSA = nullptr; + Optional MSSAU; + if (EnableMSSALoopDependency) { + MSSA = &getAnalysis().getMSSA(); + MSSAU = MemorySSAUpdater(MSSA); + } - return simplifyLoopInst(*L, DT, LI, AC, TLI); + return simplifyLoopInst(*L, DT, LI, AC, TLI, + MSSAU.hasValue() ? MSSAU.getPointer() : nullptr); } void getAnalysisUsage(AnalysisUsage &AU) const override { @@ -189,6 +210,10 @@ AU.addRequired(); AU.addRequired(); AU.setPreservesCFG(); + if (EnableMSSALoopDependency) { + AU.addRequired(); + AU.addPreserved(); + } getLoopAnalysisUsage(AU); } }; @@ -198,7 +223,13 @@ PreservedAnalyses LoopInstSimplifyPass::run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &) { - if (!simplifyLoopInst(L, AR.DT, AR.LI, AR.AC, AR.TLI)) + Optional MSSAU; + if (AR.MSSA) { + MSSAU = MemorySSAUpdater(AR.MSSA); + AR.MSSA->verifyMemorySSA(); + } + if (!simplifyLoopInst(L, AR.DT, AR.LI, AR.AC, AR.TLI, + MSSAU.hasValue() ? MSSAU.getPointer() : nullptr)) return PreservedAnalyses::all(); auto PA = getLoopPassPreservedAnalyses(); @@ -212,6 +243,7 @@ "Simplify instructions in loops", false, false) INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_DEPENDENCY(LoopPass) +INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_END(LoopInstSimplifyLegacyPass, "loop-instsimplify", "Simplify instructions in loops", false, false) Index: test/Transforms/LoopInstSimplify/basic.ll =================================================================== --- test/Transforms/LoopInstSimplify/basic.ll +++ test/Transforms/LoopInstSimplify/basic.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S %s -passes=loop-instsimplify | FileCheck %s +; RUN: opt -S %s -passes=loop-instsimplify -enable-mssa-loop-dependency=true -verify-memoryssa | FileCheck %s ; Test very basic folding and propagation occurs within a loop body. This should ; collapse to the loop iteration structure and the LCSSA PHI node.