@@ -879,21 +879,58 @@ bool Compiler::optMakeLoopDownwardsCounted(ScalarEvolutionContext& scevContext,
879
879
{
880
880
JITDUMP (" Checking if we should make " FMT_LP " downwards counted\n " , loop->GetIndex ());
881
881
882
- if (loop->ExitEdges ().size () != 1 )
882
+ BasicBlock* dominates = nullptr ;
883
+
884
+ for (FlowEdge* backEdge : loop->BackEdges ())
883
885
{
884
- // With multiple exits we generally can only compute an upper bound on
885
- // the backedge count.
886
- JITDUMP (" No; has multiple exits\n " );
887
- return false ;
886
+ if (dominates == nullptr )
887
+ {
888
+ dominates = backEdge->getSourceBlock ();
889
+ }
890
+ else
891
+ {
892
+ dominates = m_domTree->Intersect (dominates, backEdge->getSourceBlock ());
893
+ }
888
894
}
889
895
890
- BasicBlock* exiting = loop-> ExitEdge ( 0 )-> getSourceBlock () ;
891
- if (!exiting-> KindIs (BBJ_COND ))
896
+ bool changed = false ;
897
+ while ((dominates != nullptr ) && loop-> ContainsBlock (dominates ))
892
898
{
893
- JITDUMP (" No; exit is not BBJ_COND\n " );
894
- return false ;
899
+ if (dominates->KindIs (BBJ_COND) &&
900
+ (!loop->ContainsBlock (dominates->GetTrueTarget ()) || !loop->ContainsBlock (dominates->GetFalseTarget ())))
901
+ {
902
+ JITDUMP (" Considering exiting block " FMT_BB " \n " , dominates->bbNum );
903
+ // 'dominates' is an exiting block that dominates all backedges.
904
+ changed |= optMakeExitTestDownwardsCounted (scevContext, loop, dominates, loopLocals);
905
+ }
906
+
907
+ dominates = dominates->bbIDom ;
895
908
}
896
909
910
+ return changed;
911
+ }
912
+
913
+ // ------------------------------------------------------------------------
914
+ // optMakeExitTestDownwardsCounted:
915
+ // Try to modify the condition of a specific BBJ_COND exiting block to be on
916
+ // a downwards counted IV if profitable.
917
+ //
918
+ // Parameters:
919
+ // scevContext - SCEV context
920
+ // loop - The specific loop
921
+ // exiting - Exiting block
922
+ // loopLocals - Data structure tracking local uses
923
+ //
924
+ // Returns:
925
+ // True if any modification was made.
926
+ //
927
+ bool Compiler::optMakeExitTestDownwardsCounted (ScalarEvolutionContext& scevContext,
928
+ FlowGraphNaturalLoop* loop,
929
+ BasicBlock* exiting,
930
+ LoopLocalOccurrences* loopLocals)
931
+ {
932
+ assert (exiting->KindIs (BBJ_COND));
933
+
897
934
Statement* jtrueStmt = exiting->lastStmt ();
898
935
GenTree* jtrue = jtrueStmt->GetRootNode ();
899
936
assert (jtrue->OperIs (GT_JTRUE));
@@ -1016,43 +1053,6 @@ bool Compiler::optMakeLoopDownwardsCounted(ScalarEvolutionContext& scevContext,
1016
1053
return false ;
1017
1054
}
1018
1055
1019
- // Commonly there is only a single shared exit and backedge. In that case
1020
- // we do not even need to compute dominators since all backedges are
1021
- // definitely dominated by the exit.
1022
- if ((loop->BackEdges ().size () == 1 ) && loop->BackEdge (0 )->getSourceBlock () == loop->ExitEdge (0 )->getSourceBlock ())
1023
- {
1024
- // Exit definitely dominates the latch since they are the same block.
1025
- // Fall through.
1026
- JITDUMP (" Loop exit is also the only backedge\n " );
1027
- }
1028
- else
1029
- {
1030
- for (FlowEdge* backedge : loop->BackEdges ())
1031
- {
1032
- // We know dom(x, y) => ancestor(x, y), so we can utilize the
1033
- // contrapositive !ancestor(x, y) => !dom(x, y) to avoid computing
1034
- // dominators in some cases.
1035
- if (!m_dfsTree->IsAncestor (exiting, backedge->getSourceBlock ()))
1036
- {
1037
- JITDUMP (" No; exiting block " FMT_BB " is not an ancestor of backedge source " FMT_BB " \n " ,
1038
- exiting->bbNum , backedge->getSourceBlock ()->bbNum );
1039
- return false ;
1040
- }
1041
-
1042
- if (m_domTree == nullptr )
1043
- {
1044
- m_domTree = FlowGraphDominatorTree::Build (m_dfsTree);
1045
- }
1046
-
1047
- if (!m_domTree->Dominates (exiting, backedge->getSourceBlock ()))
1048
- {
1049
- JITDUMP (" No; exiting block " FMT_BB " does not dominate backedge source " FMT_BB " \n " , exiting->bbNum ,
1050
- backedge->getSourceBlock ()->bbNum );
1051
- return false ;
1052
- }
1053
- }
1054
- }
1055
-
1056
1056
// At this point we know that the single exit dominates all backedges.
1057
1057
JITDUMP (" All backedges are dominated by exiting block " FMT_BB " \n " , exiting->bbNum );
1058
1058
@@ -1177,6 +1177,7 @@ PhaseStatus Compiler::optInductionVariables()
1177
1177
1178
1178
optReachableBitVecTraits = nullptr ;
1179
1179
m_dfsTree = fgComputeDfs ();
1180
+ m_domTree = FlowGraphDominatorTree::Build (m_dfsTree);
1180
1181
m_loops = FlowGraphNaturalLoops::Find (m_dfsTree);
1181
1182
1182
1183
LoopLocalOccurrences loopLocals (m_loops);
0 commit comments