summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavide Italiano <davide@freebsd.org>2016-07-07 21:14:36 +0000
committerDavide Italiano <davide@freebsd.org>2016-07-07 21:14:36 +0000
commit16284df8ec5f2acc79a2579716caad02a19e4bfb (patch)
treec4c59c2040480a8035fac604d46a2d5ef8b85e08
parent6a78c78a03d8426afc6b5203813ec4b11d9e8df2 (diff)
downloadbcm5719-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.h31
-rw-r--r--llvm/lib/Passes/PassBuilder.cpp1
-rw-r--r--llvm/lib/Passes/PassRegistry.def1
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyInstructions.cpp106
-rw-r--r--llvm/test/Transforms/InstSimplify/call.ll1
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)
OpenPOWER on IntegriCloud