Skip to content

Commit a1a03dc

Browse files
pratikasharigcbot
authored andcommitted
Dont add fill for spilled variables that have a single def in program
and are not live-in to the BB, hence not loop carried. definition. Such variables dont need read-modify-write when spilled.
1 parent 6c5923f commit a1a03dc

File tree

2 files changed

+90
-3
lines changed

2 files changed

+90
-3
lines changed

visa/SpillManagerGMRF.cpp

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2804,6 +2804,47 @@ void SpillManagerGRF::insertSpillRangeCode(
28042804
return;
28052805
}
28062806

2807+
auto IsUniqueDef = [this, bb, spillDcl]()
2808+
{
2809+
// return true if spilled variable has a single def
2810+
// and it is not live-in to current bb (eg, loop, sub).
2811+
if (VarDefs[spillDcl] != 1)
2812+
return false;
2813+
2814+
// check whether variable is live-in to BB
2815+
if (lvInfo_->isLiveAtEntry(bb, spillDcl->getRegVar()->getId()))
2816+
return false;
2817+
2818+
return true;
2819+
};
2820+
2821+
auto PseudoKillFound = [spilledInstIter, bb, spillDcl]()
2822+
{
2823+
// Search upwards from spilledInstIter to find a pseudo kill.
2824+
// Return true if one is found, false otherwise.
2825+
// When a pseudo kill is found, it means read-modify-write is
2826+
// not needed.
2827+
auto bbBegin = bb->begin();
2828+
if (spilledInstIter == bbBegin)
2829+
return false;
2830+
auto it = spilledInstIter;
2831+
--it;
2832+
while (it != bbBegin)
2833+
{
2834+
auto inst = *it;
2835+
// check if adjacent instruction is a pseudo kill
2836+
if (inst->isPseudoKill())
2837+
{
2838+
if (inst->getDst()->getTopDcl() == spillDcl)
2839+
return true;
2840+
}
2841+
else
2842+
return false;
2843+
--it;
2844+
}
2845+
return false;
2846+
};
2847+
28072848
//subreg offset for new dst that replaces the spilled dst
28082849
auto newSubregOff = 0;
28092850

@@ -2821,7 +2862,9 @@ void SpillManagerGRF::insertSpillRangeCode(
28212862
createAndInitMHeader (
28222863
(G4_RegVarTransient *) spillRangeDcl->getRegVar());
28232864

2824-
bool needRMW = inst->isPartialWriteForSpill(!bb->isAllLaneActive());
2865+
bool needRMW = !PseudoKillFound() &&
2866+
!IsUniqueDef() &&
2867+
inst->isPartialWriteForSpill(!bb->isAllLaneActive());
28252868
if (needRMW)
28262869
{
28272870
sendInSpilledRegVarPortions(
@@ -2856,7 +2899,9 @@ void SpillManagerGRF::insertSpillRangeCode(
28562899

28572900
// Unaligned region specific handling.
28582901
unsigned int spillSendOption = InstOpt_WriteEnable;
2859-
if (shouldPreloadSpillRange(*spilledInstIter, bb)) {
2902+
if (!PseudoKillFound() &&
2903+
!IsUniqueDef() &&
2904+
shouldPreloadSpillRange(*spilledInstIter, bb)) {
28602905

28612906
// Preload the segment aligned spill range from memory to use
28622907
// as an overlay
@@ -3873,6 +3918,31 @@ void SpillManagerGRF::runSpillAnalysis()
38733918
}
38743919
}
38753920

3921+
void SpillManagerGRF::populateDefsTable()
3922+
{
3923+
for (auto bb : gra.kernel.fg)
3924+
{
3925+
for (auto inst : *bb)
3926+
{
3927+
if (inst->isPseudoKill())
3928+
continue;
3929+
3930+
auto dst = inst->getDst();
3931+
3932+
if (dst && !dst->isNullReg())
3933+
{
3934+
auto topdcl = dst->getTopDcl();
3935+
3936+
if (topdcl)
3937+
{
3938+
VarDefs[topdcl] += 1;
3939+
}
3940+
}
3941+
}
3942+
}
3943+
}
3944+
3945+
38763946
// Insert spill/fill code for all registers that have not been assigned
38773947
// physical registers in the current iteration of the graph coloring
38783948
// allocator.
@@ -3913,6 +3983,9 @@ bool SpillManagerGRF::insertSpillFillCode (
39133983
return false;
39143984
}
39153985

3986+
// Populate def table as it helps us decide whether read-modify-write is needed
3987+
populateDefsTable();
3988+
39163989
// Insert spill/fill code for all basic blocks.
39173990

39183991
FlowGraph& fg = kernel->fg;
@@ -3921,6 +3994,7 @@ bool SpillManagerGRF::insertSpillFillCode (
39213994
{
39223995
bbId_ = (*it)->getId();
39233996
INST_LIST::iterator jt = (*it)->begin();
3997+
std::list<INST_LIST_ITER> pseudoKills;
39243998

39253999
while (jt != (*it)->end()) {
39264000
INST_LIST::iterator kt = jt;
@@ -3950,7 +4024,11 @@ bool SpillManagerGRF::insertSpillFillCode (
39504024
{
39514025
if (inst->isPseudoKill())
39524026
{
3953-
(*it)->erase(jt);
4027+
// This pseudo kill corresponds to a spilled variable, so
4028+
// it can be removed. But it is preserved till spill code
4029+
// is inserted for the variable as it provides a hint to
4030+
// spill insertion that read-modify-write is not needed.
4031+
pseudoKills.push_back(jt);
39544032
jt = kt;
39554033
continue;
39564034
}
@@ -4003,6 +4081,11 @@ bool SpillManagerGRF::insertSpillFillCode (
40034081

40044082
jt = kt;
40054083
}
4084+
4085+
for(auto killIt : pseudoKills)
4086+
{
4087+
(*it)->erase(killIt);
4088+
}
40064089
}
40074090

40084091
bbId_ = UINT_MAX;

visa/SpillManagerGMRF.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,8 @@ class SpillManagerGRF
593593
}
594594
}
595595

596+
void populateDefsTable();
597+
596598
// Data
597599
GlobalRA& gra;
598600
IR_Builder * builder_;
@@ -623,6 +625,8 @@ class SpillManagerGRF
623625
const Interference * spillIntf_;
624626
vISA::Mem_Manager mem_;
625627

628+
std::unordered_map<G4_Declare*, unsigned int> VarDefs;
629+
626630
// The number of GRF spill.
627631
unsigned numGRFSpill = 0;
628632

0 commit comments

Comments
 (0)