diff --git a/llvm/include/llvm/Analysis/MemorySSAUpdater.h b/llvm/include/llvm/Analysis/MemorySSAUpdater.h --- a/llvm/include/llvm/Analysis/MemorySSAUpdater.h +++ b/llvm/include/llvm/Analysis/MemorySSAUpdater.h @@ -119,8 +119,11 @@ ArrayRef ExitBlocks, ArrayRef> VMaps, DominatorTree &DT); - /// Apply CFG updates, analogous with the DT edge updates. - void applyUpdates(ArrayRef Updates, DominatorTree &DT); + /// Apply CFG updates, analogous with the DT edge updates. By default, the + /// DT is assumed to be already up to date. If UpdateDTFirst is true, first + /// update the DT with the same updates. + void applyUpdates(ArrayRef Updates, DominatorTree &DT, + bool UpdateDTFirst = false); /// Apply CFG insert updates, analogous with the DT edge updates. void applyInsertUpdates(ArrayRef Updates, DominatorTree &DT); diff --git a/llvm/include/llvm/Support/GenericDomTree.h b/llvm/include/llvm/Support/GenericDomTree.h --- a/llvm/include/llvm/Support/GenericDomTree.h +++ b/llvm/include/llvm/Support/GenericDomTree.h @@ -550,7 +550,7 @@ /// \param Updates An unordered sequence of updates to perform. The current /// CFG and the reverse of these updates provides the pre-view of the CFG. /// \param PostViewUpdates An unordered sequence of update to perform in order - /// to obtain a post-view of the CFG. The DT will be updates assuming the + /// to obtain a post-view of the CFG. The DT will be updated assuming the /// obtained PostViewCFG is the desired end state. void applyUpdates(ArrayRef Updates, ArrayRef PostViewUpdates) { @@ -558,14 +558,18 @@ GraphDiff PostViewCFG(PostViewUpdates); DomTreeBuilder::ApplyUpdates(*this, PostViewCFG, &PostViewCFG); } else { - // TODO: // PreViewCFG needs to merge Updates and PostViewCFG. The updates in // Updates need to be reversed, and match the direction in PostViewCFG. - // Normally, a PostViewCFG is created without reversing updates, so one - // of the internal vectors needs reversing in order to do the - // legalization of the merged vector of updates. - llvm_unreachable("Currently unsupported to update given a set of " - "updates towards a PostView"); + // The PostViewCFG is created with updates reversed (equivalent to changes + // made to the CFG), so the PreViewCFG needs all the updates reverse + // applied. + SmallVector AllUpdates(Updates.begin(), Updates.end()); + for (auto &Update : PostViewUpdates) + AllUpdates.push_back(Update); + GraphDiff PreViewCFG(AllUpdates, + /*ReverseApplyUpdates=*/true); + GraphDiff PostViewCFG(PostViewUpdates); + DomTreeBuilder::ApplyUpdates(*this, PreViewCFG, &PostViewCFG); } } diff --git a/llvm/lib/Analysis/MemorySSAUpdater.cpp b/llvm/lib/Analysis/MemorySSAUpdater.cpp --- a/llvm/lib/Analysis/MemorySSAUpdater.cpp +++ b/llvm/lib/Analysis/MemorySSAUpdater.cpp @@ -810,7 +810,7 @@ } void MemorySSAUpdater::applyUpdates(ArrayRef Updates, - DominatorTree &DT) { + DominatorTree &DT, bool UpdateDT) { SmallVector DeleteUpdates; SmallVector RevDeleteUpdates; SmallVector InsertUpdates; @@ -824,10 +824,15 @@ } if (!DeleteUpdates.empty()) { - SmallVector Empty; - // Deletes are reversed applied, because this CFGView is pretending the - // deletes did not happen yet, hence the edges still exist. - DT.applyUpdates(Empty, RevDeleteUpdates); + if (!UpdateDT) { + SmallVector Empty; + // Deletes are reversed applied, because this CFGView is pretending the + // deletes did not happen yet, hence the edges still exist. + DT.applyUpdates(Empty, RevDeleteUpdates); + } else { + // Apply all updates, with the RevDeleteUpdates as PostCFGView. + DT.applyUpdates(Updates, RevDeleteUpdates); + } // Note: the MSSA update below doesn't distinguish between a GD with // (RevDelete,false) and (Delete, true), but this matters for the DT @@ -839,6 +844,8 @@ // the standard update without a postview of the CFG. DT.applyUpdates(DeleteUpdates); } else { + if (UpdateDT) + DT.applyUpdates(Updates); GraphDiff GD; applyInsertUpdates(InsertUpdates, DT, &GD); } diff --git a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp --- a/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp +++ b/llvm/lib/Transforms/Scalar/LoopSimplifyCFG.cpp @@ -415,9 +415,10 @@ FixLCSSALoop = FixLCSSALoop->getParentLoop(); assert(FixLCSSALoop && "Should be a loop!"); // We need all DT updates to be done before forming LCSSA. - DTU.applyUpdates(DTUpdates); if (MSSAU) - MSSAU->applyUpdates(DTUpdates, DT); + MSSAU->applyUpdates(DTUpdates, DT, /*UpdateDT=*/true); + else + DTU.applyUpdates(DTUpdates); DTUpdates.clear(); formLCSSARecursively(*FixLCSSALoop, DT, &LI, &SE); } @@ -425,8 +426,7 @@ if (MSSAU) { // Clear all updates now. Facilitates deletes that follow. - DTU.applyUpdates(DTUpdates); - MSSAU->applyUpdates(DTUpdates, DT); + MSSAU->applyUpdates(DTUpdates, DT, /*UpdateDT=*/true); DTUpdates.clear(); if (VerifyMemorySSA) MSSAU->getMemorySSA()->verifyMemorySSA(); diff --git a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp --- a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -960,10 +960,11 @@ if (OldBranchSucc != TrueDest && OldBranchSucc != FalseDest) { Updates.push_back({DominatorTree::Delete, OldBranchParent, OldBranchSucc}); } - DT->applyUpdates(Updates); if (MSSAU) - MSSAU->applyUpdates(Updates, *DT); + MSSAU->applyUpdates(Updates, *DT, /*UpdateDT=*/true); + else + DT->applyUpdates(Updates); } // If either edge is critical, split it. This helps preserve LoopSimplify diff --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp --- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp @@ -854,13 +854,13 @@ DTUpdates.push_back({DT.Delete, ParentBB, SplitUnswitchedPair.first}); DTUpdates.push_back({DT.Insert, OldPH, SplitUnswitchedPair.second}); } - DT.applyUpdates(DTUpdates); if (MSSAU) { - MSSAU->applyUpdates(DTUpdates, DT); + MSSAU->applyUpdates(DTUpdates, DT, /*UpdateDT=*/true); if (VerifyMemorySSA) MSSAU->getMemorySSA()->verifyMemorySSA(); - } + } else + DT.applyUpdates(DTUpdates); assert(DT.verify(DominatorTree::VerificationLevel::Fast)); diff --git a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp --- a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp @@ -499,12 +499,13 @@ Updates.push_back({DominatorTree::Insert, OrigPreheader, Exit}); Updates.push_back({DominatorTree::Insert, OrigPreheader, NewHeader}); Updates.push_back({DominatorTree::Delete, OrigPreheader, OrigHeader}); - DT->applyUpdates(Updates); if (MSSAU) { - MSSAU->applyUpdates(Updates, *DT); + MSSAU->applyUpdates(Updates, *DT, /*UpdateDT=*/true); if (VerifyMemorySSA) MSSAU->getMemorySSA()->verifyMemorySSA(); + } else { + DT->applyUpdates(Updates); } }