]> granicus.if.org Git - clang/commitdiff
Add -freroll-loops to enable loop rerolling
authorHal Finkel <hfinkel@anl.gov>
Sun, 17 Nov 2013 16:03:29 +0000 (16:03 +0000)
committerHal Finkel <hfinkel@anl.gov>
Sun, 17 Nov 2013 16:03:29 +0000 (16:03 +0000)
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

include/clang/Driver/Options.td
include/clang/Frontend/CodeGenOptions.def
lib/CodeGen/BackendUtil.cpp
lib/Driver/Tools.cpp
lib/Frontend/CompilerInvocation.cpp
test/Driver/clang_f_opts.c

index 70f8aef1be406875a63210bee75703874e7823fc..9e7dc78d63cfdc12193526ce0db5d60e94e326d2 100644 (file)
@@ -828,6 +828,10 @@ def funroll_loops : Flag<["-"], "funroll-loops">, Group<f_Group>,
   HelpText<"Turn on loop unroller">, Flags<[CC1Option]>;
 def fno_unroll_loops : Flag<["-"], "fno-unroll-loops">, Group<f_Group>,
   HelpText<"Turn off loop unroller">, Flags<[CC1Option]>;
+def freroll_loops : Flag<["-"], "freroll-loops">, Group<f_Group>,
+  HelpText<"Turn on loop reroller">, Flags<[CC1Option]>;
+def fno_reroll_loops : Flag<["-"], "fno-reroll-loops">, Group<f_Group>,
+  HelpText<"Turn off loop reroller">;
 def funsigned_bitfields : Flag<["-"], "funsigned-bitfields">, Group<f_Group>;
 def funsigned_char : Flag<["-"], "funsigned-char">, Group<f_Group>;
 def fno_unsigned_char : Flag<["-"], "fno-unsigned-char">, Group<clang_ignored_f_Group>;
index 80046620f6c5b61cda1649a642f92e50a826605c..78b825dc14ff9cfba81f06a83ce68336f33ed19d 100644 (file)
@@ -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.
index e159a7ab5dc268db122e045b3ca2bf2144038400..90b0f68bd6936f773fcbe7453d85440094faf200 100644 (file)
@@ -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,
index 9d7dc70be706c73fe9eda7a1e2ca2cd379493150..00b822cf34b6467241920f6d4af1528af6977a1c 100644 (file)
@@ -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);
index 581d56d4621758445074f5c5cfa2b7adcf6ca8c4..94a3a33235a3b2b452416d696b1d37569c792d4b 100644 (file)
@@ -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);
index a443bba547208aae9195cdb87eaac73f725c2a34..9d9cd86e829166b8b762f5ba424961f31de0a623 100644 (file)
 // 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"