@@ -6763,7 +6763,7 @@ void GraphColor::removeConstrained() {
67636763void GraphColor::determineColorOrdering () {
67646764 numColor = 0 ;
67656765 if (liveAnalysis.livenessClass (G4_GRF))
6766- numColor = totalGRFRegCount - reserveSpillGRFCount ;
6766+ numColor = totalGRFRegCount;
67676767 else if (liveAnalysis.livenessClass (G4_ADDRESS))
67686768 numColor = builder.getNumAddrRegisters ();
67696769 else if (liveAnalysis.livenessClass (G4_FLAG))
@@ -7628,6 +7628,10 @@ bool GraphColor::regAlloc(bool doBankConflictReduction,
76287628 intf.init ();
76297629 intf.computeInterference ();
76307630
7631+ if (reserveSpillGRFCount) {
7632+ preAssignSpillHeader ();
7633+ }
7634+
76317635 builder.getFreqInfoManager ().initForRegAlloc (&liveAnalysis);
76327636
76337637 // If option is true, try to get extra interference info from file
@@ -10917,6 +10921,49 @@ std::pair<unsigned, unsigned> GlobalRA::reserveGRFSpillReg(GraphColor &coloring)
1091710921 return std::make_pair (spillRegSize, indrSpillRegSize);
1091810922}
1091910923
10924+ void GraphColor::preAssignSpillHeader () {
10925+ // If spill header is used for spill/fill offset, it must have infinite spill
10926+ // cost. When running fail safe RA, if we assign this range to middle of free
10927+ // GRF space, it could cause fragmentation and other spilled ranges may not
10928+ // get an allocation. So, we pre-assign this variable at first candidate GRF
10929+ // to avoid fragmentation. This is relevant only in fail safe RA iteration.
10930+ if (!builder.hasValidSpillFillHeader ())
10931+ return ;
10932+
10933+ std::vector<bool > FreeGRFs (kernel.getNumRegTotal (), true );
10934+ auto *spillHeader = builder.getSpillFillHeader ();
10935+ if (spillHeader->getRegVar ()->getPhyReg ())
10936+ return ;
10937+ unsigned spillHeaderId = spillHeader->getRootDeclare ()->getRegVar ()->getId ();
10938+ // Compute free GRFs
10939+ const auto *intf = getIntf ();
10940+ for (auto neighbor : intf->getSparseIntfForVar (spillHeaderId)) {
10941+ auto *neighborLR = getLiveRanges ()[neighbor];
10942+ auto *neighborGRF = neighborLR->getPhyReg ();
10943+ if (!neighborGRF)
10944+ continue ;
10945+ unsigned int neighborGRFStart = neighborGRF->asGreg ()->getRegNum ();
10946+ unsigned int neighborLastGRF =
10947+ neighborGRFStart + neighborLR->getNumRegNeeded ();
10948+ for (unsigned int i = neighborGRFStart; i != neighborLastGRF; ++i) {
10949+ FreeGRFs[i] = false ;
10950+ }
10951+ }
10952+
10953+ // Find a GRF r1 onwards that can be pre-assigned to spillHeader.
10954+ // r0 is usually reserved.
10955+ for (unsigned int i = 1 ; i != FreeGRFs.size (); ++i) {
10956+ if (FreeGRFs[i]) {
10957+ // Attach assignment to temp LR and to G4_RegVar
10958+ getLiveRanges ()[spillHeaderId]->setPhyReg (regPool.getGreg (i), 0 );
10959+ spillHeader->getRegVar ()->setPhyReg (regPool.getGreg (i), 0 );
10960+ // Decrement counter as this is used later in determineColorOrdering
10961+ liveAnalysis.reduceNumUnassignedVar ();
10962+ break ;
10963+ }
10964+ }
10965+ }
10966+
1092010967// pre-allocate the bits for forbidden registers which will not be used in
1092110968// register assignment.
1092210969// Note that the order of the calls matters, as all RCs inherit from RESERVEDGRF
0 commit comments