forked from OSchip/llvm-project
[DSE] Add stat for remaining stores after DSE.
Using the existing NumFastStores statistic can be misleading when comparing the impact of DSE patches. For example, consider the case where a store gets removed from a function before it is inlined into another function. A less powerful DSE might only remove the store from functions it has been inlined into, which will result in more stores being removed, but no difference in the actual number of stores after DSE. The new stat provides the absolute number of stores surviving after DSE. Reviewers: dmgreen, bryant, asbirlea, jfb Reviewed By: asbirlea Differential Revision: https://reviews.llvm.org/D78830
This commit is contained in:
parent
9193644f77
commit
46a04940e8
|
@ -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 <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
|
@ -75,6 +76,7 @@ using namespace llvm;
|
|||
|
||||
#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 @@ PreservedAnalyses DSEPass::run(Function &F, FunctionAnalysisManager &AM) {
|
|||
const TargetLibraryInfo &TLI = AM.getResult<TargetLibraryAnalysis>(F);
|
||||
DominatorTree &DT = AM.getResult<DominatorTreeAnalysis>(F);
|
||||
|
||||
bool Changed = false;
|
||||
if (EnableMemorySSA) {
|
||||
MemorySSA &MSSA = AM.getResult<MemorySSAAnalysis>(F).getMSSA();
|
||||
PostDominatorTree &PDT = AM.getResult<PostDominatorTreeAnalysis>(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<MemoryDependenceAnalysis>(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<StoreInst>(&I);
|
||||
#endif
|
||||
|
||||
if (!Changed)
|
||||
return PreservedAnalyses::all();
|
||||
|
||||
PreservedAnalyses PA;
|
||||
PA.preserveSet<CFGAnalyses>();
|
||||
PA.preserve<GlobalsAA>();
|
||||
|
@ -2008,18 +2018,27 @@ public:
|
|||
const TargetLibraryInfo &TLI =
|
||||
getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
|
||||
|
||||
bool Changed = false;
|
||||
if (EnableMemorySSA) {
|
||||
MemorySSA &MSSA = getAnalysis<MemorySSAWrapperPass>().getMSSA();
|
||||
PostDominatorTree &PDT =
|
||||
getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
|
||||
|
||||
return eliminateDeadStoresMemorySSA(F, AA, MSSA, DT, PDT, TLI);
|
||||
eliminateDeadStoresMemorySSA(F, AA, MSSA, DT, PDT, TLI);
|
||||
} else {
|
||||
MemoryDependenceResults &MD =
|
||||
getAnalysis<MemoryDependenceWrapperPass>().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<StoreInst>(&I);
|
||||
#endif
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue