diff options
author | Arthur Eubanks <aeubanks@google.com> | 2020-11-09 11:40:49 -0800 |
---|---|---|
committer | Arthur Eubanks <aeubanks@google.com> | 2020-11-09 17:42:36 -0800 |
commit | 1cbf8e89b54de939420d53d7a528bec6fbaf0a55 (patch) | |
tree | 55099e5376ad1046c4817032539158b0d2c154d7 | |
parent | e5dba2d7e5a6ab8266954e13844355d795c8c88b (diff) | |
download | llvm-1cbf8e89b54de939420d53d7a528bec6fbaf0a55.zip llvm-1cbf8e89b54de939420d53d7a528bec6fbaf0a55.tar.gz llvm-1cbf8e89b54de939420d53d7a528bec6fbaf0a55.tar.bz2 |
[NewPM] Port -separate-const-offset-from-gep
Reviewed By: asbirlea
Differential Revision: https://reviews.llvm.org/D91095
-rw-r--r-- | llvm/include/llvm/InitializePasses.h | 2 | ||||
-rw-r--r-- | llvm/include/llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h | 27 | ||||
-rw-r--r-- | llvm/lib/Passes/PassBuilder.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Passes/PassRegistry.def | 1 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/Scalar.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp | 80 | ||||
-rw-r--r-- | llvm/test/Transforms/SeparateConstOffsetFromGEP/test-add-sub-separation.ll | 1 |
7 files changed, 92 insertions, 22 deletions
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 6f813f0..f749180 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -392,7 +392,7 @@ void initializeScalarizeMaskedMemIntrinPass(PassRegistry&); void initializeScalarizerLegacyPassPass(PassRegistry&); void initializeScavengerTestPass(PassRegistry&); void initializeScopedNoAliasAAWrapperPassPass(PassRegistry&); -void initializeSeparateConstOffsetFromGEPPass(PassRegistry&); +void initializeSeparateConstOffsetFromGEPLegacyPassPass(PassRegistry &); void initializeShadowStackGCLoweringPass(PassRegistry&); void initializeShrinkWrapPass(PassRegistry&); void initializeSimpleInlinerPass(PassRegistry&); diff --git a/llvm/include/llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h b/llvm/include/llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h new file mode 100644 index 0000000..5bd6ce1 --- /dev/null +++ b/llvm/include/llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h @@ -0,0 +1,27 @@ +//===- SeparateConstOffsetFromGEP.h ---------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_SCALAR_SEPARATECONSTOFFSETFROMGEP_H +#define LLVM_TRANSFORMS_SCALAR_SEPARATECONSTOFFSETFROMGEP_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { + +class SeparateConstOffsetFromGEPPass + : public PassInfoMixin<SeparateConstOffsetFromGEPPass> { + bool LowerGEP; + +public: + SeparateConstOffsetFromGEPPass(bool LowerGEP = false) : LowerGEP(LowerGEP) {} + PreservedAnalyses run(Function &F, FunctionAnalysisManager &); +}; + +} // end namespace llvm + +#endif // LLVM_TRANSFORMS_SCALAR_SEPARATECONSTOFFSETFROMGEP_H diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index a6496ab..e178b6e 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -189,6 +189,7 @@ #include "llvm/Transforms/Scalar/SCCP.h" #include "llvm/Transforms/Scalar/SROA.h" #include "llvm/Transforms/Scalar/Scalarizer.h" +#include "llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h" #include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h" #include "llvm/Transforms/Scalar/SimplifyCFG.h" #include "llvm/Transforms/Scalar/Sink.h" diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 2532119..9fe17d5 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -285,6 +285,7 @@ FUNCTION_PASS("print-mustexecute", MustExecutePrinterPass(dbgs())) FUNCTION_PASS("reassociate", ReassociatePass()) FUNCTION_PASS("reg2mem", RegToMemPass()) FUNCTION_PASS("scalarizer", ScalarizerPass()) +FUNCTION_PASS("separate-const-offset-from-gep", SeparateConstOffsetFromGEPPass()) FUNCTION_PASS("sccp", SCCPPass()) FUNCTION_PASS("simplifycfg", SimplifyCFGPass()) FUNCTION_PASS("sink", SinkingPass()) diff --git a/llvm/lib/Transforms/Scalar/Scalar.cpp b/llvm/lib/Transforms/Scalar/Scalar.cpp index b654562..2b6a73b 100644 --- a/llvm/lib/Transforms/Scalar/Scalar.cpp +++ b/llvm/lib/Transforms/Scalar/Scalar.cpp @@ -101,7 +101,7 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) { initializeSimpleLoopUnswitchLegacyPassPass(Registry); initializeSinkingLegacyPassPass(Registry); initializeTailCallElimPass(Registry); - initializeSeparateConstOffsetFromGEPPass(Registry); + initializeSeparateConstOffsetFromGEPLegacyPassPass(Registry); initializeSpeculativeExecutionLegacyPassPass(Registry); initializeStraightLineStrengthReduceLegacyPassPass(Registry); initializePlaceBackedgeSafepointsImplPass(Registry); diff --git a/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp b/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp index f1d2e3c..558bace 100644 --- a/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp +++ b/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp @@ -155,6 +155,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DepthFirstIterator.h" @@ -177,6 +178,7 @@ #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" #include "llvm/IR/PatternMatch.h" #include "llvm/IR/Type.h" #include "llvm/IR/User.h" @@ -342,13 +344,14 @@ private: /// A pass that tries to split every GEP in the function into a variadic /// base and a constant offset. It is a FunctionPass because searching for the /// constant offset may inspect other basic blocks. -class SeparateConstOffsetFromGEP : public FunctionPass { +class SeparateConstOffsetFromGEPLegacyPass : public FunctionPass { public: static char ID; - SeparateConstOffsetFromGEP(bool LowerGEP = false) + SeparateConstOffsetFromGEPLegacyPass(bool LowerGEP = false) : FunctionPass(ID), LowerGEP(LowerGEP) { - initializeSeparateConstOffsetFromGEPPass(*PassRegistry::getPassRegistry()); + initializeSeparateConstOffsetFromGEPLegacyPassPass( + *PassRegistry::getPassRegistry()); } void getAnalysisUsage(AnalysisUsage &AU) const override { @@ -360,14 +363,26 @@ public: AU.addRequired<TargetLibraryInfoWrapperPass>(); } - bool doInitialization(Module &M) override { - DL = &M.getDataLayout(); - return false; - } - bool runOnFunction(Function &F) override; private: + bool LowerGEP; +}; + +/// A pass that tries to split every GEP in the function into a variadic +/// base and a constant offset. It is a FunctionPass because searching for the +/// constant offset may inspect other basic blocks. +class SeparateConstOffsetFromGEP { +public: + SeparateConstOffsetFromGEP( + DominatorTree *DT, ScalarEvolution *SE, LoopInfo *LI, + TargetLibraryInfo *TLI, + function_ref<TargetTransformInfo &(Function &)> GetTTI, bool LowerGEP) + : DT(DT), SE(SE), LI(LI), TLI(TLI), GetTTI(GetTTI), LowerGEP(LowerGEP) {} + + bool run(Function &F); + +private: /// Tries to split the given GEP into a variadic base and a constant offset, /// and returns true if the splitting succeeds. bool splitGEP(GetElementPtrInst *GEP); @@ -450,9 +465,10 @@ private: const DataLayout *DL = nullptr; DominatorTree *DT = nullptr; ScalarEvolution *SE; - LoopInfo *LI; TargetLibraryInfo *TLI; + // Retrieved lazily since not always used. + function_ref<TargetTransformInfo &(Function &)> GetTTI; /// Whether to lower a GEP with multiple indices into arithmetic operations or /// multiple GEPs with a single index. @@ -464,10 +480,10 @@ private: } // end anonymous namespace -char SeparateConstOffsetFromGEP::ID = 0; +char SeparateConstOffsetFromGEPLegacyPass::ID = 0; INITIALIZE_PASS_BEGIN( - SeparateConstOffsetFromGEP, "separate-const-offset-from-gep", + SeparateConstOffsetFromGEPLegacyPass, "separate-const-offset-from-gep", "Split GEPs to a variadic base and a constant offset for better CSE", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) @@ -476,12 +492,12 @@ INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_END( - SeparateConstOffsetFromGEP, "separate-const-offset-from-gep", + SeparateConstOffsetFromGEPLegacyPass, "separate-const-offset-from-gep", "Split GEPs to a variadic base and a constant offset for better CSE", false, false) FunctionPass *llvm::createSeparateConstOffsetFromGEPPass(bool LowerGEP) { - return new SeparateConstOffsetFromGEP(LowerGEP); + return new SeparateConstOffsetFromGEPLegacyPass(LowerGEP); } bool ConstantOffsetExtractor::CanTraceInto(bool SignExtended, @@ -962,8 +978,7 @@ bool SeparateConstOffsetFromGEP::splitGEP(GetElementPtrInst *GEP) { if (!NeedsExtraction) return Changed; - TargetTransformInfo &TTI = - getAnalysis<TargetTransformInfoWrapperPass>().getTTI(*GEP->getFunction()); + TargetTransformInfo &TTI = GetTTI(*GEP->getFunction()); // If LowerGEP is disabled, before really splitting the GEP, check whether the // backend supports the addressing mode we are about to produce. If no, this @@ -1128,17 +1143,25 @@ bool SeparateConstOffsetFromGEP::splitGEP(GetElementPtrInst *GEP) { return true; } -bool SeparateConstOffsetFromGEP::runOnFunction(Function &F) { +bool SeparateConstOffsetFromGEPLegacyPass::runOnFunction(Function &F) { if (skipFunction(F)) return false; + auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); + auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE(); + auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); + auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F); + auto GetTTI = [this](Function &F) -> TargetTransformInfo & { + return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F); + }; + SeparateConstOffsetFromGEP Impl(DT, SE, LI, TLI, GetTTI, LowerGEP); + return Impl.run(F); +} +bool SeparateConstOffsetFromGEP::run(Function &F) { if (DisableSeparateConstOffsetFromGEP) return false; - DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); - SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE(); - LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); - TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F); + DL = &F.getParent()->getDataLayout(); bool Changed = false; for (BasicBlock &B : F) { for (BasicBlock::iterator I = B.begin(), IE = B.end(); I != IE;) @@ -1345,3 +1368,20 @@ void SeparateConstOffsetFromGEP::swapGEPOperand(GetElementPtrInst *First, } else First->setIsInBounds(true); } + +PreservedAnalyses +SeparateConstOffsetFromGEPPass::run(Function &F, FunctionAnalysisManager &AM) { + auto *DT = &AM.getResult<DominatorTreeAnalysis>(F); + auto *SE = &AM.getResult<ScalarEvolutionAnalysis>(F); + auto *LI = &AM.getResult<LoopAnalysis>(F); + auto *TLI = &AM.getResult<TargetLibraryAnalysis>(F); + auto GetTTI = [&AM](Function &F) -> TargetTransformInfo & { + return AM.getResult<TargetIRAnalysis>(F); + }; + SeparateConstOffsetFromGEP Impl(DT, SE, LI, TLI, GetTTI, LowerGEP); + if (!Impl.run(F)) + return PreservedAnalyses::all(); + PreservedAnalyses PA; + PA.preserveSet<CFGAnalyses>(); + return PA; +} diff --git a/llvm/test/Transforms/SeparateConstOffsetFromGEP/test-add-sub-separation.ll b/llvm/test/Transforms/SeparateConstOffsetFromGEP/test-add-sub-separation.ll index 5ece5be..72dca78 100644 --- a/llvm/test/Transforms/SeparateConstOffsetFromGEP/test-add-sub-separation.ll +++ b/llvm/test/Transforms/SeparateConstOffsetFromGEP/test-add-sub-separation.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -separate-const-offset-from-gep < %s | FileCheck %s +; RUN: opt -S -passes=separate-const-offset-from-gep < %s | FileCheck %s define void @matchingExtensions(i32* %ap, i32* %bp, i64* %result) { ; CHECK-LABEL: @matchingExtensions( |