@@ -7534,7 +7534,17 @@ bool GraphColor::regAlloc(
75347534 if (reserveSpillReg)
75357535 {
75367536 failSafeIter = reserveSpillReg;
7537- gra.determineSpillRegSize (spillRegSize, indrSpillRegSize);
7537+
7538+ if (kernel.getOption (vISA_NewFailSafeRA))
7539+ {
7540+ spillRegSize = gra.getNumReservedGRFs ();
7541+ indrSpillRegSize = 0 ;
7542+ }
7543+ else
7544+ {
7545+ gra.determineSpillRegSize (spillRegSize, indrSpillRegSize);
7546+ }
7547+
75387548 reserveSpillSize = spillRegSize + indrSpillRegSize;
75397549 MUST_BE_TRUE (reserveSpillSize < kernel.getNumCalleeSaveRegs (), " Invalid reserveSpillSize in fail-safe RA!" );
75407550 totalGRFRegCount -= reserveSpillSize;
@@ -10908,6 +10918,36 @@ int GlobalRA::coloringRegAlloc()
1090810918 loopSplit.run ();
1090910919 }
1091010920
10921+ // Very few spills in this iter. Check if we can convert this to fail safe iter.
10922+ // By converting this iter to fail safe we can save (at least) 1 additional iter
10923+ // to allocate spilled temps. But converting to fail safe needs extra checks
10924+ // because no reserved GRF may exist at this point. So push/pop needs to succeed
10925+ // without additional GRF potentially.
10926+ if (!kernel.getOption (vISA_Debug) &&
10927+ iterationNo >= 1 && kernel.getOption (vISA_NewFailSafeRA) && !reserveSpillReg &&
10928+ coloring.getSpilledLiveRanges ().size () <= BoundedRA::MaxSpillNumVars &&
10929+ liveAnalysis.getNumSelectedVar () > BoundedRA::LargeProgramSize)
10930+ {
10931+ // Stack call always has free GRF so it is safe to convert this iter to fail safe
10932+ if (builder.usesStack () ||
10933+ // If LSC has to be used for spill/fill then we need to ensure spillHeader is created
10934+ (!useLscForNonStackCallSpillFill || builder.hasValidSpillFillHeader ()) ||
10935+ // If scratch is to be used then max spill offset must be within addressable range
10936+ ((nextSpillOffset + BoundedRA::getNumPhyVarSlots (kernel)) < SCRATCH_MSG_LIMIT))
10937+ {
10938+ // Few ranges are spilled but this was not executed as fail
10939+ // safe iteration. However, we've the capability of doing
10940+ // push/pop with new fail safe RA implementation. So for very
10941+ // few spills, we insert push/pop to free up some GRFs rather
10942+ // than executing a new RA iteration. When doing so, we mark
10943+ // this RA iteration as fail safe.
10944+ reserveSpillReg = true ;
10945+ coloring.markFailSafeIter (true );
10946+ // No reserved GRFs
10947+ setNumReservedGRFsFailSafe (0 );
10948+ }
10949+ }
10950+
1091110951 // Calculate the spill caused by send to decide if global splitting is required or not
1091210952 for (auto spilled : coloring.getSpilledLiveRanges ())
1091310953 {
@@ -11037,6 +11077,10 @@ int GlobalRA::coloringRegAlloc()
1103711077
1103811078 if (!reserveSpillReg && !disableSpillCoalecse && builder.useSends ())
1103911079 {
11080+ if (builder.getOption (vISA_RATrace))
11081+ {
11082+ std::cout << " \t --spill/fill cleanup\n " ;
11083+ }
1104011084 CoalesceSpillFills c (kernel, liveAnalysis, coloring, spillGRF, iterationNo, rpe, *this );
1104111085 c.run ();
1104211086 }
0 commit comments