Skip to content

Commit 5ab421f

Browse files
committed
[LICM] Add allowspeculation pass options.
This adds a new option to control AllowSpeculation added in D119965 when using `-passes=...`. This allows reproducing #54023 using opt. Reviewed By: aeubanks Differential Revision: https://reviews.llvm.org/D121944
1 parent 208b923 commit 5ab421f

File tree

6 files changed

+139
-31
lines changed

6 files changed

+139
-31
lines changed

llvm/include/llvm/Transforms/Scalar/LICM.h

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -45,44 +45,57 @@ class LoopNest;
4545
extern cl::opt<unsigned> SetLicmMssaOptCap;
4646
extern cl::opt<unsigned> SetLicmMssaNoAccForPromotionCap;
4747

48+
struct LICMOptions {
49+
unsigned MssaOptCap;
50+
unsigned MssaNoAccForPromotionCap;
51+
bool AllowSpeculation;
52+
53+
LICMOptions()
54+
: MssaOptCap(SetLicmMssaOptCap),
55+
MssaNoAccForPromotionCap(SetLicmMssaNoAccForPromotionCap),
56+
AllowSpeculation(true) {}
57+
58+
LICMOptions(unsigned MssaOptCap, unsigned MssaNoAccForPromotionCap,
59+
bool AllowSpeculation)
60+
: MssaOptCap(MssaOptCap),
61+
MssaNoAccForPromotionCap(MssaNoAccForPromotionCap),
62+
AllowSpeculation(AllowSpeculation) {}
63+
};
64+
4865
/// Performs Loop Invariant Code Motion Pass.
4966
class LICMPass : public PassInfoMixin<LICMPass> {
50-
unsigned LicmMssaOptCap;
51-
unsigned LicmMssaNoAccForPromotionCap;
52-
bool LicmAllowSpeculation;
67+
LICMOptions Opts;
5368

5469
public:
55-
LICMPass()
56-
: LicmMssaOptCap(SetLicmMssaOptCap),
57-
LicmMssaNoAccForPromotionCap(SetLicmMssaNoAccForPromotionCap),
58-
LicmAllowSpeculation(true) {}
59-
LICMPass(unsigned LicmMssaOptCap, unsigned LicmMssaNoAccForPromotionCap,
60-
bool LicmAllowSpeculation)
61-
: LicmMssaOptCap(LicmMssaOptCap),
62-
LicmMssaNoAccForPromotionCap(LicmMssaNoAccForPromotionCap),
63-
LicmAllowSpeculation(LicmAllowSpeculation) {}
70+
LICMPass(unsigned MssaOptCap, unsigned MssaNoAccForPromotionCap,
71+
bool AllowSpeculation)
72+
: LICMPass(LICMOptions(MssaOptCap, MssaNoAccForPromotionCap,
73+
AllowSpeculation)) {}
74+
LICMPass(LICMOptions Opts) : Opts(Opts) {}
75+
6476
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
6577
LoopStandardAnalysisResults &AR, LPMUpdater &U);
78+
79+
void printPipeline(raw_ostream &OS,
80+
function_ref<StringRef(StringRef)> MapClassName2PassName);
6681
};
6782

6883
/// Performs LoopNest Invariant Code Motion Pass.
6984
class LNICMPass : public PassInfoMixin<LNICMPass> {
70-
unsigned LicmMssaOptCap;
71-
unsigned LicmMssaNoAccForPromotionCap;
72-
bool LicmAllowSpeculation;
85+
LICMOptions Opts;
7386

7487
public:
75-
LNICMPass()
76-
: LicmMssaOptCap(SetLicmMssaOptCap),
77-
LicmMssaNoAccForPromotionCap(SetLicmMssaNoAccForPromotionCap),
78-
LicmAllowSpeculation(true) {}
79-
LNICMPass(unsigned LicmMssaOptCap, unsigned LicmMssaNoAccForPromotionCap,
80-
bool LicmAllowSpeculation)
81-
: LicmMssaOptCap(LicmMssaOptCap),
82-
LicmMssaNoAccForPromotionCap(LicmMssaNoAccForPromotionCap),
83-
LicmAllowSpeculation(LicmAllowSpeculation) {}
88+
LNICMPass(unsigned MssaOptCap, unsigned MssaNoAccForPromotionCap,
89+
bool AllowSpeculation)
90+
: LNICMPass(LICMOptions(MssaOptCap, MssaNoAccForPromotionCap,
91+
AllowSpeculation)) {}
92+
LNICMPass(LICMOptions Opts) : Opts(Opts) {}
93+
8494
PreservedAnalyses run(LoopNest &L, LoopAnalysisManager &AM,
8595
LoopStandardAnalysisResults &AR, LPMUpdater &U);
96+
97+
void printPipeline(raw_ostream &OS,
98+
function_ref<StringRef(StringRef)> MapClassName2PassName);
8699
};
87100
} // end namespace llvm
88101

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,24 @@ Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
752752
return Result;
753753
}
754754

755+
Expected<LICMOptions> parseLICMOptions(StringRef Params) {
756+
LICMOptions Result;
757+
while (!Params.empty()) {
758+
StringRef ParamName;
759+
std::tie(ParamName, Params) = Params.split(';');
760+
761+
bool Enable = !ParamName.consume_front("no-");
762+
if (ParamName == "allowspeculation") {
763+
Result.AllowSpeculation = Enable;
764+
} else {
765+
return make_error<StringError>(
766+
formatv("invalid LICM pass parameter '{0}' ", ParamName).str(),
767+
inconvertibleErrorCode());
768+
}
769+
}
770+
return Result;
771+
}
772+
755773
Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
756774
bool Result = false;
757775
while (!Params.empty()) {

llvm/lib/Passes/PassRegistry.def

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,6 @@ FUNCTION_PASS_WITH_PARAMS("print<stack-lifetime>",
463463
#ifndef LOOPNEST_PASS
464464
#define LOOPNEST_PASS(NAME, CREATE_PASS)
465465
#endif
466-
LOOPNEST_PASS("lnicm", LNICMPass())
467466
LOOPNEST_PASS("loop-flatten", LoopFlattenPass())
468467
LOOPNEST_PASS("loop-interchange", LoopInterchangePass())
469468
LOOPNEST_PASS("loop-unroll-and-jam", LoopUnrollAndJamPass())
@@ -486,7 +485,6 @@ LOOP_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC))
486485
LOOP_PASS("canon-freeze", CanonicalizeFreezeInLoopsPass())
487486
LOOP_PASS("dot-ddg", DDGDotPrinterPass())
488487
LOOP_PASS("invalidate<all>", InvalidateAllAnalysesPass())
489-
LOOP_PASS("licm", LICMPass())
490488
LOOP_PASS("loop-idiom", LoopIdiomRecognizePass())
491489
LOOP_PASS("loop-instsimplify", LoopInstSimplifyPass())
492490
LOOP_PASS("loop-rotate", LoopRotatePass())
@@ -519,4 +517,18 @@ LOOP_PASS_WITH_PARAMS("simple-loop-unswitch",
519517
},
520518
parseLoopUnswitchOptions,
521519
"nontrivial;no-nontrivial;trivial;no-trivial")
520+
521+
LOOP_PASS_WITH_PARAMS("licm", "LICMPass",
522+
[](LICMOptions Params) {
523+
return LICMPass(Params);
524+
},
525+
parseLICMOptions,
526+
"allowspeculation");
527+
528+
LOOP_PASS_WITH_PARAMS("lnicm", "LNICMPass",
529+
[](LICMOptions Params) {
530+
return LNICMPass(Params);
531+
},
532+
parseLICMOptions,
533+
"allowspeculation");
522534
#undef LOOP_PASS_WITH_PARAMS

llvm/lib/Transforms/Scalar/LICM.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,8 @@ PreservedAnalyses LICMPass::run(Loop &L, LoopAnalysisManager &AM,
270270
// but ORE cannot be preserved (see comment before the pass definition).
271271
OptimizationRemarkEmitter ORE(L.getHeader()->getParent());
272272

273-
LoopInvariantCodeMotion LICM(LicmMssaOptCap, LicmMssaNoAccForPromotionCap,
274-
LicmAllowSpeculation);
273+
LoopInvariantCodeMotion LICM(Opts.MssaOptCap, Opts.MssaNoAccForPromotionCap,
274+
Opts.AllowSpeculation);
275275
if (!LICM.runOnLoop(&L, &AR.AA, &AR.LI, &AR.DT, AR.BFI, &AR.TLI, &AR.TTI,
276276
&AR.SE, AR.MSSA, &ORE))
277277
return PreservedAnalyses::all();
@@ -285,6 +285,16 @@ PreservedAnalyses LICMPass::run(Loop &L, LoopAnalysisManager &AM,
285285
return PA;
286286
}
287287

288+
void LICMPass::printPipeline(
289+
raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
290+
static_cast<PassInfoMixin<LICMPass> *>(this)->printPipeline(
291+
OS, MapClassName2PassName);
292+
293+
OS << "<";
294+
OS << (Opts.AllowSpeculation ? "" : "no-") << "allowspeculation";
295+
OS << ">";
296+
}
297+
288298
PreservedAnalyses LNICMPass::run(LoopNest &LN, LoopAnalysisManager &AM,
289299
LoopStandardAnalysisResults &AR,
290300
LPMUpdater &) {
@@ -296,8 +306,8 @@ PreservedAnalyses LNICMPass::run(LoopNest &LN, LoopAnalysisManager &AM,
296306
// but ORE cannot be preserved (see comment before the pass definition).
297307
OptimizationRemarkEmitter ORE(LN.getParent());
298308

299-
LoopInvariantCodeMotion LICM(LicmMssaOptCap, LicmMssaNoAccForPromotionCap,
300-
LicmAllowSpeculation);
309+
LoopInvariantCodeMotion LICM(Opts.MssaOptCap, Opts.MssaNoAccForPromotionCap,
310+
Opts.AllowSpeculation);
301311

302312
Loop &OutermostLoop = LN.getOutermostLoop();
303313
bool Changed = LICM.runOnLoop(&OutermostLoop, &AR.AA, &AR.LI, &AR.DT, AR.BFI,
@@ -315,6 +325,16 @@ PreservedAnalyses LNICMPass::run(LoopNest &LN, LoopAnalysisManager &AM,
315325
return PA;
316326
}
317327

328+
void LNICMPass::printPipeline(
329+
raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
330+
static_cast<PassInfoMixin<LNICMPass> *>(this)->printPipeline(
331+
OS, MapClassName2PassName);
332+
333+
OS << "<";
334+
OS << (Opts.AllowSpeculation ? "" : "no-") << "allowspeculation";
335+
OS << ">";
336+
}
337+
318338
char LegacyLICMPass::ID = 0;
319339
INITIALIZE_PASS_BEGIN(LegacyLICMPass, "licm", "Loop Invariant Code Motion",
320340
false, false)

llvm/test/Other/new-pm-print-pipeline.ll

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,13 @@
6969

7070
;; Test that the loop-nest-pass lnicm is printed with the other loop-passes in the pipeline.
7171
; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(loop-mssa(licm,loop-rotate,loop-deletion,lnicm,loop-rotate))' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-23
72-
; CHECK-23: function(loop-mssa(licm,loop-rotate,loop-deletion,lnicm,loop-rotate))
72+
; CHECK-23: function(loop-mssa(licm<allowspeculation>,loop-rotate,loop-deletion,lnicm<allowspeculation>,loop-rotate))
7373

7474
;; Test that -debugify and -check-debugify is printed correctly.
7575
; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='debugify,no-op-function,check-debugify' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-24
7676
; RUN: opt -disable-output -disable-verify -print-pipeline-passes -enable-debugify -passes='no-op-function' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-24
7777
; CHECK-24: debugify,function(no-op-function),check-debugify
78+
79+
;; Test that LICM & LNICM with options.
80+
; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(loop-mssa(licm<allowspeculation>,licm<no-allowspeculation>,lnicm<allowspeculation>,lnicm<no-allowspeculation>))' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-25
81+
; CHECK-25: function(loop-mssa(licm<allowspeculation>,licm<no-allowspeculation>,lnicm<allowspeculation>,lnicm<no-allowspeculation>))
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; RUN: opt -passes='loop-mssa(licm<allowspeculation>)' -S %s | FileCheck --check-prefixes=COMMON,SPEC_ON %s
2+
; RUN: opt -passes='loop-mssa(licm<no-allowspeculation>)' -S %s | FileCheck --check-prefixes=COMMON,SPEC_OFF %s
3+
; RUN: opt -passes='loop-mssa(lnicm<allowspeculation>)' -S %s | FileCheck --check-prefixes=COMMON,SPEC_ON %s
4+
; RUN: opt -passes='loop-mssa(lnicm<no-allowspeculation>)' -S %s | FileCheck --check-prefixes=COMMON,SPEC_OFF %s
5+
6+
define void @test([10 x i32]* %ptr, i32 %N) {
7+
; COMMON-LABEL: @test(
8+
; COMMON-NEXT: entry:
9+
; SPEC_ON-NEXT: [[GEP:%.*]] = getelementptr [10 x i32], [10 x i32]* [[PTR:%.*]], i32 0, i32 0
10+
; COMMON-NEXT: br label [[LOOP_HEADER:%.*]]
11+
; COMMON: loop.header:
12+
; COMMON-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
13+
; COMMON-NEXT: [[CMP:%.*]] = icmp ult i32 [[IV]], [[N:%.*]]
14+
; COMMON-NEXT: br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT:%.*]]
15+
; COMMON: loop.latch:
16+
; SPEC_OFF-NEXT: [[GEP:%.*]] = getelementptr [10 x i32], [10 x i32]* [[PTR:%.*]], i32 0, i32 0
17+
; COMMON-NEXT: [[GEP_IV:%.*]] = getelementptr i32, i32* [[GEP]], i32 [[IV]]
18+
; COMMON-NEXT: store i32 9999, i32* [[GEP_IV]], align 4
19+
; COMMON-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
20+
; COMMON-NEXT: br label [[LOOP_HEADER]]
21+
; COMMON: exit:
22+
; COMMON-NEXT: ret void
23+
;
24+
entry:
25+
br label %loop.header
26+
27+
loop.header:
28+
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
29+
%cmp = icmp ult i32 %iv, %N
30+
br i1 %cmp, label %loop.latch, label %exit
31+
32+
loop.latch:
33+
%gep = getelementptr [10 x i32], [10 x i32]* %ptr, i32 0, i32 0
34+
%gep.iv = getelementptr i32, i32* %gep, i32 %iv
35+
store i32 9999, i32* %gep.iv
36+
%iv.next = add i32 %iv, 1
37+
br label %loop.header
38+
39+
exit:
40+
ret void
41+
}

0 commit comments

Comments
 (0)