Skip to content

Commit 1562b70

Browse files
authored
Reapply "[DomTreeUpdater] Move critical edge splitting code to updater" (#119547)
This relands commit #115111. Use traditional way to update post dominator tree, i.e. break critical edge splitting into insert, insert, delete sequence. When splitting critical edges, the post dominator tree may change its root node, and `setNewRoot` only works in normal dominator tree... See https://github.com/llvm/llvm-project/blob/6c7e5827eda26990e872eb7c3f0d7866ee3c3171/llvm/include/llvm/Support/GenericDomTree.h#L684-L687
1 parent ada517b commit 1562b70

30 files changed

+359
-368
lines changed

llvm/include/llvm/Analysis/DomTreeUpdater.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ class DomTreeUpdater
8181

8282
///@}
8383

84+
/// Debug method to help view the internal state of this class.
85+
LLVM_DUMP_METHOD void dump() const;
86+
8487
private:
8588
class CallBackOnDeletion final : public CallbackVH {
8689
public:
@@ -109,9 +112,6 @@ class DomTreeUpdater
109112

110113
/// Returns true if at least one BasicBlock is deleted.
111114
bool forceFlushDeletedBB();
112-
113-
/// Debug method to help view the internal state of this class.
114-
LLVM_DUMP_METHOD void dump() const;
115115
};
116116

117117
extern template class GenericDomTreeUpdater<DomTreeUpdater, DominatorTree,
@@ -120,6 +120,13 @@ extern template class GenericDomTreeUpdater<DomTreeUpdater, DominatorTree,
120120
extern template void
121121
GenericDomTreeUpdater<DomTreeUpdater, DominatorTree,
122122
PostDominatorTree>::recalculate(Function &F);
123+
124+
extern template void
125+
GenericDomTreeUpdater<DomTreeUpdater, DominatorTree, PostDominatorTree>::
126+
applyUpdatesImpl</*IsForward=*/true>();
127+
extern template void
128+
GenericDomTreeUpdater<DomTreeUpdater, DominatorTree, PostDominatorTree>::
129+
applyUpdatesImpl</*IsForward=*/false>();
123130
} // namespace llvm
124131

125132
#endif // LLVM_ANALYSIS_DOMTREEUPDATER_H

llvm/include/llvm/Analysis/GenericDomTreeUpdater.h

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class GenericDomTreeUpdater {
3030
public:
3131
enum class UpdateStrategy : unsigned char { Eager = 0, Lazy = 1 };
3232
using BasicBlockT = typename DomTreeT::NodeType;
33+
using UpdateT = typename DomTreeT::UpdateType;
3334

3435
explicit GenericDomTreeUpdater(UpdateStrategy Strategy_)
3536
: Strategy(Strategy_) {}
@@ -146,7 +147,12 @@ class GenericDomTreeUpdater {
146147
/// 2. It is illegal to submit any update that has already been submitted,
147148
/// i.e., you are supposed not to insert an existent edge or delete a
148149
/// nonexistent edge.
149-
void applyUpdates(ArrayRef<typename DomTreeT::UpdateType> Updates);
150+
void applyUpdates(ArrayRef<UpdateT> Updates);
151+
152+
/// Apply updates that the critical edge (FromBB, ToBB) has been
153+
/// split with NewBB.
154+
void splitCriticalEdge(BasicBlockT *FromBB, BasicBlockT *ToBB,
155+
BasicBlockT *NewBB);
150156

151157
/// Submit updates to all available trees. It will also
152158
/// 1. discard duplicated updates,
@@ -169,7 +175,7 @@ class GenericDomTreeUpdater {
169175
/// 3. It is only legal to submit updates to an edge in the order CFG changes
170176
/// are made. The order you submit updates on different edges is not
171177
/// restricted.
172-
void applyUpdatesPermissive(ArrayRef<typename DomTreeT::UpdateType> Updates);
178+
void applyUpdatesPermissive(ArrayRef<UpdateT> Updates);
173179

174180
///@}
175181

@@ -205,7 +211,25 @@ class GenericDomTreeUpdater {
205211
LLVM_DUMP_METHOD void dump() const;
206212

207213
protected:
208-
SmallVector<typename DomTreeT::UpdateType, 16> PendUpdates;
214+
/// Helper structure used to hold all the basic blocks
215+
/// involved in the split of a critical edge.
216+
struct CriticalEdge {
217+
BasicBlockT *FromBB;
218+
BasicBlockT *ToBB;
219+
BasicBlockT *NewBB;
220+
};
221+
222+
struct DomTreeUpdate {
223+
bool IsCriticalEdgeSplit = false;
224+
union {
225+
UpdateT Update;
226+
CriticalEdge EdgeSplit;
227+
};
228+
DomTreeUpdate(UpdateT Update) : Update(Update) {}
229+
DomTreeUpdate(CriticalEdge E) : IsCriticalEdgeSplit(true), EdgeSplit(E) {}
230+
};
231+
232+
SmallVector<DomTreeUpdate, 16> PendUpdates;
209233
size_t PendDTUpdateIndex = 0;
210234
size_t PendPDTUpdateIndex = 0;
211235
DomTreeT *DT = nullptr;
@@ -216,21 +240,21 @@ class GenericDomTreeUpdater {
216240
bool IsRecalculatingPostDomTree = false;
217241

218242
/// Returns true if the update is self dominance.
219-
bool isSelfDominance(typename DomTreeT::UpdateType Update) const {
243+
bool isSelfDominance(UpdateT Update) const {
220244
// Won't affect DomTree and PostDomTree.
221245
return Update.getFrom() == Update.getTo();
222246
}
223247

224248
/// Helper function to apply all pending DomTree updates.
225-
void applyDomTreeUpdates();
249+
void applyDomTreeUpdates() { applyUpdatesImpl<true>(); }
226250

227251
/// Helper function to apply all pending PostDomTree updates.
228-
void applyPostDomTreeUpdates();
252+
void applyPostDomTreeUpdates() { applyUpdatesImpl<false>(); }
229253

230254
/// Returns true if the update appears in the LLVM IR.
231255
/// It is used to check whether an update is valid in
232256
/// insertEdge/deleteEdge or is unnecessary in the batch update.
233-
bool isUpdateValid(typename DomTreeT::UpdateType Update) const;
257+
bool isUpdateValid(UpdateT Update) const;
234258

235259
/// Erase Basic Block node before it is unlinked from Function
236260
/// in the DomTree and PostDomTree.
@@ -243,6 +267,11 @@ class GenericDomTreeUpdater {
243267
/// Drop all updates applied by all available trees and delete BasicBlocks if
244268
/// all available trees are up-to-date.
245269
void dropOutOfDateUpdates();
270+
271+
private:
272+
void splitDTCriticalEdges(ArrayRef<CriticalEdge> Updates);
273+
void splitPDTCriticalEdges(ArrayRef<CriticalEdge> Updates);
274+
template <bool IsForward> void applyUpdatesImpl();
246275
};
247276

248277
} // namespace llvm

0 commit comments

Comments
 (0)