summaryrefslogtreecommitdiffstats
path: root/polly/lib/CodeGen/BlockGenerators.cpp
diff options
context:
space:
mode:
authorMichael Kruse <llvm@meinersbur.de>2016-02-25 14:08:48 +0000
committerMichael Kruse <llvm@meinersbur.de>2016-02-25 14:08:48 +0000
commitf33c125dd253981c6ff2bb9505e1d98682c3e846 (patch)
tree14df723fc2eaa76ee3c39492bcaa687354de9ba7 /polly/lib/CodeGen/BlockGenerators.cpp
parent8c83078449b811af5a497faa1637b94f6950fdd2 (diff)
downloadbcm5719-llvm-f33c125dd253981c6ff2bb9505e1d98682c3e846.tar.gz
bcm5719-llvm-f33c125dd253981c6ff2bb9505e1d98682c3e846.zip
Fix DomTree preservation for generated subregions.
The generated dedicated subregion exit block was assumed to have the same dominance relation as the original exit block. This is incorrect if the exit block receives other edges than only from the subregion, which results in that e.g. the subregion's entry block does not dominate the exit block. llvm-svn: 261865
Diffstat (limited to 'polly/lib/CodeGen/BlockGenerators.cpp')
-rw-r--r--polly/lib/CodeGen/BlockGenerators.cpp54
1 files changed, 49 insertions, 5 deletions
diff --git a/polly/lib/CodeGen/BlockGenerators.cpp b/polly/lib/CodeGen/BlockGenerators.cpp
index d1c569f1682..2178558685a 100644
--- a/polly/lib/CodeGen/BlockGenerators.cpp
+++ b/polly/lib/CodeGen/BlockGenerators.cpp
@@ -1027,6 +1027,50 @@ BasicBlock *RegionGenerator::repairDominance(BasicBlock *BB,
return BBCopyIDom;
}
+// This is to determine whether an llvm::Value (defined in @p BB) is usable when
+// leaving a subregion. The straight-forward DT.dominates(BB, R->getExitBlock())
+// does not work in cases where the exit block has edges from outside the
+// region. In that case the llvm::Value would never be usable in in the exit
+// block. The RegionGenerator however creates an new exit block ('ExitBBCopy')
+// for the subregion's exiting edges only. We need to determine whether an
+// llvm::Value is usable in there. We do this by checking whether it dominates
+// all exiting blocks individually.
+static bool isDominatingSubregionExit(const DominatorTree &DT, Region *R,
+ BasicBlock *BB) {
+ for (auto ExitingBB : predecessors(R->getExit())) {
+ // Check for non-subregion incoming edges.
+ if (!R->contains(ExitingBB))
+ continue;
+
+ if (!DT.dominates(BB, ExitingBB))
+ return false;
+ }
+
+ return true;
+}
+
+// Find the direct dominator of the subregion's exit block if the subregion was
+// simplified.
+static BasicBlock *findExitDominator(DominatorTree &DT, Region *R) {
+ BasicBlock *Common = nullptr;
+ for (auto ExitingBB : predecessors(R->getExit())) {
+ // Check for non-subregion incoming edges.
+ if (!R->contains(ExitingBB))
+ continue;
+
+ // First exiting edge.
+ if (!Common) {
+ Common = ExitingBB;
+ continue;
+ }
+
+ Common = DT.findNearestCommonDominator(Common, ExitingBB);
+ }
+
+ assert(Common && R->contains(Common));
+ return Common;
+}
+
void RegionGenerator::copyStmt(ScopStmt &Stmt, LoopToScevMapT &LTS,
isl_id_to_ast_expr *IdToAstExp) {
assert(Stmt.isRegionStmt() &&
@@ -1119,7 +1163,7 @@ void RegionGenerator::copyStmt(ScopStmt &Stmt, LoopToScevMapT &LTS,
Blocks.push_back(*SI);
// Remember value in case it is visible after this subregion.
- if (DT.dominates(BB, ExitBB))
+ if (isDominatingSubregionExit(DT, R, BB))
ValueMap.insert(RegionMap.begin(), RegionMap.end());
}
@@ -1129,10 +1173,10 @@ void RegionGenerator::copyStmt(ScopStmt &Stmt, LoopToScevMapT &LTS,
ExitBBCopy->setName("polly.stmt." + R->getExit()->getName() + ".exit");
BlockMap[R->getExit()] = ExitBBCopy;
- if (ExitBB == R->getExit())
- repairDominance(ExitBB, ExitBBCopy);
- else
- DT.changeImmediateDominator(ExitBBCopy, BlockMap.lookup(ExitBB));
+ BasicBlock *ExitDomBBCopy = BlockMap.lookup(findExitDominator(DT, R));
+ assert(ExitDomBBCopy && "Common exit dominator must be within region; at "
+ "least the entry node must match");
+ DT.changeImmediateDominator(ExitBBCopy, ExitDomBBCopy);
// As the block generator doesn't handle control flow we need to add the
// region control flow by hand after all blocks have been copied.
OpenPOWER on IntegriCloud