Skip to content

Commit f55ad39

Browse files
committed
[DomTree] Extend update API to allow a post CFG view.
Extend the `applyUpdates` in DominatorTree to allow a post CFG view, different from the current CFG. This patch implements the functionality of updating an already up to date DT, to the desired PostCFGView. Combining a set of updates towards an up to date DT and a PostCFGView is not yet supported. Differential Revision: https://reviews.llvm.org/D85472
1 parent 72ddaed commit f55ad39

File tree

5 files changed

+89
-30
lines changed

5 files changed

+89
-30
lines changed

llvm/include/llvm/IR/Dominators.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,11 @@ extern template void DeleteEdge<BBPostDomTree>(BBPostDomTree &DT,
6666
BasicBlock *To);
6767

6868
extern template void ApplyUpdates<BBDomTree>(BBDomTree &DT,
69-
BBDomTreeGraphDiff &);
69+
BBDomTreeGraphDiff &,
70+
BBDomTreeGraphDiff *);
7071
extern template void ApplyUpdates<BBPostDomTree>(BBPostDomTree &DT,
71-
BBPostDomTreeGraphDiff &);
72+
BBPostDomTreeGraphDiff &,
73+
BBPostDomTreeGraphDiff *);
7274

7375
extern template bool Verify<BBDomTree>(const BBDomTree &DT,
7476
BBDomTree::VerificationLevel VL);

llvm/include/llvm/Support/GenericDomTree.h

+27-2
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,9 @@ void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
213213
template <typename DomTreeT>
214214
void ApplyUpdates(DomTreeT &DT,
215215
GraphDiff<typename DomTreeT::NodePtr,
216-
DomTreeT::IsPostDominator> &PreViewCFG);
216+
DomTreeT::IsPostDominator> &PreViewCFG,
217+
GraphDiff<typename DomTreeT::NodePtr,
218+
DomTreeT::IsPostDominator> *PostViewCFG);
217219

218220
template <typename DomTreeT>
219221
bool Verify(const DomTreeT &DT, typename DomTreeT::VerificationLevel VL);
@@ -543,7 +545,30 @@ class DominatorTreeBase {
543545
void applyUpdates(ArrayRef<UpdateType> Updates) {
544546
GraphDiff<NodePtr, IsPostDominator> PreViewCFG(
545547
Updates, /*ReverseApplyUpdates=*/true);
546-
DomTreeBuilder::ApplyUpdates(*this, PreViewCFG);
548+
DomTreeBuilder::ApplyUpdates(*this, PreViewCFG, nullptr);
549+
}
550+
551+
/// \param Updates An unordered sequence of updates to perform. The current
552+
/// CFG and the reverse of these updates provides the pre-view of the CFG.
553+
/// \param PostViewUpdates An unordered sequence of update to perform in order
554+
/// to obtain a post-view of the CFG. The DT will be updates assuming the
555+
/// obtained PostViewCFG is the desired end state.
556+
void applyUpdates(ArrayRef<UpdateType> Updates,
557+
ArrayRef<UpdateType> PostViewUpdates) {
558+
// GraphDiff<NodePtr, IsPostDom> *PostViewCFG = nullptr) {
559+
if (Updates.empty()) {
560+
GraphDiff<NodePtr, IsPostDom> PostViewCFG(PostViewUpdates);
561+
DomTreeBuilder::ApplyUpdates(*this, PostViewCFG, &PostViewCFG);
562+
} else {
563+
// TODO:
564+
// PreViewCFG needs to merge Updates and PostViewCFG. The updates in
565+
// Updates need to be reversed, and match the direction in PostViewCFG.
566+
// Normally, a PostViewCFG is created without reversing updates, so one
567+
// of the internal vectors needs reversing in order to do the
568+
// legalization of the merged vector of updates.
569+
llvm_unreachable("Currently unsupported to update given a set of "
570+
"updates towards a PostView");
571+
}
547572
}
548573

549574
/// Inform the dominator tree about a CFG edge insertion and update the tree.

llvm/include/llvm/Support/GenericDomTreeConstruction.h

+36-13
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,15 @@ struct SemiNCAInfo {
7979
using UpdateKind = typename DomTreeT::UpdateKind;
8080
struct BatchUpdateInfo {
8181
// Note: Updates inside PreViewCFG are aleady legalized.
82-
BatchUpdateInfo(GraphDiffT &PreViewCFG)
83-
: PreViewCFG(PreViewCFG),
82+
BatchUpdateInfo(GraphDiffT &PreViewCFG, GraphDiffT *PostViewCFG = nullptr)
83+
: PreViewCFG(PreViewCFG), PostViewCFG(PostViewCFG),
8484
NumLegalized(PreViewCFG.getNumLegalizedUpdates()) {}
8585

8686
// Remembers if the whole tree was recalculated at some point during the
8787
// current batch update.
8888
bool IsRecalculated = false;
8989
GraphDiffT &PreViewCFG;
90+
GraphDiffT *PostViewCFG;
9091
const size_t NumLegalized;
9192
};
9293

@@ -560,12 +561,21 @@ struct SemiNCAInfo {
560561
auto *Parent = DT.Parent;
561562
DT.reset();
562563
DT.Parent = Parent;
563-
SemiNCAInfo SNCA(nullptr); // Since we are rebuilding the whole tree,
564-
// there's no point doing it incrementally.
564+
// If the update is using the actual CFG, BUI is null. If it's using a view,
565+
// BUI is non-null and the PreCFGView is used. When calculating from
566+
// scratch, make the PreViewCFG equal to the PostCFGView, so Post is used.
567+
BatchUpdatePtr PostViewBUI = nullptr;
568+
if (BUI && BUI->PostViewCFG) {
569+
BUI->PreViewCFG = *BUI->PostViewCFG;
570+
PostViewBUI = BUI;
571+
}
572+
// This is rebuilding the whole tree, not incrementally, but PostViewBUI is
573+
// used in case the caller needs a DT update with a CFGView.
574+
SemiNCAInfo SNCA(PostViewBUI);
565575

566576
// Step #0: Number blocks in depth-first order and initialize variables used
567577
// in later stages of the algorithm.
568-
DT.Roots = FindRoots(DT, nullptr);
578+
DT.Roots = FindRoots(DT, PostViewBUI);
569579
SNCA.doFullDFSWalk(DT, AlwaysDescend);
570580

571581
SNCA.runSemiNCA(DT);
@@ -1139,7 +1149,10 @@ struct SemiNCAInfo {
11391149
//===--------------------- DomTree Batch Updater --------------------------===
11401150
//~~
11411151

1142-
static void ApplyUpdates(DomTreeT &DT, GraphDiffT &PreViewCFG) {
1152+
static void ApplyUpdates(DomTreeT &DT, GraphDiffT &PreViewCFG,
1153+
GraphDiffT *PostViewCFG) {
1154+
// Note: the PostViewCFG is only used when computing from scratch. It's data
1155+
// should already included in the PreViewCFG for incremental updates.
11431156
const size_t NumUpdates = PreViewCFG.getNumLegalizedUpdates();
11441157
if (NumUpdates == 0)
11451158
return;
@@ -1148,14 +1161,22 @@ struct SemiNCAInfo {
11481161
// machinery.
11491162
if (NumUpdates == 1) {
11501163
UpdateT Update = PreViewCFG.popUpdateForIncrementalUpdates();
1151-
if (Update.getKind() == UpdateKind::Insert)
1152-
InsertEdge(DT, /*BUI=*/nullptr, Update.getFrom(), Update.getTo());
1153-
else
1154-
DeleteEdge(DT, /*BUI=*/nullptr, Update.getFrom(), Update.getTo());
1164+
if (!PostViewCFG) {
1165+
if (Update.getKind() == UpdateKind::Insert)
1166+
InsertEdge(DT, /*BUI=*/nullptr, Update.getFrom(), Update.getTo());
1167+
else
1168+
DeleteEdge(DT, /*BUI=*/nullptr, Update.getFrom(), Update.getTo());
1169+
} else {
1170+
BatchUpdateInfo BUI(*PostViewCFG, PostViewCFG);
1171+
if (Update.getKind() == UpdateKind::Insert)
1172+
InsertEdge(DT, &BUI, Update.getFrom(), Update.getTo());
1173+
else
1174+
DeleteEdge(DT, &BUI, Update.getFrom(), Update.getTo());
1175+
}
11551176
return;
11561177
}
11571178

1158-
BatchUpdateInfo BUI(PreViewCFG);
1179+
BatchUpdateInfo BUI(PreViewCFG, PostViewCFG);
11591180
// Recalculate the DominatorTree when the number of updates
11601181
// exceeds a threshold, which usually makes direct updating slower than
11611182
// recalculation. We select this threshold proportional to the
@@ -1571,8 +1592,10 @@ void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
15711592
template <class DomTreeT>
15721593
void ApplyUpdates(DomTreeT &DT,
15731594
GraphDiff<typename DomTreeT::NodePtr,
1574-
DomTreeT::IsPostDominator> &PreViewCFG) {
1575-
SemiNCAInfo<DomTreeT>::ApplyUpdates(DT, PreViewCFG);
1595+
DomTreeT::IsPostDominator> &PreViewCFG,
1596+
GraphDiff<typename DomTreeT::NodePtr,
1597+
DomTreeT::IsPostDominator> *PostViewCFG) {
1598+
SemiNCAInfo<DomTreeT>::ApplyUpdates(DT, PreViewCFG, PostViewCFG);
15761599
}
15771600

15781601
template <class DomTreeT>

llvm/lib/Analysis/MemorySSAUpdater.cpp

+18-10
Original file line numberDiff line numberDiff line change
@@ -783,24 +783,32 @@ void MemorySSAUpdater::updateExitBlocksForClonedLoop(
783783
void MemorySSAUpdater::applyUpdates(ArrayRef<CFGUpdate> Updates,
784784
DominatorTree &DT) {
785785
SmallVector<CFGUpdate, 4> DeleteUpdates;
786+
SmallVector<CFGUpdate, 4> RevDeleteUpdates;
786787
SmallVector<CFGUpdate, 4> InsertUpdates;
787788
for (auto &Update : Updates) {
788789
if (Update.getKind() == DT.Insert)
789790
InsertUpdates.push_back({DT.Insert, Update.getFrom(), Update.getTo()});
790-
else
791+
else {
791792
DeleteUpdates.push_back({DT.Delete, Update.getFrom(), Update.getTo()});
793+
RevDeleteUpdates.push_back({DT.Insert, Update.getFrom(), Update.getTo()});
794+
}
792795
}
793796

794797
if (!DeleteUpdates.empty()) {
795-
// Update for inserted edges: use newDT and snapshot CFG as if deletes had
796-
// not occurred.
797-
// FIXME: This creates a new DT, so it's more expensive to do mix
798-
// delete/inserts vs just inserts. We can do an incremental update on the DT
799-
// to revert deletes, than re-delete the edges. Teaching DT to do this, is
800-
// part of a pending cleanup.
801-
DominatorTree NewDT(DT, DeleteUpdates);
802-
GraphDiff<BasicBlock *> GD(DeleteUpdates, /*ReverseApplyUpdates=*/true);
803-
applyInsertUpdates(InsertUpdates, NewDT, &GD);
798+
SmallVector<CFGUpdate, 0> Empty;
799+
// Deletes are reversed applied, because this CFGView is pretending the
800+
// deletes did not happen yet, hence the edges still exist.
801+
DT.applyUpdates(Empty, RevDeleteUpdates);
802+
803+
// Note: the MSSA update below doesn't distinguish between a GD with
804+
// (RevDelete,false) and (Delete, true), but this matters for the DT
805+
// updates above; for "children" purposes they are equivalent; but the
806+
// updates themselves convey the desired update, used inside DT only.
807+
GraphDiff<BasicBlock *> GD(RevDeleteUpdates);
808+
applyInsertUpdates(InsertUpdates, DT, &GD);
809+
// Update DT to redelete edges; this matches the real CFG so we can perform
810+
// the standard update without a postview of the CFG.
811+
DT.applyUpdates(DeleteUpdates);
804812
} else {
805813
GraphDiff<BasicBlock *> GD;
806814
applyInsertUpdates(InsertUpdates, DT, &GD);

llvm/lib/IR/Dominators.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,11 @@ template void llvm::DomTreeBuilder::DeleteEdge<DomTreeBuilder::BBPostDomTree>(
9090
DomTreeBuilder::BBPostDomTree &DT, BasicBlock *From, BasicBlock *To);
9191

9292
template void llvm::DomTreeBuilder::ApplyUpdates<DomTreeBuilder::BBDomTree>(
93-
DomTreeBuilder::BBDomTree &DT, DomTreeBuilder::BBDomTreeGraphDiff &);
93+
DomTreeBuilder::BBDomTree &DT, DomTreeBuilder::BBDomTreeGraphDiff &,
94+
DomTreeBuilder::BBDomTreeGraphDiff *);
9495
template void llvm::DomTreeBuilder::ApplyUpdates<DomTreeBuilder::BBPostDomTree>(
95-
DomTreeBuilder::BBPostDomTree &DT,
96-
DomTreeBuilder::BBPostDomTreeGraphDiff &);
96+
DomTreeBuilder::BBPostDomTree &DT, DomTreeBuilder::BBPostDomTreeGraphDiff &,
97+
DomTreeBuilder::BBPostDomTreeGraphDiff *);
9798

9899
template bool llvm::DomTreeBuilder::Verify<DomTreeBuilder::BBDomTree>(
99100
const DomTreeBuilder::BBDomTree &DT,

0 commit comments

Comments
 (0)