@@ -2825,140 +2825,113 @@ bool Compiler::fgOptimizeBranch(BasicBlock* bJump)
2825
2825
}
2826
2826
2827
2827
// -----------------------------------------------------------------------------
2828
- // fgOptimizeSwitchJump: see if a switch has a dominant case, and modify to
2829
- // check for that case up front (aka switch peeling).
2828
+ // fgPeelSwitch: Modify a switch to check for its dominant case up front.
2830
2829
//
2831
- // Returns :
2832
- // True if the switch now has an upstream check for the dominant case.
2830
+ // Parameters :
2831
+ // block - The switch block with a dominant case
2833
2832
//
2834
- bool Compiler::fgOptimizeSwitchJumps ( )
2833
+ void Compiler::fgPeelSwitch (BasicBlock* block )
2835
2834
{
2836
- if (!fgHasSwitch)
2837
- {
2838
- return false ;
2839
- }
2840
-
2841
- bool modified = false ;
2842
-
2843
- for (BasicBlock* const block : Blocks ())
2844
- {
2845
- // Lowering expands switches, so calling this method on lowered IR
2846
- // does not make sense.
2847
- //
2848
- assert (!block->IsLIR ());
2849
-
2850
- if (!block->KindIs (BBJ_SWITCH))
2851
- {
2852
- continue ;
2853
- }
2854
-
2855
- if (block->isRunRarely ())
2856
- {
2857
- continue ;
2858
- }
2859
-
2860
- if (!block->GetSwitchTargets ()->bbsHasDominantCase )
2861
- {
2862
- continue ;
2863
- }
2835
+ assert (block->KindIs (BBJ_SWITCH));
2836
+ assert (block->GetSwitchTargets ()->bbsHasDominantCase );
2837
+ assert (!block->isRunRarely ());
2864
2838
2865
- // We currently will only see dominant cases with PGO.
2866
- //
2867
- assert (block->hasProfileWeight ());
2839
+ // Lowering expands switches, so calling this method on lowered IR
2840
+ // does not make sense.
2841
+ //
2842
+ assert (!block->IsLIR ());
2868
2843
2869
- const unsigned dominantCase = block->GetSwitchTargets ()->bbsDominantCase ;
2844
+ // We currently will only see dominant cases with PGO.
2845
+ //
2846
+ assert (block->hasProfileWeight ());
2870
2847
2871
- JITDUMP (FMT_BB " has switch with dominant case %u, considering peeling\n " , block->bbNum , dominantCase);
2848
+ const unsigned dominantCase = block->GetSwitchTargets ()->bbsDominantCase ;
2849
+ JITDUMP (FMT_BB " has switch with dominant case %u, considering peeling\n " , block->bbNum , dominantCase);
2872
2850
2873
- // The dominant case should not be the default case, as we already peel that one.
2874
- //
2875
- assert (dominantCase < (block->GetSwitchTargets ()->bbsCount - 1 ));
2876
- BasicBlock* const dominantTarget = block->GetSwitchTargets ()->bbsDstTab [dominantCase]->getDestinationBlock ();
2877
- Statement* const switchStmt = block->lastStmt ();
2878
- GenTree* const switchTree = switchStmt->GetRootNode ();
2879
- assert (switchTree->OperIs (GT_SWITCH));
2880
- GenTree* const switchValue = switchTree->AsOp ()->gtGetOp1 ();
2881
-
2882
- // Split the switch block just before at the switch.
2883
- //
2884
- // After this, newBlock is the switch block, and
2885
- // block is the upstream block.
2886
- //
2887
- BasicBlock* newBlock = nullptr ;
2888
-
2889
- if (block->firstStmt () == switchStmt)
2890
- {
2891
- newBlock = fgSplitBlockAtBeginning (block);
2892
- }
2893
- else
2894
- {
2895
- newBlock = fgSplitBlockAfterStatement (block, switchStmt->GetPrevStmt ());
2896
- }
2851
+ // The dominant case should not be the default case, as we already peel that one.
2852
+ //
2853
+ assert (dominantCase < (block->GetSwitchTargets ()->bbsCount - 1 ));
2854
+ BasicBlock* const dominantTarget = block->GetSwitchTargets ()->bbsDstTab [dominantCase]->getDestinationBlock ();
2855
+ Statement* const switchStmt = block->lastStmt ();
2856
+ GenTree* const switchTree = switchStmt->GetRootNode ();
2857
+ assert (switchTree->OperIs (GT_SWITCH));
2858
+ GenTree* const switchValue = switchTree->gtGetOp1 ();
2859
+
2860
+ // Split the switch block just before at the switch.
2861
+ //
2862
+ // After this, newBlock is the switch block, and
2863
+ // block is the upstream block.
2864
+ //
2865
+ BasicBlock* newBlock = nullptr ;
2897
2866
2898
- // Set up a compare in the upstream block, "stealing" the switch value tree.
2899
- //
2900
- GenTree* const dominantCaseCompare = gtNewOperNode (GT_EQ, TYP_INT, switchValue, gtNewIconNode (dominantCase));
2901
- GenTree* const jmpTree = gtNewOperNode (GT_JTRUE, TYP_VOID, dominantCaseCompare);
2902
- Statement* const jmpStmt = fgNewStmtFromTree (jmpTree, switchStmt->GetDebugInfo ());
2903
- fgInsertStmtAtEnd (block, jmpStmt);
2867
+ if (block->firstStmt () == switchStmt)
2868
+ {
2869
+ newBlock = fgSplitBlockAtBeginning (block);
2870
+ }
2871
+ else
2872
+ {
2873
+ newBlock = fgSplitBlockAfterStatement (block, switchStmt->GetPrevStmt ());
2874
+ }
2904
2875
2905
- // Reattach switch value to the switch. This may introduce a comma
2906
- // in the upstream compare tree, if the switch value expression is complex.
2907
- //
2908
- switchTree->AsOp ()->gtOp1 = fgMakeMultiUse (&dominantCaseCompare->AsOp ()->gtOp1 );
2876
+ // Set up a compare in the upstream block, "stealing" the switch value tree.
2877
+ //
2878
+ GenTree* const dominantCaseCompare = gtNewOperNode (GT_EQ, TYP_INT, switchValue, gtNewIconNode (dominantCase));
2879
+ GenTree* const jmpTree = gtNewOperNode (GT_JTRUE, TYP_VOID, dominantCaseCompare);
2880
+ Statement* const jmpStmt = fgNewStmtFromTree (jmpTree, switchStmt->GetDebugInfo ());
2881
+ fgInsertStmtAtEnd (block, jmpStmt);
2909
2882
2910
- // Update flags
2911
- //
2912
- switchTree->gtFlags = switchTree->AsOp ()->gtOp1 ->gtFlags & GTF_ALL_EFFECT;
2913
- dominantCaseCompare->gtFlags |= dominantCaseCompare->AsOp ()->gtOp1 ->gtFlags & GTF_ALL_EFFECT;
2914
- jmpTree->gtFlags |= dominantCaseCompare->gtFlags & GTF_ALL_EFFECT;
2915
- dominantCaseCompare->gtFlags |= GTF_RELOP_JMP_USED | GTF_DONT_CSE;
2883
+ // Reattach switch value to the switch. This may introduce a comma
2884
+ // in the upstream compare tree, if the switch value expression is complex.
2885
+ //
2886
+ switchTree->AsOp ()->gtOp1 = fgMakeMultiUse (&dominantCaseCompare->AsOp ()->gtOp1 );
2916
2887
2917
- // Wire up the new control flow.
2918
- //
2919
- FlowEdge* const blockToTargetEdge = fgAddRefPred (dominantTarget, block);
2920
- FlowEdge* const blockToNewBlockEdge = newBlock->bbPreds ;
2921
- block->SetCond (blockToTargetEdge, blockToNewBlockEdge);
2888
+ // Update flags
2889
+ //
2890
+ switchTree->gtFlags = switchTree->gtGetOp1 ()->gtFlags & GTF_ALL_EFFECT;
2891
+ dominantCaseCompare->gtFlags |= dominantCaseCompare->gtGetOp1 ()->gtFlags & GTF_ALL_EFFECT;
2892
+ jmpTree->gtFlags |= dominantCaseCompare->gtFlags & GTF_ALL_EFFECT;
2893
+ dominantCaseCompare->gtFlags |= GTF_RELOP_JMP_USED | GTF_DONT_CSE;
2922
2894
2923
- // Update profile data
2924
- //
2925
- const weight_t fraction = newBlock->GetSwitchTargets ()->bbsDominantFraction ;
2926
- const weight_t blockToTargetWeight = block->bbWeight * fraction;
2895
+ // Wire up the new control flow.
2896
+ //
2897
+ FlowEdge* const blockToTargetEdge = fgAddRefPred (dominantTarget, block);
2898
+ FlowEdge* const blockToNewBlockEdge = newBlock->bbPreds ;
2899
+ block->SetCond (blockToTargetEdge, blockToNewBlockEdge);
2927
2900
2928
- newBlock->decreaseBBProfileWeight (blockToTargetWeight);
2901
+ // Update profile data
2902
+ //
2903
+ const weight_t fraction = newBlock->GetSwitchTargets ()->bbsDominantFraction ;
2904
+ const weight_t blockToTargetWeight = block->bbWeight * fraction;
2929
2905
2930
- blockToTargetEdge->setLikelihood (fraction);
2931
- blockToNewBlockEdge->setLikelihood (max (0.0 , 1.0 - fraction));
2906
+ newBlock->decreaseBBProfileWeight (blockToTargetWeight);
2932
2907
2933
- JITDUMP (" fgOptimizeSwitchJumps: Updated flow into " FMT_BB " needs to be propagated. Data %s inconsistent.\n " ,
2934
- newBlock->bbNum , fgPgoConsistent ? " is now" : " was already" );
2935
- fgPgoConsistent = false ;
2908
+ blockToTargetEdge->setLikelihood (fraction);
2909
+ blockToNewBlockEdge->setLikelihood (max (0.0 , 1.0 - fraction));
2936
2910
2937
- // For now we leave the switch as is, since there's no way
2938
- // to indicate that one of the cases is now unreachable.
2939
- //
2940
- // But it no longer has a dominant case.
2941
- //
2942
- newBlock->GetSwitchTargets ()->bbsHasDominantCase = false ;
2911
+ JITDUMP (" fgPeelSwitch: Updated flow into " FMT_BB " needs to be propagated. Data %s inconsistent.\n " ,
2912
+ newBlock->bbNum , fgPgoConsistent ? " is now" : " was already" );
2913
+ fgPgoConsistent = false ;
2943
2914
2944
- if (fgNodeThreading == NodeThreading::AllTrees)
2945
- {
2946
- // The switch tree has been modified.
2947
- JITDUMP ( " Rethreading " FMT_STMT " \n " , switchStmt-> GetID ());
2948
- gtSetStmtInfo (switchStmt);
2949
- fgSetStmtSeq (switchStmt) ;
2915
+ // For now we leave the switch as is, since there's no way
2916
+ // to indicate that one of the cases is now unreachable.
2917
+ //
2918
+ // But it no longer has a dominant case.
2919
+ //
2920
+ newBlock-> GetSwitchTargets ()-> bbsHasDominantCase = false ;
2950
2921
2951
- // fgNewStmtFromTree() already threaded the tree, but calling fgMakeMultiUse() might have
2952
- // added new nodes if a COMMA was introduced.
2953
- JITDUMP ( " Rethreading " FMT_STMT " \n " , jmpStmt-> GetID ());
2954
- gtSetStmtInfo (jmpStmt );
2955
- fgSetStmtSeq (jmpStmt );
2956
- }
2922
+ if (fgNodeThreading == NodeThreading::AllTrees)
2923
+ {
2924
+ // The switch tree has been modified.
2925
+ JITDUMP ( " Rethreading " FMT_STMT " \n " , switchStmt-> GetID () );
2926
+ gtSetStmtInfo (switchStmt );
2927
+ fgSetStmtSeq (switchStmt);
2957
2928
2958
- modified = true ;
2929
+ // fgNewStmtFromTree() already threaded the tree, but calling fgMakeMultiUse() might have
2930
+ // added new nodes if a COMMA was introduced.
2931
+ JITDUMP (" Rethreading " FMT_STMT " \n " , jmpStmt->GetID ());
2932
+ gtSetStmtInfo (jmpStmt);
2933
+ fgSetStmtSeq (jmpStmt);
2959
2934
}
2960
-
2961
- return modified;
2962
2935
}
2963
2936
2964
2937
// -----------------------------------------------------------------------------
@@ -3317,19 +3290,6 @@ bool Compiler::fgReorderBlocks(bool useProfile)
3317
3290
}
3318
3291
#endif // FEATURE_EH_WINDOWS_X86
3319
3292
3320
- //
3321
- // If we are using profile weights we can change some
3322
- // switch jumps into conditional test and jump
3323
- //
3324
- if (fgIsUsingProfileWeights ())
3325
- {
3326
- optimizedSwitches = fgOptimizeSwitchJumps ();
3327
- if (optimizedSwitches)
3328
- {
3329
- fgUpdateFlowGraph ();
3330
- }
3331
- }
3332
-
3333
3293
if (useProfile)
3334
3294
{
3335
3295
// Don't run the new layout until we get to the backend,
0 commit comments