diff options
| -rw-r--r-- | polly/include/polly/ScopInfo.h | 4 | ||||
| -rw-r--r-- | polly/lib/Analysis/ScopInfo.cpp | 43 | ||||
| -rw-r--r-- | polly/test/ScopInfo/non-pure-function-calls-causes-dead-blocks.ll | 3 |
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: } |

