diff options
author | David Green <david.green@arm.com> | 2021-06-08 21:23:08 +0100 |
---|---|---|
committer | David Green <david.green@arm.com> | 2021-06-08 21:23:08 +0100 |
commit | 297088d1add70cae554c8f96dde3a97a3e8d56a5 (patch) | |
tree | 7ce36867576533618adbabf0d61d426db6160711 /llvm/lib | |
parent | a7142f5c91ba0e4dbe6dbd36e3f4ac6ccd33a418 (diff) | |
download | llvm-297088d1add70cae554c8f96dde3a97a3e8d56a5.zip llvm-297088d1add70cae554c8f96dde3a97a3e8d56a5.tar.gz llvm-297088d1add70cae554c8f96dde3a97a3e8d56a5.tar.bz2 |
Revert "[DSE] Remove stores in the same loop iteration"
Apparently non-dead stores are being removed, as noted in D100464.
This reverts commit 222aeb4d51a46c5a81c9e4ccb16d1d19dd21ec95.
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp | 78 |
1 files changed, 19 insertions, 59 deletions
diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp index e6b9c2a..94f3e0d 100644 --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -40,12 +40,10 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/CaptureTracking.h" #include "llvm/Analysis/GlobalsModRef.h" -#include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/MemoryLocation.h" #include "llvm/Analysis/MemorySSA.h" #include "llvm/Analysis/MemorySSAUpdater.h" -#include "llvm/Analysis/MustExecute.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/ValueTracking.h" @@ -855,11 +853,6 @@ struct DSEState { PostDominatorTree &PDT; const TargetLibraryInfo &TLI; const DataLayout &DL; - const LoopInfo &LI; - - // Whether the function contains any irreducible control flow, useful for - // being accurately able to detect loops. - bool ContainsIrreducibleLoops; // All MemoryDefs that potentially could kill other MemDefs. SmallVector<MemoryDef *, 64> MemDefs; @@ -883,15 +876,14 @@ struct DSEState { DenseMap<BasicBlock *, InstOverlapIntervalsTy> IOLs; DSEState(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, DominatorTree &DT, - PostDominatorTree &PDT, const TargetLibraryInfo &TLI, - const LoopInfo &LI) + PostDominatorTree &PDT, const TargetLibraryInfo &TLI) : F(F), AA(AA), BatchAA(AA), MSSA(MSSA), DT(DT), PDT(PDT), TLI(TLI), - DL(F.getParent()->getDataLayout()), LI(LI) {} + DL(F.getParent()->getDataLayout()) {} static DSEState get(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, DominatorTree &DT, PostDominatorTree &PDT, - const TargetLibraryInfo &TLI, const LoopInfo &LI) { - DSEState State(F, AA, MSSA, DT, PDT, TLI, LI); + const TargetLibraryInfo &TLI) { + DSEState State(F, AA, MSSA, DT, PDT, TLI); // Collect blocks with throwing instructions not modeled in MemorySSA and // alloc-like objects. unsigned PO = 0; @@ -919,9 +911,6 @@ struct DSEState { State.InvisibleToCallerAfterRet.insert({&AI, true}); } - // Collect whether there is any irreducible control flow in the function. - State.ContainsIrreducibleLoops = mayContainIrreducibleControl(F, &LI); - return State; } @@ -936,12 +925,6 @@ struct DSEState { isOverwrite(const Instruction *LaterI, const Instruction *EarlierI, const MemoryLocation &Later, const MemoryLocation &Earlier, int64_t &EarlierOff, int64_t &LaterOff) { - // AliasAnalysis does not always account for loops. Limit overwrite checks - // to dependencies for which we can guarantee they are independant of any - // loops they are in. - if (!isGuaranteedLoopIndependent(EarlierI, LaterI, Earlier)) - return OW_Unknown; - // FIXME: Vet that this works for size upper-bounds. Seems unlikely that we'll // get imprecise values here, though (except for unknown sizes). if (!Later.Size.isPrecise() || !Earlier.Size.isPrecise()) { @@ -1267,27 +1250,11 @@ struct DSEState { return isRefSet(BatchAA.getModRefInfo(UseInst, DefLoc)); } - /// Returns true if a dependency between \p Current and \p KillingDef is - /// guaranteed to be loop invariant for the loops that they are in. Either - /// because they are known to be in the same block, in the same loop level or - /// by guaranteeing that \p CurrentLoc only references a single MemoryLocation - /// during execution of the containing function. - bool isGuaranteedLoopIndependent(const Instruction *Current, - const Instruction *KillingDef, - const MemoryLocation &CurrentLoc) { - // If the dependency is within the same block or loop level (being careful of - // irreducible loops), we know that AA will return a valid result for the - // memory dependency. (Both at the function level, outside of any loop, - // would also be valid but we currently disable that to limit compile time). - if (Current->getParent() == KillingDef->getParent()) - return true; - const Loop *CurrentLI = LI.getLoopFor(Current->getParent()); - if (!ContainsIrreducibleLoops && CurrentLI && - CurrentLI == LI.getLoopFor(KillingDef->getParent())) - return true; - - // Otherwise check the memory location is invariant to any loops. - auto IsGuaranteedLoopInvariantBase = [this](const Value *Ptr) { + /// Returns true if \p Ptr is guaranteed to be loop invariant for any possible + /// loop. In particular, this guarantees that it only references a single + /// MemoryLocation during execution of the containing function. + bool IsGuaranteedLoopInvariant(Value *Ptr) { + auto IsGuaranteedLoopInvariantBase = [this](Value *Ptr) { Ptr = Ptr->stripPointerCasts(); if (auto *I = dyn_cast<Instruction>(Ptr)) { if (isa<AllocaInst>(Ptr)) @@ -1301,7 +1268,7 @@ struct DSEState { return true; }; - const Value *Ptr = CurrentLoc.Ptr->stripPointerCasts(); + Ptr = Ptr->stripPointerCasts(); if (auto *I = dyn_cast<Instruction>(Ptr)) { if (I->getParent()->isEntryBlock()) return true; @@ -1431,9 +1398,9 @@ struct DSEState { // AliasAnalysis does not account for loops. Limit elimination to // candidates for which we can guarantee they always store to the same - // memory location and not located in different loops. - if (!isGuaranteedLoopIndependent(CurrentI, KillingI, *CurrentLoc)) { - LLVM_DEBUG(dbgs() << " ... not guaranteed loop independent\n"); + // memory location and not multiple locations in a loop. + if (Current->getBlock() != KillingDef->getBlock() && + !IsGuaranteedLoopInvariant(const_cast<Value *>(CurrentLoc->Ptr))) { StepAgain = true; Current = CurrentDef->getDefiningAccess(); WalkerStepLimit -= 1; @@ -1869,13 +1836,12 @@ struct DSEState { } }; -static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, - DominatorTree &DT, PostDominatorTree &PDT, - const TargetLibraryInfo &TLI, - const LoopInfo &LI) { +bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, + DominatorTree &DT, PostDominatorTree &PDT, + const TargetLibraryInfo &TLI) { bool MadeChange = false; - DSEState State = DSEState::get(F, AA, MSSA, DT, PDT, TLI, LI); + DSEState State = DSEState::get(F, AA, MSSA, DT, PDT, TLI); // For each store: for (unsigned I = 0; I < State.MemDefs.size(); I++) { MemoryDef *KillingDef = State.MemDefs[I]; @@ -2048,9 +2014,8 @@ PreservedAnalyses DSEPass::run(Function &F, FunctionAnalysisManager &AM) { DominatorTree &DT = AM.getResult<DominatorTreeAnalysis>(F); MemorySSA &MSSA = AM.getResult<MemorySSAAnalysis>(F).getMSSA(); PostDominatorTree &PDT = AM.getResult<PostDominatorTreeAnalysis>(F); - LoopInfo &LI = AM.getResult<LoopAnalysis>(F); - bool Changed = eliminateDeadStores(F, AA, MSSA, DT, PDT, TLI, LI); + bool Changed = eliminateDeadStores(F, AA, MSSA, DT, PDT, TLI); #ifdef LLVM_ENABLE_STATS if (AreStatisticsEnabled()) @@ -2064,7 +2029,6 @@ PreservedAnalyses DSEPass::run(Function &F, FunctionAnalysisManager &AM) { PreservedAnalyses PA; PA.preserveSet<CFGAnalyses>(); PA.preserve<MemorySSAAnalysis>(); - PA.preserve<LoopAnalysis>(); return PA; } @@ -2090,9 +2054,8 @@ public: MemorySSA &MSSA = getAnalysis<MemorySSAWrapperPass>().getMSSA(); PostDominatorTree &PDT = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree(); - LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); - bool Changed = eliminateDeadStores(F, AA, MSSA, DT, PDT, TLI, LI); + bool Changed = eliminateDeadStores(F, AA, MSSA, DT, PDT, TLI); #ifdef LLVM_ENABLE_STATS if (AreStatisticsEnabled()) @@ -2114,8 +2077,6 @@ public: AU.addRequired<MemorySSAWrapperPass>(); AU.addPreserved<PostDominatorTreeWrapperPass>(); AU.addPreserved<MemorySSAWrapperPass>(); - AU.addRequired<LoopInfoWrapperPass>(); - AU.addPreserved<LoopInfoWrapperPass>(); } }; @@ -2132,7 +2093,6 @@ INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass) INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass) INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) -INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) INITIALIZE_PASS_END(DSELegacyPass, "dse", "Dead Store Elimination", false, false) |