@@ -33,6 +33,7 @@ void ProfileSynthesis::Run(ProfileSynthesisOption option)
33
33
m_dfsTree = m_comp->fgComputeDfs ();
34
34
m_loops = FlowGraphNaturalLoops::Find (m_dfsTree);
35
35
m_improperLoopHeaders = m_loops->ImproperLoopHeaders ();
36
+ m_entryBlock = m_comp->opts .IsOSR () ? m_comp->fgEntryBB : m_comp->fgFirstBB ;
36
37
37
38
// Retain or compute edge likelihood information
38
39
//
@@ -71,13 +72,18 @@ void ProfileSynthesis::Run(ProfileSynthesisOption option)
71
72
break ;
72
73
}
73
74
75
+ // Save entry block's weight.
76
+ // If the entry block is a loop header, its weight will be overwritten by ComputeCyclicProbabilities.
77
+ //
78
+ weight_t entryBlockWeight = m_entryBlock->bbWeight ;
79
+
74
80
// Determine cyclic probabilities
75
81
//
76
82
ComputeCyclicProbabilities ();
77
83
78
84
// Assign weights to entry points in the flow graph
79
85
//
80
- AssignInputWeights (option );
86
+ AssignInputWeights (entryBlockWeight );
81
87
82
88
// Compute the block weights given the inputs and edge likelihoods
83
89
//
@@ -108,12 +114,13 @@ void ProfileSynthesis::Run(ProfileSynthesisOption option)
108
114
m_approximate = false ;
109
115
m_overflow = false ;
110
116
m_cappedCyclicProbabilities = 0 ;
117
+ entryBlockWeight = m_entryBlock->bbWeight ;
111
118
112
119
// Regularize the edge likelihoods...
113
120
//
114
121
BlendLikelihoods ();
115
122
ComputeCyclicProbabilities ();
116
- AssignInputWeights (option );
123
+ AssignInputWeights (entryBlockWeight );
117
124
ComputeBlockWeights ();
118
125
119
126
// Increase blend factor and decrease synthetic loop likelihoods
@@ -975,7 +982,7 @@ void ProfileSynthesis::ComputeCyclicProbabilities(FlowGraphNaturalLoop* loop)
975
982
// fgAssignInputWeights: provide initial profile weights for all blocks
976
983
//
977
984
// Arguments:
978
- // option - profile synthesis option
985
+ // entryBlockWeight - total flow (including method call count) into the entry block
979
986
//
980
987
// Notes:
981
988
// For finallys we will pick up new entry weights when we process
@@ -986,51 +993,26 @@ void ProfileSynthesis::ComputeCyclicProbabilities(FlowGraphNaturalLoop* loop)
986
993
//
987
994
// Some parts of the jit are sensitive to the absolute weights.
988
995
//
989
- void ProfileSynthesis::AssignInputWeights (ProfileSynthesisOption option )
996
+ void ProfileSynthesis::AssignInputWeights (weight_t entryBlockWeight )
990
997
{
991
- // Determine input weight for method entry
998
+ // Determine input weight for method entry.
999
+ // Ideally, we'd use fgCalledCount, but it may not be available yet.
992
1000
//
993
- BasicBlock* const entryBlock = m_comp-> opts . IsOSR () ? m_comp-> fgEntryBB : m_comp-> fgFirstBB ;
994
- weight_t entryWeight = BB_UNITY_WEIGHT ;
1001
+ weight_t entryWeight = entryBlockWeight ;
1002
+ FlowGraphNaturalLoop* const loop = m_loops-> GetLoopByHeader (m_entryBlock) ;
995
1003
996
- switch (option )
1004
+ if (loop != nullptr )
997
1005
{
998
- case ProfileSynthesisOption::BlendLikelihoods:
999
- case ProfileSynthesisOption::RepairLikelihoods:
1000
- {
1001
- // Try and retain entryBlock's weight.
1002
- // Easiest to do when the block has no preds.
1003
- //
1004
- if (entryBlock->hasProfileWeight ())
1005
- {
1006
- weight_t currentEntryWeight = entryBlock->bbWeight ;
1007
-
1008
- if (!Compiler::fgProfileWeightsEqual (currentEntryWeight, 0.0 , epsilon))
1009
- {
1010
- if (entryBlock->bbPreds == nullptr )
1011
- {
1012
- entryWeight = currentEntryWeight;
1013
- }
1014
- else
1015
- {
1016
- // TODO: something similar to how we compute fgCalledCount;
1017
- // try and sum return weights?
1018
- }
1019
- }
1020
- else
1021
- {
1022
- // Entry weight was zero or nearly zero, just use default
1023
- }
1024
- }
1025
- else
1026
- {
1027
- // Entry was unprofiled, just use default
1028
- }
1029
- break ;
1030
- }
1006
+ const weight_t cyclicProbability = m_cyclicProbabilities[loop->GetIndex ()];
1007
+ assert (cyclicProbability != BB_ZERO_WEIGHT);
1008
+ entryWeight /= cyclicProbability;
1009
+ }
1031
1010
1032
- default :
1033
- break ;
1011
+ // Fall back to BB_UNITY_WEIGHT if we have zero entry weight
1012
+ //
1013
+ if (Compiler::fgProfileWeightsEqual (entryWeight, BB_ZERO_WEIGHT, epsilon))
1014
+ {
1015
+ entryWeight = BB_UNITY_WEIGHT;
1034
1016
}
1035
1017
1036
1018
// Reset existing weights
@@ -1042,8 +1024,8 @@ void ProfileSynthesis::AssignInputWeights(ProfileSynthesisOption option)
1042
1024
1043
1025
// Set entry weight
1044
1026
//
1045
- JITDUMP (" Synthesis: entry " FMT_BB " has input weight " FMT_WT " \n " , entryBlock ->bbNum , entryWeight);
1046
- entryBlock ->setBBProfileWeight (entryWeight);
1027
+ JITDUMP (" Synthesis: entry " FMT_BB " has input weight " FMT_WT " \n " , m_entryBlock ->bbNum , entryWeight);
1028
+ m_entryBlock ->setBBProfileWeight (entryWeight);
1047
1029
1048
1030
// Determine input weight for EH regions, if any.
1049
1031
//
@@ -1210,9 +1192,6 @@ void ProfileSynthesis::GaussSeidelSolver()
1210
1192
bool checkEntryExitWeight = true ;
1211
1193
bool showDetails = false ;
1212
1194
1213
- // Remember the entry block
1214
- //
1215
- BasicBlock* const entryBlock = m_comp->opts .IsOSR () ? m_comp->fgEntryBB : m_comp->fgFirstBB ;
1216
1195
JITDUMP (" Synthesis solver: flow graph has %u improper loop headers\n " , m_improperLoopHeaders);
1217
1196
1218
1197
// This is an iterative solver, and it may require a lot of iterations
@@ -1268,7 +1247,7 @@ void ProfileSynthesis::GaussSeidelSolver()
1268
1247
1269
1248
// Some blocks have additional profile weights that don't come from flow edges.
1270
1249
//
1271
- if (block == entryBlock )
1250
+ if (block == m_entryBlock )
1272
1251
{
1273
1252
newWeight = block->bbWeight ;
1274
1253
entryWeight = newWeight;
@@ -1459,7 +1438,7 @@ void ProfileSynthesis::GaussSeidelSolver()
1459
1438
if (entryExitRelResidual > relResidual)
1460
1439
{
1461
1440
relResidual = entryExitRelResidual;
1462
- relResidualBlock = entryBlock ;
1441
+ relResidualBlock = m_entryBlock ;
1463
1442
}
1464
1443
}
1465
1444
0 commit comments