From e8c686aa867eafa9c6e5639c515228dcb65fe807 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. llvm-svn: 227725 --- llvm/include/llvm/Transforms/Scalar/EarlyCSE.h | 45 ++++++++++++++++++++++ llvm/lib/Transforms/Scalar/EarlyCSE.cpp | 24 +++++++++++- .../test/Transforms/EarlyCSE/AArch64/intrinsics.ll | 1 + llvm/test/Transforms/EarlyCSE/basic.ll | 1 + llvm/tools/opt/PassRegistry.def | 1 + llvm/tools/opt/Passes.cpp | 1 + 6 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 llvm/include/llvm/Transforms/Scalar/EarlyCSE.h diff --git a/llvm/include/llvm/Transforms/Scalar/EarlyCSE.h b/llvm/include/llvm/Transforms/Scalar/EarlyCSE.h new file mode 100644 index 0000000..0d277c7 --- /dev/null +++ b/llvm/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/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp index 11e347f..5daac84 100644 --- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp +++ b/llvm/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/llvm/test/Transforms/EarlyCSE/AArch64/intrinsics.ll b/llvm/test/Transforms/EarlyCSE/AArch64/intrinsics.ll index d827fc9..d166ff1 100644 --- a/llvm/test/Transforms/EarlyCSE/AArch64/intrinsics.ll +++ b/llvm/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/llvm/test/Transforms/EarlyCSE/basic.ll b/llvm/test/Transforms/EarlyCSE/basic.ll index 155d36f..dee428c 100644 --- a/llvm/test/Transforms/EarlyCSE/basic.ll +++ b/llvm/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/llvm/tools/opt/PassRegistry.def b/llvm/tools/opt/PassRegistry.def index 4ee9e97..db1c25f 100644 --- a/llvm/tools/opt/PassRegistry.def +++ b/llvm/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/llvm/tools/opt/Passes.cpp b/llvm/tools/opt/Passes.cpp index b098a7c..357cf41 100644 --- a/llvm/tools/opt/Passes.cpp +++ b/llvm/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; -- 2.7.4