@@ -2804,128 +2804,9 @@ void SpillManagerGRF::insertSpillRangeCode(
28042804 return ;
28052805 }
28062806
2807- auto IsUniqueDef = [this , inst, 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].size () != 1 )
2812- {
2813- // check whether multiple defs exist in program for current
2814- // lb, rb
2815- auto dst = inst->getDst ();
2816- auto lb = dst->getLeftBound ();
2817- auto rb = dst->getRightBound ();
2818-
2819- unsigned int count = 0 ;
2820- auto & defs = VarDefs[spillDcl];
2821- for (auto & def : defs)
2822- {
2823- if (def.first <= rb &&
2824- def.second >= lb)
2825- ++count;
2826- }
2827-
2828- if (count > 1 )
2829- return false ;
2830-
2831- // spill/fill intrinsics work at either hword/grf granularity. so even
2832- // if a def is unique, if it only writes part of a GRF (say upper 8 words)
2833- // then a fill is still needed to preserve rest of GRF written by another
2834- // def.
2835- bool partialGRFDef = ((dst->getRightBound () + 1 ) % getGRFSize ()) != 0 ||
2836- (dst->getLeftBound () % getGRFSize ()) != 0 ;
2837- if (partialGRFDef)
2838- return false ;
2839- }
2840-
2841- // check whether variable is live-in to BB
2842- if (lvInfo_->isLiveAtEntry (bb, spillDcl->getRegVar ()->getId ()))
2843- return false ;
2844-
2845- return true ;
2846- };
2847-
2848- auto PseudoKillFound = [spilledInstIter, bb, spillDcl]()
2849- {
2850- // Search upwards from spilledInstIter to find a pseudo kill.
2851- // Return true if one is found, false otherwise.
2852- // When a pseudo kill is found, it means read-modify-write is
2853- // not needed.
2854- auto bbBegin = bb->begin ();
2855- if (spilledInstIter == bbBegin)
2856- return false ;
2857- auto it = spilledInstIter;
2858- --it;
2859- unsigned int pseudoKillDist = 0 ;
2860- auto dst = (*spilledInstIter)->getDst ();
2861- bool partialGRFDef = ((dst->getRightBound () + 1 ) % getGRFSize ()) != 0 ||
2862- (dst->getLeftBound () % getGRFSize ()) != 0 ;
2863- while (it != bbBegin)
2864- {
2865- auto inst = *it;
2866- // check if adjacent instruction is a pseudo kill
2867- if (inst->isPseudoKill ())
2868- {
2869- if (inst->getDst ()->getTopDcl () == spillDcl)
2870- {
2871- // if pseudo_kill is previous instruction, then no need for fill
2872- // however, if there are other instructions in between current and
2873- // pseudo_kill then a fill can be skipped only if the def defines
2874- // full GRF as spill/fill is currently in GRF granularity.
2875- if (pseudoKillDist == 0 || !partialGRFDef)
2876- return true ;
2877- return false ;
2878- }
2879- }
2880- else
2881- {
2882- auto dst = inst->getDst ();
2883- if (!dst)
2884- return false ;
2885-
2886- // recognize pattern where V10 is spilled:
2887- // pseudo_kill V10
2888- // op (8) V10(0,0) ...
2889- // op (8) V10(2,0) ... <-- Current inst
2890- //
2891- // becomes:
2892- // pseudo_kill V10
2893- // op (8) SP_V10(0,0) ... [2]
2894- // intrinsic_spill (8) ... SP_V10 ... [1]
2895- // op (8) V10(2,0) <-- Current inst
2896- if (inst->isSpillIntrinsic () &&
2897- inst->asSpillIntrinsic ()->getPayload () &&
2898- inst->asSpillIntrinsic ()->getPayload ()->getTopDcl ()->getRegVar ()->isRegVarTransient ())
2899- {
2900- auto spillBase = ((G4_RegVarTransient*)inst->asSpillIntrinsic ()->getPayload ()->getTopDcl ()->getRegVar ())->getAbsBaseRegVar ();
2901- if (spillBase->getDeclare ()->getRootDeclare () != spillDcl)
2902- return false ;
2903- // Fall through for instruction [1] above
2904- }
2905- else if (dst &&
2906- dst->getTopDcl () &&
2907- dst->getTopDcl ()->getRegVar ()->isRegVarTransient ())
2908- {
2909- auto spillBase = ((G4_RegVarTransient*)dst->getTopDcl ()->getRegVar ())->getAbsBaseRegVar ();
2910- if (spillBase->getDeclare ()->getRootDeclare () != spillDcl)
2911- return false ;
2912- // Fall through for instruction [2] above
2913- }
2914- else if (inst->getDst ()->getTopDcl () != spillDcl)
2915- return false ;
2916-
2917- ++pseudoKillDist;
2918- }
2919- --it;
2920- }
2921- return false ;
2922- };
2923-
29242807 // subreg offset for new dst that replaces the spilled dst
29252808 auto newSubregOff = 0 ;
29262809
2927- auto pseudoKillFound = PseudoKillFound ();
2928- auto isUniqueDef = IsUniqueDef ();
29292810 if (inst->mayExceedTwoGRF ())
29302811 {
29312812 // Handle send instructions (special treatment)
@@ -2940,9 +2821,7 @@ void SpillManagerGRF::insertSpillRangeCode(
29402821 createAndInitMHeader (
29412822 (G4_RegVarTransient *) spillRangeDcl->getRegVar ());
29422823
2943- bool needRMW = !pseudoKillFound &&
2944- !isUniqueDef &&
2945- inst->isPartialWriteForSpill (!bb->isAllLaneActive ());
2824+ bool needRMW = inst->isPartialWriteForSpill (!bb->isAllLaneActive ());
29462825 if (needRMW)
29472826 {
29482827 sendInSpilledRegVarPortions (
@@ -2977,9 +2856,7 @@ void SpillManagerGRF::insertSpillRangeCode(
29772856
29782857 // Unaligned region specific handling.
29792858 unsigned int spillSendOption = InstOpt_WriteEnable;
2980- if (!pseudoKillFound &&
2981- !isUniqueDef &&
2982- shouldPreloadSpillRange (*spilledInstIter, bb)) {
2859+ if (shouldPreloadSpillRange (*spilledInstIter, bb)) {
29832860
29842861 // Preload the segment aligned spill range from memory to use
29852862 // as an overlay
@@ -3061,13 +2938,7 @@ void SpillManagerGRF::insertSpillRangeCode(
30612938 newSubregOff = spilledRegion->getSubRegOff ();
30622939 if (!bb->isAllLaneActive ())
30632940 {
3064- if (!pseudoKillFound &&
3065- !isUniqueDef)
3066- {
3067- // If either pseudo kill is found or if the range is a unique def,
3068- // use WriteEnable option in spill.
3069- spillSendOption = (*spilledInstIter)->getMaskOption ();
3070- }
2941+ spillSendOption = (*spilledInstIter)->getMaskOption ();
30712942 }
30722943 }
30732944
@@ -4002,33 +3873,6 @@ void SpillManagerGRF::runSpillAnalysis()
40023873 }
40033874}
40043875
4005- void SpillManagerGRF::populateDefsTable ()
4006- {
4007- for (auto bb : gra.kernel .fg )
4008- {
4009- for (auto inst : *bb)
4010- {
4011- if (inst->isPseudoKill ())
4012- continue ;
4013-
4014- auto dst = inst->getDst ();
4015-
4016- if (dst && !dst->isNullReg ())
4017- {
4018- auto topdcl = dst->getTopDcl ();
4019-
4020- if (topdcl)
4021- {
4022- auto lb = dst->getLeftBound ();
4023- auto rb = dst->getRightBound ();
4024- VarDefs[topdcl].push_back (std::make_pair (lb, rb));
4025- }
4026- }
4027- }
4028- }
4029- }
4030-
4031-
40323876// Insert spill/fill code for all registers that have not been assigned
40333877// physical registers in the current iteration of the graph coloring
40343878// allocator.
@@ -4069,9 +3913,6 @@ bool SpillManagerGRF::insertSpillFillCode (
40693913 return false ;
40703914 }
40713915
4072- // Populate def table as it helps us decide whether read-modify-write is needed
4073- populateDefsTable ();
4074-
40753916 // Insert spill/fill code for all basic blocks.
40763917
40773918 FlowGraph& fg = kernel->fg ;
@@ -4080,7 +3921,6 @@ bool SpillManagerGRF::insertSpillFillCode (
40803921 {
40813922 bbId_ = (*it)->getId ();
40823923 INST_LIST::iterator jt = (*it)->begin ();
4083- std::list<INST_LIST_ITER> pseudoKills;
40843924
40853925 while (jt != (*it)->end ()) {
40863926 INST_LIST::iterator kt = jt;
@@ -4110,11 +3950,7 @@ bool SpillManagerGRF::insertSpillFillCode (
41103950 {
41113951 if (inst->isPseudoKill ())
41123952 {
4113- // This pseudo kill corresponds to a spilled variable, so
4114- // it can be removed. But it is preserved till spill code
4115- // is inserted for the variable as it provides a hint to
4116- // spill insertion that read-modify-write is not needed.
4117- pseudoKills.push_back (jt);
3953+ (*it)->erase (jt);
41183954 jt = kt;
41193955 continue ;
41203956 }
@@ -4167,11 +4003,6 @@ bool SpillManagerGRF::insertSpillFillCode (
41674003
41684004 jt = kt;
41694005 }
4170-
4171- for (auto killIt : pseudoKills)
4172- {
4173- (*it)->erase (killIt);
4174- }
41754006 }
41764007
41774008 bbId_ = UINT_MAX;
0 commit comments