@@ -5745,7 +5745,7 @@ bool GraphColor::assignColors(ColorHeuristic colorHeuristicGRF, bool doBankConfl
57455745
57465746 auto & varSplitPass = *gra.getVarSplitPass ();
57475747
5748- auto assignColor = [&](LiveRange* lr, bool ignoreChildrenIntf = false )
5748+ auto assignColor = [&](LiveRange* lr, bool ignoreChildrenIntf = false , bool spillAllowed = true )
57495749 {
57505750 auto lrVar = lr->getVar ();
57515751
@@ -5925,7 +5925,13 @@ bool GraphColor::assignColors(ColorHeuristic colorHeuristicGRF, bool doBankConfl
59255925 else
59265926 {
59275927 // for first-fit register assignment track spilled live ranges
5928- spilledLRs.push_back (lr);
5928+ if (spillAllowed)
5929+ {
5930+ // When retrying a coalesceable assignment, dont spill
5931+ // if there is no GRF available.
5932+ spilledLRs.push_back (lr);
5933+ lr->setSpilled (true );
5934+ }
59295935 }
59305936 }
59315937 else
@@ -5949,6 +5955,11 @@ bool GraphColor::assignColors(ColorHeuristic colorHeuristicGRF, bool doBankConfl
59495955 for (auto iter = colorOrder.rbegin (), iterEnd = colorOrder.rend (); iter != iterEnd; ++iter)
59505956 {
59515957 auto lr = (*iter);
5958+
5959+ // in case child/parent was already spilled earlier, dont recolor
5960+ if (lr->isSpilled ())
5961+ continue ;
5962+
59525963 bool ret = assignColor (lr);
59535964
59545965 // early exit
@@ -5969,7 +5980,8 @@ bool GraphColor::assignColors(ColorHeuristic colorHeuristicGRF, bool doBankConfl
59695980 auto childLR = lrs[child->getRegVar ()->getId ()];
59705981 if (!childLR->getPhyReg ())
59715982 {
5972- assignColor (childLR);
5983+ auto isChildSpilled = childLR->isSpilled ();
5984+ assignColor (childLR, false , !isChildSpilled);
59735985 }
59745986 else
59755987 {
@@ -5980,7 +5992,7 @@ bool GraphColor::assignColors(ColorHeuristic colorHeuristicGRF, bool doBankConfl
59805992 if (oldPhyReg->asGreg ()->getRegNum () == hint)
59815993 continue ;
59825994 childLR->resetPhyReg ();
5983- bool success = assignColor (childLR);
5995+ bool success = assignColor (childLR, false , false );
59845996 if (!success || childLR->getPhyReg ()->asGreg ()->getRegNum () != hint)
59855997 childLR->setPhyReg (oldPhyReg, oldPhySubReg);
59865998 }
@@ -5997,16 +6009,24 @@ bool GraphColor::assignColors(ColorHeuristic colorHeuristicGRF, bool doBankConfl
59976009 auto parentLR = getLiveRanges ()[parentDcl->getRegVar ()->getId ()];
59986010 auto oldPhyReg = parentLR->getPhyReg ();
59996011 auto oldPhySubReg = parentLR->getPhyRegOff ();
6012+ bool isParentSpilled = parentLR->isSpilled ();
60006013 parentLR->resetPhyReg ();
60016014 varSplitPass.writeHints (lr->getDcl (), getLiveRanges ());
6002- assignColor (parentLR, true );
6015+ assignColor (parentLR, true , !isParentSpilled );
60036016 // If parent's assigned GRF is non-coalesceable assignment then
60046017 // undo it as it is risky to keep this because parent's intf
60056018 // doesnt include children.
60066019 auto newParentAssignment = parentLR->getPhyReg ();
60076020 if ((newParentAssignment && newParentAssignment->asGreg ()->getRegNum () != parentLR->getAllocHint ()) ||
60086021 !newParentAssignment)
60096022 parentLR->setPhyReg (oldPhyReg, oldPhySubReg);
6023+
6024+ if (isParentSpilled && parentLR->getPhyReg ())
6025+ {
6026+ // remove parent from spill list since it got an allocation this time
6027+ spilledLRs.remove (parentLR);
6028+ parentLR->setSpilled (false );
6029+ }
60106030 }
60116031 }
60126032 }
@@ -6024,6 +6044,34 @@ bool GraphColor::assignColors(ColorHeuristic colorHeuristicGRF, bool doBankConfl
60246044 }
60256045 }
60266046
6047+ #ifdef _DEBUG
6048+ // Verify that spilledLRs has no duplicate
6049+ for (auto item : spilledLRs)
6050+ {
6051+ unsigned int count = 0 ;
6052+ for (auto checkItem : spilledLRs)
6053+ {
6054+ if (checkItem == item)
6055+ {
6056+ MUST_BE_TRUE (count == 0 , " Duplicate entry found in spilledLRs" );
6057+ count++;
6058+ }
6059+ }
6060+ }
6061+
6062+ // Verify that none of spilledLRs have an allocation
6063+ for (auto lr : spilledLRs)
6064+ {
6065+ MUST_BE_TRUE (lr->getPhyReg () == nullptr , " Spilled LR contains valid allocation" );
6066+ }
6067+
6068+ // Verify that all spilled LRs are synced
6069+ for (auto lr : spilledLRs)
6070+ {
6071+ MUST_BE_TRUE (lr->isSpilled (), " LR not marked as spilled, but inserted in spilledLRs list" );
6072+ }
6073+ #endif
6074+
60276075 return true ;
60286076}
60296077
0 commit comments