@@ -88,9 +88,10 @@ void GCNRegPressure::inc(unsigned Reg,
8888 }
8989}
9090
91- bool GCNRegPressure::less (const GCNSubtarget &ST,
92- const GCNRegPressure& O,
91+ bool GCNRegPressure::less (const MachineFunction &MF, const GCNRegPressure &O,
9392 unsigned MaxOccupancy) const {
93+ const GCNSubtarget &ST = MF.getSubtarget <GCNSubtarget>();
94+
9495 const auto SGPROcc = std::min (MaxOccupancy,
9596 ST.getOccupancyWithNumSGPRs (getSGPRNum ()));
9697 const auto VGPROcc =
@@ -104,18 +105,103 @@ bool GCNRegPressure::less(const GCNSubtarget &ST,
104105
105106 const auto Occ = std::min (SGPROcc, VGPROcc);
106107 const auto OtherOcc = std::min (OtherSGPROcc, OtherVGPROcc);
108+
109+ // Give first precedence to the better occupancy.
107110 if (Occ != OtherOcc)
108111 return Occ > OtherOcc;
109112
113+ unsigned MaxVGPRs = ST.getMaxNumVGPRs (MF);
114+ unsigned MaxSGPRs = ST.getMaxNumSGPRs (MF);
115+
116+ // SGPR excess pressure conditions
117+ unsigned ExcessSGPR = std::max (static_cast <int >(getSGPRNum () - MaxSGPRs), 0 );
118+ unsigned OtherExcessSGPR =
119+ std::max (static_cast <int >(O.getSGPRNum () - MaxSGPRs), 0 );
120+
121+ auto WaveSize = ST.getWavefrontSize ();
122+ // The number of virtual VGPRs required to handle excess SGPR
123+ unsigned VGPRForSGPRSpills = (ExcessSGPR + (WaveSize - 1 )) / WaveSize;
124+ unsigned OtherVGPRForSGPRSpills =
125+ (OtherExcessSGPR + (WaveSize - 1 )) / WaveSize;
126+
127+ unsigned MaxArchVGPRs = ST.getAddressableNumArchVGPRs ();
128+
129+ // Unified excess pressure conditions, accounting for VGPRs used for SGPR
130+ // spills
131+ unsigned ExcessVGPR =
132+ std::max (static_cast <int >(getVGPRNum (ST.hasGFX90AInsts ()) +
133+ VGPRForSGPRSpills - MaxVGPRs),
134+ 0 );
135+ unsigned OtherExcessVGPR =
136+ std::max (static_cast <int >(O.getVGPRNum (ST.hasGFX90AInsts ()) +
137+ OtherVGPRForSGPRSpills - MaxVGPRs),
138+ 0 );
139+ // Arch VGPR excess pressure conditions, accounting for VGPRs used for SGPR
140+ // spills
141+ unsigned ExcessArchVGPR = std::max (
142+ static_cast <int >(getVGPRNum (false ) + VGPRForSGPRSpills - MaxArchVGPRs),
143+ 0 );
144+ unsigned OtherExcessArchVGPR =
145+ std::max (static_cast <int >(O.getVGPRNum (false ) + OtherVGPRForSGPRSpills -
146+ MaxArchVGPRs),
147+ 0 );
148+ // AGPR excess pressure conditions
149+ unsigned ExcessAGPR = std::max (
150+ static_cast <int >(ST.hasGFX90AInsts () ? (getAGPRNum () - MaxArchVGPRs)
151+ : (getAGPRNum () - MaxVGPRs)),
152+ 0 );
153+ unsigned OtherExcessAGPR = std::max (
154+ static_cast <int >(ST.hasGFX90AInsts () ? (O.getAGPRNum () - MaxArchVGPRs)
155+ : (O.getAGPRNum () - MaxVGPRs)),
156+ 0 );
157+
158+ bool ExcessRP = ExcessSGPR || ExcessVGPR || ExcessArchVGPR || ExcessAGPR;
159+ bool OtherExcessRP = OtherExcessSGPR || OtherExcessVGPR ||
160+ OtherExcessArchVGPR || OtherExcessAGPR;
161+
162+ // Give second precedence to the reduced number of spills to hold the register
163+ // pressure.
164+ if (ExcessRP || OtherExcessRP) {
165+ // The difference in excess VGPR pressure, after including VGPRs used for
166+ // SGPR spills
167+ int VGPRDiff = ((OtherExcessVGPR + OtherExcessArchVGPR + OtherExcessAGPR) -
168+ (ExcessVGPR + ExcessArchVGPR + ExcessAGPR));
169+
170+ int SGPRDiff = OtherExcessSGPR - ExcessSGPR;
171+
172+ if (VGPRDiff != 0 )
173+ return VGPRDiff > 0 ;
174+ if (SGPRDiff != 0 ) {
175+ unsigned PureExcessVGPR =
176+ std::max (static_cast <int >(getVGPRNum (ST.hasGFX90AInsts ()) - MaxVGPRs),
177+ 0 ) +
178+ std::max (static_cast <int >(getVGPRNum (false ) - MaxArchVGPRs), 0 );
179+ unsigned OtherPureExcessVGPR =
180+ std::max (
181+ static_cast <int >(O.getVGPRNum (ST.hasGFX90AInsts ()) - MaxVGPRs),
182+ 0 ) +
183+ std::max (static_cast <int >(O.getVGPRNum (false ) - MaxArchVGPRs), 0 );
184+
185+ // If we have a special case where there is a tie in excess VGPR, but one
186+ // of the pressures has VGPR usage from SGPR spills, prefer the pressure
187+ // with SGPR spills.
188+ if (PureExcessVGPR != OtherPureExcessVGPR)
189+ return SGPRDiff < 0 ;
190+ // If both pressures have the same excess pressure before and after
191+ // accounting for SGPR spills, prefer fewer SGPR spills.
192+ return SGPRDiff > 0 ;
193+ }
194+ }
195+
110196 bool SGPRImportant = SGPROcc < VGPROcc;
111197 const bool OtherSGPRImportant = OtherSGPROcc < OtherVGPROcc;
112198
113- // if both pressures disagree on what is more important compare vgprs
199+ // If both pressures disagree on what is more important compare vgprs.
114200 if (SGPRImportant != OtherSGPRImportant) {
115201 SGPRImportant = false ;
116202 }
117203
118- // compare large regs pressure
204+ // Give third precedence to lower register tuple pressure.
119205 bool SGPRFirst = SGPRImportant;
120206 for (int I = 2 ; I > 0 ; --I, SGPRFirst = !SGPRFirst) {
121207 if (SGPRFirst) {
@@ -130,6 +216,8 @@ bool GCNRegPressure::less(const GCNSubtarget &ST,
130216 return VW < OtherVW;
131217 }
132218 }
219+
220+ // Give final precedence to lower general RP.
133221 return SGPRImportant ? (getSGPRNum () < O.getSGPRNum ()):
134222 (getVGPRNum (ST.hasGFX90AInsts ()) <
135223 O.getVGPRNum (ST.hasGFX90AInsts ()));
0 commit comments