@@ -6763,7 +6763,7 @@ void GraphColor::removeConstrained() {
6763
6763
void GraphColor::determineColorOrdering () {
6764
6764
numColor = 0 ;
6765
6765
if (liveAnalysis.livenessClass (G4_GRF))
6766
- numColor = totalGRFRegCount - reserveSpillGRFCount ;
6766
+ numColor = totalGRFRegCount;
6767
6767
else if (liveAnalysis.livenessClass (G4_ADDRESS))
6768
6768
numColor = builder.getNumAddrRegisters ();
6769
6769
else if (liveAnalysis.livenessClass (G4_FLAG))
@@ -7628,6 +7628,10 @@ bool GraphColor::regAlloc(bool doBankConflictReduction,
7628
7628
intf.init ();
7629
7629
intf.computeInterference ();
7630
7630
7631
+ if (reserveSpillGRFCount) {
7632
+ preAssignSpillHeader ();
7633
+ }
7634
+
7631
7635
builder.getFreqInfoManager ().initForRegAlloc (&liveAnalysis);
7632
7636
7633
7637
// If option is true, try to get extra interference info from file
@@ -10917,6 +10921,49 @@ std::pair<unsigned, unsigned> GlobalRA::reserveGRFSpillReg(GraphColor &coloring)
10917
10921
return std::make_pair (spillRegSize, indrSpillRegSize);
10918
10922
}
10919
10923
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
+
10920
10967
// pre-allocate the bits for forbidden registers which will not be used in
10921
10968
// register assignment.
10922
10969
// Note that the order of the calls matters, as all RCs inherit from RESERVEDGRF
0 commit comments