16
16
#ifndef LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H
17
17
#define LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H
18
18
19
+ #include " llvm/ADT/SmallBitVector.h"
19
20
#include " llvm/Analysis/GenericDomTreeUpdater.h"
20
21
#include " llvm/Support/Debug.h"
21
22
#include " llvm/Support/raw_ostream.h"
@@ -61,6 +62,9 @@ void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::applyUpdates(
61
62
return ;
62
63
63
64
if (Strategy == UpdateStrategy::Lazy) {
65
+ if (!CriticalEdgesToSplit.empty ())
66
+ applySplitCriticalEdges ();
67
+
64
68
PendUpdates.reserve (PendUpdates.size () + Updates.size ());
65
69
for (const auto &U : Updates)
66
70
if (!isSelfDominance (U))
@@ -136,6 +140,7 @@ GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::getDomTree() {
136
140
assert (DT && " Invalid acquisition of a null DomTree" );
137
141
applyDomTreeUpdates ();
138
142
dropOutOfDateUpdates ();
143
+ applySplitCriticalEdges ();
139
144
return *DT;
140
145
}
141
146
@@ -145,6 +150,7 @@ GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::getPostDomTree() {
145
150
assert (PDT && " Invalid acquisition of a null PostDomTree" );
146
151
applyPostDomTreeUpdates ();
147
152
dropOutOfDateUpdates ();
153
+ applySplitCriticalEdges ();
148
154
return *PDT;
149
155
}
150
156
@@ -201,7 +207,7 @@ GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::dump() const {
201
207
if (To) {
202
208
auto S = To->getName ();
203
209
if (!To->hasName ())
204
- S = " (no_name )" ;
210
+ S = " (no name )" ;
205
211
OS << S << " (" << To << " )\n " ;
206
212
} else {
207
213
OS << " (badref)\n " ;
@@ -229,6 +235,22 @@ GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::dump() const {
229
235
printUpdates (I, PendUpdates.end ());
230
236
}
231
237
238
+ auto printCriticalEdges = [&](const CriticalEdge &E) {
239
+ auto FromName = E.FromBB ->getName ();
240
+ if (!E.FromBB ->hasName ())
241
+ FromName = " (no name)" ;
242
+ auto NewName = E.NewBB ->getName ();
243
+ if (!E.NewBB ->hasName ())
244
+ NewName = " (no name)" ;
245
+ auto ToName = E.ToBB ->getName ();
246
+ if (!E.ToBB ->hasName ())
247
+ ToName = " (no name)" ;
248
+ OS << " " << FromName << " , " << NewName << " , " << ToName << ' \n ' ;
249
+ };
250
+ OS << " Critical edges to be split:\n " ;
251
+ for (const auto &E : CriticalEdgesToSplit)
252
+ printCriticalEdges (E);
253
+
232
254
OS << " Pending DeletedBBs:\n " ;
233
255
Index = 0 ;
234
256
for (const auto *BB : DeletedBBs) {
@@ -237,7 +259,7 @@ GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::dump() const {
237
259
if (BB->hasName ())
238
260
OS << BB->getName () << " (" ;
239
261
else
240
- OS << " (no_name )(" ;
262
+ OS << " (no name )(" ;
241
263
OS << BB << " )\n " ;
242
264
}
243
265
#endif
@@ -348,6 +370,123 @@ void GenericDomTreeUpdater<DerivedT, DomTreeT,
348
370
PendPDTUpdateIndex -= dropIndex;
349
371
}
350
372
373
+ template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
374
+ void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::
375
+ applyUpdatesForCriticalEdgeSplitting (BasicBlockT *FromBB, BasicBlockT *ToBB,
376
+ BasicBlockT *NewBB) {
377
+ if (!DT && !PDT)
378
+ return ;
379
+ CriticalEdgesToSplit.push_back ({FromBB, ToBB, NewBB});
380
+ bool Inserted = NewBBs.insert (NewBB).second ;
381
+ (void )Inserted;
382
+ assert (Inserted &&
383
+ " A basic block inserted via edge splitting cannot appear twice" );
384
+ if (Strategy == UpdateStrategy::Lazy) {
385
+ applyDomTreeUpdates ();
386
+ applyPostDomTreeUpdates ();
387
+ }
388
+ if (Strategy == UpdateStrategy::Eager)
389
+ applySplitCriticalEdges ();
390
+ }
391
+
392
+ template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
393
+ void GenericDomTreeUpdater<DerivedT, DomTreeT,
394
+ PostDomTreeT>::applySplitCriticalEdges() {
395
+ // Bail out early if there is nothing to do.
396
+ if (CriticalEdgesToSplit.empty ())
397
+ return ;
398
+
399
+ // For each element in CriticalEdgesToSplit, remember whether or not element
400
+ // is the new immediate domminator of its successor. The mapping is done by
401
+ // index, i.e., the information for the ith element of CriticalEdgesToSplit is
402
+ // the ith element of IsNewIDom.
403
+ SmallBitVector IsNewIDom (CriticalEdgesToSplit.size (), true );
404
+ SmallBitVector IsNewIPDom (CriticalEdgesToSplit.size (), true );
405
+ size_t Idx = 0 ;
406
+
407
+ // Collect all the dominance properties info, before invalidating
408
+ // the underlying DT.
409
+ for (CriticalEdge &Edge : CriticalEdgesToSplit) {
410
+ // Update dominator information.
411
+ if (DT) {
412
+ BasicBlockT *Succ = Edge.ToBB ;
413
+ auto *SuccDTNode = DT->getNode (Succ);
414
+
415
+ for (BasicBlockT *PredBB : predecessors (Succ)) {
416
+ if (PredBB == Edge.NewBB )
417
+ continue ;
418
+ // If we are in this situation:
419
+ // FromBB1 FromBB2
420
+ // + +
421
+ // + + + +
422
+ // + + + +
423
+ // ... Split1 Split2 ...
424
+ // + +
425
+ // + +
426
+ // +
427
+ // Succ
428
+ // Instead of checking the domiance property with Split2, we check it
429
+ // with FromBB2 since Split2 is still unknown of the underlying DT
430
+ // structure.
431
+ if (NewBBs.count (PredBB)) {
432
+ assert (pred_size (PredBB) == 1 && " A basic block resulting from a "
433
+ " critical edge split has more "
434
+ " than one predecessor!" );
435
+ PredBB = *pred_begin (PredBB);
436
+ }
437
+ if (!DT->dominates (SuccDTNode, DT->getNode (PredBB))) {
438
+ IsNewIDom[Idx] = false ;
439
+ break ;
440
+ }
441
+ }
442
+ }
443
+
444
+ // Same as DT version but from another direction.
445
+ if (PDT) {
446
+ BasicBlockT *Pred = Edge.FromBB ;
447
+ auto *PredDTNode = PDT->getNode (Pred);
448
+ for (BasicBlockT *SuccBB : successors (Pred)) {
449
+ if (SuccBB == Edge.NewBB )
450
+ continue ;
451
+ if (NewBBs.count (SuccBB)) {
452
+ assert (succ_size (SuccBB) == 1 && " A basic block resulting from a "
453
+ " critical edge split has more "
454
+ " than one predecessor!" );
455
+ SuccBB = *succ_begin (SuccBB);
456
+ }
457
+ if (!PDT->dominates (PredDTNode, PDT->getNode (SuccBB))) {
458
+ IsNewIPDom[Idx] = false ;
459
+ break ;
460
+ }
461
+ }
462
+ }
463
+ ++Idx;
464
+ }
465
+
466
+ // Now, update DT with the collected dominance properties info.
467
+ Idx = 0 ;
468
+ for (CriticalEdge &Edge : CriticalEdgesToSplit) {
469
+ if (DT) {
470
+ // We know FromBB dominates NewBB.
471
+ auto *NewDTNode = DT->addNewBlock (Edge.NewBB , Edge.FromBB );
472
+
473
+ // If all the other predecessors of "Succ" are dominated by "Succ" itself
474
+ // then the new block is the new immediate dominator of "Succ". Otherwise,
475
+ // the new block doesn't dominate anything.
476
+ if (IsNewIDom[Idx])
477
+ DT->changeImmediateDominator (DT->getNode (Edge.ToBB ), NewDTNode);
478
+ }
479
+ if (PDT) {
480
+ auto *NewPDTNode = PDT->addNewBlock (Edge.NewBB , Edge.ToBB );
481
+ if (IsNewIPDom[Idx])
482
+ PDT->changeImmediateDominator (PDT->getNode (Edge.FromBB ), NewPDTNode);
483
+ }
484
+ ++Idx;
485
+ }
486
+ NewBBs.clear ();
487
+ CriticalEdgesToSplit.clear ();
488
+ }
489
+
351
490
} // namespace llvm
352
491
353
492
#endif // LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H
0 commit comments