Skip to content

Commit 4ecc6af

Browse files
committed
[InstCombine] create a pass options container and add "use-loop-info" argument
This is a cleanup/modernization patch requested in D144045 to make loop analysis a proper optional parameter to the pass rather than a semi-arbitrary value inherited via the pass pipeline. It's a bit more complicated than the recent patch I started copying from (D143980) because InstCombine already has an option for MaxIterations (added with D71145). I debated just deleting that option, but it was used by a pair of existing tests, so I put it into a struct (code largely copied from SimplifyCFG's implementation) to make the code more flexible for future options enhancements. I didn't alter the pass manager invocations of InstCombine in this patch because the patch was already getting big, but that will be a small follow-up as noted with the TODO comment. Differential Revision: https://reviews.llvm.org/D144199
1 parent e03d254 commit 4ecc6af

File tree

8 files changed

+85
-18
lines changed

8 files changed

+85
-18
lines changed

llvm/include/llvm/Transforms/InstCombine/InstCombine.h

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,35 @@
2525

2626
namespace llvm {
2727

28+
static constexpr unsigned InstCombineDefaultMaxIterations = 1000;
29+
30+
struct InstCombineOptions {
31+
bool UseLoopInfo;
32+
unsigned MaxIterations;
33+
34+
InstCombineOptions()
35+
: UseLoopInfo(false), MaxIterations(InstCombineDefaultMaxIterations) {}
36+
37+
InstCombineOptions &setUseLoopInfo(bool Value) {
38+
UseLoopInfo = Value;
39+
return *this;
40+
}
41+
42+
InstCombineOptions &setMaxIterations(unsigned Value) {
43+
MaxIterations = Value;
44+
return *this;
45+
}
46+
};
47+
2848
class InstCombinePass : public PassInfoMixin<InstCombinePass> {
49+
private:
2950
InstructionWorklist Worklist;
30-
const unsigned MaxIterations;
51+
InstCombineOptions Options;
3152

3253
public:
33-
explicit InstCombinePass();
34-
explicit InstCombinePass(unsigned MaxIterations);
54+
explicit InstCombinePass(InstCombineOptions Opts = {});
55+
void printPipeline(raw_ostream &OS,
56+
function_ref<StringRef(StringRef)> MapClassName2PassName);
3557

3658
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
3759
};

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,33 @@ Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
778778
return Result;
779779
}
780780

781+
Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
782+
InstCombineOptions Result;
783+
while (!Params.empty()) {
784+
StringRef ParamName;
785+
std::tie(ParamName, Params) = Params.split(';');
786+
787+
bool Enable = !ParamName.consume_front("no-");
788+
if (ParamName == "use-loop-info") {
789+
Result.setUseLoopInfo(Enable);
790+
} else if (Enable && ParamName.consume_front("max-iterations=")) {
791+
APInt MaxIterations;
792+
if (ParamName.getAsInteger(0, MaxIterations))
793+
return make_error<StringError>(
794+
formatv("invalid argument to InstCombine pass max-iterations "
795+
"parameter: '{0}' ",
796+
ParamName).str(),
797+
inconvertibleErrorCode());
798+
Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
799+
} else {
800+
return make_error<StringError>(
801+
formatv("invalid InstCombine pass parameter '{0}' ", ParamName).str(),
802+
inconvertibleErrorCode());
803+
}
804+
}
805+
return Result;
806+
}
807+
781808
/// Parser of parameters for LoopVectorize pass.
782809
Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
783810
LoopVectorizeOptions Opts;

llvm/lib/Passes/PassRegistry.def

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,15 @@ FUNCTION_PASS_WITH_PARAMS("loop-vectorize",
477477
parseLoopVectorizeOptions,
478478
"no-interleave-forced-only;interleave-forced-only;"
479479
"no-vectorize-forced-only;vectorize-forced-only")
480+
FUNCTION_PASS_WITH_PARAMS("instcombine",
481+
"InstCombinePass",
482+
[](InstCombineOptions Opts) {
483+
return InstCombinePass(Opts);
484+
},
485+
parseInstCombineOptions,
486+
"no-use-loop-info;use-loop-info;"
487+
"max-iterations=N"
488+
)
480489
FUNCTION_PASS_WITH_PARAMS("mldst-motion",
481490
"MergedLoadStoreMotionPass",
482491
[](MergedLoadStoreMotionOptions Opts) {

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ DEBUG_COUNTER(VisitCounter, "instcombine-visit",
129129
"Controls which instructions are visited");
130130

131131
// FIXME: these limits eventually should be as low as 2.
132-
static constexpr unsigned InstCombineDefaultMaxIterations = 1000;
133132
#ifndef NDEBUG
134133
static constexpr unsigned InstCombineDefaultInfiniteLoopThreshold = 100;
135134
#else
@@ -144,11 +143,6 @@ static cl::opt<unsigned> MaxSinkNumUsers(
144143
"instcombine-max-sink-users", cl::init(32),
145144
cl::desc("Maximum number of undroppable users for instruction sinking"));
146145

147-
static cl::opt<unsigned> LimitMaxIterations(
148-
"instcombine-max-iterations",
149-
cl::desc("Limit the maximum number of instruction combining iterations"),
150-
cl::init(InstCombineDefaultMaxIterations));
151-
152146
static cl::opt<unsigned> InfiniteLoopDetectionThreshold(
153147
"instcombine-infinite-loop-threshold",
154148
cl::desc("Number of instruction combining iterations considered an "
@@ -4584,7 +4578,6 @@ static bool combineInstructionsOverFunction(
45844578
DominatorTree &DT, OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI,
45854579
ProfileSummaryInfo *PSI, unsigned MaxIterations, LoopInfo *LI) {
45864580
auto &DL = F.getParent()->getDataLayout();
4587-
MaxIterations = std::min(MaxIterations, LimitMaxIterations.getValue());
45884581

45894582
/// Builder - This is an IRBuilder that automatically inserts new
45904583
/// instructions into the worklist when they are created.
@@ -4646,10 +4639,17 @@ static bool combineInstructionsOverFunction(
46464639
return MadeIRChange;
46474640
}
46484641

4649-
InstCombinePass::InstCombinePass() : MaxIterations(LimitMaxIterations) {}
4642+
InstCombinePass::InstCombinePass(InstCombineOptions Opts) : Options(Opts) {}
46504643

4651-
InstCombinePass::InstCombinePass(unsigned MaxIterations)
4652-
: MaxIterations(MaxIterations) {}
4644+
void InstCombinePass::printPipeline(
4645+
raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
4646+
static_cast<PassInfoMixin<InstCombinePass> *>(this)->printPipeline(
4647+
OS, MapClassName2PassName);
4648+
OS << '<';
4649+
OS << "max-iterations=" << Options.MaxIterations << ";";
4650+
OS << (Options.UseLoopInfo ? "" : "no-") << "use-loop-info";
4651+
OS << '>';
4652+
}
46534653

46544654
PreservedAnalyses InstCombinePass::run(Function &F,
46554655
FunctionAnalysisManager &AM) {
@@ -4659,7 +4659,11 @@ PreservedAnalyses InstCombinePass::run(Function &F,
46594659
auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
46604660
auto &TTI = AM.getResult<TargetIRAnalysis>(F);
46614661

4662+
// TODO: Only use LoopInfo when the option is set. This requires that the
4663+
// callers in the pass pipeline explicitly set the option.
46624664
auto *LI = AM.getCachedResult<LoopAnalysis>(F);
4665+
if (!LI && Options.UseLoopInfo)
4666+
LI = &AM.getResult<LoopAnalysis>(F);
46634667

46644668
auto *AA = &AM.getResult<AAManager>(F);
46654669
auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
@@ -4669,7 +4673,7 @@ PreservedAnalyses InstCombinePass::run(Function &F,
46694673
&AM.getResult<BlockFrequencyAnalysis>(F) : nullptr;
46704674

46714675
if (!combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, TTI, DT, ORE,
4672-
BFI, PSI, MaxIterations, LI))
4676+
BFI, PSI, Options.MaxIterations, LI))
46734677
// No changes, all analyses are preserved.
46744678
return PreservedAnalyses::all();
46754679

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,8 @@
9292

9393
;; Test SeparateConstOffsetFromGEPPass option.
9494
; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='separate-const-offset-from-gep<lower-gep>' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-27
95-
; CHECK-27: function(separate-const-offset-from-gep<lower-gep>)
95+
; CHECK-27: function(separate-const-offset-from-gep<lower-gep>)
96+
97+
;; Test InstCombine options - the first pass checks default settings, and the second checks customized options.
98+
; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(instcombine,instcombine<use-loop-info;max-iterations=42>)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-28
99+
; CHECK-28: function(instcombine<max-iterations=1000;no-use-loop-info>,instcombine<max-iterations=42;use-loop-info>)

llvm/test/Transforms/InstCombine/gep-combine-loop-invariant.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2-
; RUN: opt -opaque-pointers=0 < %s -passes='require<loops>,instcombine' -S | FileCheck %s
2+
; RUN: opt -opaque-pointers=0 < %s -passes='instcombine<use-loop-info>' -S | FileCheck %s
3+
34
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
45
target triple = "x86_64-unknown-linux-gnu"
56

llvm/test/Transforms/InstCombine/statepoint-cleanup.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2-
; RUN: opt < %s -passes=instcombine -instcombine-max-iterations=1 -S | FileCheck %s
2+
; RUN: opt < %s -passes='instcombine<max-iterations=1>' -S | FileCheck %s
33
; These tests check the optimizations specific to
44
; pointers being relocated at a statepoint.
55

llvm/test/Transforms/InstCombine/statepoint-iter.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2-
; RUN: opt < %s -passes=instcombine -instcombine-max-iterations=1 -S | FileCheck %s
2+
; RUN: opt < %s -passes='instcombine<max-iterations=1>' -S | FileCheck %s
33
; These tests check the optimizations specific to
44
; pointers being relocated at a statepoint.
55

0 commit comments

Comments
 (0)