aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/LoopUnroll.cpp
diff options
context:
space:
mode:
authorArthur Eubanks <aeubanks@google.com>2023-01-19 16:59:36 -0800
committerArthur Eubanks <aeubanks@google.com>2023-01-19 17:01:15 -0800
commitc5ea42bcf48c8f3d3e35a6bff620b06d2a499108 (patch)
tree5b1176374b66a976ea7eaf0c45174dc50df834a6 /llvm/lib/Transforms/Utils/LoopUnroll.cpp
parentd5cbaa047004335a29dc3bcaf6aaa1c26fc27f36 (diff)
downloadllvm-c5ea42bcf48c8f3d3e35a6bff620b06d2a499108.zip
llvm-c5ea42bcf48c8f3d3e35a6bff620b06d2a499108.tar.gz
llvm-c5ea42bcf48c8f3d3e35a6bff620b06d2a499108.tar.bz2
Revert "[LoopUnroll] Directly update DT instead of DTU."
This reverts commit d0907ce7ed9f159562ca3f4cfd8d87e89e93febe. Causes `opt -passes=loop-unroll-full` to crash on ``` define void @foo() { bb: br label %bb1 bb1: ; preds = %bb1, %bb1, %bb switch i1 true, label %bb1 [ i1 true, label %bb2 i1 false, label %bb1 ] bb2: ; preds = %bb1 ret void } ```
Diffstat (limited to 'llvm/lib/Transforms/Utils/LoopUnroll.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/LoopUnroll.cpp53
1 files changed, 10 insertions, 43 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopUnroll.cpp b/llvm/lib/Transforms/Utils/LoopUnroll.cpp
index f8251ee9..cc96d15 100644
--- a/llvm/lib/Transforms/Utils/LoopUnroll.cpp
+++ b/llvm/lib/Transforms/Utils/LoopUnroll.cpp
@@ -321,7 +321,6 @@ LoopUnrollResult llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
unsigned TripMultiple;
unsigned BreakoutTrip;
bool ExitOnTrue;
- BasicBlock *FirstExitingBlock = nullptr;
SmallVector<BasicBlock *> ExitingBlocks;
};
DenseMap<BasicBlock *, ExitInfo> ExitInfos;
@@ -681,7 +680,8 @@ LoopUnrollResult llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
assert(!UnrollVerifyDomtree ||
DT->verify(DominatorTree::VerificationLevel::Fast));
- SmallVector<DominatorTree::UpdateType> DTUpdates;
+ DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
+
auto SetDest = [&](BasicBlock *Src, bool WillExit, bool ExitOnTrue) {
auto *Term = cast<BranchInst>(Src->getTerminator());
const unsigned Idx = ExitOnTrue ^ WillExit;
@@ -695,7 +695,7 @@ LoopUnrollResult llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
BranchInst::Create(Dest, Term);
Term->eraseFromParent();
- DTUpdates.emplace_back(DominatorTree::Delete, Src, DeadSucc);
+ DTU.applyUpdates({{DominatorTree::Delete, Src, DeadSucc}});
};
auto WillExit = [&](const ExitInfo &Info, unsigned i, unsigned j,
@@ -733,56 +733,28 @@ LoopUnrollResult llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
// Fold branches for iterations where we know that they will exit or not
// exit.
- for (auto &Pair : ExitInfos) {
- ExitInfo &Info = Pair.second;
+ for (const auto &Pair : ExitInfos) {
+ const ExitInfo &Info = Pair.second;
for (unsigned i = 0, e = Info.ExitingBlocks.size(); i != e; ++i) {
// The branch destination.
unsigned j = (i + 1) % e;
bool IsLatch = Pair.first == LatchBlock;
std::optional<bool> KnownWillExit = WillExit(Info, i, j, IsLatch);
- if (!KnownWillExit) {
- if (!Info.FirstExitingBlock)
- Info.FirstExitingBlock = Info.ExitingBlocks[i];
+ if (!KnownWillExit)
continue;
- }
// We don't fold known-exiting branches for non-latch exits here,
// because this ensures that both all loop blocks and all exit blocks
// remain reachable in the CFG.
// TODO: We could fold these branches, but it would require much more
// sophisticated updates to LoopInfo.
- if (*KnownWillExit && !IsLatch) {
- if (!Info.FirstExitingBlock)
- Info.FirstExitingBlock = Info.ExitingBlocks[i];
+ if (*KnownWillExit && !IsLatch)
continue;
- }
SetDest(Info.ExitingBlocks[i], *KnownWillExit, Info.ExitOnTrue);
}
}
- DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
- DomTreeUpdater *DTUToUse = &DTU;
- if (ExitingBlocks.size() == 1) {
- // Manually update the DT if there's a single exiting node. In that case
- // there's a single exit node and it is sufficient to update the nodes
- // immediately dominated by the original exiting block. They will become
- // dominated by the first exiting block that leaves the loop after
- // unrolling. Note that the CFG inside the loop does not change, so there's
- // no need to update the DT inside the unrolled loop.
- DTUToUse = nullptr;
- auto &[OriginalExit, Info] = *ExitInfos.begin();
- if (!Info.FirstExitingBlock)
- Info.FirstExitingBlock = Info.ExitingBlocks.back();
- for (auto *C : to_vector(DT->getNode(OriginalExit)->children())) {
- if (L->contains(C->getBlock()))
- continue;
- C->setIDom(DT->getNode(Info.FirstExitingBlock));
- }
- } else {
- DTU.applyUpdates(DTUpdates);
- }
-
// When completely unrolling, the last latch becomes unreachable.
if (!LatchIsExiting && CompletelyUnroll) {
// There is no need to update the DT here, because there must be a unique
@@ -802,21 +774,16 @@ LoopUnrollResult llvm::UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
if (Term && Term->isUnconditional()) {
BasicBlock *Dest = Term->getSuccessor(0);
BasicBlock *Fold = Dest->getUniquePredecessor();
- if (MergeBlockIntoPredecessor(Dest, /*DTU=*/DTUToUse, LI,
- /*MSSAU=*/nullptr, /*MemDep=*/nullptr,
- /*PredecessorWithTwoSuccessors=*/false,
- DTUToUse ? nullptr : DT)) {
+ if (MergeBlockIntoPredecessor(Dest, &DTU, LI)) {
// Dest has been folded into Fold. Update our worklists accordingly.
std::replace(Latches.begin(), Latches.end(), Dest, Fold);
llvm::erase_value(UnrolledLoopBlocks, Dest);
}
}
}
+ // Apply updates to the DomTree.
+ DT = &DTU.getDomTree();
- if (DTUToUse) {
- // Apply updates to the DomTree.
- DT = &DTU.getDomTree();
- }
assert(!UnrollVerifyDomtree ||
DT->verify(DominatorTree::VerificationLevel::Fast));