summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
diff options
context:
space:
mode:
authorMax Kazantsev <max.kazantsev@azul.com>2019-02-08 08:12:41 +0000
committerMax Kazantsev <max.kazantsev@azul.com>2019-02-08 08:12:41 +0000
commit6b63d3a27709e8b9165b77819cb21696791339e6 (patch)
tree2f56ad74e044ec3b6b1a28c8b4c3499aed2f35bd /llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
parent5b09834bc364313e48cc54dccd8f251232d84b65 (diff)
downloadbcm5719-llvm-6b63d3a27709e8b9165b77819cb21696791339e6.tar.gz
bcm5719-llvm-6b63d3a27709e8b9165b77819cb21696791339e6.zip
[LoopSimplifyCFG] Use DTU.applyUpdates instead of insert/deleteEdge
`insert/deleteEdge` methods in DTU can make updates incorrectly in some cases (see https://bugs.llvm.org/show_bug.cgi?id=40528), and it is recommended to use `applyUpdates` methods instead when it is needed to make a mass update in CFG. Differential Revision: https://reviews.llvm.org/D57316 Reviewed By: kuhar llvm-svn: 353502
Diffstat (limited to 'llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp33
1 files changed, 22 insertions, 11 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
index dbe68d00c50..01d770ca515 100644
--- a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
@@ -89,6 +89,8 @@ private:
DominatorTree &DT;
ScalarEvolution &SE;
MemorySSAUpdater *MSSAU;
+ DomTreeUpdater DTU;
+ SmallVector<DominatorTree::UpdateType, 16> DTUpdates;
// Whether or not the current loop has irreducible CFG.
bool HasIrreducibleCFG = false;
@@ -319,14 +321,13 @@ private:
// Construct split preheader and the dummy switch to thread edges from it to
// dead exits.
- DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
BasicBlock *Preheader = L.getLoopPreheader();
BasicBlock *NewPreheader = Preheader->splitBasicBlock(
Preheader->getTerminator(),
Twine(Preheader->getName()).concat("-split"));
- DTU.deleteEdge(Preheader, L.getHeader());
- DTU.insertEdge(NewPreheader, L.getHeader());
- DTU.insertEdge(Preheader, NewPreheader);
+ DTUpdates.push_back({DominatorTree::Delete, Preheader, L.getHeader()});
+ DTUpdates.push_back({DominatorTree::Insert, NewPreheader, L.getHeader()});
+ DTUpdates.push_back({DominatorTree::Insert, Preheader, NewPreheader});
IRBuilder<> Builder(Preheader->getTerminator());
SwitchInst *DummySwitch =
Builder.CreateSwitch(Builder.getInt32(0), NewPreheader);
@@ -345,7 +346,7 @@ private:
}
assert(DummyIdx != 0 && "Too many dead exits!");
DummySwitch->addCase(Builder.getInt32(DummyIdx++), BB);
- DTU.insertEdge(Preheader, BB);
+ DTUpdates.push_back({DominatorTree::Insert, Preheader, BB});
++NumLoopExitsDeleted;
}
@@ -389,6 +390,9 @@ private:
while (FixLCSSALoop->getParentLoop() != StillReachable)
FixLCSSALoop = FixLCSSALoop->getParentLoop();
assert(FixLCSSALoop && "Should be a loop!");
+ // We need all DT updates to be done before forming LCSSA.
+ DTU.applyUpdates(DTUpdates);
+ DTUpdates.clear();
formLCSSARecursively(*FixLCSSALoop, DT, &LI, &SE);
}
}
@@ -397,7 +401,6 @@ private:
/// Delete loop blocks that have become unreachable after folding. Make all
/// relevant updates to DT and LI.
void deleteDeadLoopBlocks() {
- DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
if (MSSAU) {
SmallPtrSet<BasicBlock *, 8> DeadLoopBlocksSet(DeadLoopBlocks.begin(),
DeadLoopBlocks.end());
@@ -415,15 +418,18 @@ private:
LI.removeBlock(BB);
}
- DeleteDeadBlocks(DeadLoopBlocks, &DTU);
+ DetatchDeadBlocks(DeadLoopBlocks, &DTUpdates);
+ DTU.applyUpdates(DTUpdates);
+ DTUpdates.clear();
+ for (auto *BB : DeadLoopBlocks)
+ BB->eraseFromParent();
+
NumLoopBlocksDeleted += DeadLoopBlocks.size();
}
/// Constant-fold terminators of blocks acculumated in FoldCandidates into the
/// unconditional branches.
void foldTerminators() {
- DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
-
for (BasicBlock *BB : FoldCandidates) {
assert(LI.getLoopFor(BB) == &L && "Should be a loop block!");
BasicBlock *TheOnlySucc = getOnlyLiveSuccessor(BB);
@@ -465,7 +471,7 @@ private:
Term->eraseFromParent();
for (auto *DeadSucc : DeadSuccessors)
- DTU.deleteEdge(BB, DeadSucc);
+ DTUpdates.push_back({DominatorTree::Delete, BB, DeadSucc});
++NumTerminatorsFolded;
}
@@ -475,7 +481,8 @@ public:
ConstantTerminatorFoldingImpl(Loop &L, LoopInfo &LI, DominatorTree &DT,
ScalarEvolution &SE,
MemorySSAUpdater *MSSAU)
- : L(L), LI(LI), DT(DT), SE(SE), MSSAU(MSSAU) {}
+ : L(L), LI(LI), DT(DT), SE(SE), MSSAU(MSSAU),
+ DTU(DT, DomTreeUpdater::UpdateStrategy::Eager) {}
bool run() {
assert(L.getLoopLatch() && "Should be single latch!");
@@ -539,6 +546,10 @@ public:
<< " dead blocks in loop " << L.getHeader()->getName()
<< "\n");
deleteDeadLoopBlocks();
+ } else {
+ // If we didn't do updates inside deleteDeadLoopBlocks, do them here.
+ DTU.applyUpdates(DTUpdates);
+ DTUpdates.clear();
}
#ifndef NDEBUG
OpenPOWER on IntegriCloud