1616#ifndef LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H
1717#define LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H
1818
19+ #include " llvm/ADT/SmallBitVector.h"
1920#include " llvm/Analysis/GenericDomTreeUpdater.h"
2021#include " llvm/Support/Debug.h"
2122#include " llvm/Support/raw_ostream.h"
@@ -61,6 +62,9 @@ void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::applyUpdates(
6162 return ;
6263
6364 if (Strategy == UpdateStrategy::Lazy) {
65+ if (!CriticalEdgesToSplit.empty ())
66+ applySplitCriticalEdges ();
67+
6468 PendUpdates.reserve (PendUpdates.size () + Updates.size ());
6569 for (const auto &U : Updates)
6670 if (!isSelfDominance (U))
@@ -136,6 +140,7 @@ GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::getDomTree() {
136140 assert (DT && " Invalid acquisition of a null DomTree" );
137141 applyDomTreeUpdates ();
138142 dropOutOfDateUpdates ();
143+ applySplitCriticalEdges ();
139144 return *DT;
140145}
141146
@@ -145,6 +150,7 @@ GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::getPostDomTree() {
145150 assert (PDT && " Invalid acquisition of a null PostDomTree" );
146151 applyPostDomTreeUpdates ();
147152 dropOutOfDateUpdates ();
153+ applySplitCriticalEdges ();
148154 return *PDT;
149155}
150156
@@ -201,7 +207,7 @@ GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::dump() const {
201207 if (To) {
202208 auto S = To->getName ();
203209 if (!To->hasName ())
204- S = " (no_name )" ;
210+ S = " (no name )" ;
205211 OS << S << " (" << To << " )\n " ;
206212 } else {
207213 OS << " (badref)\n " ;
@@ -229,6 +235,22 @@ GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::dump() const {
229235 printUpdates (I, PendUpdates.end ());
230236 }
231237
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+
232254 OS << " Pending DeletedBBs:\n " ;
233255 Index = 0 ;
234256 for (const auto *BB : DeletedBBs) {
@@ -237,7 +259,7 @@ GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::dump() const {
237259 if (BB->hasName ())
238260 OS << BB->getName () << " (" ;
239261 else
240- OS << " (no_name )(" ;
262+ OS << " (no name )(" ;
241263 OS << BB << " )\n " ;
242264 }
243265#endif
@@ -348,6 +370,123 @@ void GenericDomTreeUpdater<DerivedT, DomTreeT,
348370 PendPDTUpdateIndex -= dropIndex;
349371}
350372
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+
351490} // namespace llvm
352491
353492#endif // LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H
0 commit comments