From 6cf9af28824441eabb7cde7e93ae8a535b952a14 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Thu, 10 Jun 2021 23:32:17 -0700 Subject: [PATCH] Consider reloadWeight while evaluating spill cost (#53853) * Consider reloadWeight while evaluating spill cost * fix linux arm issue * jit format --- src/coreclr/jit/lsra.cpp | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index af168348e194d..e137b7f678a0d 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -11258,13 +11258,36 @@ void LinearScan::RegisterSelection::try_SPILL_COST() continue; } - float currentSpillWeight = linearScan->spillCost[spillCandidateRegNum]; -#ifdef TARGET_ARM - if (currentInterval->registerType == TYP_DOUBLE) + float currentSpillWeight = 0; + RefPosition* recentRefPosition = spillCandidateRegRecord->assignedInterval != nullptr + ? spillCandidateRegRecord->assignedInterval->recentRefPosition + : nullptr; + if ((recentRefPosition != nullptr) && (recentRefPosition->RegOptional()) && + !(currentInterval->isLocalVar && recentRefPosition->IsActualRef())) { - currentSpillWeight = max(currentSpillWeight, linearScan->spillCost[REG_NEXT(spillCandidateRegNum)]); + // We do not "spillAfter" if previous (recent) refPosition was regOptional or if it + // is not an actual ref. In those cases, we will reload in future (next) refPosition. + // For such cases, consider the spill cost of next refposition. + // See notes in "spillInterval()". + RefPosition* reloadRefPosition = spillCandidateRegRecord->assignedInterval->getNextRefPosition(); + if (reloadRefPosition != nullptr) + { + currentSpillWeight = linearScan->getWeight(reloadRefPosition); + } } + + // Only consider spillCost if we were not able to calculate weight of reloadRefPosition. + if (currentSpillWeight == 0) + { + currentSpillWeight = linearScan->spillCost[spillCandidateRegNum]; +#ifdef TARGET_ARM + if (currentInterval->registerType == TYP_DOUBLE) + { + currentSpillWeight = max(currentSpillWeight, linearScan->spillCost[REG_NEXT(spillCandidateRegNum)]); + } #endif + } + if (currentSpillWeight < bestSpillWeight) { bestSpillWeight = currentSpillWeight;