Skip to content

Commit 79047fa

Browse files
authored
[DomTreeUpdater] Move critical edge splitting code to updater (#115111)
Support critical edge splitting in dominator tree updater. Continue the work in #100856. Compile time check: https://llvm-compile-time-tracker.com/compare.php?from=87c35d782795b54911b3e3a91a5b738d4d870e55&to=42b3e5623a9ab4c3648564dc0926b36f3b438a3a&stat=instructions%3Au
1 parent 30ea0f0 commit 79047fa

30 files changed

+380
-374
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)