<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>