summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--polly/include/polly/ScopDetectionDiagnostic.h29
-rw-r--r--polly/lib/Analysis/ScopDetection.cpp16
-rw-r--r--polly/lib/Analysis/ScopDetectionDiagnostic.cpp20
-rw-r--r--polly/test/Isl/CodeGen/loop_partially_in_scop.ll49
-rw-r--r--polly/test/ScopDetectionDiagnostics/loop_partially_in_scop-2.ll24
-rw-r--r--polly/test/ScopDetectionDiagnostics/loop_partially_in_scop.ll34
6 files changed, 120 insertions, 52 deletions
diff --git a/polly/include/polly/ScopDetectionDiagnostic.h b/polly/include/polly/ScopDetectionDiagnostic.h
index 4dfd0fc8d82..f9b28f561e5 100644
--- a/polly/include/polly/ScopDetectionDiagnostic.h
+++ b/polly/include/polly/ScopDetectionDiagnostic.h
@@ -85,6 +85,7 @@ enum class RejectReasonKind {
LoopBound,
LoopHasNoExit,
+ LoopOnlySomeLatches,
FuncCall,
NonSimpleMemoryAccess,
@@ -566,6 +567,34 @@ public:
};
//===----------------------------------------------------------------------===//
+/// Captures errors when not all loop latches are part of the scop.
+class ReportLoopOnlySomeLatches : public RejectReason {
+ //===--------------------------------------------------------------------===//
+
+ /// The loop for which not all loop latches are part of the scop.
+ Loop *L;
+
+ const DebugLoc Loc;
+
+public:
+ ReportLoopOnlySomeLatches(Loop *L)
+ : RejectReason(RejectReasonKind::LoopOnlySomeLatches), L(L),
+ Loc(L->getStartLoc()) {}
+
+ /// @name LLVM-RTTI interface
+ //@{
+ static bool classof(const RejectReason *RR);
+ //@}
+
+ /// @name RejectReason interface
+ //@{
+ virtual std::string getMessage() const override;
+ virtual const DebugLoc &getDebugLoc() const override;
+ virtual std::string getEndUserMessage() const override;
+ //@}
+};
+
+//===----------------------------------------------------------------------===//
/// Captures errors with non-side-effect-known function calls.
class ReportFuncCall : public RejectReason {
//===--------------------------------------------------------------------===//
diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp
index c56d2cc4adb..27dfc930db8 100644
--- a/polly/lib/Analysis/ScopDetection.cpp
+++ b/polly/lib/Analysis/ScopDetection.cpp
@@ -1402,9 +1402,19 @@ bool ScopDetection::allBlocksValid(DetectionContext &Context) const {
for (const BasicBlock *BB : CurRegion.blocks()) {
Loop *L = LI.getLoopFor(BB);
- if (L && L->getHeader() == BB && CurRegion.contains(L) &&
- (!isValidLoop(L, Context) && !KeepGoing))
- return false;
+ if (L && L->getHeader() == BB) {
+ if (CurRegion.contains(L)) {
+ if (!isValidLoop(L, Context) && !KeepGoing)
+ return false;
+ } else {
+ SmallVector<BasicBlock *, 1> Latches;
+ L->getLoopLatches(Latches);
+ for (BasicBlock *Latch : Latches)
+ if (CurRegion.contains(Latch))
+ return invalid<ReportLoopOnlySomeLatches>(Context, /*Assert=*/true,
+ L);
+ }
+ }
}
for (BasicBlock *BB : CurRegion.blocks()) {
diff --git a/polly/lib/Analysis/ScopDetectionDiagnostic.cpp b/polly/lib/Analysis/ScopDetectionDiagnostic.cpp
index ca70018e8fb..ffc259f991a 100644
--- a/polly/lib/Analysis/ScopDetectionDiagnostic.cpp
+++ b/polly/lib/Analysis/ScopDetectionDiagnostic.cpp
@@ -60,6 +60,7 @@ llvm::Statistic RejectStatistics[] = {
SCOP_STAT(LastAffFunc, ""),
SCOP_STAT(LoopBound, "Uncomputable loop bounds"),
SCOP_STAT(LoopHasNoExit, "Loop without exit"),
+ SCOP_STAT(LoopOnlySomeLatches, "Not all loop latches in scop"),
SCOP_STAT(FuncCall, "Function call with side effects"),
SCOP_STAT(NonSimpleMemoryAccess,
"Compilated access semantics (volatile or atomic)"),
@@ -393,6 +394,25 @@ std::string ReportLoopHasNoExit::getEndUserMessage() const {
}
//===----------------------------------------------------------------------===//
+// ReportLoopOnlySomeLatches
+
+std::string ReportLoopOnlySomeLatches::getMessage() const {
+ return "Not all latches of loop " + L->getHeader()->getName() +
+ " part of scop.";
+}
+
+bool ReportLoopOnlySomeLatches::classof(const RejectReason *RR) {
+ return RR->getKind() == RejectReasonKind::LoopHasNoExit;
+}
+
+const DebugLoc &ReportLoopOnlySomeLatches::getDebugLoc() const { return Loc; }
+
+std::string ReportLoopOnlySomeLatches::getEndUserMessage() const {
+ return "Loop cannot be handled because not all latches are part of loop "
+ "region.";
+}
+
+//===----------------------------------------------------------------------===//
// ReportFuncCall.
ReportFuncCall::ReportFuncCall(Instruction *Inst)
diff --git a/polly/test/Isl/CodeGen/loop_partially_in_scop.ll b/polly/test/Isl/CodeGen/loop_partially_in_scop.ll
deleted file mode 100644
index 3cf7f1e73cb..00000000000
--- a/polly/test/Isl/CodeGen/loop_partially_in_scop.ll
+++ /dev/null
@@ -1,49 +0,0 @@
-; RUN: opt %loadPolly -S -polly-codegen < %s | FileCheck %s
-;
-; Verify we do not crash for this test case and additionally check the code
-; that we generate for the %tmp PHI node in the non-affine region. This code
-; is difficult to generate as some incoming edges are from basic blocks
-; from within the region and others from basic blocks from outside of the
-; non-affine region. As visible in the CHECK lines, the code we generate
-; currently loads from the PHI twice in %polly.stmt.bb2.entry, which is
-; something we should avoid.
-;
-; CHECK: polly.start
-
-; CHECK: polly.stmt.bb2.entry: ; preds = %polly.start
-; CHECK-NEXT: %tmp.phiops.reload = load i32, i32* %tmp.phiops
-; CHECK-NEXT: br label %polly.stmt.bb2
-
-; CHECK: polly.stmt.bb2: ; preds = %polly.stmt.bb2, %polly.stmt.bb2.entry
-; CHECK-NEXT: %polly.tmp = phi i32 [ %tmp.phiops.reload, %polly.stmt.bb2.entry ], [ %p_tmp4, %polly.stmt.bb2 ]
-; CHECK-NEXT: %p_tmp3 = or i32 undef, undef
-; CHECK-NEXT: %p_tmp4 = udiv i32 %p_tmp3, 10
-; CHECK-NEXT: %p_tmp6 = icmp eq i8 undef, 0
-; CHECK-NEXT: br i1 %p_tmp6, label %polly.stmt.polly.merge_new_and_old.exit, label %polly.stmt.bb2
-
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-
-define void @baz(i32 %before) {
-bb:
- br label %bb1
-
-bb1: ; preds = %bb
- br label %bb2
-
-bb2: ; preds = %bb8, %bb7, %bb2, %bb1
- %tmp = phi i32 [ %before, %bb1 ], [ 0, %bb8 ], [ %tmp4, %bb7 ], [ %tmp4, %bb2 ]
- %tmp3 = or i32 undef, undef
- %tmp4 = udiv i32 %tmp3, 10
- %tmp5 = trunc i32 undef to i8
- %tmp6 = icmp eq i8 %tmp5, 0
- br i1 %tmp6, label %bb7, label %bb2
-
-bb7: ; preds = %bb2
- br i1 undef, label %bb8, label %bb2
-
-bb8: ; preds = %bb7
- br i1 undef, label %bb9, label %bb2
-
-bb9: ; preds = %bb8
- unreachable
-}
diff --git a/polly/test/ScopDetectionDiagnostics/loop_partially_in_scop-2.ll b/polly/test/ScopDetectionDiagnostics/loop_partially_in_scop-2.ll
new file mode 100644
index 00000000000..2eb039cc2d9
--- /dev/null
+++ b/polly/test/ScopDetectionDiagnostics/loop_partially_in_scop-2.ll
@@ -0,0 +1,24 @@
+; RUN: opt %loadPolly -analyze -polly-detect \
+; RUN: -pass-remarks-missed="polly-detect" \
+; RUN: < %s 2>&1| FileCheck %s
+
+; CHECK: remark: <unknown>:0:0: Loop cannot be handled because not all latches are part of loop region.
+
+define void @foo(i8* %str0) {
+if.end32:
+ br label %while.cond
+
+while.cond:
+ %str.1 = phi i8* [%str0, %if.end32], [%incdec.ptr58364, %lor.end], [%incdec.ptr58364, %while.cond]
+ %tmp5 = load i8, i8* %str.1, align 1
+ %.off367 = add i8 %tmp5, -48
+ %tmp6 = icmp ult i8 %.off367, 10
+ %incdec.ptr58364 = getelementptr inbounds i8, i8* %str.1, i64 1
+ br i1 %tmp6, label %while.cond, label %lor.end
+
+lor.end:
+ br i1 false, label %exit, label %while.cond
+
+exit:
+ ret void
+}
diff --git a/polly/test/ScopDetectionDiagnostics/loop_partially_in_scop.ll b/polly/test/ScopDetectionDiagnostics/loop_partially_in_scop.ll
new file mode 100644
index 00000000000..af01cadd91c
--- /dev/null
+++ b/polly/test/ScopDetectionDiagnostics/loop_partially_in_scop.ll
@@ -0,0 +1,34 @@
+; RUN: opt %loadPolly -analyze -polly-detect \
+; RUN: -pass-remarks-missed="polly-detect" \
+; RUN: < %s 2>&1| FileCheck %s
+
+; CHECK: remark: <unknown>:0:0: Loop cannot be handled because not all latches are part of loop region.
+; CHECK: remark: <unknown>:0:0: Loop cannot be handled because not all latches are part of loop region.
+
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @baz(i32 %before) {
+bb:
+ br label %bb1
+
+bb1: ; preds = %bb
+ br label %bb2
+
+bb2: ; preds = %bb8, %bb7, %bb2, %bb1
+ %tmp = phi i32 [ %before, %bb1 ], [ 0, %bb8 ], [ %tmp4, %bb7 ], [ %tmp4, %bb2 ]
+ %tmp3 = or i32 undef, undef
+ %tmp4 = udiv i32 %tmp3, 10
+ %tmp5 = trunc i32 undef to i8
+ %tmp6 = icmp eq i8 %tmp5, 0
+ br i1 %tmp6, label %bb7, label %bb2
+
+bb7: ; preds = %bb2
+ br i1 undef, label %bb8, label %bb2
+
+bb8: ; preds = %bb7
+ br i1 undef, label %bb9, label %bb2
+
+bb9: ; preds = %bb8
+ unreachable
+}
OpenPOWER on IntegriCloud