summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--polly/include/polly/ScopInfo.h4
-rw-r--r--polly/lib/Analysis/ScopInfo.cpp43
-rw-r--r--polly/test/ScopInfo/non-pure-function-calls-causes-dead-blocks.ll3
3 files changed, 48 insertions, 2 deletions
diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h
index 975bc020b17..0abe493c366 100644
--- a/polly/include/polly/ScopInfo.h
+++ b/polly/include/polly/ScopInfo.h
@@ -1218,6 +1218,10 @@ private:
/// @param R The region we currently build branching conditions for.
void propagateDomainConstraints(Region *R);
+ /// @brief Remove domains of error blocks/regions (and blocks dominated by
+ /// them).
+ void removeErrorBlockDomains();
+
/// @brief Compute the domain for each basic block in @p R.
///
/// @param R The region we currently traverse.
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp
index 2eef4d36ac7..b78423f2edd 100644
--- a/polly/lib/Analysis/ScopInfo.cpp
+++ b/polly/lib/Analysis/ScopInfo.cpp
@@ -23,6 +23,7 @@
#include "polly/Support/GICHelper.h"
#include "polly/Support/SCEVValidator.h"
#include "polly/Support/ScopHelper.h"
+#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/STLExtras.h"
@@ -2005,6 +2006,38 @@ isl_set *Scop::getDomainConditions(BasicBlock *BB) {
return isl_set_copy(DomainMap[BB]);
}
+void Scop::removeErrorBlockDomains() {
+ auto removeDomains = [this](BasicBlock *Start) {
+ auto BBNode = DT.getNode(Start);
+ for (auto ErrorChild : depth_first(BBNode)) {
+ auto ErrorChildBlock = ErrorChild->getBlock();
+ auto CurrentDomain = DomainMap[ErrorChildBlock];
+ auto Empty = isl_set_empty(isl_set_get_space(CurrentDomain));
+ DomainMap[ErrorChildBlock] = Empty;
+ isl_set_free(CurrentDomain);
+ }
+ };
+
+ std::vector<Region *> Todo = {&R};
+
+ while (!Todo.empty()) {
+ auto SubRegion = Todo.back();
+ Todo.pop_back();
+
+ if (!SD.isNonAffineSubRegion(SubRegion, &getRegion())) {
+ for (auto &Child : *SubRegion)
+ Todo.push_back(Child.get());
+ continue;
+ }
+ if (containsErrorBlock(SubRegion->getNode(), getRegion(), LI, DT))
+ removeDomains(SubRegion->getEntry());
+ }
+
+ for (auto BB : R.blocks())
+ if (isErrorBlock(*BB, R, LI, DT))
+ removeDomains(BB);
+}
+
void Scop::buildDomains(Region *R) {
auto *EntryBB = R->getEntry();
@@ -2024,6 +2057,16 @@ void Scop::buildDomains(Region *R) {
buildDomainsWithBranchConstraints(R);
propagateDomainConstraints(R);
+
+ // Error blocks and blocks dominated by them have been assumed to never be
+ // executed. Representing them in the Scop does not add any value. In fact,
+ // it is likely to cause issues during construction of the ScopStmts. The
+ // contents of error blocks have not been verfied to be expressible and
+ // will cause problems when building up a ScopStmt for them.
+ // Furthermore, basic blocks dominated by error blocks may reference
+ // instructions in the error block which, if the error block is not modeled,
+ // can themselves not be constructed properly.
+ removeErrorBlockDomains();
}
void Scop::buildDomainsWithBranchConstraints(Region *R) {
diff --git a/polly/test/ScopInfo/non-pure-function-calls-causes-dead-blocks.ll b/polly/test/ScopInfo/non-pure-function-calls-causes-dead-blocks.ll
index 0de19eb0512..437d9b3d615 100644
--- a/polly/test/ScopInfo/non-pure-function-calls-causes-dead-blocks.ll
+++ b/polly/test/ScopInfo/non-pure-function-calls-causes-dead-blocks.ll
@@ -37,8 +37,7 @@
; CHECK: Assumed Context:
; CHECK-NEXT: [timeit, N] -> { : timeit = 0 }
; CHECK: Statements {
-; CHECK: Stmt_if_then_split
-; CHECK: [timeit, N] -> { Stmt_if_then_split[] : timeit <= -1 or timeit >= 1 };
+; CHECK-NOT: Stmt_if_then_split
; CHECK: Stmt_for_body
; CHECK: Stmt_for_body_9
; CHECK: }
OpenPOWER on IntegriCloud