@@ -184,6 +184,24 @@ void GenericCycleInfo<ContextT>::moveTopLevelCycleToNewParent(CycleT *NewParent,
184
184
It.second = NewParent;
185
185
}
186
186
187
+ template <typename ContextT>
188
+ void GenericCycleInfo<ContextT>::addBlockToCycle(BlockT *Block, CycleT *Cycle) {
189
+ // FixMe: Appending NewBlock is fine as a set of blocks in a cycle. When
190
+ // printing, cycle NewBlock is at the end of list but it should be in the
191
+ // middle to represent actual traversal of a cycle.
192
+ Cycle->appendBlock (Block);
193
+ BlockMap.try_emplace (Block, Cycle);
194
+
195
+ CycleT *ParentCycle = Cycle->getParentCycle ();
196
+ while (ParentCycle) {
197
+ Cycle = ParentCycle;
198
+ Cycle->appendBlock (Block);
199
+ ParentCycle = Cycle->getParentCycle ();
200
+ }
201
+
202
+ BlockMapTopLevel.try_emplace (Block, Cycle);
203
+ }
204
+
187
205
// / \brief Main function of the cycle info computations.
188
206
template <typename ContextT>
189
207
void GenericCycleInfoCompute<ContextT>::run(BlockT *EntryBlock) {
@@ -368,17 +386,11 @@ void GenericCycleInfo<ContextT>::splitCriticalEdge(BlockT *Pred, BlockT *Succ,
368
386
BlockT *NewBlock) {
369
387
// Edge Pred-Succ is replaced by edges Pred-NewBlock and NewBlock-Succ, all
370
388
// cycles that had blocks Pred and Succ also get NewBlock.
371
- CycleT *Cycle = this ->getCycle (Pred);
372
- if (Cycle && Cycle->contains (Succ)) {
373
- while (Cycle) {
374
- // FixMe: Appending NewBlock is fine as a set of blocks in a cycle. When
375
- // printing cycle NewBlock is at the end of list but it should be in the
376
- // middle to represent actual traversal of a cycle.
377
- Cycle->appendBlock (NewBlock);
378
- BlockMap.try_emplace (NewBlock, Cycle);
379
- Cycle = Cycle->getParentCycle ();
380
- }
381
- }
389
+ CycleT *Cycle = getSmallestCommonCycle (getCycle (Pred), getCycle (Succ));
390
+ if (!Cycle)
391
+ return ;
392
+
393
+ addBlockToCycle (NewBlock, Cycle);
382
394
assert (validateTree ());
383
395
}
384
396
@@ -392,6 +404,35 @@ auto GenericCycleInfo<ContextT>::getCycle(const BlockT *Block) const
392
404
return BlockMap.lookup (Block);
393
405
}
394
406
407
+ // / \brief Find the innermost cycle containing both given cycles.
408
+ // /
409
+ // / \returns the innermost cycle containing both \p A and \p B
410
+ // / or nullptr if there is no such cycle.
411
+ template <typename ContextT>
412
+ auto GenericCycleInfo<ContextT>::getSmallestCommonCycle(CycleT *A,
413
+ CycleT *B) const
414
+ -> CycleT * {
415
+ if (!A || !B)
416
+ return nullptr ;
417
+
418
+ // If cycles A and B have different depth replace them with parent cycle
419
+ // until they have the same depth.
420
+ while (A->getDepth () > B->getDepth ())
421
+ A = A->getParentCycle ();
422
+ while (B->getDepth () > A->getDepth ())
423
+ B = B->getParentCycle ();
424
+
425
+ // Cycles A and B are at same depth but may be disjoint, replace them with
426
+ // parent cycles until we find cycle that contains both or we run out of
427
+ // parent cycles.
428
+ while (A != B) {
429
+ A = A->getParentCycle ();
430
+ B = B->getParentCycle ();
431
+ }
432
+
433
+ return A;
434
+ }
435
+
395
436
// / \brief get the depth for the cycle which containing a given block.
396
437
// /
397
438
// / \returns the depth for the innermost cycle containing \p Block or 0 if it is
0 commit comments