[polly] r179159 - Support SCoPs with multiple exit edges

Tobias Grosser grosser at fim.uni-passau.de
Tue Apr 9 23:55:31 PDT 2013


Author: grosser
Date: Wed Apr 10 01:55:31 2013
New Revision: 179159

URL: http://llvm.org/viewvc/llvm-project?rev=179159&view=rev
Log:
Support SCoPs with multiple exit edges

Regions that have multiple exit edges are very common. A simple if condition
yields e.g. such a region:

        if
      /   \
  then     else
      \   /
      after

Region: if -> after

This regions contains the bbs 'if', 'then', 'else', but not 'after'. It has
two exit edges 'then' -> 'after' and 'else' -> 'after'.

Previously we scheduled the RegionSimplify pass to translate such regions into
simple regions. With this patch, we now support them natively.

Contributed-by: Star Tan <tanmx_star at yeah.net>

Added:
    polly/trunk/test/Isl/CodeGen/simple_loop_non_single_exit.ll
      - copied, changed from r179158, polly/trunk/test/ScopDetect/simple_loop_non_single_exit.ll
    polly/trunk/test/Isl/CodeGen/simple_loop_non_single_exit_2.ll
      - copied, changed from r179158, polly/trunk/test/ScopDetect/simple_loop_non_single_exit_2.ll
    polly/trunk/test/ScopDetect/cross_loop_non_single_exit.ll
      - copied, changed from r179158, polly/trunk/test/ScopDetect/simple_loop_non_single_exit.ll
    polly/trunk/test/ScopDetect/cross_loop_non_single_exit_2.ll
      - copied, changed from r179158, polly/trunk/test/ScopDetect/simple_loop_non_single_exit.ll
    polly/trunk/test/ScopDetect/nested_loop_single_exit.ll
      - copied, changed from r179158, polly/trunk/test/ScopDetect/simple_loop_non_single_exit_2.ll
Modified:
    polly/trunk/lib/Analysis/ScopDetection.cpp
    polly/trunk/lib/CodeGen/CodeGeneration.cpp
    polly/trunk/lib/CodeGen/IslCodeGeneration.cpp
    polly/trunk/test/ScopDetect/simple_loop_non_single_exit.ll
    polly/trunk/test/ScopDetect/simple_loop_non_single_exit_2.ll

Modified: polly/trunk/lib/Analysis/ScopDetection.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopDetection.cpp?rev=179159&r1=179158&r2=179159&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopDetection.cpp (original)
+++ polly/trunk/lib/Analysis/ScopDetection.cpp Wed Apr 10 01:55:31 2013
@@ -554,9 +554,9 @@ bool ScopDetection::isValidRegion(Detect
   if (R.getEntry() == &(R.getEntry()->getParent()->getEntryBlock()))
     INVALID(Other, "Region containing entry block of function is invalid!");
 
-  // Only a simple region is allowed.
-  if (!R.isSimple())
-    INVALID(SimpleRegion, "Region not simple: " << R.getNameStr());
+  // Only regions that have a single entry are allowed.
+  if (!R.getEnteringBlock())
+    INVALID(SimpleRegion, "Region has multiple entries: " << R.getNameStr());
 
   if (!isValidExit(Context))
     return false;

Modified: polly/trunk/lib/CodeGen/CodeGeneration.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/CodeGeneration.cpp?rev=179159&r1=179158&r2=179159&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/CodeGeneration.cpp (original)
+++ polly/trunk/lib/CodeGen/CodeGeneration.cpp Wed Apr 10 01:55:31 2013
@@ -34,6 +34,7 @@
 #include "polly/CodeGen/PTXGenerator.h"
 #include "polly/CodeGen/Utils.h"
 #include "polly/Support/GICHelper.h"
+#include "polly/Support/ScopHelper.h"
 
 #include "llvm/IR/Module.h"
 #include "llvm/ADT/SetVector.h"
@@ -983,7 +984,16 @@ public:
   bool runOnScop(Scop &S) {
     ParallelLoops.clear();
 
-    assert(S.getRegion().isSimple() && "Only simple regions are supported");
+    Region &R = S.getRegion();
+
+    assert (!R.isTopLevelRegion() && "Top level regions are not supported");
+    assert (R.getEnteringBlock() && "Only support regions with a single entry");
+
+    if (!R.getExitingBlock()) {
+      BasicBlock *newExit = createSingleExitEdge(&R, this);
+      for (Region::const_iterator RI = R.begin(), RE = R.end(); RI != RE; ++RI)
+        (*RI)->replaceExitRecursive(newExit);
+    }
 
     BasicBlock *StartBlock = executeScopConditionally(S, this);
 

Modified: polly/trunk/lib/CodeGen/IslCodeGeneration.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslCodeGeneration.cpp?rev=179159&r1=179158&r2=179159&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslCodeGeneration.cpp (original)
+++ polly/trunk/lib/CodeGen/IslCodeGeneration.cpp Wed Apr 10 01:55:31 2013
@@ -30,6 +30,7 @@
 #include "polly/CodeGen/LoopGenerators.h"
 #include "polly/CodeGen/Utils.h"
 #include "polly/Support/GICHelper.h"
+#include "polly/Support/ScopHelper.h"
 
 #include "llvm/IR/Module.h"
 #include "llvm/Analysis/LoopInfo.h"
@@ -1024,7 +1025,17 @@ public:
 
   bool runOnScop(Scop &S) {
     IslAstInfo &AstInfo = getAnalysis<IslAstInfo>();
-    assert(S.getRegion().isSimple() && "Only simple regions are supported");
+
+    Region &R = S.getRegion();
+
+    assert (!R.isTopLevelRegion() && "Top level regions are not supported");
+    assert (R.getEnteringBlock() && "Only support regions with a single entry");
+
+    if (!R.getExitingBlock()) {
+      BasicBlock *newExit = createSingleExitEdge(&R, this);
+      for (Region::const_iterator RI = R.begin(), RE = R.end(); RI != RE; ++RI)
+        (*RI)->replaceExitRecursive(newExit);
+    }
 
     BasicBlock *StartBlock = executeScopConditionally(S, this);
     isl_ast_node *Ast = AstInfo.getAst();

Copied: polly/trunk/test/Isl/CodeGen/simple_loop_non_single_exit.ll (from r179158, polly/trunk/test/ScopDetect/simple_loop_non_single_exit.ll)
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/simple_loop_non_single_exit.ll?p2=polly/trunk/test/Isl/CodeGen/simple_loop_non_single_exit.ll&p1=polly/trunk/test/ScopDetect/simple_loop_non_single_exit.ll&r1=179158&r2=179159&rev=179159&view=diff
==============================================================================
--- polly/trunk/test/ScopDetect/simple_loop_non_single_exit.ll (original)
+++ polly/trunk/test/Isl/CodeGen/simple_loop_non_single_exit.ll Wed Apr 10 01:55:31 2013
@@ -1,7 +1,5 @@
-; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -polly-region-simplify -polly-detect -analyze < %s | FileCheck %s -check-prefix=CHECK-SIMPLIFY
-; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -polly-region-simplify -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s -check-prefix=CHECK-SIMPLIFY
+; RUN: opt %loadPolly -polly-codegen-isl -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-codegen-isl -S < %s | FileCheck %s -check-prefix=CHECK-CODE
 
 ; void f(long A[], long N) {
 ;   long i;
@@ -34,5 +32,6 @@ return:
   ret void
 }
 
-; CHECK: Valid Region for Scop: for.i => return
-; CHECK-SIMPLIFY: Valid Region for Scop: next => return
+; CHECK: Create LLVM-IR from SCoPs' for region: 'next => polly.merge_new_and_old'
+; CHECK-CODE: polly.split_new_and_old
+; CHECK-CODE: polly.merge_new_and_old

Copied: polly/trunk/test/Isl/CodeGen/simple_loop_non_single_exit_2.ll (from r179158, polly/trunk/test/ScopDetect/simple_loop_non_single_exit_2.ll)
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/simple_loop_non_single_exit_2.ll?p2=polly/trunk/test/Isl/CodeGen/simple_loop_non_single_exit_2.ll&p1=polly/trunk/test/ScopDetect/simple_loop_non_single_exit_2.ll&r1=179158&r2=179159&rev=179159&view=diff
==============================================================================
--- polly/trunk/test/ScopDetect/simple_loop_non_single_exit_2.ll (original)
+++ polly/trunk/test/Isl/CodeGen/simple_loop_non_single_exit_2.ll Wed Apr 10 01:55:31 2013
@@ -1,7 +1,5 @@
-; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -polly-region-simplify -polly-detect -analyze < %s | FileCheck %s -check-prefix=CHECK-SIMPLIFY
-; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -polly-region-simplify -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s -check-prefix=CHECK-SIMPLIFY
+; RUN: opt %loadPolly -polly-codegen-isl -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-codegen-isl -S < %s | FileCheck %s -check-prefix=CHECK-CODE
 
 ; void f(long A[], long N) {
 ;   long i;
@@ -35,5 +33,6 @@ return:
   ret void
 }
 
-; CHECK: Valid Region for Scop: for.i => return
-; CHECK-SIMPLIFY: Valid Region for Scop: next => return.single_exit1
+; CHECK: Create LLVM-IR from SCoPs' for region: 'for.i => return'
+; CHECK-CODE: polly.split_new_and_old
+; CHECK-CODE: polly.merge_new_and_old

Copied: polly/trunk/test/ScopDetect/cross_loop_non_single_exit.ll (from r179158, polly/trunk/test/ScopDetect/simple_loop_non_single_exit.ll)
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopDetect/cross_loop_non_single_exit.ll?p2=polly/trunk/test/ScopDetect/cross_loop_non_single_exit.ll&p1=polly/trunk/test/ScopDetect/simple_loop_non_single_exit.ll&r1=179158&r2=179159&rev=179159&view=diff
==============================================================================
--- polly/trunk/test/ScopDetect/simple_loop_non_single_exit.ll (original)
+++ polly/trunk/test/ScopDetect/cross_loop_non_single_exit.ll Wed Apr 10 01:55:31 2013
@@ -1,13 +1,14 @@
 ; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -polly-region-simplify -polly-detect -analyze < %s | FileCheck %s -check-prefix=CHECK-SIMPLIFY
 ; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -polly-region-simplify -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s -check-prefix=CHECK-SIMPLIFY
 
 ; void f(long A[], long N) {
 ;   long i;
 ;   if (true)
 ;     for (i = 0; i < N; ++i)
 ;       A[i] = i;
+;   else
+;     for (j = 0; j < N; ++j)
+;        A[j] = j;
 ; }
 
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
@@ -16,7 +17,18 @@ target triple = "x86_64-unknown-linux-gn
 define void @f(i64* %A, i64 %N) nounwind {
 entry:
   fence seq_cst
-  br label %next
+  br i1 true, label %next, label %next2
+
+next2:
+  br i1 true, label %for.j, label %return
+
+for.j:
+  %indvar2 = phi i64 [ 0, %next2], [ %indvar2.next2, %for.j]
+  %scevgep2 = getelementptr i64* %A, i64 %indvar2
+  store i64 %indvar2, i64* %scevgep2
+  %indvar2.next2 = add nsw i64 %indvar2, 1
+  %exitcond2 = icmp eq i64 %indvar2.next2, %N
+  br i1 %exitcond2, label %return, label %for.j
 
 next:
   br i1 true, label %for.i, label %return
@@ -34,5 +46,5 @@ return:
   ret void
 }
 
-; CHECK: Valid Region for Scop: for.i => return
-; CHECK-SIMPLIFY: Valid Region for Scop: next => return
+; CHECK: Valid Region for Scop: next => return
+; CHECK: Valid Region for Scop: next2 => return

Copied: polly/trunk/test/ScopDetect/cross_loop_non_single_exit_2.ll (from r179158, polly/trunk/test/ScopDetect/simple_loop_non_single_exit.ll)
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopDetect/cross_loop_non_single_exit_2.ll?p2=polly/trunk/test/ScopDetect/cross_loop_non_single_exit_2.ll&p1=polly/trunk/test/ScopDetect/simple_loop_non_single_exit.ll&r1=179158&r2=179159&rev=179159&view=diff
==============================================================================
--- polly/trunk/test/ScopDetect/simple_loop_non_single_exit.ll (original)
+++ polly/trunk/test/ScopDetect/cross_loop_non_single_exit_2.ll Wed Apr 10 01:55:31 2013
@@ -1,22 +1,36 @@
 ; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -polly-region-simplify -polly-detect -analyze < %s | FileCheck %s -check-prefix=CHECK-SIMPLIFY
 ; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -polly-region-simplify -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s -check-prefix=CHECK-SIMPLIFY
 
 ; void f(long A[], long N) {
 ;   long i;
 ;   if (true)
 ;     for (i = 0; i < N; ++i)
 ;       A[i] = i;
+;   else
+;     for (j = 0; j < N; ++j)
+;        A[j] = j;
 ; }
 
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
 target triple = "x86_64-unknown-linux-gnu"
 
+declare i64 @foo()
+
 define void @f(i64* %A, i64 %N) nounwind {
 entry:
   fence seq_cst
-  br label %next
+  br i1 true, label %next, label %next2
+
+next2:
+  br i1 true, label %for.j, label %return
+
+for.j:
+  %indvar2 = phi i64 [ 0, %next2], [ %indvar2.next2, %for.j]
+  %scevgep2 = getelementptr i64* %A, i64 %indvar2
+  store i64 %indvar2, i64* %scevgep2
+  %indvar2.next2 = add nsw i64 %indvar2, 1
+  %exitcond2 = icmp eq i64 %indvar2.next2, %N
+  br i1 %exitcond2, label %return, label %for.j
 
 next:
   br i1 true, label %for.i, label %return
@@ -25,14 +39,24 @@ for.i:
   %indvar = phi i64 [ 0, %next], [ %indvar.next, %for.i ]
   %scevgep = getelementptr i64* %A, i64 %indvar
   store i64 %indvar, i64* %scevgep
+  %i = call i64 @foo()
   %indvar.next = add nsw i64 %indvar, 1
   %exitcond = icmp eq i64 %indvar.next, %N
   br i1 %exitcond, label %return, label %for.i
 
 return:
+  br i1 true, label %return_a, label %return_b
+
+return_a:
+  br label %return_join
+
+return_b:
+  br label %return_join
+
+return_join:
   fence seq_cst
   ret void
 }
 
-; CHECK: Valid Region for Scop: for.i => return
-; CHECK-SIMPLIFY: Valid Region for Scop: next => return
+; CHECK-NOT: Valid Region for Scop: next => return
+; CHECK: Valid Region for Scop: next2 => return

Copied: polly/trunk/test/ScopDetect/nested_loop_single_exit.ll (from r179158, polly/trunk/test/ScopDetect/simple_loop_non_single_exit_2.ll)
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopDetect/nested_loop_single_exit.ll?p2=polly/trunk/test/ScopDetect/nested_loop_single_exit.ll&p1=polly/trunk/test/ScopDetect/simple_loop_non_single_exit_2.ll&r1=179158&r2=179159&rev=179159&view=diff
==============================================================================
--- polly/trunk/test/ScopDetect/simple_loop_non_single_exit_2.ll (original)
+++ polly/trunk/test/ScopDetect/nested_loop_single_exit.ll Wed Apr 10 01:55:31 2013
@@ -1,12 +1,12 @@
 ; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -polly-region-simplify -polly-detect -analyze < %s | FileCheck %s -check-prefix=CHECK-SIMPLIFY
-; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -polly-region-simplify -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s -check-prefix=CHECK-SIMPLIFY
+; RUN: opt %loadPolly -polly-region-simplify -polly-detect -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-detect -polly-codegen-isl -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-region-simplify -polly-detect -polly-codegen-isl -analyze < %s | FileCheck %s
 
 ; void f(long A[], long N) {
-;   long i;
+;   long i, j;
 ;   if (true)
-;     if (true)
+;     for (j = 0; j < N; ++j)
 ;       for (i = 0; i < N; ++i)
 ;         A[i] = i;
 ; }
@@ -17,23 +17,31 @@ target triple = "x86_64-unknown-linux-gn
 define void @f(i64* %A, i64 %N) nounwind {
 entry:
   fence seq_cst
-  br i1 true, label %next, label %return
+  br label %next
 
 next:
-  br i1 true, label %for.i, label %return
+  br i1 true, label %for.j, label %return
+
+for.j:
+  %j.015 = phi i64 [ %inc5, %for.inc8 ], [ 0, %next ]
+  br label %for.i
 
 for.i:
-  %indvar = phi i64 [ 0, %next], [ %indvar.next, %for.i ]
+  %indvar = phi i64 [ 0, %for.j], [ %indvar.next, %for.i ]
   %scevgep = getelementptr i64* %A, i64 %indvar
   store i64 %indvar, i64* %scevgep
   %indvar.next = add nsw i64 %indvar, 1
   %exitcond = icmp eq i64 %indvar.next, %N
-  br i1 %exitcond, label %return, label %for.i
+  br i1 %exitcond, label %for.inc8, label %for.i
+
+for.inc8:                                         ; preds = %for.body3
+  %inc5 = add nsw i64 %j.015, 1
+  %exitcond16 = icmp eq i64 %inc5, %N
+  br i1 %exitcond16, label %return, label %for.j
 
 return:
   fence seq_cst
   ret void
 }
 
-; CHECK: Valid Region for Scop: for.i => return
-; CHECK-SIMPLIFY: Valid Region for Scop: next => return.single_exit1
+; CHECK: Valid Region for Scop: next => return

Modified: polly/trunk/test/ScopDetect/simple_loop_non_single_exit.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopDetect/simple_loop_non_single_exit.ll?rev=179159&r1=179158&r2=179159&view=diff
==============================================================================
--- polly/trunk/test/ScopDetect/simple_loop_non_single_exit.ll (original)
+++ polly/trunk/test/ScopDetect/simple_loop_non_single_exit.ll Wed Apr 10 01:55:31 2013
@@ -1,7 +1,7 @@
 ; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -polly-region-simplify -polly-detect -analyze < %s | FileCheck %s -check-prefix=CHECK-SIMPLIFY
+; RUN: opt %loadPolly -polly-region-simplify -polly-detect -analyze < %s | FileCheck %s
 ; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -polly-region-simplify -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s -check-prefix=CHECK-SIMPLIFY
+; RUN: opt %loadPolly -polly-region-simplify -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
 
 ; void f(long A[], long N) {
 ;   long i;
@@ -34,5 +34,4 @@ return:
   ret void
 }
 
-; CHECK: Valid Region for Scop: for.i => return
-; CHECK-SIMPLIFY: Valid Region for Scop: next => return
+; CHECK: Valid Region for Scop: next => return

Modified: polly/trunk/test/ScopDetect/simple_loop_non_single_exit_2.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopDetect/simple_loop_non_single_exit_2.ll?rev=179159&r1=179158&r2=179159&view=diff
==============================================================================
--- polly/trunk/test/ScopDetect/simple_loop_non_single_exit_2.ll (original)
+++ polly/trunk/test/ScopDetect/simple_loop_non_single_exit_2.ll Wed Apr 10 01:55:31 2013
@@ -1,7 +1,7 @@
 ; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -polly-region-simplify -polly-detect -analyze < %s | FileCheck %s -check-prefix=CHECK-SIMPLIFY
+; RUN: opt %loadPolly -polly-region-simplify -polly-detect -analyze < %s | FileCheck %s
 ; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
-; RUN: opt %loadPolly -polly-region-simplify -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s -check-prefix=CHECK-SIMPLIFY
+; RUN: opt %loadPolly -polly-region-simplify -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
 
 ; void f(long A[], long N) {
 ;   long i;
@@ -35,5 +35,4 @@ return:
   ret void
 }
 
-; CHECK: Valid Region for Scop: for.i => return
-; CHECK-SIMPLIFY: Valid Region for Scop: next => return.single_exit1
+; CHECK: Valid Region for Scop: next => return





More information about the llvm-commits mailing list