@@ -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
@@ -395,6 +407,35 @@ auto GenericCycleInfo<ContextT>::getCycle(const BlockT *Block) const
395
407
return nullptr ;
396
408
}
397
409
410
+ // / \brief Find the innermost cycle containing both given cycles.
411
+ // /
412
+ // / \returns the innermost cycle containing both \p A and \p B
413
+ // / or nullptr if there is no such cycle.
414
+ template <typename ContextT>
415
+ auto GenericCycleInfo<ContextT>::getSmallestCommonCycle(CycleT *A,
416
+ CycleT *B) const
417
+ -> CycleT * {
418
+ if (!A || !B)
419
+ return nullptr ;
420
+
421
+ // If cycles A and B have different depth replace them with parent cycle
422
+ // until they have the same depth.
423
+ while (A->getDepth () > B->getDepth ())
424
+ A = A->getParentCycle ();
425
+ while (B->getDepth () > A->getDepth ())
426
+ B = B->getParentCycle ();
427
+
428
+ // Cycles A and B are at same depth but may be disjoint, replace them with
429
+ // parent cycles until we find cycle that contains both or we run out of
430
+ // parent cycles.
431
+ while (A != B) {
432
+ A = A->getParentCycle ();
433
+ B = B->getParentCycle ();
434
+ }
435
+
436
+ return A;
437
+ }
438
+
398
439
// / \brief get the depth for the cycle which containing a given block.
399
440
// /
400
441
// / \returns the depth for the innermost cycle containing \p Block or 0 if it is
0 commit comments