From: Hal Finkel Date: Sun, 17 Nov 2013 16:03:29 +0000 (+0000) Subject: Add -freroll-loops to enable loop rerolling X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ce5b5f13a6c90904040b29b9eb765bb7cd736f0b;p=clang Add -freroll-loops to enable loop rerolling This adds -freroll-loops (and -fno-reroll-loops in the usual way) to enable loop rerolling as part of the optimization pass manager. This transformation can enable vectorization, reduce code size (or both). Briefly, loop rerolling can transform a loop like this: for (int i = 0; i < 3200; i += 5) { a[i] += alpha * b[i]; a[i + 1] += alpha * b[i + 1]; a[i + 2] += alpha * b[i + 2]; a[i + 3] += alpha * b[i + 3]; a[i + 4] += alpha * b[i + 4]; } into this: for (int i = 0; i < 3200; ++i) { a[i] += alpha * b[i]; } Loop rerolling is currently disabled by default at all optimization levels. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@194967 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 70f8aef1be..9e7dc78d63 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -828,6 +828,10 @@ def funroll_loops : Flag<["-"], "funroll-loops">, Group, HelpText<"Turn on loop unroller">, Flags<[CC1Option]>; def fno_unroll_loops : Flag<["-"], "fno-unroll-loops">, Group, HelpText<"Turn off loop unroller">, Flags<[CC1Option]>; +def freroll_loops : Flag<["-"], "freroll-loops">, Group, + HelpText<"Turn on loop reroller">, Flags<[CC1Option]>; +def fno_reroll_loops : Flag<["-"], "fno-reroll-loops">, Group, + HelpText<"Turn off loop reroller">; def funsigned_bitfields : Flag<["-"], "funsigned-bitfields">, Group; def funsigned_char : Flag<["-"], "funsigned-char">, Group; def fno_unsigned_char : Flag<["-"], "fno-unsigned-char">, Group; diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def index 80046620f6..78b825dc14 100644 --- a/include/clang/Frontend/CodeGenOptions.def +++ b/include/clang/Frontend/CodeGenOptions.def @@ -107,6 +107,7 @@ CODEGENOPT(TimePasses , 1, 0) ///< Set when -ftime-report is enabled. CODEGENOPT(UnitAtATime , 1, 1) ///< Unused. For mirroring GCC optimization ///< selection. CODEGENOPT(UnrollLoops , 1, 0) ///< Control whether loops are unrolled. +CODEGENOPT(RerollLoops , 1, 0) ///< Control whether loops are rerolled. CODEGENOPT(UnsafeFPMath , 1, 0) ///< Allow unsafe floating point optzns. CODEGENOPT(UnwindTables , 1, 0) ///< Emit unwind tables. CODEGENOPT(VectorizeBB , 1, 0) ///< Run basic block vectorizer. diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index e159a7ab5d..90b0f68bd6 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/lib/CodeGen/BackendUtil.cpp @@ -242,6 +242,7 @@ void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) { PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime; PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops; + PMBuilder.RerollLoops = CodeGenOpts.RerollLoops; if (!CodeGenOpts.SampleProfileFile.empty()) PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 9d7dc70be7..00b822cf34 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -3058,6 +3058,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (A->getOption().matches(options::OPT_fno_strict_overflow)) CmdArgs.push_back("-fwrapv"); } + + if (Arg *A = Args.getLastArg(options::OPT_freroll_loops, + options::OPT_fno_reroll_loops)) + if (A->getOption().matches(options::OPT_freroll_loops)) + CmdArgs.push_back("-freroll-loops"); + Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings); Args.AddLastArg(CmdArgs, options::OPT_funroll_loops, options::OPT_fno_unroll_loops); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 581d56d462..94a3a33235 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -355,6 +355,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.UnrollLoops = Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops, (Opts.OptimizationLevel > 1 && !Opts.OptimizeSize)); + Opts.RerollLoops = Args.hasArg(OPT_freroll_loops); Opts.Autolink = !Args.hasArg(OPT_fno_autolink); Opts.SampleProfileFile = Args.getLastArgValue(OPT_fprofile_sample_use_EQ); diff --git a/test/Driver/clang_f_opts.c b/test/Driver/clang_f_opts.c index a443bba547..9d9cd86e82 100644 --- a/test/Driver/clang_f_opts.c +++ b/test/Driver/clang_f_opts.c @@ -44,6 +44,13 @@ // CHECK-UNROLL-LOOPS: "-funroll-loops" // CHECK-NO-UNROLL-LOOPS: "-fno-unroll-loops" +// RUN: %clang -### -S -freroll-loops %s 2>&1 | FileCheck -check-prefix=CHECK-REROLL-LOOPS %s +// RUN: %clang -### -S -fno-reroll-loops %s 2>&1 | FileCheck -check-prefix=CHECK-NO-REROLL-LOOPS %s +// RUN: %clang -### -S -fno-reroll-loops -freroll-loops %s 2>&1 | FileCheck -check-prefix=CHECK-REROLL-LOOPS %s +// RUN: %clang -### -S -freroll-loops -fno-reroll-loops %s 2>&1 | FileCheck -check-prefix=CHECK-NO-REROLL-LOOPS %s +// CHECK-REROLL-LOOPS: "-freroll-loops" +// CHECK-NO-REROLL-LOOPS-NOT: "-freroll-loops" + // RUN: %clang -### -S -fprofile-sample-use=%S/Inputs/file.prof %s 2>&1 | FileCheck -check-prefix=CHECK-SAMPLE-PROFILE %s // CHECK-SAMPLE-PROFILE: "-fprofile-sample-use={{.*}}/file.prof"