@@ -30,6 +30,7 @@ class GenericDomTreeUpdater {
30
30
public:
31
31
enum class UpdateStrategy : unsigned char { Eager = 0 , Lazy = 1 };
32
32
using BasicBlockT = typename DomTreeT::NodeType;
33
+ using UpdateT = typename DomTreeT::UpdateType;
33
34
34
35
explicit GenericDomTreeUpdater (UpdateStrategy Strategy_)
35
36
: Strategy(Strategy_) {}
@@ -146,7 +147,12 @@ class GenericDomTreeUpdater {
146
147
// / 2. It is illegal to submit any update that has already been submitted,
147
148
// / i.e., you are supposed not to insert an existent edge or delete a
148
149
// / 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);
150
156
151
157
// / Submit updates to all available trees. It will also
152
158
// / 1. discard duplicated updates,
@@ -169,7 +175,7 @@ class GenericDomTreeUpdater {
169
175
// / 3. It is only legal to submit updates to an edge in the order CFG changes
170
176
// / are made. The order you submit updates on different edges is not
171
177
// / restricted.
172
- void applyUpdatesPermissive (ArrayRef<typename DomTreeT::UpdateType > Updates);
178
+ void applyUpdatesPermissive (ArrayRef<UpdateT > Updates);
173
179
174
180
// /@}
175
181
@@ -205,7 +211,25 @@ class GenericDomTreeUpdater {
205
211
LLVM_DUMP_METHOD void dump () const ;
206
212
207
213
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;
209
233
size_t PendDTUpdateIndex = 0 ;
210
234
size_t PendPDTUpdateIndex = 0 ;
211
235
DomTreeT *DT = nullptr ;
@@ -216,21 +240,21 @@ class GenericDomTreeUpdater {
216
240
bool IsRecalculatingPostDomTree = false ;
217
241
218
242
// / Returns true if the update is self dominance.
219
- bool isSelfDominance (typename DomTreeT::UpdateType Update) const {
243
+ bool isSelfDominance (UpdateT Update) const {
220
244
// Won't affect DomTree and PostDomTree.
221
245
return Update.getFrom () == Update.getTo ();
222
246
}
223
247
224
248
// / Helper function to apply all pending DomTree updates.
225
- void applyDomTreeUpdates ();
249
+ void applyDomTreeUpdates () { applyUpdatesImpl< true >(); }
226
250
227
251
// / Helper function to apply all pending PostDomTree updates.
228
- void applyPostDomTreeUpdates ();
252
+ void applyPostDomTreeUpdates () { applyUpdatesImpl< false >(); }
229
253
230
254
// / Returns true if the update appears in the LLVM IR.
231
255
// / It is used to check whether an update is valid in
232
256
// / insertEdge/deleteEdge or is unnecessary in the batch update.
233
- bool isUpdateValid (typename DomTreeT::UpdateType Update) const ;
257
+ bool isUpdateValid (UpdateT Update) const ;
234
258
235
259
// / Erase Basic Block node before it is unlinked from Function
236
260
// / in the DomTree and PostDomTree.
@@ -243,6 +267,11 @@ class GenericDomTreeUpdater {
243
267
// / Drop all updates applied by all available trees and delete BasicBlocks if
244
268
// / all available trees are up-to-date.
245
269
void dropOutOfDateUpdates ();
270
+
271
+ private:
272
+ void splitDTCriticalEdges (ArrayRef<CriticalEdge> Updates);
273
+ void splitPDTCriticalEdges (ArrayRef<CriticalEdge> Updates);
274
+ template <bool IsForward> void applyUpdatesImpl ();
246
275
};
247
276
248
277
} // namespace llvm
0 commit comments