Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -2193,6 +2193,8 @@ // As we are only interested in non-loop carried constraints here we can // simply skip loop back edges. + auto *RI = R->getRegionInfo(); + SmallPtrSet FinishedExitBlocks; ReversePostOrderTraversal RTraversal(R); for (auto *RN : RTraversal) { @@ -2223,6 +2225,27 @@ Loop *BBLoop = getRegionNodeLoop(RN, LI); int BBLoopDepth = getRelativeLoopDepth(BBLoop); + // Check if we can use the region info to determine the domain of some + // other block from the domain of this one. + auto *BBReg = RI ? RI->getRegionFor(BB) : nullptr; + if (BBReg && BBReg->getEntry() == BB) { + auto *ExitBB = BBReg->getExit(); + if (BBLoop == LI.getLoopFor(ExitBB)) { + isl_set *&ExitDomain = DomainMap[ExitBB]; + if (ExitDomain) + ExitDomain = isl_set_union(isl_set_copy(Domain), ExitDomain); + else + ExitDomain = isl_set_copy(Domain); + FinishedExitBlocks.insert(ExitBB); + } + } + + if (std::all_of(succ_begin(BB), succ_end(BB), + [&FinishedExitBlocks](BasicBlock *SuccBB) { + return FinishedExitBlocks.count(SuccBB); + })) + continue; + // Build the condition sets for the successor nodes of the current region // node. If it is a non-affine subregion we will always execute the single // exit node, hence the single entry node domain is the condition set. For @@ -2242,6 +2265,11 @@ isl_set *CondSet = ConditionSets[u]; BasicBlock *SuccBB = getRegionNodeSuccessor(RN, TI, u); + if (FinishedExitBlocks.count(SuccBB)) { + isl_set_free(CondSet); + continue; + } + // Skip back edges. if (DT.dominates(SuccBB, BB)) { isl_set_free(CondSet); Index: test/ScopInfo/remarks.ll =================================================================== --- test/ScopInfo/remarks.ll +++ test/ScopInfo/remarks.ll @@ -1,9 +1,9 @@ ; RUN: opt %loadPolly -pass-remarks-analysis="polly-scops" -polly-scops -disable-output < %s 2>&1 | FileCheck %s ; ; CHECK: remark: test/ScopInfo/remarks.c:4:7: SCoP begins here. -; CHECK: remark: test/ScopInfo/remarks.c:8:5: Finite loop restriction: [M, N, Debug] -> { : M < 0 and N > 0 } +; CHECK: remark: test/ScopInfo/remarks.c:8:5: Finite loop restriction: [M, N] -> { : M < 0 and N > 0 } ; CHECK: remark: test/ScopInfo/remarks.c:13:7: No-error restriction: [M, N, Debug] -> { : M >= 0 and N > 0 and (Debug < 0 or Debug > 0) } -; CHECK: remark: test/ScopInfo/remarks.c:9:7: Inbounds assumption: [M, N, Debug] -> { : M <= 100 or (M > 0 and N <= 0) } +; CHECK: remark: test/ScopInfo/remarks.c:9:7: Inbounds assumption: [M, N] -> { : M <= 100 or (M > 0 and N <= 0) } ; CHECK: remark: :0:0: No-overflows restriction: [N, M, Debug] -> { : M <= -2147483649 - N or M >= 2147483648 - N } ; CHECK: remark: test/ScopInfo/remarks.c:9:18: Possibly aliasing pointer, use restrict keyword. ; CHECK: remark: test/ScopInfo/remarks.c:9:33: Possibly aliasing pointer, use restrict keyword.