diff options
-rw-r--r-- | polly/include/polly/ScopDetectionDiagnostic.h | 29 | ||||
-rw-r--r-- | polly/lib/Analysis/ScopDetection.cpp | 16 | ||||
-rw-r--r-- | polly/lib/Analysis/ScopDetectionDiagnostic.cpp | 20 | ||||
-rw-r--r-- | polly/test/Isl/CodeGen/loop_partially_in_scop.ll | 49 | ||||
-rw-r--r-- | polly/test/ScopDetectionDiagnostics/loop_partially_in_scop-2.ll | 24 | ||||
-rw-r--r-- | polly/test/ScopDetectionDiagnostics/loop_partially_in_scop.ll | 34 |
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 +} |