@@ -581,15 +581,17 @@ struct AllSwitchPaths {
581
581
VisitedBlocks VB;
582
582
// Get paths from the determinator BBs to SwitchPhiDefBB
583
583
std::vector<ThreadingPath> PathsToPhiDef =
584
- getPathsFromStateDefMap (StateDef, SwitchPhi, VB);
585
- if (SwitchPhiDefBB == SwitchBlock) {
584
+ getPathsFromStateDefMap (StateDef, SwitchPhi, VB, MaxNumPaths );
585
+ if (SwitchPhiDefBB == SwitchBlock || PathsToPhiDef. empty () ) {
586
586
TPaths = std::move (PathsToPhiDef);
587
587
return ;
588
588
}
589
589
590
+ assert (MaxNumPaths >= PathsToPhiDef.size () && !PathsToPhiDef.empty ());
591
+ auto PathsLimit = MaxNumPaths / PathsToPhiDef.size ();
590
592
// Find and append paths from SwitchPhiDefBB to SwitchBlock.
591
593
PathsType PathsToSwitchBB =
592
- paths (SwitchPhiDefBB, SwitchBlock, VB, /* PathDepth = */ 1 );
594
+ paths (SwitchPhiDefBB, SwitchBlock, VB, /* PathDepth = */ 1 , PathsLimit );
593
595
if (PathsToSwitchBB.empty ())
594
596
return ;
595
597
@@ -610,13 +612,16 @@ struct AllSwitchPaths {
610
612
typedef DenseMap<const BasicBlock *, const PHINode *> StateDefMap;
611
613
std::vector<ThreadingPath> getPathsFromStateDefMap (StateDefMap &StateDef,
612
614
PHINode *Phi,
613
- VisitedBlocks &VB) {
615
+ VisitedBlocks &VB,
616
+ unsigned PathsLimit) {
614
617
std::vector<ThreadingPath> Res;
615
618
auto *PhiBB = Phi->getParent ();
616
619
VB.insert (PhiBB);
617
620
618
621
VisitedBlocks UniqueBlocks;
619
622
for (auto *IncomingBB : Phi->blocks ()) {
623
+ if (Res.size () >= PathsLimit)
624
+ break ;
620
625
if (!UniqueBlocks.insert (IncomingBB).second )
621
626
continue ;
622
627
if (!SwitchOuterLoop->contains (IncomingBB))
@@ -652,8 +657,9 @@ struct AllSwitchPaths {
652
657
653
658
// Direct predecessor, just add to the path.
654
659
if (IncomingPhiDefBB == IncomingBB) {
655
- std::vector<ThreadingPath> PredPaths =
656
- getPathsFromStateDefMap (StateDef, IncomingPhi, VB);
660
+ assert (PathsLimit > Res.size ());
661
+ std::vector<ThreadingPath> PredPaths = getPathsFromStateDefMap (
662
+ StateDef, IncomingPhi, VB, PathsLimit - Res.size ());
657
663
for (ThreadingPath &Path : PredPaths) {
658
664
Path.push_back (PhiBB);
659
665
Res.push_back (std::move (Path));
@@ -666,13 +672,17 @@ struct AllSwitchPaths {
666
672
continue ;
667
673
668
674
PathsType IntermediatePaths;
669
- IntermediatePaths =
670
- paths (IncomingPhiDefBB, IncomingBB, VB, /* PathDepth = */ 1 );
675
+ assert (PathsLimit > Res.size ());
676
+ auto InterPathLimit = PathsLimit - Res.size ();
677
+ IntermediatePaths = paths (IncomingPhiDefBB, IncomingBB, VB,
678
+ /* PathDepth = */ 1 , InterPathLimit);
671
679
if (IntermediatePaths.empty ())
672
680
continue ;
673
681
682
+ assert (InterPathLimit >= IntermediatePaths.size ());
683
+ auto PredPathLimit = InterPathLimit / IntermediatePaths.size ();
674
684
std::vector<ThreadingPath> PredPaths =
675
- getPathsFromStateDefMap (StateDef, IncomingPhi, VB);
685
+ getPathsFromStateDefMap (StateDef, IncomingPhi, VB, PredPathLimit );
676
686
for (const ThreadingPath &Path : PredPaths) {
677
687
for (const PathType &IPath : IntermediatePaths) {
678
688
ThreadingPath NewPath (Path);
@@ -687,7 +697,7 @@ struct AllSwitchPaths {
687
697
}
688
698
689
699
PathsType paths (BasicBlock *BB, BasicBlock *ToBB, VisitedBlocks &Visited,
690
- unsigned PathDepth) {
700
+ unsigned PathDepth, unsigned PathsLimit ) {
691
701
PathsType Res;
692
702
693
703
// Stop exploring paths after visiting MaxPathLength blocks
@@ -714,6 +724,8 @@ struct AllSwitchPaths {
714
724
// is used to prevent a duplicate path from being generated
715
725
SmallPtrSet<BasicBlock *, 4 > Successors;
716
726
for (BasicBlock *Succ : successors (BB)) {
727
+ if (Res.size () >= PathsLimit)
728
+ break ;
717
729
if (!Successors.insert (Succ).second )
718
730
continue ;
719
731
@@ -735,14 +747,12 @@ struct AllSwitchPaths {
735
747
// coverage and compile time.
736
748
if (LI->getLoopFor (Succ) != CurrLoop)
737
749
continue ;
738
-
739
- PathsType SuccPaths = paths (Succ, ToBB, Visited, PathDepth + 1 );
750
+ assert (PathsLimit > Res.size ());
751
+ PathsType SuccPaths =
752
+ paths (Succ, ToBB, Visited, PathDepth + 1 , PathsLimit - Res.size ());
740
753
for (PathType &Path : SuccPaths) {
741
754
Path.push_front (BB);
742
755
Res.push_back (Path);
743
- if (Res.size () >= MaxNumPaths) {
744
- return Res;
745
- }
746
756
}
747
757
}
748
758
// This block could now be visited again from a different predecessor. Note
0 commit comments