From 80c55f265d1a68b7f03845a3e9356447f7d258c8 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sun, 1 Feb 2015 10:51:23 +0000 Subject: [PATCH] [PM] Port EarlyCSE to the new pass manager. I've added RUN lines both to the basic test for EarlyCSE and the target-specific test, as this serves as a nice test that the TTI layer in the new pass manager is in fact working well. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227725 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Transforms/Scalar/EarlyCSE.h | 45 +++++++++++++++++++ lib/Transforms/Scalar/EarlyCSE.cpp | 24 +++++++++- .../Transforms/EarlyCSE/AArch64/intrinsics.ll | 1 + test/Transforms/EarlyCSE/basic.ll | 1 + tools/opt/PassRegistry.def | 1 + tools/opt/Passes.cpp | 1 + 6 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 include/llvm/Transforms/Scalar/EarlyCSE.h diff --git a/include/llvm/Transforms/Scalar/EarlyCSE.h b/include/llvm/Transforms/Scalar/EarlyCSE.h new file mode 100644 index 00000000000..0d277c7a885 --- /dev/null +++ b/include/llvm/Transforms/Scalar/EarlyCSE.h @@ -0,0 +1,45 @@ +//===- EarlyCSE.h - Simple and fast CSE pass --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file provides the interface for a simple, fast CSE pass. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_SCALAR_EARLYCSE_H +#define LLVM_TRANSFORMS_SCALAR_EARLYCSE_H + +#include "llvm/IR/Function.h" +#include "llvm/IR/PassManager.h" + +namespace llvm { + +/// \brief A simple and fast domtree-based CSE pass. +/// +/// This pass does a simple depth-first walk over the dominator tree, +/// eliminating trivially redundant instructions and using instsimplify to +/// canonicalize things as it goes. It is intended to be fast and catch obvious +/// cases so that instcombine and other passes are more effective. It is +/// expected that a later pass of GVN will catch the interesting/hard cases. +class EarlyCSEPass { +public: + static StringRef name() { return "EarlyCSEPass"; } + + /// \brief Run the pass over the function. + /// + /// This will lower all of th expect intrinsic calls in this function into + /// branch weight metadata. That metadata will subsequently feed the analysis + /// of the probabilities and frequencies of the CFG. After running this pass, + /// no more expect intrinsics remain, allowing the rest of the optimizer to + /// ignore them. + PreservedAnalyses run(Function &F, AnalysisManager *AM); +}; + +} + +#endif diff --git a/lib/Transforms/Scalar/EarlyCSE.cpp b/lib/Transforms/Scalar/EarlyCSE.cpp index 11e347f708a..5daac84aa3e 100644 --- a/lib/Transforms/Scalar/EarlyCSE.cpp +++ b/lib/Transforms/Scalar/EarlyCSE.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Scalar/EarlyCSE.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/ScopedHashTable.h" #include "llvm/ADT/Statistic.h" @@ -28,6 +28,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/RecyclingAllocator.h" #include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Local.h" #include using namespace llvm; @@ -689,6 +690,27 @@ bool EarlyCSE::run() { return Changed; } +PreservedAnalyses EarlyCSEPass::run(Function &F, + AnalysisManager *AM) { + const DataLayout *DL = F.getParent()->getDataLayout(); + + auto &TLI = AM->getResult(F); + auto &TTI = AM->getResult(F); + auto &DT = AM->getResult(F); + auto &AC = AM->getResult(F); + + EarlyCSE CSE(F, DL, TLI, TTI, DT, AC); + + if (!CSE.run()) + return PreservedAnalyses::all(); + + // CSE preserves the dominator tree because it doesn't mutate the CFG. + // FIXME: Bundle this with other CFG-preservation. + PreservedAnalyses PA; + PA.preserve(); + return PA; +} + namespace { /// \brief A simple and fast domtree-based CSE pass. /// diff --git a/test/Transforms/EarlyCSE/AArch64/intrinsics.ll b/test/Transforms/EarlyCSE/AArch64/intrinsics.ll index d827fc9d603..d166ff1e109 100644 --- a/test/Transforms/EarlyCSE/AArch64/intrinsics.ll +++ b/test/Transforms/EarlyCSE/AArch64/intrinsics.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -S -mtriple=aarch64-none-linux-gnu -mattr=+neon -early-cse | FileCheck %s +; RUN: opt < %s -S -mtriple=aarch64-none-linux-gnu -mattr=+neon -passes=early-cse | FileCheck %s define <4 x i32> @test_cse(i32* %a, [2 x <4 x i32>] %s.coerce, i32 %n) { entry: diff --git a/test/Transforms/EarlyCSE/basic.ll b/test/Transforms/EarlyCSE/basic.ll index 155d36f60e2..dee428cc28f 100644 --- a/test/Transforms/EarlyCSE/basic.ll +++ b/test/Transforms/EarlyCSE/basic.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -S -early-cse | FileCheck %s +; RUN: opt < %s -S -passes=early-cse | FileCheck %s declare void @llvm.assume(i1) nounwind diff --git a/tools/opt/PassRegistry.def b/tools/opt/PassRegistry.def index 4ee9e97158e..db1c25f4856 100644 --- a/tools/opt/PassRegistry.def +++ b/tools/opt/PassRegistry.def @@ -62,6 +62,7 @@ FUNCTION_ANALYSIS("targetir", #ifndef FUNCTION_PASS #define FUNCTION_PASS(NAME, CREATE_PASS) #endif +FUNCTION_PASS("early-cse", EarlyCSEPass()) FUNCTION_PASS("instcombine", InstCombinePass()) FUNCTION_PASS("invalidate", InvalidateAllAnalysesPass()) FUNCTION_PASS("no-op-function", NoOpFunctionPass()) diff --git a/tools/opt/Passes.cpp b/tools/opt/Passes.cpp index b098a7c2351..357cf41d076 100644 --- a/tools/opt/Passes.cpp +++ b/tools/opt/Passes.cpp @@ -28,6 +28,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/InstCombine/InstCombine.h" +#include "llvm/Transforms/Scalar/EarlyCSE.h" #include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h" using namespace llvm;