[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