@@ -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,14 +613,15 @@ 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 ()) {
621
- if (Res.size () >= MaxNumPaths )
624
+ if (Res.size () >= PathsLimit )
622
625
break ;
623
626
if (!UniqueBlocks.insert (IncomingBB).second )
624
627
continue ;
@@ -655,12 +658,11 @@ struct AllSwitchPaths {
655
658
656
659
// Direct predecessor, just add to the path.
657
660
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 ());
660
664
for (ThreadingPath &Path : PredPaths) {
661
665
Path.push_back (PhiBB);
662
- if (Res.size () >= MaxNumPaths)
663
- break ;
664
666
Res.push_back (std::move (Path));
665
667
}
666
668
continue ;
@@ -671,22 +673,22 @@ struct AllSwitchPaths {
671
673
continue ;
672
674
673
675
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);
676
680
if (IntermediatePaths.empty ())
677
681
continue ;
678
682
683
+ assert (InterPathLimit >= IntermediatePaths.size ());
684
+ auto PredPathLimit = InterPathLimit / IntermediatePaths.size ();
679
685
std::vector<ThreadingPath> PredPaths =
680
- getPathsFromStateDefMap (StateDef, IncomingPhi, VB);
686
+ getPathsFromStateDefMap (StateDef, IncomingPhi, VB, PredPathLimit );
681
687
for (const ThreadingPath &Path : PredPaths) {
682
688
for (const PathType &IPath : IntermediatePaths) {
683
689
ThreadingPath NewPath (Path);
684
690
NewPath.appendExcludingFirst (IPath);
685
691
NewPath.push_back (PhiBB);
686
- if (Res.size () >= MaxNumPaths) {
687
- VB.erase (PhiBB);
688
- return Res;
689
- }
690
692
Res.push_back (NewPath);
691
693
}
692
694
}
@@ -696,7 +698,7 @@ struct AllSwitchPaths {
696
698
}
697
699
698
700
PathsType paths (BasicBlock *BB, BasicBlock *ToBB, VisitedBlocks &Visited,
699
- unsigned PathDepth) {
701
+ unsigned PathDepth, unsigned PathsLimit ) {
700
702
PathsType Res;
701
703
702
704
// Stop exploring paths after visiting MaxPathLength blocks
@@ -723,6 +725,8 @@ struct AllSwitchPaths {
723
725
// is used to prevent a duplicate path from being generated
724
726
SmallSet<BasicBlock *, 4 > Successors;
725
727
for (BasicBlock *Succ : successors (BB)) {
728
+ if (Res.size () >= PathsLimit)
729
+ break ;
726
730
if (!Successors.insert (Succ).second )
727
731
continue ;
728
732
@@ -744,14 +748,12 @@ struct AllSwitchPaths {
744
748
// coverage and compile time.
745
749
if (LI->getLoopFor (Succ) != CurrLoop)
746
750
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 ());
749
754
for (PathType &Path : SuccPaths) {
750
755
Path.push_front (BB);
751
756
Res.push_back (Path);
752
- if (Res.size () >= MaxNumPaths) {
753
- return Res;
754
- }
755
757
}
756
758
}
757
759
// This block could now be visited again from a different predecessor. Note
0 commit comments