diff options
author | Arthur Eubanks <aeubanks@google.com> | 2023-01-19 16:59:36 -0800 |
---|---|---|
committer | Arthur Eubanks <aeubanks@google.com> | 2023-01-19 17:01:15 -0800 |
commit | c5ea42bcf48c8f3d3e35a6bff620b06d2a499108 (patch) | |
tree | 5b1176374b66a976ea7eaf0c45174dc50df834a6 /llvm/lib/Transforms/Utils/LoopUnroll.cpp | |
parent | d5cbaa047004335a29dc3bcaf6aaa1c26fc27f36 (diff) | |
download | llvm-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.cpp | 53 |
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)); |