[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