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 @@ -42,6 +42,7 @@ #include "llvm/IR/DataLayout.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" +#include "llvm/IR/InstIterator.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" @@ -61,8 +62,8 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/AssumeBundleBuilder.h" +#include "llvm/Transforms/Utils/Local.h" #include #include #include @@ -75,6 +76,7 @@ #define DEBUG_TYPE "dse" +STATISTIC(NumRemainingStores, "Number of stores remaining after DSE"); STATISTIC(NumRedundantStores, "Number of redundant stores deleted"); STATISTIC(NumFastStores, "Number of stores deleted"); STATISTIC(NumFastOther, "Number of other instrs removed"); @@ -1965,19 +1967,27 @@ const TargetLibraryInfo &TLI = AM.getResult(F); DominatorTree &DT = AM.getResult(F); + bool Changed = false; if (EnableMemorySSA) { MemorySSA &MSSA = AM.getResult(F).getMSSA(); PostDominatorTree &PDT = AM.getResult(F); - if (!eliminateDeadStoresMemorySSA(F, AA, MSSA, DT, PDT, TLI)) - return PreservedAnalyses::all(); + Changed = eliminateDeadStoresMemorySSA(F, AA, MSSA, DT, PDT, TLI); } else { MemoryDependenceResults &MD = AM.getResult(F); - if (!eliminateDeadStores(F, &AA, &MD, &DT, &TLI)) - return PreservedAnalyses::all(); + Changed = eliminateDeadStores(F, &AA, &MD, &DT, &TLI); } +#ifdef LLVM_ENABLE_STATS + if (AreStatisticsEnabled()) + for (auto &I : instructions(F)) + NumRemainingStores += isa(&I); +#endif + + if (!Changed) + return PreservedAnalyses::all(); + PreservedAnalyses PA; PA.preserveSet(); PA.preserve(); @@ -2008,18 +2018,27 @@ const TargetLibraryInfo &TLI = getAnalysis().getTLI(F); + bool Changed = false; if (EnableMemorySSA) { MemorySSA &MSSA = getAnalysis().getMSSA(); PostDominatorTree &PDT = getAnalysis().getPostDomTree(); - return eliminateDeadStoresMemorySSA(F, AA, MSSA, DT, PDT, TLI); + eliminateDeadStoresMemorySSA(F, AA, MSSA, DT, PDT, TLI); } else { MemoryDependenceResults &MD = getAnalysis().getMemDep(); - return eliminateDeadStores(F, &AA, &MD, &DT, &TLI); + Changed = eliminateDeadStores(F, &AA, &MD, &DT, &TLI); } + +#ifdef LLVM_ENABLE_STATS + if (AreStatisticsEnabled()) + for (auto &I : instructions(F)) + NumRemainingStores += isa(&I); +#endif + + return Changed; } void getAnalysisUsage(AnalysisUsage &AU) const override { diff --git a/llvm/test/Transforms/DeadStoreElimination/MSSA/stats.ll b/llvm/test/Transforms/DeadStoreElimination/MSSA/stats.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/DeadStoreElimination/MSSA/stats.ll @@ -0,0 +1,36 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -basicaa -dse -enable-dse-memoryssa -stats -S 2>&1 | FileCheck %s + +; REQUIRES: asserts + +target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" + + +define void @test2(i32* noalias %P, i32* noalias %C, i1 %c) { +; CHECK-LABEL: @test2( +; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: store i32 3, i32* [[C:%.*]] +; CHECK-NEXT: br label [[BB3:%.*]] +; CHECK: bb2: +; CHECK-NEXT: store i32 4, i32* [[C]] +; CHECK-NEXT: br label [[BB3]] +; CHECK: bb3: +; CHECK-NEXT: store i32 0, i32* [[P:%.*]] +; CHECK-NEXT: ret void +; + store i32 1, i32* %P + br i1 %c, label %bb1, label %bb2 +bb1: + store i32 3, i32* %C + br label %bb3 +bb2: + store i32 4, i32* %C + br label %bb3 +bb3: + store i32 0, i32* %P + ret void +} + +; CHECK: 1 dse - Number of stores deleted +; CHECK: 3 dse - Number of stores remaining after DSE