@@ -73,7 +73,11 @@ struct SemiNCAInfo {
73
73
// Number to node mapping is 1-based. Initialize the mapping to start with
74
74
// a dummy element.
75
75
SmallVector<NodePtr, 64 > NumToNode = {nullptr };
76
- DenseMap<NodePtr, InfoRec> NodeToInfo;
76
+ // If blocks have numbers (e.g., BasicBlock, MachineBasicBlock), store node
77
+ // infos in a vector. Otherwise, store them in a map.
78
+ std::conditional_t <GraphHasNodeNumbers<NodePtr>, SmallVector<InfoRec, 64 >,
79
+ DenseMap<NodePtr, InfoRec>>
80
+ NodeInfos;
77
81
78
82
using UpdateT = typename DomTreeT::UpdateType;
79
83
using UpdateKind = typename DomTreeT::UpdateKind;
@@ -99,7 +103,7 @@ struct SemiNCAInfo {
99
103
100
104
void clear () {
101
105
NumToNode = {nullptr }; // Restore to initial state with a dummy start node.
102
- NodeToInfo .clear ();
106
+ NodeInfos .clear ();
103
107
// Don't reset the pointer to BatchUpdateInfo here -- if there's an update
104
108
// in progress, we need this information to continue it.
105
109
}
@@ -123,13 +127,25 @@ struct SemiNCAInfo {
123
127
return Res;
124
128
}
125
129
126
- NodePtr getIDom (NodePtr BB) const {
127
- auto InfoIt = NodeToInfo.find (BB);
128
- if (InfoIt == NodeToInfo.end ()) return nullptr ;
129
-
130
- return InfoIt->second .IDom ;
130
+ InfoRec &getNodeInfo (NodePtr BB) {
131
+ if constexpr (GraphHasNodeNumbers<NodePtr>) {
132
+ unsigned Idx = BB ? GraphTraits<NodePtr>::getNumber (BB) + 1 : 0 ;
133
+ if (Idx >= NodeInfos.size ()) {
134
+ unsigned Max = 0 ;
135
+ if (BB)
136
+ Max = GraphTraits<decltype (BB->getParent ())>::getMaxNumber (
137
+ BB->getParent ());
138
+ // Max might be zero, graphs might not support getMaxNumber().
139
+ NodeInfos.resize (Max ? Max + 1 : Idx + 1 );
140
+ }
141
+ return NodeInfos[Idx];
142
+ } else {
143
+ return NodeInfos[BB];
144
+ }
131
145
}
132
146
147
+ NodePtr getIDom (NodePtr BB) { return getNodeInfo (BB).IDom ; }
148
+
133
149
TreeNodePtr getNodeForBlock (NodePtr BB, DomTreeT &DT) {
134
150
if (TreeNodePtr Node = DT.getNode (BB)) return Node;
135
151
@@ -181,11 +197,11 @@ struct SemiNCAInfo {
181
197
const NodeOrderMap *SuccOrder = nullptr ) {
182
198
assert (V);
183
199
SmallVector<std::pair<NodePtr, unsigned >, 64 > WorkList = {{V, AttachToNum}};
184
- NodeToInfo[V] .Parent = AttachToNum;
200
+ getNodeInfo (V) .Parent = AttachToNum;
185
201
186
202
while (!WorkList.empty ()) {
187
203
const auto [BB, ParentNum] = WorkList.pop_back_val ();
188
- auto &BBInfo = NodeToInfo[BB] ;
204
+ auto &BBInfo = getNodeInfo (BB) ;
189
205
BBInfo.ReverseChildren .push_back (ParentNum);
190
206
191
207
// Visited nodes always have positive DFS numbers.
@@ -264,7 +280,7 @@ struct SemiNCAInfo {
264
280
// Initialize IDoms to spanning tree parents.
265
281
for (unsigned i = 1 ; i < NextDFSNum; ++i) {
266
282
const NodePtr V = NumToNode[i];
267
- auto &VInfo = NodeToInfo[V] ;
283
+ auto &VInfo = getNodeInfo (V) ;
268
284
VInfo.IDom = NumToNode[VInfo.Parent ];
269
285
NumToInfo.push_back (&VInfo);
270
286
}
@@ -292,7 +308,7 @@ struct SemiNCAInfo {
292
308
const unsigned SDomNum = NumToInfo[WInfo.Semi ]->DFSNum ;
293
309
NodePtr WIDomCandidate = WInfo.IDom ;
294
310
while (true ) {
295
- auto &WIDomCandidateInfo = NodeToInfo. find (WIDomCandidate)-> second ;
311
+ auto &WIDomCandidateInfo = getNodeInfo (WIDomCandidate);
296
312
if (WIDomCandidateInfo.DFSNum <= SDomNum)
297
313
break ;
298
314
WIDomCandidate = WIDomCandidateInfo.IDom ;
@@ -311,7 +327,7 @@ struct SemiNCAInfo {
311
327
assert (IsPostDom && " Only postdominators have a virtual root" );
312
328
assert (NumToNode.size () == 1 && " SNCAInfo must be freshly constructed" );
313
329
314
- auto &BBInfo = NodeToInfo[ nullptr ] ;
330
+ auto &BBInfo = getNodeInfo ( nullptr ) ;
315
331
BBInfo.DFSNum = BBInfo.Semi = BBInfo.Label = 1 ;
316
332
317
333
NumToNode.push_back (nullptr ); // NumToNode[1] = nullptr;
@@ -393,7 +409,7 @@ struct SemiNCAInfo {
393
409
auto InitSuccOrderOnce = [&]() {
394
410
SuccOrder = NodeOrderMap ();
395
411
for (const auto Node : nodes (DT.Parent ))
396
- if (SNCA.NodeToInfo . count (Node) == 0 )
412
+ if (SNCA.getNodeInfo (Node). DFSNum == 0 )
397
413
for (const auto Succ : getChildren<false >(Node, SNCA.BatchUpdates ))
398
414
SuccOrder->try_emplace (Succ, 0 );
399
415
@@ -417,7 +433,7 @@ struct SemiNCAInfo {
417
433
// unreachable node once, we may just visit it in two directions,
418
434
// depending on how lucky we get.
419
435
for (const NodePtr I : nodes (DT.Parent )) {
420
- if (SNCA.NodeToInfo . count (I) == 0 ) {
436
+ if (SNCA.getNodeInfo (I). DFSNum == 0 ) {
421
437
LLVM_DEBUG (dbgs ()
422
438
<< " \t\t\t Visiting node " << BlockNamePrinter (I) << " \n " );
423
439
// Find the furthest away we can get by following successors, then
@@ -449,7 +465,7 @@ struct SemiNCAInfo {
449
465
const NodePtr N = SNCA.NumToNode [i];
450
466
LLVM_DEBUG (dbgs () << " \t\t\t\t Removing DFS info for "
451
467
<< BlockNamePrinter (N) << " \n " );
452
- SNCA.NodeToInfo . erase (N);
468
+ SNCA.getNodeInfo (N) = {} ;
453
469
SNCA.NumToNode .pop_back ();
454
470
}
455
471
const unsigned PrevNum = Num;
@@ -582,7 +598,7 @@ struct SemiNCAInfo {
582
598
583
599
void attachNewSubtree (DomTreeT& DT, const TreeNodePtr AttachTo) {
584
600
// Attach the first unreachable block to AttachTo.
585
- NodeToInfo[ NumToNode[1 ]] .IDom = AttachTo->getBlock ();
601
+ getNodeInfo ( NumToNode[1 ]) .IDom = AttachTo->getBlock ();
586
602
// Loop over all of the discovered blocks in the function...
587
603
for (NodePtr W : llvm::drop_begin (NumToNode)) {
588
604
if (DT.getNode (W))
@@ -600,11 +616,11 @@ struct SemiNCAInfo {
600
616
}
601
617
602
618
void reattachExistingSubtree (DomTreeT &DT, const TreeNodePtr AttachTo) {
603
- NodeToInfo[ NumToNode[1 ]] .IDom = AttachTo->getBlock ();
619
+ getNodeInfo ( NumToNode[1 ]) .IDom = AttachTo->getBlock ();
604
620
for (const NodePtr N : llvm::drop_begin (NumToNode)) {
605
621
const TreeNodePtr TN = DT.getNode (N);
606
622
assert (TN);
607
- const TreeNodePtr NewIDom = DT.getNode (NodeToInfo[N] .IDom );
623
+ const TreeNodePtr NewIDom = DT.getNode (getNodeInfo (N) .IDom );
608
624
TN->setIDom (NewIDom);
609
625
}
610
626
}
@@ -1239,7 +1255,7 @@ struct SemiNCAInfo {
1239
1255
// Virtual root has a corresponding virtual CFG node.
1240
1256
if (DT.isVirtualRoot (TN)) continue ;
1241
1257
1242
- if (NodeToInfo. count (BB) == 0 ) {
1258
+ if (getNodeInfo (BB). DFSNum == 0 ) {
1243
1259
errs () << " DomTree node " << BlockNamePrinter (BB)
1244
1260
<< " not found by DFS walk!\n " ;
1245
1261
errs ().flush ();
@@ -1453,7 +1469,7 @@ struct SemiNCAInfo {
1453
1469
});
1454
1470
1455
1471
for (TreeNodePtr Child : TN->children ())
1456
- if (NodeToInfo. count (Child->getBlock ()) != 0 ) {
1472
+ if (getNodeInfo (Child->getBlock ()). DFSNum != 0 ) {
1457
1473
errs () << " Child " << BlockNamePrinter (Child)
1458
1474
<< " reachable after its parent " << BlockNamePrinter (BB)
1459
1475
<< " is removed!\n " ;
@@ -1491,7 +1507,7 @@ struct SemiNCAInfo {
1491
1507
for (const TreeNodePtr S : TN->children ()) {
1492
1508
if (S == N) continue ;
1493
1509
1494
- if (NodeToInfo. count (S->getBlock ()) == 0 ) {
1510
+ if (getNodeInfo (S->getBlock ()). DFSNum == 0 ) {
1495
1511
errs () << " Node " << BlockNamePrinter (S)
1496
1512
<< " not reachable when its sibling " << BlockNamePrinter (N)
1497
1513
<< " is removed!\n " ;
0 commit comments