Enable runtime unrolling with unroll pragma metadata
authorMark Heffernan <meheff@google.com>
Mon, 13 Jul 2015 18:26:27 +0000 (18:26 +0000)
committerMark Heffernan <meheff@google.com>
Mon, 13 Jul 2015 18:26:27 +0000 (18:26 +0000)
Enable runtime unrolling for loops with unroll count metadata ("#pragma unroll N")
and a runtime trip count. Also, do not unroll loops with unroll full metadata if the
loop has a runtime loop count. Previously, such loops would be unrolled with a
very large threshold (pragma-unroll-threshold) if runtime unrolled happened to be
enabled resulting in a very large (and likely unwise) unroll factor.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242047 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/LoopUnrollPass.cpp
test/Transforms/LoopUnroll/unroll-pragmas.ll

index 9e7558d9c45fd2e0e78da534580331999527bf2c..d78db6c369b3520d754ebfbc2b859db806ebc3d8 100644 (file)
@@ -840,8 +840,10 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
 
   // Reduce count based on the type of unrolling and the threshold values.
   unsigned OriginalCount = Count;
-  bool AllowRuntime = UserRuntime ? CurrentRuntime : UP.Runtime;
-  if (HasRuntimeUnrollDisablePragma(L)) {
+  bool AllowRuntime =
+      (PragmaCount > 0) || (UserRuntime ? CurrentRuntime : UP.Runtime);
+  // Don't unroll a runtime trip count loop with unroll full pragma.
+  if (HasRuntimeUnrollDisablePragma(L) || PragmaFullUnroll) {
     AllowRuntime = false;
   }
   if (Unrolling == Partial) {
index 1354181becd0ce1d91446f49dbe044a6c1f39d51..8e0d77513cc10fdeac398811fedc4c9287cc27de 100644 (file)
@@ -86,9 +86,9 @@ for.end:                                          ; preds = %for.body
 ; #pragma clang loop unroll(full)
 ; Loop should be fully unrolled.
 ;
-; CHECK-LABEL: @loop64_with_enable(
+; CHECK-LABEL: @loop64_with_full(
 ; CHECK-NOT: br i1
-define void @loop64_with_enable(i32* nocapture %a) {
+define void @loop64_with_full(i32* nocapture %a) {
 entry:
   br label %for.body
 
@@ -139,14 +139,13 @@ for.end:                                          ; preds = %for.body
 !6 = !{!"llvm.loop.unroll.count", i32 4}
 
 ; #pragma clang loop unroll(full)
-; Full unrolling is requested, but loop has a dynamic trip count so
+; Full unrolling is requested, but loop has a runtime trip count so
 ; no unrolling should occur.
 ;
-; CHECK-LABEL: @dynamic_loop_with_enable(
+; CHECK-LABEL: @runtime_loop_with_full(
 ; CHECK: store i32
 ; CHECK-NOT: store i32
-; CHECK: br i1
-define void @dynamic_loop_with_enable(i32* nocapture %a, i32 %b) {
+define void @runtime_loop_with_full(i32* nocapture %a, i32 %b) {
 entry:
   %cmp3 = icmp sgt i32 %b, 0
   br i1 %cmp3, label %for.body, label %for.end, !llvm.loop !8
@@ -168,22 +167,22 @@ for.end:                                          ; preds = %for.body, %entry
 !8 = !{!8, !4}
 
 ; #pragma clang loop unroll_count(4)
-; Loop has a dynamic trip count.  Unrolling should occur, but no
-; conditional branches can be removed.
+; Loop has a runtime trip count.  Runtime unrolling should occur and loop
+; should be duplicated (original and 4x unrolled).
 ;
-; CHECK-LABEL: @dynamic_loop_with_count4(
+; CHECK-LABEL: @runtime_loop_with_count4(
+; CHECK: for.body.prol:
+; CHECK: store
 ; CHECK-NOT: store
 ; CHECK: br i1
+; CHECK: for.body
 ; CHECK: store
-; CHECK: br i1
 ; CHECK: store
-; CHECK: br i1
 ; CHECK: store
-; CHECK: br i1
 ; CHECK: store
+; CHECK-NOT: store
 ; CHECK: br i1
-; CHECK-NOT: br i1
-define void @dynamic_loop_with_count4(i32* nocapture %a, i32 %b) {
+define void @runtime_loop_with_count4(i32* nocapture %a, i32 %b) {
 entry:
   %cmp3 = icmp sgt i32 %b, 0
   br i1 %cmp3, label %for.body, label %for.end, !llvm.loop !9