Sitelet https://web.archive.org/web/20260424103154/https://github.com/llvm/llvm-project/commit/1cbf8e89b54d
Skip to content

Commit 1cbf8e8

Browse files
committed
[NewPM] Port -separate-const-offset-from-gep
Reviewed By: asbirlea Differential Revision: https://reviews.llvm.org/D91095
1 parent e5dba2d commit 1cbf8e8

7 files changed

Lines changed: 92 additions & 22 deletions

File tree

‎llvm/include/llvm/InitializePasses.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ void initializeScalarizeMaskedMemIntrinPass(PassRegistry&);
392392
void initializeScalarizerLegacyPassPass(PassRegistry&);
393393
void initializeScavengerTestPass(PassRegistry&);
394394
void initializeScopedNoAliasAAWrapperPassPass(PassRegistry&);
395-
void initializeSeparateConstOffsetFromGEPPass(PassRegistry&);
395+
void initializeSeparateConstOffsetFromGEPLegacyPassPass(PassRegistry &);
396396
void initializeShadowStackGCLoweringPass(PassRegistry&);
397397
void initializeShrinkWrapPass(PassRegistry&);
398398
void initializeSimpleInlinerPass(PassRegistry&);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===- SeparateConstOffsetFromGEP.h ---------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_TRANSFORMS_SCALAR_SEPARATECONSTOFFSETFROMGEP_H
10+
#define LLVM_TRANSFORMS_SCALAR_SEPARATECONSTOFFSETFROMGEP_H
11+
12+
#include "llvm/IR/PassManager.h"
13+
14+
namespace llvm {
15+
16+
class SeparateConstOffsetFromGEPPass
17+
: public PassInfoMixin<SeparateConstOffsetFromGEPPass> {
18+
bool LowerGEP;
19+
20+
public:
21+
SeparateConstOffsetFromGEPPass(bool LowerGEP = false) : LowerGEP(LowerGEP) {}
22+
PreservedAnalyses run(Function &F, FunctionAnalysisManager &);
23+
};
24+
25+
} // end namespace llvm
26+
27+
#endif // LLVM_TRANSFORMS_SCALAR_SEPARATECONSTOFFSETFROMGEP_H

‎llvm/lib/Passes/PassBuilder.cpp‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@
189189
#include "llvm/Transforms/Scalar/SCCP.h"
190190
#include "llvm/Transforms/Scalar/SROA.h"
191191
#include "llvm/Transforms/Scalar/Scalarizer.h"
192+
#include "llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h"
192193
#include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h"
193194
#include "llvm/Transforms/Scalar/SimplifyCFG.h"
194195
#include "llvm/Transforms/Scalar/Sink.h"

‎llvm/lib/Passes/PassRegistry.def‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ FUNCTION_PASS("print-mustexecute", MustExecutePrinterPass(dbgs()))
285285
FUNCTION_PASS("reassociate", ReassociatePass())
286286
FUNCTION_PASS("reg2mem", RegToMemPass())
287287
FUNCTION_PASS("scalarizer", ScalarizerPass())
288+
FUNCTION_PASS("separate-const-offset-from-gep", SeparateConstOffsetFromGEPPass())
288289
FUNCTION_PASS("sccp", SCCPPass())
289290
FUNCTION_PASS("simplifycfg", SimplifyCFGPass())
290291
FUNCTION_PASS("sink", SinkingPass())

‎llvm/lib/Transforms/Scalar/Scalar.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) {
101101
initializeSimpleLoopUnswitchLegacyPassPass(Registry);
102102
initializeSinkingLegacyPassPass(Registry);
103103
initializeTailCallElimPass(Registry);
104-
initializeSeparateConstOffsetFromGEPPass(Registry);
104+
initializeSeparateConstOffsetFromGEPLegacyPassPass(Registry);
105105
initializeSpeculativeExecutionLegacyPassPass(Registry);
106106
initializeStraightLineStrengthReduceLegacyPassPass(Registry);
107107
initializePlaceBackedgeSafepointsImplPass(Registry);

‎llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp‎

Lines changed: 60 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@
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"
@@ -177,6 +178,7 @@
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 {
346348
public:
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+
370385
private:
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

469485
INITIALIZE_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)
473489
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
@@ -476,12 +492,12 @@ INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
476492
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
477493
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
478494
INITIALIZE_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

483499
FunctionPass *llvm::createSeparateConstOffsetFromGEPPass(bool LowerGEP) {
484-
return new SeparateConstOffsetFromGEP(LowerGEP);
500+
return new SeparateConstOffsetFromGEPLegacyPass(LowerGEP);
485501
}
486502

487503
bool 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+
}

‎llvm/test/Transforms/SeparateConstOffsetFromGEP/test-add-sub-separation.ll‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
22
; RUN: opt -S -separate-const-offset-from-gep < %s | FileCheck %s
3+
; RUN: opt -S -passes=separate-const-offset-from-gep < %s | FileCheck %s
34

45
define void @matchingExtensions(i32* %ap, i32* %bp, i64* %result) {
56
; CHECK-LABEL: @matchingExtensions(

0 commit comments

Comments
 (0)