Author: Sjoerd Meijer Date: 2025-02-07T10:31:24Z New Revision: 612df14c0058572c876f59d41ec56c89710cee15
URL: https://github.com/llvm/llvm-project/commit/612df14c0058572c876f59d41ec56c89710cee15 DIFF: https://github.com/llvm/llvm-project/commit/612df14c0058572c876f59d41ec56c89710cee15.diff LOG: [Clang][Driver] Add an option to control loop-interchange (#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 (#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. Added: Modified: clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/Driver/clang_f_opts.c llvm/include/llvm/Passes/PassBuilder.h llvm/lib/Passes/PassBuilderPipelines.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index cf0474470c08b93..68831093c6ad89f 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -320,6 +320,7 @@ CODEGENOPT(TimePassesPerRun , 1, 0) ///< Set when -ftime-report=per-pass-run is CODEGENOPT(TimeTrace , 1, 0) ///< Set when -ftime-trace is enabled. VALUE_CODEGENOPT(TimeTraceGranularity, 32, 500) ///< Minimum time granularity (in microseconds), ///< traced by time profiler +CODEGENOPT(InterchangeLoops , 1, 0) ///< Run loop-interchange. CODEGENOPT(UnrollLoops , 1, 0) ///< Control whether loops are unrolled. CODEGENOPT(RerollLoops , 1, 0) ///< Control whether loops are rerolled. CODEGENOPT(NoUseJumpTables , 1, 0) ///< Set when -fno-jump-tables is enabled. diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 77ca2d2aac31be1..df226fd9e9aa269 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4069,6 +4069,10 @@ def ftrap_function_EQ : Joined<["-"], "ftrap-function=">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>, HelpText<"Issue call to specified function rather than a trap instruction">, MarshallingInfoString<CodeGenOpts<"TrapFuncName">>; +def floop_interchange : Flag<["-"], "floop-interchange">, Group<f_Group>, + HelpText<"Enable the loop interchange pass">, Visibility<[ClangOption, CC1Option]>; +def fno_loop_interchange: Flag<["-"], "fno-loop-interchange">, Group<f_Group>, + HelpText<"Disable the loop interchange pass">, Visibility<[ClangOption, CC1Option]>; def funroll_loops : Flag<["-"], "funroll-loops">, Group<f_Group>, HelpText<"Turn on loop unroller">, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>; def fno_unroll_loops : Flag<["-"], "fno-unroll-loops">, Group<f_Group>, diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 97e9bbccd61ef1b..57106e4287765ea 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -890,6 +890,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline( PipelineTuningOptions PTO; PTO.LoopUnrolling = CodeGenOpts.UnrollLoops; + PTO.LoopInterchange = CodeGenOpts.InterchangeLoops; // For historical reasons, loop interleaving is set to mirror setting for loop // unrolling. PTO.LoopInterleaving = CodeGenOpts.UnrollLoops; @@ -1314,6 +1315,7 @@ runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex, initTargetOptions(CI, Diags, Conf.Options); Conf.SampleProfile = std::move(SampleProfile); Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops; + Conf.PTO.LoopInterchange = CGOpts.InterchangeLoops; // For historical reasons, loop interleaving is set to mirror setting for loop // unrolling. Conf.PTO.LoopInterleaving = CGOpts.UnrollLoops; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index c0891d46b0a62cd..045cae0a2c468ee 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6974,6 +6974,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings); Args.AddLastArg(CmdArgs, options::OPT_funroll_loops, options::OPT_fno_unroll_loops); + Args.AddLastArg(CmdArgs, options::OPT_floop_interchange, + options::OPT_fno_loop_interchange); Args.AddLastArg(CmdArgs, options::OPT_fstrict_flex_arrays_EQ); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 8b1bbf104ce39b2..014e629c959e252 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1665,6 +1665,11 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts, else if (!Opts.UnrollLoops && Opts.OptimizationLevel > 1) GenerateArg(Consumer, OPT_fno_unroll_loops); + if (Opts.InterchangeLoops) + GenerateArg(Consumer, OPT_floop_interchange); + else + GenerateArg(Consumer, OPT_fno_loop_interchange); + if (!Opts.BinutilsVersion.empty()) GenerateArg(Consumer, OPT_fbinutils_version_EQ, Opts.BinutilsVersion); @@ -1971,6 +1976,8 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.UnrollLoops = Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops, (Opts.OptimizationLevel > 1)); + Opts.InterchangeLoops = + Args.hasFlag(OPT_floop_interchange, OPT_fno_loop_interchange, false); Opts.BinutilsVersion = std::string(Args.getLastArgValue(OPT_fbinutils_version_EQ)); diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c index 38f25898c955682..7454ce3d30f5fc3 100644 --- a/clang/test/Driver/clang_f_opts.c +++ b/clang/test/Driver/clang_f_opts.c @@ -45,6 +45,13 @@ // CHECK-UNROLL-LOOPS: "-funroll-loops" // CHECK-NO-UNROLL-LOOPS: "-fno-unroll-loops" +// RUN: %clang -### -S -floop-interchange %s 2>&1 | FileCheck -check-prefix=CHECK-INTERCHANGE-LOOPS %s +// RUN: %clang -### -S -fno-loop-interchange %s 2>&1 | FileCheck -check-prefix=CHECK-NO-INTERCHANGE-LOOPS %s +// RUN: %clang -### -S -fno-loop-interchange -floop-interchange %s 2>&1 | FileCheck -check-prefix=CHECK-INTERCHANGE-LOOPS %s +// RUN: %clang -### -S -floop-interchange -fno-loop-interchange %s 2>&1 | FileCheck -check-prefix=CHECK-NO-INTERCHANGE-LOOPS %s +// CHECK-INTERCHANGE-LOOPS: "-floop-interchange" +// CHECK-NO-INTERCHANGE-LOOPS: "-fno-loop-interchange" + // RUN: %clang -### -S -fprofile-sample-accurate %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-SAMPLE-ACCURATE %s // CHECK-PROFILE-SAMPLE-ACCURATE: "-fprofile-sample-accurate" diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h index 1b54855a5c6f44f..51ccaa53447d798 100644 --- a/llvm/include/llvm/Passes/PassBuilder.h +++ b/llvm/include/llvm/Passes/PassBuilder.h @@ -60,6 +60,10 @@ class PipelineTuningOptions { /// Tuning option to enable/disable loop unrolling. Its default value is true. bool LoopUnrolling; + /// Tuning option to enable/disable loop interchange. Its default value is + /// false. + bool LoopInterchange; + /// Tuning option to forget all SCEV loops in LoopUnroll. Its default value /// is that of the flag: `-forget-scev-loop-unroll`. bool ForgetAllSCEVInLoopUnroll; diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp index 7ad9c8bf206dd26..63e70d7e182bd6b 100644 --- a/llvm/lib/Passes/PassBuilderPipelines.cpp +++ b/llvm/lib/Passes/PassBuilderPipelines.cpp @@ -200,9 +200,9 @@ static cl::opt<bool> ExtraVectorizerPasses( static cl::opt<bool> RunNewGVN("enable-newgvn", cl::init(false), cl::Hidden, cl::desc("Run the NewGVN pass")); -static cl::opt<bool> EnableLoopInterchange( - "enable-loopinterchange", cl::init(false), cl::Hidden, - cl::desc("Enable the experimental LoopInterchange Pass")); +static cl::opt<bool> + EnableLoopInterchange("enable-loopinterchange", cl::init(false), cl::Hidden, + cl::desc("Enable the LoopInterchange Pass")); static cl::opt<bool> EnableUnrollAndJam("enable-unroll-and-jam", cl::init(false), cl::Hidden, @@ -316,6 +316,7 @@ PipelineTuningOptions::PipelineTuningOptions() { LoopVectorization = true; SLPVectorization = false; LoopUnrolling = true; + LoopInterchange = EnableLoopInterchange; ForgetAllSCEVInLoopUnroll = ForgetSCEVInLoopUnroll; LicmMssaOptCap = SetLicmMssaOptCap; LicmMssaNoAccForPromotionCap = SetLicmMssaNoAccForPromotionCap; @@ -485,7 +486,7 @@ PassBuilder::buildO1FunctionSimplificationPipeline(OptimizationLevel Level, LPM2.addPass(LoopDeletionPass()); - if (EnableLoopInterchange) + if (PTO.LoopInterchange) LPM2.addPass(LoopInterchangePass()); // Do not enable unrolling in PreLinkThinLTO phase during sample PGO @@ -676,7 +677,7 @@ PassBuilder::buildFunctionSimplificationPipeline(OptimizationLevel Level, LPM2.addPass(LoopDeletionPass()); - if (EnableLoopInterchange) + if (PTO.LoopInterchange) LPM2.addPass(LoopInterchangePass()); // Do not enable unrolling in PreLinkThinLTO phase during sample PGO _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits