diff --git a/llvm/include/llvm/Analysis/AliasAnalysis.h b/llvm/include/llvm/Analysis/AliasAnalysis.h --- a/llvm/include/llvm/Analysis/AliasAnalysis.h +++ b/llvm/include/llvm/Analysis/AliasAnalysis.h @@ -185,12 +185,9 @@ /// This is used for cache invalidation purposes. DenseMap> Inst2Obj; - const SmallPtrSetImpl &EphValues; - public: - EarliestEscapeInfo(DominatorTree &DT, const LoopInfo &LI, - const SmallPtrSetImpl &EphValues) - : DT(DT), LI(LI), EphValues(EphValues) {} + EarliestEscapeInfo(DominatorTree &DT, const LoopInfo &LI) + : DT(DT), LI(LI) {} bool isNotCapturedBeforeOrAt(const Value *Object, const Instruction *I) override; diff --git a/llvm/include/llvm/Analysis/CaptureTracking.h b/llvm/include/llvm/Analysis/CaptureTracking.h --- a/llvm/include/llvm/Analysis/CaptureTracking.h +++ b/llvm/include/llvm/Analysis/CaptureTracking.h @@ -25,7 +25,6 @@ class DominatorTree; class LoopInfo; class Function; - template class SmallPtrSetImpl; /// getDefaultMaxUsesToExploreForCaptureTracking - Return default value of /// the maximal number of uses to explore before giving up. It is used by @@ -42,14 +41,8 @@ /// MaxUsesToExplore specifies how many uses the analysis should explore for /// one value before giving up due too "too many uses". If MaxUsesToExplore /// is zero, a default value is assumed. - bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, - bool StoreCaptures, unsigned MaxUsesToExplore = 0); - - /// Variant of the above function which accepts a set of Values that are - /// ephemeral and cannot cause pointers to escape. bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures, - const SmallPtrSetImpl &EphValues, unsigned MaxUsesToExplore = 0); /// PointerMayBeCapturedBefore - Return true if this pointer value may be @@ -83,7 +76,6 @@ Instruction * FindEarliestCapture(const Value *V, Function &F, bool ReturnCaptures, bool StoreCaptures, const DominatorTree &DT, - const SmallPtrSetImpl &EphValues, unsigned MaxUsesToExplore = 0); /// This callback is used in conjunction with PointerMayBeCaptured. In diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -206,7 +206,7 @@ if (Iter.second) { Instruction *EarliestCapture = FindEarliestCapture( Object, *const_cast(I->getFunction()), - /*ReturnCaptures=*/false, /*StoreCaptures=*/true, DT, EphValues); + /*ReturnCaptures=*/false, /*StoreCaptures=*/true, DT); if (EarliestCapture) { auto Ins = Inst2Obj.insert({EarliestCapture, {}}); Ins.first->second.push_back(Object); diff --git a/llvm/lib/Analysis/CaptureTracking.cpp b/llvm/lib/Analysis/CaptureTracking.cpp --- a/llvm/lib/Analysis/CaptureTracking.cpp +++ b/llvm/lib/Analysis/CaptureTracking.cpp @@ -16,7 +16,6 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/CaptureTracking.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" @@ -75,10 +74,8 @@ namespace { struct SimpleCaptureTracker : public CaptureTracker { - explicit SimpleCaptureTracker( - - const SmallPtrSetImpl &EphValues, bool ReturnCaptures) - : EphValues(EphValues), ReturnCaptures(ReturnCaptures) {} + explicit SimpleCaptureTracker(bool ReturnCaptures) + : ReturnCaptures(ReturnCaptures) {} void tooManyUses() override { LLVM_DEBUG(dbgs() << "Captured due to too many uses\n"); @@ -89,17 +86,12 @@ if (isa(U->getUser()) && !ReturnCaptures) return false; - if (EphValues.contains(U->getUser())) - return false; - LLVM_DEBUG(dbgs() << "Captured by: " << *U->getUser() << "\n"); Captured = true; return true; } - const SmallPtrSetImpl &EphValues; - bool ReturnCaptures; bool Captured = false; @@ -167,9 +159,8 @@ // escape are not in a cycle. struct EarliestCaptures : public CaptureTracker { - EarliestCaptures(bool ReturnCaptures, Function &F, const DominatorTree &DT, - const SmallPtrSetImpl &EphValues) - : EphValues(EphValues), DT(DT), ReturnCaptures(ReturnCaptures), F(F) {} + EarliestCaptures(bool ReturnCaptures, Function &F, const DominatorTree &DT) + : DT(DT), ReturnCaptures(ReturnCaptures), F(F) {} void tooManyUses() override { Captured = true; @@ -181,9 +172,6 @@ if (isa(I) && !ReturnCaptures) return false; - if (EphValues.contains(I)) - return false; - if (!EarliestCapture) EarliestCapture = I; else @@ -195,8 +183,6 @@ return false; } - const SmallPtrSetImpl &EphValues; - Instruction *EarliestCapture = nullptr; const DominatorTree &DT; @@ -216,18 +202,8 @@ /// counts as capturing it or not. The boolean StoreCaptures specified whether /// storing the value (or part of it) into memory anywhere automatically /// counts as capturing it or not. -bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures, - bool StoreCaptures, unsigned MaxUsesToExplore) { - SmallPtrSet Empty; - return PointerMayBeCaptured(V, ReturnCaptures, StoreCaptures, Empty, - MaxUsesToExplore); -} - -/// Variant of the above function which accepts a set of Values that are -/// ephemeral and cannot cause pointers to escape. -bool llvm::PointerMayBeCaptured(const Value *V, bool ReturnCaptures, - bool StoreCaptures, - const SmallPtrSetImpl &EphValues, +bool llvm::PointerMayBeCaptured(const Value *V, + bool ReturnCaptures, bool StoreCaptures, unsigned MaxUsesToExplore) { assert(!isa(V) && "It doesn't make sense to ask whether a global is captured."); @@ -240,7 +216,7 @@ LLVM_DEBUG(dbgs() << "Captured?: " << *V << " = "); - SimpleCaptureTracker SCT(EphValues, ReturnCaptures); + SimpleCaptureTracker SCT(ReturnCaptures); PointerMayBeCaptured(V, &SCT, MaxUsesToExplore); if (SCT.Captured) ++NumCaptured; @@ -287,13 +263,11 @@ Instruction * llvm::FindEarliestCapture(const Value *V, Function &F, bool ReturnCaptures, bool StoreCaptures, const DominatorTree &DT, - - const SmallPtrSetImpl &EphValues, unsigned MaxUsesToExplore) { assert(!isa(V) && "It doesn't make sense to ask whether a global is captured."); - EarliestCaptures CB(ReturnCaptures, F, DT, EphValues); + EarliestCaptures CB(ReturnCaptures, F, DT); PointerMayBeCaptured(V, &CB, MaxUsesToExplore); if (CB.Captured) ++NumCapturedBefore; diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -38,9 +38,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringRef.h" #include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/CaptureTracking.h" -#include "llvm/Analysis/CodeMetrics.h" #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/MemoryBuiltins.h" @@ -850,9 +848,6 @@ // Post-order numbers for each basic block. Used to figure out if memory // accesses are executed before another access. DenseMap PostOrderNumbers; - // Values that are only used with assumes. Used to refine pointer escape - // analysis. - SmallPtrSet EphValues; /// Keep track of instructions (partly) overlapping with killing MemoryDefs per /// basic block. @@ -872,9 +867,9 @@ DSEState &operator=(const DSEState &) = delete; DSEState(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, DominatorTree &DT, - PostDominatorTree &PDT, AssumptionCache &AC, + PostDominatorTree &PDT, const TargetLibraryInfo &TLI, const LoopInfo &LI) - : F(F), AA(AA), EI(DT, LI, EphValues), BatchAA(AA, &EI), MSSA(MSSA), + : F(F), AA(AA), EI(DT, LI), BatchAA(AA, &EI), MSSA(MSSA), DT(DT), PDT(PDT), TLI(TLI), DL(F.getParent()->getDataLayout()), LI(LI) { // Collect blocks with throwing instructions not modeled in MemorySSA and // alloc-like objects. @@ -905,8 +900,6 @@ AnyUnreachableExit = any_of(PDT.roots(), [](const BasicBlock *E) { return isa(E->getTerminator()); }); - - CodeMetrics::collectEphemeralValues(&F, &AC, EphValues); } LocationSize strengthenLocationSize(const Instruction *I, @@ -1076,7 +1069,7 @@ if (!isInvisibleToCallerOnUnwind(V)) { I.first->second = false; } else if (isNoAliasCall(V)) { - I.first->second = !PointerMayBeCaptured(V, true, false, EphValues); + I.first->second = !PointerMayBeCaptured(V, true, false); } } return I.first->second; @@ -1095,7 +1088,7 @@ // with the killing MemoryDef. But we refrain from doing so for now to // limit compile-time and this does not cause any changes to the number // of stores removed on a large test set in practice. - I.first->second = PointerMayBeCaptured(V, false, true, EphValues); + I.first->second = PointerMayBeCaptured(V, false, true); return !I.first->second; } @@ -2064,13 +2057,12 @@ static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, DominatorTree &DT, PostDominatorTree &PDT, - AssumptionCache &AC, const TargetLibraryInfo &TLI, const LoopInfo &LI) { bool MadeChange = false; MSSA.ensureOptimizedUses(); - DSEState State(F, AA, MSSA, DT, PDT, AC, TLI, LI); + DSEState State(F, AA, MSSA, DT, PDT, TLI, LI); // For each store: for (unsigned I = 0; I < State.MemDefs.size(); I++) { MemoryDef *KillingDef = State.MemDefs[I]; @@ -2251,10 +2243,9 @@ DominatorTree &DT = AM.getResult(F); MemorySSA &MSSA = AM.getResult(F).getMSSA(); PostDominatorTree &PDT = AM.getResult(F); - AssumptionCache &AC = AM.getResult(F); LoopInfo &LI = AM.getResult(F); - bool Changed = eliminateDeadStores(F, AA, MSSA, DT, PDT, AC, TLI, LI); + bool Changed = eliminateDeadStores(F, AA, MSSA, DT, PDT, TLI, LI); #ifdef LLVM_ENABLE_STATS if (AreStatisticsEnabled()) @@ -2271,3 +2262,4 @@ PA.preserve(); return PA; } + diff --git a/llvm/test/Transforms/DeadStoreElimination/assume.ll b/llvm/test/Transforms/DeadStoreElimination/assume.ll --- a/llvm/test/Transforms/DeadStoreElimination/assume.ll +++ b/llvm/test/Transforms/DeadStoreElimination/assume.ll @@ -8,6 +8,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = call noalias ptr @_Znwm(i64 32) ; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt ptr [[TMP1]], @global ; CHECK-NEXT: call void @llvm.assume(i1 [[TMP2]]) +; CHECK-NEXT: store i8 0, i8* [[TMP1]], align 1 ; CHECK-NEXT: ret void ; %tmp1 = call noalias ptr @_Znwm(i64 32) diff --git a/llvm/test/Transforms/PhaseOrdering/dse-ephemeral-value-captures.ll b/llvm/test/Transforms/PhaseOrdering/dse-ephemeral-value-captures.ll --- a/llvm/test/Transforms/PhaseOrdering/dse-ephemeral-value-captures.ll +++ b/llvm/test/Transforms/PhaseOrdering/dse-ephemeral-value-captures.ll @@ -26,7 +26,13 @@ define i32 @test() { ; CHECK-LABEL: define i32 @test() { ; CHECK-NEXT: entry: -; CHECK-NEXT: unreachable +; CHECK-NEXT: br label [[THEN_I:%.*]] +; CHECK: then.i: +; CHECK-NEXT: [[RES_I:%.*]] = call i1 @cond() +; CHECK-NEXT: br label [[CHECK_COND_EXIT:%.*]] +; CHECK: check_cond.exit: +; CHECK-NEXT: call void @llvm.assume(i1 [[RES_I]]) +; CHECK-NEXT: ret i32 0 ; entry: %a = alloca i32, align 4