@@ -346,6 +346,53 @@ std::pair<BasicBlock *, bool> ControlFlowHub::finalize(
346346 return {FirstGuardBlock, true };
347347}
348348
349+ // Check if the given cycle is disjoint with the cycle of the given basic block.
350+ // If the basic block does not belong to any cycle, this is regarded as
351+ // disjoint, too.
352+ static bool disjointWithBlock (CycleInfo *CI, Cycle *C, BasicBlock *BB) {
353+ Cycle *CC = CI->getCycle (BB);
354+ if (!CC)
355+ return true ;
356+ Cycle *CommonC = CI->getSmallestCommonCycle (C, CC);
357+ return CommonC != C && CommonC != CC;
358+ }
359+
360+ // Check if the given loop is disjoint with the loop of the given basic block.
361+ // If the basic block does not belong to any loop, this is regarded as
362+ // disjoint, too.
363+ static bool disjointWithBlock (LoopInfo *LI, Loop *L, BasicBlock *BB) {
364+ Loop *LL = LI->getLoopFor (BB);
365+ return LL && !L->contains (LL) && !LL->contains (L);
366+ }
367+
368+ template <typename TI, typename T>
369+ static void updateCycleLoopInfo (TI *LCI, bool AttachToCallBr,
370+ BasicBlock *CallBrBlock,
371+ BasicBlock *CallBrTarget, BasicBlock *Succ) {
372+ static_assert (std::is_same_v<TI, CycleInfo> || std::is_same_v<TI, LoopInfo>,
373+ " type must be CycleInfo or LoopInfo" );
374+ if (!LCI)
375+ return ;
376+
377+ T *LC;
378+ if constexpr (std::is_same_v<TI, CycleInfo>)
379+ LC = LCI->getCycle (AttachToCallBr ? CallBrBlock : Succ);
380+ else
381+ LC = LCI->getLoopFor (AttachToCallBr ? CallBrBlock : Succ);
382+ if (!LC)
383+ return ;
384+
385+ // Check if the cycles/loops are disjoint. In that case, we do not add the
386+ // intermediate target to any cycle/loop.
387+ if (AttachToCallBr && disjointWithBlock (LCI, LC, Succ))
388+ return ;
389+
390+ if constexpr (std::is_same_v<TI, CycleInfo>)
391+ LCI->addBlockToCycle (CallBrTarget, LC);
392+ else
393+ LC->addBasicBlockToLoop (CallBrTarget, *LCI);
394+ }
395+
349396BasicBlock *ControlFlowHub::createCallBrTarget (
350397 CallBrInst *CallBr, BasicBlock *Succ, unsigned SuccIdx, bool AttachToCallBr,
351398 CycleInfo *CI, DomTreeUpdater *DTU, LoopInfo *LI) {
@@ -359,36 +406,10 @@ BasicBlock *ControlFlowHub::createCallBrTarget(
359406 CallBr->setSuccessor (SuccIdx, CallBrTarget);
360407 // Jump from the new target block to the original successor.
361408 BranchInst::Create (Succ, CallBrTarget);
362- if (LI) {
363- if (Loop *L = LI->getLoopFor (AttachToCallBr ? CallBrBlock : Succ)) {
364- bool AddToLoop = true ;
365- if (AttachToCallBr) {
366- // Check if the loops are disjoint. In that case, we do not add the
367- // intermediate target to any loop.
368- if (auto *LL = LI->getLoopFor (Succ);
369- LL && !L->contains (LL) && !LL->contains (L))
370- AddToLoop = false ;
371- }
372- if (AddToLoop)
373- L->addBasicBlockToLoop (CallBrTarget, *LI);
374- }
375- }
376- if (CI) {
377- if (auto *C = CI->getCycle (AttachToCallBr ? CallBrBlock : Succ); C) {
378- bool AddToCycle = true ;
379- if (AttachToCallBr) {
380- // Check if the cycles are disjoint. In that case, we do not add the
381- // intermediate target to any cycle.
382- if (auto *CC = CI->getCycle (Succ); CC) {
383- auto *CommonC = CI->getSmallestCommonCycle (C, CC);
384- if (CommonC != C && CommonC != CC)
385- AddToCycle = false ;
386- }
387- }
388- if (AddToCycle)
389- CI->addBlockToCycle (CallBrTarget, C);
390- }
391- }
409+ updateCycleLoopInfo<LoopInfo, Loop>(LI, AttachToCallBr, CallBrBlock,
410+ CallBrTarget, Succ);
411+ updateCycleLoopInfo<CycleInfo, Cycle>(CI, AttachToCallBr, CallBrBlock,
412+ CallBrTarget, Succ);
392413 if (DTU) {
393414 DTU->applyUpdates ({{DominatorTree::Insert, CallBrBlock, CallBrTarget}});
394415 if (DTU->getDomTree ().dominates (CallBrBlock, Succ))
0 commit comments