<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, May 10, 2016 at 10:15 PM, Justin Bogner via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div class=""><div class="h5">Jake VanAdrighem <<a href="mailto:jvanadrighem@gmail.com">jvanadrighem@gmail.com</a>> writes:<br>
> JakeVanAdrighem created this revision.<br>
> JakeVanAdrighem added reviewers: davide, chandlerc, bogner.<br>
> JakeVanAdrighem added a subscriber: llvm-commits.<br>
> JakeVanAdrighem set the repository for this revision to rL LLVM.<br>
><br>
> I've copied what was done for SROA/GlobalOpt/GlobalDCE.<br>
><br>
> Repository:<br>
>   rL LLVM<br>
><br>
> <a href="http://reviews.llvm.org/D20146" rel="noreferrer" target="_blank">http://reviews.llvm.org/D20146</a><br>
><br>
> Files:<br>
>   include/llvm/InitializePasses.h<br>
>   include/llvm/Transforms/Scalar/DeadStoreElimination.h<br>
>   lib/Passes/PassBuilder.cpp<br>
>   lib/Passes/PassRegistry.def<br>
>   lib/Transforms/Scalar/DeadStoreElimination.cpp<br>
>   lib/Transforms/Scalar/Scalar.cpp<br>
>   test/Transforms/DeadStoreElimination/simple.ll<br>
><br>
</div></div>> Index: test/Transforms/DeadStoreElimination/simple.ll<br>
> ===================================================================<br>
> --- test/Transforms/DeadStoreElimination/simple.ll<br>
> +++ test/Transforms/DeadStoreElimination/simple.ll<br>
> @@ -1,4 +1,5 @@<br>
>  ; RUN: opt < %s -basicaa -dse -S | FileCheck %s<br>
> +; RUN: opt < %s -aa-pipeline=basic-aa -passes=dse -S | FileCheck %s<br>
>  target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"<br>
><br>
>  declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind<br>
> Index: lib/Transforms/Scalar/Scalar.cpp<br>
> ===================================================================<br>
> --- lib/Transforms/Scalar/Scalar.cpp<br>
> +++ lib/Transforms/Scalar/Scalar.cpp<br>
> @@ -40,7 +40,7 @@<br>
>    initializeDCELegacyPassPass(Registry);<br>
>    initializeDeadInstEliminationPass(Registry);<br>
>    initializeScalarizerPass(Registry);<br>
> -  initializeDSEPass(Registry);<br>
> +  initializeDSELegacyPassPass(Registry);<br>
>    initializeGVNLegacyPassPass(Registry);<br>
>    initializeEarlyCSELegacyPassPass(Registry);<br>
>    initializeFlattenCFGPassPass(Registry);<br>
> Index: lib/Transforms/Scalar/DeadStoreElimination.cpp<br>
> ===================================================================<br>
> --- lib/Transforms/Scalar/DeadStoreElimination.cpp<br>
> +++ lib/Transforms/Scalar/DeadStoreElimination.cpp<br>
> @@ -15,7 +15,7 @@<br>
>  //<br>
>  //===----------------------------------------------------------------------===//<br>
><br>
> -#include "llvm/Transforms/Scalar.h"<br>
> +#include "llvm/Transforms/Scalar/DeadStoreElimination.h"<br>
>  #include "llvm/ADT/STLExtras.h"<br>
>  #include "llvm/ADT/SetVector.h"<br>
>  #include "llvm/ADT/Statistic.h"<br>
> @@ -36,8 +36,10 @@<br>
>  #include "llvm/Pass.h"<br>
>  #include "llvm/Support/Debug.h"<br>
>  #include "llvm/Support/raw_ostream.h"<br>
> +#include "llvm/Transforms/Scalar.h"<br>
>  #include "llvm/Transforms/Utils/Local.h"<br>
>  using namespace llvm;<br>
> +using namespace llvm::dse;<br>
><br>
>  #define DEBUG_TYPE "dse"<br>
><br>
> @@ -45,69 +47,6 @@<br>
>  STATISTIC(NumFastStores, "Number of stores deleted");<br>
>  STATISTIC(NumFastOther , "Number of other instrs removed");<br>
><br>
> -namespace {<br>
> -  struct DSE : public FunctionPass {<br>
> -    AliasAnalysis *AA;<br>
> -    MemoryDependenceResults *MD;<br>
> -    DominatorTree *DT;<br>
> -    const TargetLibraryInfo *TLI;<br>
> -<br>
> -    static char ID; // Pass identification, replacement for typeid<br>
> -    DSE() : FunctionPass(ID), AA(nullptr), MD(nullptr), DT(nullptr) {<br>
> -      initializeDSEPass(*PassRegistry::getPassRegistry());<br>
> -    }<br>
> -<br>
> -    bool runOnFunction(Function &F) override {<br>
> -      if (skipFunction(F))<br>
> -        return false;<br>
> -<br>
> -      AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();<br>
> -      MD = &getAnalysis<MemoryDependenceWrapperPass>().getMemDep();<br>
> -      DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();<br>
> -      TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();<br>
> -<br>
> -      bool Changed = false;<br>
> -      for (BasicBlock &I : F)<br>
> -        // Only check non-dead blocks.  Dead blocks may have strange pointer<br>
> -        // cycles that will confuse alias analysis.<br>
> -        if (DT->isReachableFromEntry(&I))<br>
> -          Changed |= runOnBasicBlock(I);<br>
> -<br>
> -      AA = nullptr; MD = nullptr; DT = nullptr;<br>
> -      return Changed;<br>
> -    }<br>
> -<br>
> -    bool runOnBasicBlock(BasicBlock &BB);<br>
> -    bool MemoryIsNotModifiedBetween(Instruction *FirstI, Instruction *SecondI);<br>
> -    bool HandleFree(CallInst *F);<br>
> -    bool handleEndBlock(BasicBlock &BB);<br>
> -    void RemoveAccessedObjects(const MemoryLocation &LoadedLoc,<br>
> -                               SmallSetVector<Value *, 16> &DeadStackObjects,<br>
> -                               const DataLayout &DL);<br>
> -<br>
> -    void getAnalysisUsage(AnalysisUsage &AU) const override {<br>
> -      AU.setPreservesCFG();<br>
> -      AU.addRequired<DominatorTreeWrapperPass>();<br>
> -      AU.addRequired<AAResultsWrapperPass>();<br>
> -      AU.addRequired<MemoryDependenceWrapperPass>();<br>
> -      AU.addRequired<TargetLibraryInfoWrapperPass>();<br>
> -      AU.addPreserved<DominatorTreeWrapperPass>();<br>
> -      AU.addPreserved<GlobalsAAWrapperPass>();<br>
> -      AU.addPreserved<MemoryDependenceWrapperPass>();<br>
> -    }<br>
> -  };<br>
> -}<br>
> -<br>
> -char DSE::ID = 0;<br>
> -INITIALIZE_PASS_BEGIN(DSE, "dse", "Dead Store Elimination", false, false)<br>
> -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)<br>
> -INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)<br>
> -INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)<br>
> -INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass)<br>
> -INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)<br>
> -INITIALIZE_PASS_END(DSE, "dse", "Dead Store Elimination", false, false)<br>
> -<br>
> -FunctionPass *llvm::createDeadStoreEliminationPass() { return new DSE(); }<br>
><br>
>  //===----------------------------------------------------------------------===//<br>
>  // Helper functions<br>
> @@ -1004,3 +943,87 @@<br>
>      return !AA->isNoAlias(StackLoc, LoadedLoc);<br>
>    });<br>
>  }<br>
> +<br>
> +PreservedAnalyses DSE::run(Function &F, FunctionAnalysisManager &AM) {<br>
> +  return runImpl(F, AM.getResult<AAManager>(F),<br>
> +                 AM.getResult<MemoryDependenceAnalysis>(F),<br>
> +                 AM.getResult<DominatorTreeAnalysis>(F),<br>
> +                 AM.getResult<TargetLibraryAnalysis>(F));<br>
> +}<br>
> +<br>
> +PreservedAnalyses DSE::runImpl(Function &F, AliasAnalysis &RunAA,<br>
> +                               MemoryDependenceResults &RunMemDep,<br>
> +                               DominatorTree &RunDT,<br>
> +                               TargetLibraryInfo &RunTLI) {<br>
> +  AA = &RunAA;<br>
> +  MD = &RunMemDep;<br>
> +  DT = &RunDT;<br>
> +  TLI = &RunTLI;<br>
> +<br>
> +  bool Changed = false;<br>
> +  for (BasicBlock &I : F)<br>
> +    // Only check non-dead blocks.  Dead blocks may have strange pointer<br>
> +    // cycles that will confuse alias analysis.<br>
> +    if (DT->isReachableFromEntry(&I))<br>
> +      Changed |= runOnBasicBlock(I);<br>
> +<br>
> +  AA = nullptr;<br>
> +  MD = nullptr;<br>
> +  DT = nullptr;<br>
<br>
I'm not a big fan of this pattern. How ugly is it to feed these through<br>
the APIs rather than keeping them as members?<br></blockquote><div><br></div><div>SaveAndRestore might make it a bit nicer if it turns out to be too ugly to thread them through arguments</div><div><a href="http://llvm.org/docs/doxygen/html/structllvm_1_1SaveAndRestore.html">http://llvm.org/docs/doxygen/html/structllvm_1_1SaveAndRestore.html</a><br></div><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<br>
> +<br>
> +  return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();<br>
> +}<br>
> +<br>
> +/// A legacy pass for the legacy pass manager that wraps the \c DSE pass.<br>
> +///<br>
> +/// This is in the llvm namespace purely to allow it to be a friend of the \c<br>
> +/// DSE pass.<br>
> +class llvm::dse::DSELegacyPass : public FunctionPass {<br>
> +  /// The DSE Implementation<br>
> +  DSE Impl;<br>
> +<br>
> +public:<br>
> +  DSELegacyPass() : FunctionPass(ID) {<br>
> +    initializeDSELegacyPassPass(*PassRegistry::getPassRegistry());<br>
> +  }<br>
> +<br>
> +  bool runOnFunction(Function &F) override {<br>
> +    if (skipFunction(F))<br>
> +      return false;<br>
> +<br>
> +    auto PA =<br>
> +        Impl.runImpl(F, getAnalysis<AAResultsWrapperPass>().getAAResults(),<br>
> +                     getAnalysis<MemoryDependenceWrapperPass>().getMemDep(),<br>
> +                     getAnalysis<DominatorTreeWrapperPass>().getDomTree(),<br>
> +                     getAnalysis<TargetLibraryInfoWrapperPass>().getTLI());<br>
> +    return !PA.areAllPreserved();<br>
> +  }<br>
> +<br>
> +  void getAnalysisUsage(AnalysisUsage &AU) const override {<br>
> +    AU.setPreservesCFG();<br>
> +    AU.addRequired<DominatorTreeWrapperPass>();<br>
> +    AU.addRequired<AAResultsWrapperPass>();<br>
> +    AU.addRequired<MemoryDependenceWrapperPass>();<br>
> +    AU.addRequired<TargetLibraryInfoWrapperPass>();<br>
> +    AU.addPreserved<DominatorTreeWrapperPass>();<br>
> +    AU.addPreserved<GlobalsAAWrapperPass>();<br>
> +    AU.addPreserved<MemoryDependenceWrapperPass>();<br>
> +  }<br>
> +<br>
> +  static char ID; // Pass identification, replacement for typeid<br>
> +};<br>
> +<br>
> +char DSELegacyPass::ID = 0;<br>
> +INITIALIZE_PASS_BEGIN(DSELegacyPass, "dse", "Dead Store Elimination", false,<br>
> +                      false)<br>
> +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)<br>
> +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)<br>
> +INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)<br>
> +INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass)<br>
> +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)<br>
> +INITIALIZE_PASS_END(DSELegacyPass, "dse", "Dead Store Elimination", false,<br>
> +                    false)<br>
> +<br>
> +FunctionPass *llvm::createDeadStoreEliminationPass() {<br>
> +  return new DSELegacyPass();<br>
> +}<br>
> Index: lib/Passes/PassRegistry.def<br>
> ===================================================================<br>
> --- lib/Passes/PassRegistry.def<br>
> +++ lib/Passes/PassRegistry.def<br>
> @@ -109,6 +109,7 @@<br>
>  FUNCTION_PASS("aa-eval", AAEvaluator())<br>
>  FUNCTION_PASS("adce", ADCEPass())<br>
<span class="">>  FUNCTION_PASS("dce", DCEPass())<br>
> +FUNCTION_PASS("dse", DSE())<br>
>  FUNCTION_PASS("early-cse", EarlyCSEPass())<br>
</span>>  FUNCTION_PASS("instcombine", InstCombinePass())<br>
>  FUNCTION_PASS("invalidate<all>", InvalidateAllAnalysesPass())<br>
> Index: lib/Passes/PassBuilder.cpp<br>
> ===================================================================<br>
> --- lib/Passes/PassBuilder.cpp<br>
> +++ lib/Passes/PassBuilder.cpp<br>
> @@ -63,6 +63,7 @@<br>
>  #include "llvm/Transforms/PGOInstrumentation.h"<br>
>  #include "llvm/Transforms/Scalar/ADCE.h"<br>
>  #include "llvm/Transforms/Scalar/DCE.h"<br>
> +#include "llvm/Transforms/Scalar/DeadStoreElimination.h"<br>
>  #include "llvm/Transforms/Scalar/EarlyCSE.h"<br>
>  #include "llvm/Transforms/Scalar/GVN.h"<br>
>  #include "llvm/Transforms/Scalar/LoopRotation.h"<br>
> Index: include/llvm/Transforms/Scalar/DeadStoreElimination.h<br>
> ===================================================================<br>
> --- /dev/null<br>
> +++ include/llvm/Transforms/Scalar/DeadStoreElimination.h<br>
> @@ -0,0 +1,67 @@<br>
> +//===- DeadStoreElimination.h - Fast Dead Store Elimination -------------===//<br>
> +//<br>
> +//                     The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open Source<br>
> +// License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +//<br>
> +// This file implements a trivial dead store elimination that only considers<br>
> +// basic-block local redundant stores.<br>
> +//<br>
> +// FIXME: This should eventually be extended to be a post-dominator tree<br>
> +// traversal.  Doing so would be pretty trivial.<br>
> +//<br>
> +//===----------------------------------------------------------------------===//<br>
> +<br>
> +#ifndef LLVM_TRANSFORMS_SCALAR_DSE_H<br>
> +#define LLVM_TRANSFORMS_SCALAR_DSE_H<br>
> +<br>
> +#include "llvm/ADT/SetVector.h"<br>
> +#include "llvm/Analysis/AliasAnalysis.h"<br>
> +#include "llvm/Analysis/MemoryDependenceAnalysis.h"<br>
> +#include "llvm/Analysis/TargetLibraryInfo.h"<br>
> +#include "llvm/IR/Dominators.h"<br>
> +#include "llvm/IR/Function.h"<br>
> +#include "llvm/IR/PassManager.h"<br>
> +<br>
> +namespace llvm {<br>
> +<br>
> +/// A private "module" namespace for types and utilities used by DSE. These<br>
> +/// are implementation details and should not be used by clients.<br>
> +namespace dse {<br>
> +class DSELegacyPass;<br>
> +}<br>
<span class="">> +<br>
> +class DSE : public PassInfoMixin<DSE> {<br>
> +public:<br>
</span>> +  DSE() : AA(nullptr), MD(nullptr), DT(nullptr) {}<br>
> +<br>
> +  /// \brief Run the pass over the function.<br>
> +  PreservedAnalyses run(Function &F, AnalysisManager<Function> &FAM);<br>
> +<br>
> +private:<br>
> +  friend class dse::DSELegacyPass;<br>
> +<br>
> +  /// Helper used by both the public run method and by the legacy pass.<br>
> +  PreservedAnalyses runImpl(Function &F, AliasAnalysis &RunAA,<br>
> +                            MemoryDependenceResults &RunMemDep,<br>
> +                            DominatorTree &RunDT, TargetLibraryInfo &RunTLI);<br>
> +<br>
> +  AliasAnalysis *AA;<br>
> +  MemoryDependenceResults *MD;<br>
> +  DominatorTree *DT;<br>
> +  const TargetLibraryInfo *TLI;<br>
<span class="">> +<br>
> +  bool runOnBasicBlock(BasicBlock &BB);<br>
> +  bool MemoryIsNotModifiedBetween(Instruction *FirstI, Instruction *SecondI);<br>
</span>> +  bool HandleFree(CallInst *F);<br>
> +  bool handleEndBlock(BasicBlock &BB);<br>
> +  void RemoveAccessedObjects(const MemoryLocation &LoadedLoc,<br>
> +                             SmallSetVector<Value *, 16> &DeadStackObjects,<br>
> +                             const DataLayout &DL);<br>
> +};<br>
> +}<br>
> +<br>
> +#endif // LLVM_TRANSFORMS_SCALAR_DSE_H<br>
> Index: include/llvm/InitializePasses.h<br>
> ===================================================================<br>
> --- include/llvm/InitializePasses.h<br>
> +++ include/llvm/InitializePasses.h<br>
> @@ -105,7 +105,7 @@<br>
>  void initializeDAEPass(PassRegistry&);<br>
>  void initializeDAHPass(PassRegistry&);<br>
>  void initializeDCELegacyPassPass(PassRegistry&);<br>
> -void initializeDSEPass(PassRegistry&);<br>
> +void initializeDSELegacyPassPass(PassRegistry&);<br>
>  void initializeDeadInstEliminationPass(PassRegistry&);<br>
>  void initializeDeadMachineInstructionElimPass(PassRegistry&);<br>
>  void initializeDelinearizationPass(PassRegistry &);<br>
<div class=""><div class="h5">_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</div></div></blockquote></div><br></div></div>