diff options
author | Davide Italiano <davide@freebsd.org> | 2016-07-07 21:14:36 +0000 |
---|---|---|
committer | Davide Italiano <davide@freebsd.org> | 2016-07-07 21:14:36 +0000 |
commit | 16284df8ec5f2acc79a2579716caad02a19e4bfb (patch) | |
tree | c4c59c2040480a8035fac604d46a2d5ef8b85e08 | |
parent | 6a78c78a03d8426afc6b5203813ec4b11d9e8df2 (diff) | |
download | bcm5719-llvm-16284df8ec5f2acc79a2579716caad02a19e4bfb.tar.gz bcm5719-llvm-16284df8ec5f2acc79a2579716caad02a19e4bfb.zip |
[PM] Port InstSimplify to the new pass manager.
llvm-svn: 274796
-rw-r--r-- | llvm/include/llvm/Transforms/Utils/SimplifyInstructions.h | 31 | ||||
-rw-r--r-- | llvm/lib/Passes/PassBuilder.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Passes/PassRegistry.def | 1 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyInstructions.cpp | 106 | ||||
-rw-r--r-- | llvm/test/Transforms/InstSimplify/call.ll | 1 |
5 files changed, 96 insertions, 44 deletions
diff --git a/llvm/include/llvm/Transforms/Utils/SimplifyInstructions.h b/llvm/include/llvm/Transforms/Utils/SimplifyInstructions.h new file mode 100644 index 00000000000..ea491dc5058 --- /dev/null +++ b/llvm/include/llvm/Transforms/Utils/SimplifyInstructions.h @@ -0,0 +1,31 @@ +//===- SimplifyInstructions.h - Remove redundant instructions ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is a utility pass used for testing the InstructionSimplify analysis. +// The analysis is applied to every instruction, and if it simplifies then the +// instruction is replaced by the simplification. If you are looking for a pass +// that performs serious instruction folding, use the instcombine pass instead. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYINSTRUCTIONS_H +#define LLVM_TRANSFORMS_UTILS_SIMPLIFYINSTRUCTIONS_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { + +/// This pass removes redundant instructions. +class InstSimplifierPass : public PassInfoMixin<InstSimplifierPass> { +public: + PreservedAnalyses run(Function &F, AnalysisManager<Function> &AM); +}; +} // end namespace llvm + +#endif // LLVM_TRANSFORMS_UTILS_SIMPLIFYINSTRUCTIONS_H diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 58bd55b92f9..bed602325e9 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -103,6 +103,7 @@ #include "llvm/Transforms/Utils/LCSSA.h" #include "llvm/Transforms/Utils/Mem2Reg.h" #include "llvm/Transforms/Utils/MemorySSA.h" +#include "llvm/Transforms/Utils/SimplifyInstructions.h" #include <type_traits> diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index a970ef466d7..3bc73771f89 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -132,6 +132,7 @@ FUNCTION_PASS("dce", DCEPass()) FUNCTION_PASS("dse", DSEPass()) FUNCTION_PASS("early-cse", EarlyCSEPass()) FUNCTION_PASS("instcombine", InstCombinePass()) +FUNCTION_PASS("instsimplify", InstSimplifierPass()) FUNCTION_PASS("invalidate<all>", InvalidateAllAnalysesPass()) FUNCTION_PASS("float2int", Float2IntPass()) FUNCTION_PASS("no-op-function", NoOpFunctionPass()) diff --git a/llvm/lib/Transforms/Utils/SimplifyInstructions.cpp b/llvm/lib/Transforms/Utils/SimplifyInstructions.cpp index edba5d2656e..df299067094 100644 --- a/llvm/lib/Transforms/Utils/SimplifyInstructions.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyInstructions.cpp @@ -14,7 +14,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/SimplifyInstructions.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" @@ -27,12 +27,60 @@ #include "llvm/IR/Type.h" #include "llvm/Pass.h" #include "llvm/Transforms/Utils/Local.h" +#include "llvm/Transforms/Scalar.h" using namespace llvm; #define DEBUG_TYPE "instsimplify" STATISTIC(NumSimplified, "Number of redundant instructions removed"); +static bool runImpl(Function &F, const DominatorTree *DT, const TargetLibraryInfo *TLI, + AssumptionCache *AC) { + const DataLayout &DL = F.getParent()->getDataLayout(); + SmallPtrSet<const Instruction*, 8> S1, S2, *ToSimplify = &S1, *Next = &S2; + bool Changed = false; + + do { + for (BasicBlock *BB : depth_first(&F.getEntryBlock())) + // Here be subtlety: the iterator must be incremented before the loop + // body (not sure why), so a range-for loop won't work here. + for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { + Instruction *I = &*BI++; + // The first time through the loop ToSimplify is empty and we try to + // simplify all instructions. On later iterations ToSimplify is not + // empty and we only bother simplifying instructions that are in it. + if (!ToSimplify->empty() && !ToSimplify->count(I)) + continue; + // Don't waste time simplifying unused instructions. + if (!I->use_empty()) + if (Value *V = SimplifyInstruction(I, DL, TLI, DT, AC)) { + // Mark all uses for resimplification next time round the loop. + for (User *U : I->users()) + Next->insert(cast<Instruction>(U)); + I->replaceAllUsesWith(V); + ++NumSimplified; + Changed = true; + } + bool res = RecursivelyDeleteTriviallyDeadInstructions(I, TLI); + if (res) { + // RecursivelyDeleteTriviallyDeadInstruction can remove + // more than one instruction, so simply incrementing the + // iterator does not work. When instructions get deleted + // re-iterate instead. + BI = BB->begin(); BE = BB->end(); + Changed |= res; + } + } + + // Place the list of instructions to simplify on the next loop iteration + // into ToSimplify. + std::swap(ToSimplify, Next); + Next->clear(); + } while (!ToSimplify->empty()); + + return Changed; +} + namespace { struct InstSimplifier : public FunctionPass { static char ID; // Pass identification, replacement for typeid @@ -54,53 +102,11 @@ namespace { const DominatorTreeWrapperPass *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>(); const DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr; - const DataLayout &DL = F.getParent()->getDataLayout(); const TargetLibraryInfo *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); AssumptionCache *AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F); - SmallPtrSet<const Instruction*, 8> S1, S2, *ToSimplify = &S1, *Next = &S2; - bool Changed = false; - - do { - for (BasicBlock *BB : depth_first(&F.getEntryBlock())) - // Here be subtlety: the iterator must be incremented before the loop - // body (not sure why), so a range-for loop won't work here. - for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { - Instruction *I = &*BI++; - // The first time through the loop ToSimplify is empty and we try to - // simplify all instructions. On later iterations ToSimplify is not - // empty and we only bother simplifying instructions that are in it. - if (!ToSimplify->empty() && !ToSimplify->count(I)) - continue; - // Don't waste time simplifying unused instructions. - if (!I->use_empty()) - if (Value *V = SimplifyInstruction(I, DL, TLI, DT, AC)) { - // Mark all uses for resimplification next time round the loop. - for (User *U : I->users()) - Next->insert(cast<Instruction>(U)); - I->replaceAllUsesWith(V); - ++NumSimplified; - Changed = true; - } - bool res = RecursivelyDeleteTriviallyDeadInstructions(I, TLI); - if (res) { - // RecursivelyDeleteTriviallyDeadInstruction can remove - // more than one instruction, so simply incrementing the - // iterator does not work. When instructions get deleted - // re-iterate instead. - BI = BB->begin(); BE = BB->end(); - Changed |= res; - } - } - - // Place the list of instructions to simplify on the next loop iteration - // into ToSimplify. - std::swap(ToSimplify, Next); - Next->clear(); - } while (!ToSimplify->empty()); - - return Changed; + return runImpl(F, DT, TLI, AC); } }; } @@ -118,3 +124,15 @@ char &llvm::InstructionSimplifierID = InstSimplifier::ID; FunctionPass *llvm::createInstructionSimplifierPass() { return new InstSimplifier(); } + +PreservedAnalyses InstSimplifierPass::run(Function &F, + AnalysisManager<Function> &AM) { + auto *DT = AM.getCachedResult<DominatorTreeAnalysis>(F); + auto &TLI = AM.getResult<TargetLibraryAnalysis>(F); + auto &AC = AM.getResult<AssumptionAnalysis>(F); + bool Changed = runImpl(F, DT, &TLI, &AC); + if (!Changed) + return PreservedAnalyses::all(); + // FIXME: This should also 'preserve the CFG'. + return PreservedAnalyses::none(); +} diff --git a/llvm/test/Transforms/InstSimplify/call.ll b/llvm/test/Transforms/InstSimplify/call.ll index 814f1f21aca..244ce81d5ba 100644 --- a/llvm/test/Transforms/InstSimplify/call.ll +++ b/llvm/test/Transforms/InstSimplify/call.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -instsimplify -S | FileCheck %s +; RUN: opt < %s -passes=instsimplify -S | FileCheck %s declare {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a, i8 %b) declare {i8, i1} @llvm.usub.with.overflow.i8(i8 %a, i8 %b) |