diff options
-rw-r--r-- | polly/include/polly/ScopDetectionDiagnostic.h | 25 | ||||
-rw-r--r-- | polly/lib/Analysis/ScopDetection.cpp | 8 | ||||
-rw-r--r-- | polly/lib/Analysis/ScopDetectionDiagnostic.cpp | 19 | ||||
-rw-r--r-- | polly/test/ScopDetectionDiagnostics/ReportUnreachableInExit.ll | 31 |
4 files changed, 82 insertions, 1 deletions
diff --git a/polly/include/polly/ScopDetectionDiagnostic.h b/polly/include/polly/ScopDetectionDiagnostic.h index f53855c50a7..226ed9e9993 100644 --- a/polly/include/polly/ScopDetectionDiagnostic.h +++ b/polly/include/polly/ScopDetectionDiagnostic.h @@ -67,6 +67,7 @@ enum class RejectReasonKind { CFG, InvalidTerminator, IrreducibleRegion, + UnreachableInExit, LastCFG, // Non-Affinity @@ -230,6 +231,30 @@ public: }; //===----------------------------------------------------------------------===// +/// Captures regions with an unreachable in the exit block. +class ReportUnreachableInExit : public ReportCFG { + BasicBlock *BB; + DebugLoc DbgLoc; + +public: + ReportUnreachableInExit(BasicBlock *BB, DebugLoc DbgLoc) + : ReportCFG(RejectReasonKind::UnreachableInExit), BB(BB), DbgLoc(DbgLoc) { + } + + /// @name LLVM-RTTI interface + //@{ + static bool classof(const RejectReason *RR); + //@} + + /// @name RejectReason interface + //@{ + virtual std::string getMessage() const override; + virtual std::string getEndUserMessage() const override; + virtual const DebugLoc &getDebugLoc() const override; + //@} +}; + +//===----------------------------------------------------------------------===// /// Base class for non-affine reject reasons. /// /// Scop candidates that violate restrictions to affinity are reported under diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp index a637afa5a41..690655201a1 100644 --- a/polly/lib/Analysis/ScopDetection.cpp +++ b/polly/lib/Analysis/ScopDetection.cpp @@ -1428,6 +1428,13 @@ bool ScopDetection::isValidRegion(DetectionContext &Context) const { return false; } + DebugLoc DbgLoc; + if (isa<UnreachableInst>(CurRegion.getExit()->getTerminator())) { + DEBUG(dbgs() << "Unreachable in exit\n"); + return invalid<ReportUnreachableInExit>(Context, /*Assert=*/true, + CurRegion.getExit(), DbgLoc); + } + if (!CurRegion.getEntry()->getName().count(OnlyRegion)) { DEBUG({ dbgs() << "Region entry does not match -polly-region-only"; @@ -1445,7 +1452,6 @@ bool ScopDetection::isValidRegion(DetectionContext &Context) const { if (!allBlocksValid(Context)) return false; - DebugLoc DbgLoc; if (!isReducibleRegion(CurRegion, DbgLoc)) return invalid<ReportIrreducibleRegion>(Context, /*Assert=*/true, &CurRegion, DbgLoc); diff --git a/polly/lib/Analysis/ScopDetectionDiagnostic.cpp b/polly/lib/Analysis/ScopDetectionDiagnostic.cpp index b2b566bdffd..ca70018e8fb 100644 --- a/polly/lib/Analysis/ScopDetectionDiagnostic.cpp +++ b/polly/lib/Analysis/ScopDetectionDiagnostic.cpp @@ -44,6 +44,7 @@ using namespace llvm; llvm::Statistic RejectStatistics[] = { SCOP_STAT(CFG, ""), SCOP_STAT(InvalidTerminator, "Unsupported terminator instruction"), + SCOP_STAT(UnreachableInExit, "Unreachable in exit block"), SCOP_STAT(IrreducibleRegion, "Irreducible loops"), SCOP_STAT(LastCFG, ""), SCOP_STAT(AffFunc, ""), @@ -190,6 +191,24 @@ bool ReportInvalidTerminator::classof(const RejectReason *RR) { } //===----------------------------------------------------------------------===// +// UnreachableInExit. + +std::string ReportUnreachableInExit::getMessage() const { + std::string BBName = BB->getName(); + return "Unreachable in exit block" + BBName; +} + +const DebugLoc &ReportUnreachableInExit::getDebugLoc() const { return DbgLoc; } + +std::string ReportUnreachableInExit::getEndUserMessage() const { + return "Unreachable in exit block."; +} + +bool ReportUnreachableInExit::classof(const RejectReason *RR) { + return RR->getKind() == RejectReasonKind::UnreachableInExit; +} + +//===----------------------------------------------------------------------===// // ReportIrreducibleRegion. std::string ReportIrreducibleRegion::getMessage() const { diff --git a/polly/test/ScopDetectionDiagnostics/ReportUnreachableInExit.ll b/polly/test/ScopDetectionDiagnostics/ReportUnreachableInExit.ll new file mode 100644 index 00000000000..b775d2886f1 --- /dev/null +++ b/polly/test/ScopDetectionDiagnostics/ReportUnreachableInExit.ll @@ -0,0 +1,31 @@ +; RUN: opt %loadPolly -polly-detect -analyze < %s \ +; RUN: -pass-remarks-missed="polly-detect" 2>&1 | FileCheck %s + +; void f(long A[], long N) { +; long i; +; for (i = 0; i < N; ++i) +; A[i] = i; +; unreachable() +; } + +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" + +define void @f(i64* %A, i64 %N) nounwind { +entry: + fence seq_cst + br label %for.i + +for.i: + %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.i ] + %scevgep = getelementptr i64, 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 + +return: + fence seq_cst + unreachable +} + +; CHECK: Unreachable in exit block |