Index: include/polly/ScopDetectionDiagnostic.h =================================================================== --- include/polly/ScopDetectionDiagnostic.h +++ include/polly/ScopDetectionDiagnostic.h @@ -86,7 +86,6 @@ LastAffFunc, LoopBound, - LoopHasNoExit, LoopOnlySomeLatches, FuncCall, @@ -577,36 +576,6 @@ //@} }; -//===----------------------------------------------------------------------===// -/// Captures errors when loop has no exit. -class ReportLoopHasNoExit : public RejectReason { - //===--------------------------------------------------------------------===// - - /// The loop that has no exit. - Loop *L; - - const DebugLoc Loc; - -public: - ReportLoopHasNoExit(Loop *L) - : RejectReason(RejectReasonKind::LoopHasNoExit), L(L), - Loc(L->getStartLoc()) {} - - /// @name LLVM-RTTI interface - //@{ - static bool classof(const RejectReason *RR); - //@} - - /// @name RejectReason interface - //@{ - virtual std::string getRemarkName() const override; - virtual const Value *getRemarkBB() const override; - virtual std::string getMessage() const override; - virtual const DebugLoc &getDebugLoc() const override; - virtual std::string getEndUserMessage() const override; - //@} -}; - //===----------------------------------------------------------------------===// /// Captures errors when not all loop latches are part of the scop. class ReportLoopOnlySomeLatches : public RejectReason { Index: lib/Analysis/ScopDetection.cpp =================================================================== --- lib/Analysis/ScopDetection.cpp +++ lib/Analysis/ScopDetection.cpp @@ -1165,17 +1165,6 @@ return invalid(Context, /*Assert=*/true, &Inst); } -/// Check whether @p L has exiting blocks. -/// -/// @param L The loop of interest -/// -/// @return True if the loop has exiting blocks, false otherwise. -static bool hasExitingBlocks(Loop *L) { - SmallVector ExitingBlocks; - L->getExitingBlocks(ExitingBlocks); - return !ExitingBlocks.empty(); -} - bool ScopDetection::canUseISLTripCount(Loop *L, DetectionContext &Context) const { // Ensure the loop has valid exiting blocks as well as latches, otherwise we @@ -1196,34 +1185,18 @@ // Loops that contain part but not all of the blocks of a region cannot be // handled by the schedule generation. Such loop constructs can happen // because a region can contain BBs that have no path to the exit block - // (Infinite loops, UnreachableInst), but such blocks are never part of a - // loop. - // - // _______________ - // | Loop Header | <-----------. - // --------------- | - // | | - // _______________ ______________ - // | RegionEntry |-----> | RegionExit |-----> - // --------------- -------------- - // | - // _______________ - // | EndlessLoop | <--. - // --------------- | - // | | - // \------------/ - // - // In the example above, the loop (LoopHeader,RegionEntry,RegionExit) is - // neither entirely contained in the region RegionEntry->RegionExit - // (containing RegionEntry,EndlessLoop) nor is the region entirely contained - // in the loop. - // The block EndlessLoop is contained in the region because Region::contains - // tests whether it is not dominated by RegionExit. This is probably to not - // having to query the PostdominatorTree. Instead of an endless loop, a dead - // end can also be formed by an UnreachableInst. This case is already caught - // by isErrorBlock(). We hence only have to reject endless loops here. - if (!hasExitingBlocks(L)) - return invalid(Context, /*Assert=*/true, L); + // (infinite loops, UnreachableInst). + // We do not have to verify against infinite loops here -- they are + // postdominated only by the virtual exit and do not appear in regions. + // Instead of an infinite loop, a dead end can also be formed by an + // UnreachableInst. This case is already caught by isErrorBlock(). + +#ifndef NDEBUG + // Make sure that the loop has exits (i.e. is not infinite). + SmallVector ExitingBlocks; + L->getExitingBlocks(ExitingBlocks); + assert(!ExitingBlocks.empty() && "Region with an infinite loop found!"); +#endif if (canUseISLTripCount(L, Context)) return true; Index: lib/Analysis/ScopDetectionDiagnostic.cpp =================================================================== --- lib/Analysis/ScopDetectionDiagnostic.cpp +++ lib/Analysis/ScopDetectionDiagnostic.cpp @@ -60,7 +60,6 @@ SCOP_STAT(DifferentElementSize, "Accesses with differing sizes"), 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, @@ -459,29 +458,6 @@ return "Failed to derive an affine function from the loop bounds."; } -//===----------------------------------------------------------------------===// -// ReportLoopHasNoExit. - -std::string ReportLoopHasNoExit::getRemarkName() const { - return "LoopHasNoExit"; -} - -const Value *ReportLoopHasNoExit::getRemarkBB() const { return L->getHeader(); } - -std::string ReportLoopHasNoExit::getMessage() const { - return "Loop " + L->getHeader()->getName() + " has no exit."; -} - -bool ReportLoopHasNoExit::classof(const RejectReason *RR) { - return RR->getKind() == RejectReasonKind::LoopHasNoExit; -} - -const DebugLoc &ReportLoopHasNoExit::getDebugLoc() const { return Loc; } - -std::string ReportLoopHasNoExit::getEndUserMessage() const { - return "Loop cannot be handled because it has no exit."; -} - //===----------------------------------------------------------------------===// // ReportLoopOnlySomeLatches @@ -499,7 +475,7 @@ } bool ReportLoopOnlySomeLatches::classof(const RejectReason *RR) { - return RR->getKind() == RejectReasonKind::LoopHasNoExit; + return RR->getKind() == RejectReasonKind::LoopOnlySomeLatches; } const DebugLoc &ReportLoopOnlySomeLatches::getDebugLoc() const { return Loc; } Index: test/ScopDetectionDiagnostics/ReportLoopHasNoExit.ll =================================================================== --- test/ScopDetectionDiagnostics/ReportLoopHasNoExit.ll +++ test/ScopDetectionDiagnostics/ReportLoopHasNoExit.ll @@ -1,3 +1,9 @@ +; XFAIL: * + +; The test case stopped making sense after r310940 that added infinite loops to the +; PostDominatorTree. Infinite loops are postdominated ony by the virtual root, which +; causes them not to appear in regions in ScopDetection anymore. + ; RUN: opt %loadPolly -pass-remarks-missed="polly-detect" -polly-allow-nonaffine-loops -analyze -polly-detect < %s 2>&1 | FileCheck %s ; RUN: opt %loadPolly -pass-remarks-missed="polly-detect" -polly-allow-nonaffine-loops=false -analyze -polly-detect < %s 2>&1 | FileCheck %s