@@ -582,15 +582,17 @@ struct AllSwitchPaths {
582582 VisitedBlocks VB;
583583 // Get paths from the determinator BBs to SwitchPhiDefBB
584584 std::vector<ThreadingPath> PathsToPhiDef =
585- getPathsFromStateDefMap (StateDef, SwitchPhi, VB);
585+ getPathsFromStateDefMap (StateDef, SwitchPhi, VB, MaxNumPaths );
586586 if (SwitchPhiDefBB == SwitchBlock) {
587587 TPaths = std::move (PathsToPhiDef);
588588 return ;
589589 }
590590
591+ assert (MaxNumPaths >= PathsToPhiDef.size ());
592+ auto PathsLimit = MaxNumPaths / PathsToPhiDef.size ();
591593 // Find and append paths from SwitchPhiDefBB to SwitchBlock.
592594 PathsType PathsToSwitchBB =
593- paths (SwitchPhiDefBB, SwitchBlock, VB, /* PathDepth = */ 1 );
595+ paths (SwitchPhiDefBB, SwitchBlock, VB, /* PathDepth = */ 1 , PathsLimit );
594596 if (PathsToSwitchBB.empty ())
595597 return ;
596598
@@ -611,14 +613,15 @@ struct AllSwitchPaths {
611613 typedef DenseMap<const BasicBlock *, const PHINode *> StateDefMap;
612614 std::vector<ThreadingPath> getPathsFromStateDefMap (StateDefMap &StateDef,
613615 PHINode *Phi,
614- VisitedBlocks &VB) {
616+ VisitedBlocks &VB,
617+ unsigned PathsLimit) {
615618 std::vector<ThreadingPath> Res;
616619 auto *PhiBB = Phi->getParent ();
617620 VB.insert (PhiBB);
618621
619622 VisitedBlocks UniqueBlocks;
620623 for (auto *IncomingBB : Phi->blocks ()) {
621- if (Res.size () >= MaxNumPaths )
624+ if (Res.size () >= PathsLimit )
622625 break ;
623626 if (!UniqueBlocks.insert (IncomingBB).second )
624627 continue ;
@@ -655,12 +658,11 @@ struct AllSwitchPaths {
655658
656659 // Direct predecessor, just add to the path.
657660 if (IncomingPhiDefBB == IncomingBB) {
658- std::vector<ThreadingPath> PredPaths =
659- getPathsFromStateDefMap (StateDef, IncomingPhi, VB);
661+ assert (PathsLimit > Res.size ());
662+ std::vector<ThreadingPath> PredPaths = getPathsFromStateDefMap (
663+ StateDef, IncomingPhi, VB, PathsLimit - Res.size ());
660664 for (ThreadingPath &Path : PredPaths) {
661665 Path.push_back (PhiBB);
662- if (Res.size () >= MaxNumPaths)
663- break ;
664666 Res.push_back (std::move (Path));
665667 }
666668 continue ;
@@ -671,22 +673,22 @@ struct AllSwitchPaths {
671673 continue ;
672674
673675 PathsType IntermediatePaths;
674- IntermediatePaths =
675- paths (IncomingPhiDefBB, IncomingBB, VB, /* PathDepth = */ 1 );
676+ assert (PathsLimit > Res.size ());
677+ auto InterPathLimit = PathsLimit - Res.size ();
678+ IntermediatePaths = paths (IncomingPhiDefBB, IncomingBB, VB,
679+ /* PathDepth = */ 1 , InterPathLimit);
676680 if (IntermediatePaths.empty ())
677681 continue ;
678682
683+ assert (InterPathLimit >= IntermediatePaths.size ());
684+ auto PredPathLimit = InterPathLimit / IntermediatePaths.size ();
679685 std::vector<ThreadingPath> PredPaths =
680- getPathsFromStateDefMap (StateDef, IncomingPhi, VB);
686+ getPathsFromStateDefMap (StateDef, IncomingPhi, VB, PredPathLimit );
681687 for (const ThreadingPath &Path : PredPaths) {
682688 for (const PathType &IPath : IntermediatePaths) {
683689 ThreadingPath NewPath (Path);
684690 NewPath.appendExcludingFirst (IPath);
685691 NewPath.push_back (PhiBB);
686- if (Res.size () >= MaxNumPaths) {
687- VB.erase (PhiBB);
688- return Res;
689- }
690692 Res.push_back (NewPath);
691693 }
692694 }
@@ -696,7 +698,7 @@ struct AllSwitchPaths {
696698 }
697699
698700 PathsType paths (BasicBlock *BB, BasicBlock *ToBB, VisitedBlocks &Visited,
699- unsigned PathDepth) {
701+ unsigned PathDepth, unsigned PathsLimit ) {
700702 PathsType Res;
701703
702704 // Stop exploring paths after visiting MaxPathLength blocks
@@ -723,6 +725,8 @@ struct AllSwitchPaths {
723725 // is used to prevent a duplicate path from being generated
724726 SmallSet<BasicBlock *, 4 > Successors;
725727 for (BasicBlock *Succ : successors (BB)) {
728+ if (Res.size () >= PathsLimit)
729+ break ;
726730 if (!Successors.insert (Succ).second )
727731 continue ;
728732
@@ -744,14 +748,12 @@ struct AllSwitchPaths {
744748 // coverage and compile time.
745749 if (LI->getLoopFor (Succ) != CurrLoop)
746750 continue ;
747-
748- PathsType SuccPaths = paths (Succ, ToBB, Visited, PathDepth + 1 );
751+ assert (PathsLimit > Res.size ());
752+ PathsType SuccPaths =
753+ paths (Succ, ToBB, Visited, PathDepth + 1 , PathsLimit - Res.size ());
749754 for (PathType &Path : SuccPaths) {
750755 Path.push_front (BB);
751756 Res.push_back (Path);
752- if (Res.size () >= MaxNumPaths) {
753- return Res;
754- }
755757 }
756758 }
757759 // This block could now be visited again from a different predecessor. Note
0 commit comments