Skip to content

Commit 36cf657

Browse files
sjoerdmeijerIcohedron
authored andcommitted
[Clang][Driver] Add an option to control loop-interchange (llvm#125830)
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 (llvm#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 9832ee6 commit 36cf657

File tree

8 files changed

+33
-5
lines changed

8 files changed

+33
-5
lines changed

clang/include/clang/Basic/CodeGenOptions.def

+1
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ CODEGENOPT(TimePassesPerRun , 1, 0) ///< Set when -ftime-report=per-pass-run is
320320
CODEGENOPT(TimeTrace , 1, 0) ///< Set when -ftime-trace is enabled.
321321
VALUE_CODEGENOPT(TimeTraceGranularity, 32, 500) ///< Minimum time granularity (in microseconds),
322322
///< traced by time profiler
323+
CODEGENOPT(InterchangeLoops , 1, 0) ///< Run loop-interchange.
323324
CODEGENOPT(UnrollLoops , 1, 0) ///< Control whether loops are unrolled.
324325
CODEGENOPT(RerollLoops , 1, 0) ///< Control whether loops are rerolled.
325326
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
@@ -4069,6 +4069,10 @@ def ftrap_function_EQ : Joined<["-"], "ftrap-function=">, Group<f_Group>,
40694069
Visibility<[ClangOption, CC1Option]>,
40704070
HelpText<"Issue call to specified function rather than a trap instruction">,
40714071
MarshallingInfoString<CodeGenOpts<"TrapFuncName">>;
4072+
def floop_interchange : Flag<["-"], "floop-interchange">, Group<f_Group>,
4073+
HelpText<"Enable the loop interchange pass">, Visibility<[ClangOption, CC1Option]>;
4074+
def fno_loop_interchange: Flag<["-"], "fno-loop-interchange">, Group<f_Group>,
4075+
HelpText<"Disable the loop interchange pass">, Visibility<[ClangOption, CC1Option]>;
40724076
def funroll_loops : Flag<["-"], "funroll-loops">, Group<f_Group>,
40734077
HelpText<"Turn on loop unroller">, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>;
40744078
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
@@ -890,6 +890,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
890890

891891
PipelineTuningOptions PTO;
892892
PTO.LoopUnrolling = CodeGenOpts.UnrollLoops;
893+
PTO.LoopInterchange = CodeGenOpts.InterchangeLoops;
893894
// For historical reasons, loop interleaving is set to mirror setting for loop
894895
// unrolling.
895896
PTO.LoopInterleaving = CodeGenOpts.UnrollLoops;
@@ -1314,6 +1315,7 @@ runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex,
13141315
initTargetOptions(CI, Diags, Conf.Options);
13151316
Conf.SampleProfile = std::move(SampleProfile);
13161317
Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops;
1318+
Conf.PTO.LoopInterchange = CGOpts.InterchangeLoops;
13171319
// For historical reasons, loop interleaving is set to mirror setting for loop
13181320
// unrolling.
13191321
Conf.PTO.LoopInterleaving = CGOpts.UnrollLoops;

clang/lib/Driver/ToolChains/Clang.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -6974,6 +6974,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
69746974
Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
69756975
Args.AddLastArg(CmdArgs, options::OPT_funroll_loops,
69766976
options::OPT_fno_unroll_loops);
6977+
Args.AddLastArg(CmdArgs, options::OPT_floop_interchange,
6978+
options::OPT_fno_loop_interchange);
69776979

69786980
Args.AddLastArg(CmdArgs, options::OPT_fstrict_flex_arrays_EQ);
69796981

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

@@ -1971,6 +1976,8 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
19711976
Opts.UnrollLoops =
19721977
Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops,
19731978
(Opts.OptimizationLevel > 1));
1979+
Opts.InterchangeLoops =
1980+
Args.hasFlag(OPT_floop_interchange, OPT_fno_loop_interchange, false);
19741981
Opts.BinutilsVersion =
19751982
std::string(Args.getLastArgValue(OPT_fbinutils_version_EQ));
19761983

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

+6-5
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,9 @@ static cl::opt<bool> ExtraVectorizerPasses(
200200
static cl::opt<bool> RunNewGVN("enable-newgvn", cl::init(false), cl::Hidden,
201201
cl::desc("Run the NewGVN pass"));
202202

203-
static cl::opt<bool> EnableLoopInterchange(
204-
"enable-loopinterchange", cl::init(false), cl::Hidden,
205-
cl::desc("Enable the experimental LoopInterchange Pass"));
203+
static cl::opt<bool>
204+
EnableLoopInterchange("enable-loopinterchange", cl::init(false), cl::Hidden,
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;
@@ -485,7 +486,7 @@ PassBuilder::buildO1FunctionSimplificationPipeline(OptimizationLevel Level,
485486

486487
LPM2.addPass(LoopDeletionPass());
487488

488-
if (EnableLoopInterchange)
489+
if (PTO.LoopInterchange)
489490
LPM2.addPass(LoopInterchangePass());
490491

491492
// Do not enable unrolling in PreLinkThinLTO phase during sample PGO
@@ -676,7 +677,7 @@ PassBuilder::buildFunctionSimplificationPipeline(OptimizationLevel Level,
676677

677678
LPM2.addPass(LoopDeletionPass());
678679

679-
if (EnableLoopInterchange)
680+
if (PTO.LoopInterchange)
680681
LPM2.addPass(LoopInterchangePass());
681682

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

0 commit comments

Comments
 (0)