@@ -11258,13 +11258,36 @@ void LinearScan::RegisterSelection::try_SPILL_COST()
1125811258 continue ;
1125911259 }
1126011260
11261- float currentSpillWeight = linearScan->spillCost [spillCandidateRegNum];
11262- #ifdef TARGET_ARM
11263- if (currentInterval->registerType == TYP_DOUBLE)
11261+ float currentSpillWeight = 0 ;
11262+ RefPosition* recentRefPosition = spillCandidateRegRecord->assignedInterval != nullptr
11263+ ? spillCandidateRegRecord->assignedInterval ->recentRefPosition
11264+ : nullptr ;
11265+ if ((recentRefPosition != nullptr ) && (recentRefPosition->RegOptional ()) &&
11266+ !(currentInterval->isLocalVar && recentRefPosition->IsActualRef ()))
1126411267 {
11265- currentSpillWeight = max (currentSpillWeight, linearScan->spillCost [REG_NEXT (spillCandidateRegNum)]);
11268+ // We do not "spillAfter" if previous (recent) refPosition was regOptional or if it
11269+ // is not an actual ref. In those cases, we will reload in future (next) refPosition.
11270+ // For such cases, consider the spill cost of next refposition.
11271+ // See notes in "spillInterval()".
11272+ RefPosition* reloadRefPosition = spillCandidateRegRecord->assignedInterval ->getNextRefPosition ();
11273+ if (reloadRefPosition != nullptr )
11274+ {
11275+ currentSpillWeight = linearScan->getWeight (reloadRefPosition);
11276+ }
1126611277 }
11278+
11279+ // Only consider spillCost if we were not able to calculate weight of reloadRefPosition.
11280+ if (currentSpillWeight == 0 )
11281+ {
11282+ currentSpillWeight = linearScan->spillCost [spillCandidateRegNum];
11283+ #ifdef TARGET_ARM
11284+ if (currentInterval->registerType == TYP_DOUBLE)
11285+ {
11286+ currentSpillWeight = max (currentSpillWeight, linearScan->spillCost [REG_NEXT (spillCandidateRegNum)]);
11287+ }
1126711288#endif
11289+ }
11290+
1126811291 if (currentSpillWeight < bestSpillWeight)
1126911292 {
1127011293 bestSpillWeight = currentSpillWeight;
0 commit comments