155155//
156156// ===----------------------------------------------------------------------===//
157157
158+ #include " llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h"
158159#include " llvm/ADT/APInt.h"
159160#include " llvm/ADT/DenseMap.h"
160161#include " llvm/ADT/DepthFirstIterator.h"
177178#include " llvm/IR/Instruction.h"
178179#include " llvm/IR/Instructions.h"
179180#include " llvm/IR/Module.h"
181+ #include " llvm/IR/PassManager.h"
180182#include " llvm/IR/PatternMatch.h"
181183#include " llvm/IR/Type.h"
182184#include " llvm/IR/User.h"
@@ -342,13 +344,14 @@ class ConstantOffsetExtractor {
342344// / A pass that tries to split every GEP in the function into a variadic
343345// / base and a constant offset. It is a FunctionPass because searching for the
344346// / constant offset may inspect other basic blocks.
345- class SeparateConstOffsetFromGEP : public FunctionPass {
347+ class SeparateConstOffsetFromGEPLegacyPass : public FunctionPass {
346348public:
347349 static char ID;
348350
349- SeparateConstOffsetFromGEP (bool LowerGEP = false )
351+ SeparateConstOffsetFromGEPLegacyPass (bool LowerGEP = false )
350352 : FunctionPass(ID), LowerGEP(LowerGEP) {
351- initializeSeparateConstOffsetFromGEPPass (*PassRegistry::getPassRegistry ());
353+ initializeSeparateConstOffsetFromGEPLegacyPassPass (
354+ *PassRegistry::getPassRegistry ());
352355 }
353356
354357 void getAnalysisUsage (AnalysisUsage &AU) const override {
@@ -360,13 +363,25 @@ class SeparateConstOffsetFromGEP : public FunctionPass {
360363 AU.addRequired <TargetLibraryInfoWrapperPass>();
361364 }
362365
363- bool doInitialization (Module &M) override {
364- DL = &M.getDataLayout ();
365- return false ;
366- }
367-
368366 bool runOnFunction (Function &F) override ;
369367
368+ private:
369+ bool LowerGEP;
370+ };
371+
372+ // / A pass that tries to split every GEP in the function into a variadic
373+ // / base and a constant offset. It is a FunctionPass because searching for the
374+ // / constant offset may inspect other basic blocks.
375+ class SeparateConstOffsetFromGEP {
376+ public:
377+ SeparateConstOffsetFromGEP (
378+ DominatorTree *DT, ScalarEvolution *SE, LoopInfo *LI,
379+ TargetLibraryInfo *TLI,
380+ function_ref<TargetTransformInfo &(Function &)> GetTTI, bool LowerGEP)
381+ : DT(DT), SE(SE), LI(LI), TLI(TLI), GetTTI(GetTTI), LowerGEP(LowerGEP) {}
382+
383+ bool run (Function &F);
384+
370385private:
371386 // / Tries to split the given GEP into a variadic base and a constant offset,
372387 // / and returns true if the splitting succeeds.
@@ -450,9 +465,10 @@ class SeparateConstOffsetFromGEP : public FunctionPass {
450465 const DataLayout *DL = nullptr ;
451466 DominatorTree *DT = nullptr ;
452467 ScalarEvolution *SE;
453-
454468 LoopInfo *LI;
455469 TargetLibraryInfo *TLI;
470+ // Retrieved lazily since not always used.
471+ function_ref<TargetTransformInfo &(Function &)> GetTTI;
456472
457473 // / Whether to lower a GEP with multiple indices into arithmetic operations or
458474 // / multiple GEPs with a single index.
@@ -464,10 +480,10 @@ class SeparateConstOffsetFromGEP : public FunctionPass {
464480
465481} // end anonymous namespace
466482
467- char SeparateConstOffsetFromGEP ::ID = 0 ;
483+ char SeparateConstOffsetFromGEPLegacyPass ::ID = 0 ;
468484
469485INITIALIZE_PASS_BEGIN (
470- SeparateConstOffsetFromGEP , " separate-const-offset-from-gep" ,
486+ SeparateConstOffsetFromGEPLegacyPass , " separate-const-offset-from-gep" ,
471487 " Split GEPs to a variadic base and a constant offset for better CSE" , false ,
472488 false )
473489INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
@@ -476,12 +492,12 @@ INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
476492INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
477493INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
478494INITIALIZE_PASS_END(
479- SeparateConstOffsetFromGEP , " separate-const-offset-from-gep" ,
495+ SeparateConstOffsetFromGEPLegacyPass , " separate-const-offset-from-gep" ,
480496 " Split GEPs to a variadic base and a constant offset for better CSE" , false ,
481497 false )
482498
483499FunctionPass *llvm::createSeparateConstOffsetFromGEPPass(bool LowerGEP) {
484- return new SeparateConstOffsetFromGEP (LowerGEP);
500+ return new SeparateConstOffsetFromGEPLegacyPass (LowerGEP);
485501}
486502
487503bool ConstantOffsetExtractor::CanTraceInto (bool SignExtended,
@@ -962,8 +978,7 @@ bool SeparateConstOffsetFromGEP::splitGEP(GetElementPtrInst *GEP) {
962978 if (!NeedsExtraction)
963979 return Changed;
964980
965- TargetTransformInfo &TTI =
966- getAnalysis<TargetTransformInfoWrapperPass>().getTTI (*GEP->getFunction ());
981+ TargetTransformInfo &TTI = GetTTI (*GEP->getFunction ());
967982
968983 // If LowerGEP is disabled, before really splitting the GEP, check whether the
969984 // backend supports the addressing mode we are about to produce. If no, this
@@ -1128,17 +1143,25 @@ bool SeparateConstOffsetFromGEP::splitGEP(GetElementPtrInst *GEP) {
11281143 return true ;
11291144}
11301145
1131- bool SeparateConstOffsetFromGEP ::runOnFunction (Function &F) {
1146+ bool SeparateConstOffsetFromGEPLegacyPass ::runOnFunction (Function &F) {
11321147 if (skipFunction (F))
11331148 return false ;
1149+ auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree ();
1150+ auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE ();
1151+ auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo ();
1152+ auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI (F);
1153+ auto GetTTI = [this ](Function &F) -> TargetTransformInfo & {
1154+ return this ->getAnalysis <TargetTransformInfoWrapperPass>().getTTI (F);
1155+ };
1156+ SeparateConstOffsetFromGEP Impl (DT, SE, LI, TLI, GetTTI, LowerGEP);
1157+ return Impl.run (F);
1158+ }
11341159
1160+ bool SeparateConstOffsetFromGEP::run (Function &F) {
11351161 if (DisableSeparateConstOffsetFromGEP)
11361162 return false ;
11371163
1138- DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree ();
1139- SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE ();
1140- LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo ();
1141- TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI (F);
1164+ DL = &F.getParent ()->getDataLayout ();
11421165 bool Changed = false ;
11431166 for (BasicBlock &B : F) {
11441167 for (BasicBlock::iterator I = B.begin (), IE = B.end (); I != IE;)
@@ -1345,3 +1368,20 @@ void SeparateConstOffsetFromGEP::swapGEPOperand(GetElementPtrInst *First,
13451368 } else
13461369 First->setIsInBounds (true );
13471370}
1371+
1372+ PreservedAnalyses
1373+ SeparateConstOffsetFromGEPPass::run (Function &F, FunctionAnalysisManager &AM) {
1374+ auto *DT = &AM.getResult <DominatorTreeAnalysis>(F);
1375+ auto *SE = &AM.getResult <ScalarEvolutionAnalysis>(F);
1376+ auto *LI = &AM.getResult <LoopAnalysis>(F);
1377+ auto *TLI = &AM.getResult <TargetLibraryAnalysis>(F);
1378+ auto GetTTI = [&AM](Function &F) -> TargetTransformInfo & {
1379+ return AM.getResult <TargetIRAnalysis>(F);
1380+ };
1381+ SeparateConstOffsetFromGEP Impl (DT, SE, LI, TLI, GetTTI, LowerGEP);
1382+ if (!Impl.run (F))
1383+ return PreservedAnalyses::all ();
1384+ PreservedAnalyses PA;
1385+ PA.preserveSet <CFGAnalyses>();
1386+ return PA;
1387+ }
0 commit comments