[PATCH] D20146: [PM] Port DSE to the new pass manager.

Justin Bogner via llvm-commits llvm-commits at lists.llvm.org
Tue May 10 22:15:20 PDT 2016


Jake VanAdrighem <jvanadrighem at gmail.com> writes:
> JakeVanAdrighem created this revision.
> JakeVanAdrighem added reviewers: davide, chandlerc, bogner.
> JakeVanAdrighem added a subscriber: llvm-commits.
> JakeVanAdrighem set the repository for this revision to rL LLVM.
>
> I've copied what was done for SROA/GlobalOpt/GlobalDCE.
>
> Repository:
>   rL LLVM
>
> http://reviews.llvm.org/D20146
>
> Files:
>   include/llvm/InitializePasses.h
>   include/llvm/Transforms/Scalar/DeadStoreElimination.h
>   lib/Passes/PassBuilder.cpp
>   lib/Passes/PassRegistry.def
>   lib/Transforms/Scalar/DeadStoreElimination.cpp
>   lib/Transforms/Scalar/Scalar.cpp
>   test/Transforms/DeadStoreElimination/simple.ll
>
> Index: test/Transforms/DeadStoreElimination/simple.ll
> ===================================================================
> --- test/Transforms/DeadStoreElimination/simple.ll
> +++ test/Transforms/DeadStoreElimination/simple.ll
> @@ -1,4 +1,5 @@
>  ; RUN: opt < %s -basicaa -dse -S | FileCheck %s
> +; RUN: opt < %s -aa-pipeline=basic-aa -passes=dse -S | FileCheck %s
>  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"
>  
>  declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
> Index: lib/Transforms/Scalar/Scalar.cpp
> ===================================================================
> --- lib/Transforms/Scalar/Scalar.cpp
> +++ lib/Transforms/Scalar/Scalar.cpp
> @@ -40,7 +40,7 @@
>    initializeDCELegacyPassPass(Registry);
>    initializeDeadInstEliminationPass(Registry);
>    initializeScalarizerPass(Registry);
> -  initializeDSEPass(Registry);
> +  initializeDSELegacyPassPass(Registry);
>    initializeGVNLegacyPassPass(Registry);
>    initializeEarlyCSELegacyPassPass(Registry);
>    initializeFlattenCFGPassPass(Registry);
> Index: lib/Transforms/Scalar/DeadStoreElimination.cpp
> ===================================================================
> --- lib/Transforms/Scalar/DeadStoreElimination.cpp
> +++ lib/Transforms/Scalar/DeadStoreElimination.cpp
> @@ -15,7 +15,7 @@
>  //
>  //===----------------------------------------------------------------------===//
>  
> -#include "llvm/Transforms/Scalar.h"
> +#include "llvm/Transforms/Scalar/DeadStoreElimination.h"
>  #include "llvm/ADT/STLExtras.h"
>  #include "llvm/ADT/SetVector.h"
>  #include "llvm/ADT/Statistic.h"
> @@ -36,8 +36,10 @@
>  #include "llvm/Pass.h"
>  #include "llvm/Support/Debug.h"
>  #include "llvm/Support/raw_ostream.h"
> +#include "llvm/Transforms/Scalar.h"
>  #include "llvm/Transforms/Utils/Local.h"
>  using namespace llvm;
> +using namespace llvm::dse;
>  
>  #define DEBUG_TYPE "dse"
>  
> @@ -45,69 +47,6 @@
>  STATISTIC(NumFastStores, "Number of stores deleted");
>  STATISTIC(NumFastOther , "Number of other instrs removed");
>  
> -namespace {
> -  struct DSE : public FunctionPass {
> -    AliasAnalysis *AA;
> -    MemoryDependenceResults *MD;
> -    DominatorTree *DT;
> -    const TargetLibraryInfo *TLI;
> -
> -    static char ID; // Pass identification, replacement for typeid
> -    DSE() : FunctionPass(ID), AA(nullptr), MD(nullptr), DT(nullptr) {
> -      initializeDSEPass(*PassRegistry::getPassRegistry());
> -    }
> -
> -    bool runOnFunction(Function &F) override {
> -      if (skipFunction(F))
> -        return false;
> -
> -      AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
> -      MD = &getAnalysis<MemoryDependenceWrapperPass>().getMemDep();
> -      DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
> -      TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
> -
> -      bool Changed = false;
> -      for (BasicBlock &I : F)
> -        // Only check non-dead blocks.  Dead blocks may have strange pointer
> -        // cycles that will confuse alias analysis.
> -        if (DT->isReachableFromEntry(&I))
> -          Changed |= runOnBasicBlock(I);
> -
> -      AA = nullptr; MD = nullptr; DT = nullptr;
> -      return Changed;
> -    }
> -
> -    bool runOnBasicBlock(BasicBlock &BB);
> -    bool MemoryIsNotModifiedBetween(Instruction *FirstI, Instruction *SecondI);
> -    bool HandleFree(CallInst *F);
> -    bool handleEndBlock(BasicBlock &BB);
> -    void RemoveAccessedObjects(const MemoryLocation &LoadedLoc,
> -                               SmallSetVector<Value *, 16> &DeadStackObjects,
> -                               const DataLayout &DL);
> -
> -    void getAnalysisUsage(AnalysisUsage &AU) const override {
> -      AU.setPreservesCFG();
> -      AU.addRequired<DominatorTreeWrapperPass>();
> -      AU.addRequired<AAResultsWrapperPass>();
> -      AU.addRequired<MemoryDependenceWrapperPass>();
> -      AU.addRequired<TargetLibraryInfoWrapperPass>();
> -      AU.addPreserved<DominatorTreeWrapperPass>();
> -      AU.addPreserved<GlobalsAAWrapperPass>();
> -      AU.addPreserved<MemoryDependenceWrapperPass>();
> -    }
> -  };
> -}
> -
> -char DSE::ID = 0;
> -INITIALIZE_PASS_BEGIN(DSE, "dse", "Dead Store Elimination", false, false)
> -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
> -INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
> -INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
> -INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass)
> -INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
> -INITIALIZE_PASS_END(DSE, "dse", "Dead Store Elimination", false, false)
> -
> -FunctionPass *llvm::createDeadStoreEliminationPass() { return new DSE(); }
>  
>  //===----------------------------------------------------------------------===//
>  // Helper functions
> @@ -1004,3 +943,87 @@
>      return !AA->isNoAlias(StackLoc, LoadedLoc);
>    });
>  }
> +
> +PreservedAnalyses DSE::run(Function &F, FunctionAnalysisManager &AM) {
> +  return runImpl(F, AM.getResult<AAManager>(F),
> +                 AM.getResult<MemoryDependenceAnalysis>(F),
> +                 AM.getResult<DominatorTreeAnalysis>(F),
> +                 AM.getResult<TargetLibraryAnalysis>(F));
> +}
> +
> +PreservedAnalyses DSE::runImpl(Function &F, AliasAnalysis &RunAA,
> +                               MemoryDependenceResults &RunMemDep,
> +                               DominatorTree &RunDT,
> +                               TargetLibraryInfo &RunTLI) {
> +  AA = &RunAA;
> +  MD = &RunMemDep;
> +  DT = &RunDT;
> +  TLI = &RunTLI;
> +
> +  bool Changed = false;
> +  for (BasicBlock &I : F)
> +    // Only check non-dead blocks.  Dead blocks may have strange pointer
> +    // cycles that will confuse alias analysis.
> +    if (DT->isReachableFromEntry(&I))
> +      Changed |= runOnBasicBlock(I);
> +
> +  AA = nullptr;
> +  MD = nullptr;
> +  DT = nullptr;

I'm not a big fan of this pattern. How ugly is it to feed these through
the APIs rather than keeping them as members?

> +
> +  return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
> +}
> +
> +/// A legacy pass for the legacy pass manager that wraps the \c DSE pass.
> +///
> +/// This is in the llvm namespace purely to allow it to be a friend of the \c
> +/// DSE pass.
> +class llvm::dse::DSELegacyPass : public FunctionPass {
> +  /// The DSE Implementation
> +  DSE Impl;
> +
> +public:
> +  DSELegacyPass() : FunctionPass(ID) {
> +    initializeDSELegacyPassPass(*PassRegistry::getPassRegistry());
> +  }
> +
> +  bool runOnFunction(Function &F) override {
> +    if (skipFunction(F))
> +      return false;
> +
> +    auto PA =
> +        Impl.runImpl(F, getAnalysis<AAResultsWrapperPass>().getAAResults(),
> +                     getAnalysis<MemoryDependenceWrapperPass>().getMemDep(),
> +                     getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
> +                     getAnalysis<TargetLibraryInfoWrapperPass>().getTLI());
> +    return !PA.areAllPreserved();
> +  }
> +
> +  void getAnalysisUsage(AnalysisUsage &AU) const override {
> +    AU.setPreservesCFG();
> +    AU.addRequired<DominatorTreeWrapperPass>();
> +    AU.addRequired<AAResultsWrapperPass>();
> +    AU.addRequired<MemoryDependenceWrapperPass>();
> +    AU.addRequired<TargetLibraryInfoWrapperPass>();
> +    AU.addPreserved<DominatorTreeWrapperPass>();
> +    AU.addPreserved<GlobalsAAWrapperPass>();
> +    AU.addPreserved<MemoryDependenceWrapperPass>();
> +  }
> +
> +  static char ID; // Pass identification, replacement for typeid
> +};
> +
> +char DSELegacyPass::ID = 0;
> +INITIALIZE_PASS_BEGIN(DSELegacyPass, "dse", "Dead Store Elimination", false,
> +                      false)
> +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
> +INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
> +INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
> +INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass)
> +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
> +INITIALIZE_PASS_END(DSELegacyPass, "dse", "Dead Store Elimination", false,
> +                    false)
> +
> +FunctionPass *llvm::createDeadStoreEliminationPass() {
> +  return new DSELegacyPass();
> +}
> Index: lib/Passes/PassRegistry.def
> ===================================================================
> --- lib/Passes/PassRegistry.def
> +++ lib/Passes/PassRegistry.def
> @@ -109,6 +109,7 @@
>  FUNCTION_PASS("aa-eval", AAEvaluator())
>  FUNCTION_PASS("adce", ADCEPass())
>  FUNCTION_PASS("dce", DCEPass())
> +FUNCTION_PASS("dse", DSE())
>  FUNCTION_PASS("early-cse", EarlyCSEPass())
>  FUNCTION_PASS("instcombine", InstCombinePass())
>  FUNCTION_PASS("invalidate<all>", InvalidateAllAnalysesPass())
> Index: lib/Passes/PassBuilder.cpp
> ===================================================================
> --- lib/Passes/PassBuilder.cpp
> +++ lib/Passes/PassBuilder.cpp
> @@ -63,6 +63,7 @@
>  #include "llvm/Transforms/PGOInstrumentation.h"
>  #include "llvm/Transforms/Scalar/ADCE.h"
>  #include "llvm/Transforms/Scalar/DCE.h"
> +#include "llvm/Transforms/Scalar/DeadStoreElimination.h"
>  #include "llvm/Transforms/Scalar/EarlyCSE.h"
>  #include "llvm/Transforms/Scalar/GVN.h"
>  #include "llvm/Transforms/Scalar/LoopRotation.h"
> Index: include/llvm/Transforms/Scalar/DeadStoreElimination.h
> ===================================================================
> --- /dev/null
> +++ include/llvm/Transforms/Scalar/DeadStoreElimination.h
> @@ -0,0 +1,67 @@
> +//===- DeadStoreElimination.h - Fast Dead Store Elimination -------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// This file implements a trivial dead store elimination that only considers
> +// basic-block local redundant stores.
> +//
> +// FIXME: This should eventually be extended to be a post-dominator tree
> +// traversal.  Doing so would be pretty trivial.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_TRANSFORMS_SCALAR_DSE_H
> +#define LLVM_TRANSFORMS_SCALAR_DSE_H
> +
> +#include "llvm/ADT/SetVector.h"
> +#include "llvm/Analysis/AliasAnalysis.h"
> +#include "llvm/Analysis/MemoryDependenceAnalysis.h"
> +#include "llvm/Analysis/TargetLibraryInfo.h"
> +#include "llvm/IR/Dominators.h"
> +#include "llvm/IR/Function.h"
> +#include "llvm/IR/PassManager.h"
> +
> +namespace llvm {
> +
> +/// A private "module" namespace for types and utilities used by DSE. These
> +/// are implementation details and should not be used by clients.
> +namespace dse {
> +class DSELegacyPass;
> +}
> +
> +class DSE : public PassInfoMixin<DSE> {
> +public:
> +  DSE() : AA(nullptr), MD(nullptr), DT(nullptr) {}
> +
> +  /// \brief Run the pass over the function.
> +  PreservedAnalyses run(Function &F, AnalysisManager<Function> &FAM);
> +
> +private:
> +  friend class dse::DSELegacyPass;
> +
> +  /// Helper used by both the public run method and by the legacy pass.
> +  PreservedAnalyses runImpl(Function &F, AliasAnalysis &RunAA,
> +                            MemoryDependenceResults &RunMemDep,
> +                            DominatorTree &RunDT, TargetLibraryInfo &RunTLI);
> +
> +  AliasAnalysis *AA;
> +  MemoryDependenceResults *MD;
> +  DominatorTree *DT;
> +  const TargetLibraryInfo *TLI;
> +
> +  bool runOnBasicBlock(BasicBlock &BB);
> +  bool MemoryIsNotModifiedBetween(Instruction *FirstI, Instruction *SecondI);
> +  bool HandleFree(CallInst *F);
> +  bool handleEndBlock(BasicBlock &BB);
> +  void RemoveAccessedObjects(const MemoryLocation &LoadedLoc,
> +                             SmallSetVector<Value *, 16> &DeadStackObjects,
> +                             const DataLayout &DL);
> +};
> +}
> +
> +#endif // LLVM_TRANSFORMS_SCALAR_DSE_H
> Index: include/llvm/InitializePasses.h
> ===================================================================
> --- include/llvm/InitializePasses.h
> +++ include/llvm/InitializePasses.h
> @@ -105,7 +105,7 @@
>  void initializeDAEPass(PassRegistry&);
>  void initializeDAHPass(PassRegistry&);
>  void initializeDCELegacyPassPass(PassRegistry&);
> -void initializeDSEPass(PassRegistry&);
> +void initializeDSELegacyPassPass(PassRegistry&);
>  void initializeDeadInstEliminationPass(PassRegistry&);
>  void initializeDeadMachineInstructionElimPass(PassRegistry&);
>  void initializeDelinearizationPass(PassRegistry &);


More information about the llvm-commits mailing list