ScopInfo: Remove domains of error blocks (and blocks they dominate) early on

Trying to build up access functions for any of these blocks is likely to fail,
as error blocks may contain invalid/non-representable instructions, and blocks
dominated by error blocks may reference such instructions, which wil also cause
failures. As all of these blocks are anyhow assumed to not be executed, we can
just remove them early on.

This fixes http://llvm.org/PR25596

llvm-svn: 253818
This commit is contained in:
Tobias Grosser 2015-11-22 11:06:51 +00:00
parent 71d403effb
commit 9737c7b431
3 changed files with 48 additions and 2 deletions

View File

@ -1218,6 +1218,10 @@ private:
/// @param R The region we currently build branching conditions for. /// @param R The region we currently build branching conditions for.
void propagateDomainConstraints(Region *R); 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. /// @brief Compute the domain for each basic block in @p R.
/// ///
/// @param R The region we currently traverse. /// @param R The region we currently traverse.

View File

@ -23,6 +23,7 @@
#include "polly/Support/GICHelper.h" #include "polly/Support/GICHelper.h"
#include "polly/Support/SCEVValidator.h" #include "polly/Support/SCEVValidator.h"
#include "polly/Support/ScopHelper.h" #include "polly/Support/ScopHelper.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/MapVector.h" #include "llvm/ADT/MapVector.h"
#include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
@ -2005,6 +2006,38 @@ isl_set *Scop::getDomainConditions(BasicBlock *BB) {
return isl_set_copy(DomainMap[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) { void Scop::buildDomains(Region *R) {
auto *EntryBB = R->getEntry(); auto *EntryBB = R->getEntry();
@ -2024,6 +2057,16 @@ void Scop::buildDomains(Region *R) {
buildDomainsWithBranchConstraints(R); buildDomainsWithBranchConstraints(R);
propagateDomainConstraints(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) { void Scop::buildDomainsWithBranchConstraints(Region *R) {

View File

@ -37,8 +37,7 @@
; CHECK: Assumed Context: ; CHECK: Assumed Context:
; CHECK-NEXT: [timeit, N] -> { : timeit = 0 } ; CHECK-NEXT: [timeit, N] -> { : timeit = 0 }
; CHECK: Statements { ; CHECK: Statements {
; CHECK: Stmt_if_then_split ; CHECK-NOT: Stmt_if_then_split
; CHECK: [timeit, N] -> { Stmt_if_then_split[] : timeit <= -1 or timeit >= 1 };
; CHECK: Stmt_for_body ; CHECK: Stmt_for_body
; CHECK: Stmt_for_body_9 ; CHECK: Stmt_for_body_9
; CHECK: } ; CHECK: }