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