Skip to content

Commit 1a655eb

Browse files
committed
[Clang][Driver] Add an option to control loop-interchange
This introduces options -floop-interchange and -fno-loop-interchange to enable/disable the loop-interchange pass. This is part of the work that tries to get that pass enabled by default (#124911), where it was remarked that a user facing option to control this would be convenient to have. The option (name) is the same as GCC's.
1 parent cb714e7 commit 1a655eb

File tree

8 files changed

+31
-3
lines changed

8 files changed

+31
-3
lines changed

clang/include/clang/Basic/CodeGenOptions.def

+1
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ CODEGENOPT(TimePassesPerRun , 1, 0) ///< Set when -ftime-report=per-pass-run is
319319
CODEGENOPT(TimeTrace , 1, 0) ///< Set when -ftime-trace is enabled.
320320
VALUE_CODEGENOPT(TimeTraceGranularity, 32, 500) ///< Minimum time granularity (in microseconds),
321321
///< traced by time profiler
322+
CODEGENOPT(InterchangeLoops , 1, 0) ///< Run loop-interchange.
322323
CODEGENOPT(UnrollLoops , 1, 0) ///< Control whether loops are unrolled.
323324
CODEGENOPT(RerollLoops , 1, 0) ///< Control whether loops are rerolled.
324325
CODEGENOPT(NoUseJumpTables , 1, 0) ///< Set when -fno-jump-tables is enabled.

clang/include/clang/Driver/Options.td

+4
Original file line numberDiff line numberDiff line change
@@ -4161,6 +4161,10 @@ def ftrap_function_EQ : Joined<["-"], "ftrap-function=">, Group<f_Group>,
41614161
Visibility<[ClangOption, CC1Option]>,
41624162
HelpText<"Issue call to specified function rather than a trap instruction">,
41634163
MarshallingInfoString<CodeGenOpts<"TrapFuncName">>;
4164+
def floop_interchange : Flag<["-"], "floop-interchange">, Group<f_Group>,
4165+
HelpText<"Enable the loop interchange pass">, Visibility<[ClangOption, CC1Option]>;
4166+
def fno_loop_interchange: Flag<["-"], "fno-loop-interchange">, Group<f_Group>,
4167+
HelpText<"Disable the loop interchange pass">, Visibility<[ClangOption, CC1Option]>;
41644168
def funroll_loops : Flag<["-"], "funroll-loops">, Group<f_Group>,
41654169
HelpText<"Turn on loop unroller">, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>;
41664170
def fno_unroll_loops : Flag<["-"], "fno-unroll-loops">, Group<f_Group>,

clang/lib/CodeGen/BackendUtil.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
881881

882882
PipelineTuningOptions PTO;
883883
PTO.LoopUnrolling = CodeGenOpts.UnrollLoops;
884+
PTO.LoopInterchange = CodeGenOpts.InterchangeLoops;
884885
// For historical reasons, loop interleaving is set to mirror setting for loop
885886
// unrolling.
886887
PTO.LoopInterleaving = CodeGenOpts.UnrollLoops;
@@ -1305,6 +1306,7 @@ runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex,
13051306
initTargetOptions(CI, Diags, Conf.Options);
13061307
Conf.SampleProfile = std::move(SampleProfile);
13071308
Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops;
1309+
Conf.PTO.LoopInterchange = CGOpts.InterchangeLoops;
13081310
// For historical reasons, loop interleaving is set to mirror setting for loop
13091311
// unrolling.
13101312
Conf.PTO.LoopInterleaving = CGOpts.UnrollLoops;

clang/lib/Driver/ToolChains/Clang.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -7041,6 +7041,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
70417041
Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
70427042
Args.AddLastArg(CmdArgs, options::OPT_funroll_loops,
70437043
options::OPT_fno_unroll_loops);
7044+
Args.AddLastArg(CmdArgs, options::OPT_floop_interchange,
7045+
options::OPT_fno_loop_interchange);
70447046

70457047
Args.AddLastArg(CmdArgs, options::OPT_fstrict_flex_arrays_EQ);
70467048

clang/lib/Frontend/CompilerInvocation.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -1665,6 +1665,11 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts,
16651665
else if (!Opts.UnrollLoops && Opts.OptimizationLevel > 1)
16661666
GenerateArg(Consumer, OPT_fno_unroll_loops);
16671667

1668+
if (Opts.InterchangeLoops)
1669+
GenerateArg(Consumer, OPT_floop_interchange);
1670+
else
1671+
GenerateArg(Consumer, OPT_fno_loop_interchange);
1672+
16681673
if (!Opts.BinutilsVersion.empty())
16691674
GenerateArg(Consumer, OPT_fbinutils_version_EQ, Opts.BinutilsVersion);
16701675

@@ -1968,6 +1973,8 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
19681973
Opts.UnrollLoops =
19691974
Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops,
19701975
(Opts.OptimizationLevel > 1));
1976+
Opts.InterchangeLoops =
1977+
Args.hasFlag(OPT_floop_interchange, OPT_fno_loop_interchange, false);
19711978
Opts.BinutilsVersion =
19721979
std::string(Args.getLastArgValue(OPT_fbinutils_version_EQ));
19731980

clang/test/Driver/clang_f_opts.c

+7
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@
4545
// CHECK-UNROLL-LOOPS: "-funroll-loops"
4646
// CHECK-NO-UNROLL-LOOPS: "-fno-unroll-loops"
4747

48+
// RUN: %clang -### -S -floop-interchange %s 2>&1 | FileCheck -check-prefix=CHECK-INTERCHANGE-LOOPS %s
49+
// RUN: %clang -### -S -fno-loop-interchange %s 2>&1 | FileCheck -check-prefix=CHECK-NO-INTERCHANGE-LOOPS %s
50+
// RUN: %clang -### -S -fno-loop-interchange -floop-interchange %s 2>&1 | FileCheck -check-prefix=CHECK-INTERCHANGE-LOOPS %s
51+
// RUN: %clang -### -S -floop-interchange -fno-loop-interchange %s 2>&1 | FileCheck -check-prefix=CHECK-NO-INTERCHANGE-LOOPS %s
52+
// CHECK-INTERCHANGE-LOOPS: "-floop-interchange"
53+
// CHECK-NO-INTERCHANGE-LOOPS: "-fno-loop-interchange"
54+
4855
// RUN: %clang -### -S -fprofile-sample-accurate %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-SAMPLE-ACCURATE %s
4956
// CHECK-PROFILE-SAMPLE-ACCURATE: "-fprofile-sample-accurate"
5057

llvm/include/llvm/Passes/PassBuilder.h

+4
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ class PipelineTuningOptions {
6060
/// Tuning option to enable/disable loop unrolling. Its default value is true.
6161
bool LoopUnrolling;
6262

63+
/// Tuning option to enable/disable loop interchange. Its default value is
64+
/// false.
65+
bool LoopInterchange;
66+
6367
/// Tuning option to forget all SCEV loops in LoopUnroll. Its default value
6468
/// is that of the flag: `-forget-scev-loop-unroll`.
6569
bool ForgetAllSCEVInLoopUnroll;

llvm/lib/Passes/PassBuilderPipelines.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ static cl::opt<bool> RunNewGVN("enable-newgvn", cl::init(false), cl::Hidden,
202202

203203
static cl::opt<bool> EnableLoopInterchange(
204204
"enable-loopinterchange", cl::init(false), cl::Hidden,
205-
cl::desc("Enable the experimental LoopInterchange Pass"));
205+
cl::desc("Enable the LoopInterchange Pass"));
206206

207207
static cl::opt<bool> EnableUnrollAndJam("enable-unroll-and-jam",
208208
cl::init(false), cl::Hidden,
@@ -316,6 +316,7 @@ PipelineTuningOptions::PipelineTuningOptions() {
316316
LoopVectorization = true;
317317
SLPVectorization = false;
318318
LoopUnrolling = true;
319+
LoopInterchange = EnableLoopInterchange;
319320
ForgetAllSCEVInLoopUnroll = ForgetSCEVInLoopUnroll;
320321
LicmMssaOptCap = SetLicmMssaOptCap;
321322
LicmMssaNoAccForPromotionCap = SetLicmMssaNoAccForPromotionCap;
@@ -480,7 +481,7 @@ PassBuilder::buildO1FunctionSimplificationPipeline(OptimizationLevel Level,
480481

481482
LPM2.addPass(LoopDeletionPass());
482483

483-
if (EnableLoopInterchange)
484+
if (PTO.LoopInterchange)
484485
LPM2.addPass(LoopInterchangePass());
485486

486487
// Do not enable unrolling in PreLinkThinLTO phase during sample PGO
@@ -671,7 +672,7 @@ PassBuilder::buildFunctionSimplificationPipeline(OptimizationLevel Level,
671672

672673
LPM2.addPass(LoopDeletionPass());
673674

674-
if (EnableLoopInterchange)
675+
if (PTO.LoopInterchange)
675676
LPM2.addPass(LoopInterchangePass());
676677

677678
// Do not enable unrolling in PreLinkThinLTO phase during sample PGO

0 commit comments

Comments
 (0)