Add support for mixed pre/post CFG views.
Update usages of the MemorySSAUpdater to use the new DT API by
requesting the DT updates to be done by the MSSAUpdater.
Differential Revision: https://reviews.llvm.org/D93371
ArrayRef<BasicBlock *> ExitBlocks,
ArrayRef<std::unique_ptr<ValueToValueMapTy>> VMaps, DominatorTree &DT);
- /// Apply CFG updates, analogous with the DT edge updates.
- void applyUpdates(ArrayRef<CFGUpdate> 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<CFGUpdate> Updates, DominatorTree &DT,
+ bool UpdateDTFirst = false);
/// Apply CFG insert updates, analogous with the DT edge updates.
void applyInsertUpdates(ArrayRef<CFGUpdate> Updates, DominatorTree &DT);
/// \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<UpdateType> Updates,
ArrayRef<UpdateType> PostViewUpdates) {
GraphDiff<NodePtr, IsPostDom> 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<UpdateType> AllUpdates(Updates.begin(), Updates.end());
+ for (auto &Update : PostViewUpdates)
+ AllUpdates.push_back(Update);
+ GraphDiff<NodePtr, IsPostDom> PreViewCFG(AllUpdates,
+ /*ReverseApplyUpdates=*/true);
+ GraphDiff<NodePtr, IsPostDom> PostViewCFG(PostViewUpdates);
+ DomTreeBuilder::ApplyUpdates(*this, PreViewCFG, &PostViewCFG);
}
}
}
void MemorySSAUpdater::applyUpdates(ArrayRef<CFGUpdate> Updates,
- DominatorTree &DT) {
+ DominatorTree &DT, bool UpdateDT) {
SmallVector<CFGUpdate, 4> DeleteUpdates;
SmallVector<CFGUpdate, 4> RevDeleteUpdates;
SmallVector<CFGUpdate, 4> InsertUpdates;
}
if (!DeleteUpdates.empty()) {
- SmallVector<CFGUpdate, 0> 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<CFGUpdate, 0> 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
// the standard update without a postview of the CFG.
DT.applyUpdates(DeleteUpdates);
} else {
+ if (UpdateDT)
+ DT.applyUpdates(Updates);
GraphDiff<BasicBlock *> GD;
applyInsertUpdates(InsertUpdates, DT, &GD);
}
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);
}
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();
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
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));
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);
}
}