@@ -166,66 +166,60 @@ static LaneBitmask getDefRegMask(const MachineOperand &MO,
166
166
MRI.getTargetRegisterInfo ()->getSubRegIndexLaneMask (MO.getSubReg ());
167
167
}
168
168
169
- static LaneBitmask getUsedRegMask (const MachineOperand &MO,
170
- const MachineRegisterInfo &MRI,
171
- const LiveIntervals &LIS) {
172
- assert (MO.isUse () && MO.isReg () && MO.getReg ().isVirtual ());
173
-
174
- if (auto SubReg = MO.getSubReg ())
175
- return MRI.getTargetRegisterInfo ()->getSubRegIndexLaneMask (SubReg);
176
-
177
- auto MaxMask = MRI.getMaxLaneMaskForVReg (MO.getReg ());
178
- if (SIRegisterInfo::getNumCoveredRegs (MaxMask) > 1 ) // cannot have subregs
179
- return MaxMask;
180
-
181
- // For a tentative schedule LIS isn't updated yet but livemask should remain
182
- // the same on any schedule. Subreg defs can be reordered but they all must
183
- // dominate uses anyway.
184
- auto SI = LIS.getInstructionIndex (*MO.getParent ()).getBaseIndex ();
185
- return getLiveLaneMask (MO.getReg (), SI, LIS, MRI);
186
- }
187
-
188
- static SmallVector<RegisterMaskPair, 8 >
189
- collectVirtualRegUses (const MachineInstr &MI, const LiveIntervals &LIS,
169
+ static void
170
+ collectVirtualRegUses (SmallVectorImpl<RegisterMaskPair> &RegMaskPairs,
171
+ const MachineInstr &MI, const LiveIntervals &LIS,
190
172
const MachineRegisterInfo &MRI) {
191
- SmallVector<RegisterMaskPair, 8 > Res ;
173
+ SlotIndex InstrSI ;
192
174
for (const auto &MO : MI.operands ()) {
193
175
if (!MO.isReg () || !MO.getReg ().isVirtual ())
194
176
continue ;
195
177
if (!MO.isUse () || !MO.readsReg ())
196
178
continue ;
197
179
198
- auto const UsedMask = getUsedRegMask (MO, MRI, LIS);
180
+ Register Reg = MO.getReg ();
181
+ if (llvm::any_of (RegMaskPairs, [Reg](const RegisterMaskPair &RM) {
182
+ return RM.RegUnit == Reg;
183
+ }))
184
+ continue ;
185
+
186
+ LaneBitmask UseMask;
187
+ auto &LI = LIS.getInterval (Reg);
188
+ if (!LI.hasSubRanges ())
189
+ UseMask = MRI.getMaxLaneMaskForVReg (Reg);
190
+ else {
191
+ // For a tentative schedule LIS isn't updated yet but livemask should
192
+ // remain the same on any schedule. Subreg defs can be reordered but they
193
+ // all must dominate uses anyway.
194
+ if (!InstrSI)
195
+ InstrSI = LIS.getInstructionIndex (*MO.getParent ()).getBaseIndex ();
196
+ UseMask = getLiveLaneMask (LI, InstrSI, MRI);
197
+ }
199
198
200
- auto Reg = MO.getReg ();
201
- auto I = llvm::find_if (
202
- Res, [Reg](const RegisterMaskPair &RM) { return RM.RegUnit == Reg; });
203
- if (I != Res.end ())
204
- I->LaneMask |= UsedMask;
205
- else
206
- Res.push_back (RegisterMaskPair (Reg, UsedMask));
199
+ RegMaskPairs.emplace_back (Reg, UseMask);
207
200
}
208
- return Res;
209
201
}
210
202
211
203
// /////////////////////////////////////////////////////////////////////////////
212
204
// GCNRPTracker
213
205
214
- LaneBitmask llvm::getLiveLaneMask (unsigned Reg,
215
- SlotIndex SI,
206
+ LaneBitmask llvm::getLiveLaneMask (unsigned Reg, SlotIndex SI,
216
207
const LiveIntervals &LIS,
217
208
const MachineRegisterInfo &MRI) {
209
+ return getLiveLaneMask (LIS.getInterval (Reg), SI, MRI);
210
+ }
211
+
212
+ LaneBitmask llvm::getLiveLaneMask (const LiveInterval &LI, SlotIndex SI,
213
+ const MachineRegisterInfo &MRI) {
218
214
LaneBitmask LiveMask;
219
- const auto &LI = LIS.getInterval (Reg);
220
215
if (LI.hasSubRanges ()) {
221
216
for (const auto &S : LI.subranges ())
222
217
if (S.liveAt (SI)) {
223
218
LiveMask |= S.LaneMask ;
224
- assert (LiveMask < MRI.getMaxLaneMaskForVReg (Reg) ||
225
- LiveMask == MRI.getMaxLaneMaskForVReg (Reg));
219
+ assert (LiveMask == (LiveMask & MRI.getMaxLaneMaskForVReg (LI.reg ())));
226
220
}
227
221
} else if (LI.liveAt (SI)) {
228
- LiveMask = MRI.getMaxLaneMaskForVReg (Reg );
222
+ LiveMask = MRI.getMaxLaneMaskForVReg (LI. reg () );
229
223
}
230
224
return LiveMask;
231
225
}
@@ -261,15 +255,14 @@ void GCNRPTracker::reset(const MachineInstr &MI,
261
255
MaxPressure = CurPressure = getRegPressure (*MRI, LiveRegs);
262
256
}
263
257
264
- void GCNUpwardRPTracker::reset (const MachineInstr &MI,
265
- const LiveRegSet *LiveRegsCopy) {
266
- GCNRPTracker::reset (MI, LiveRegsCopy, true );
267
- }
258
+ // //////////////////////////////////////////////////////////////////////////////
259
+ // GCNUpwardRPTracker
268
260
269
261
void GCNUpwardRPTracker::reset (const MachineRegisterInfo &MRI_,
270
262
const LiveRegSet &LiveRegs_) {
271
263
MRI = &MRI_;
272
264
LiveRegs = LiveRegs_;
265
+ LastTrackedMI = nullptr ;
273
266
MaxPressure = CurPressure = getRegPressure (MRI_, LiveRegs_);
274
267
}
275
268
@@ -281,41 +274,55 @@ void GCNUpwardRPTracker::recede(const MachineInstr &MI) {
281
274
if (MI.isDebugInstr ())
282
275
return ;
283
276
284
- auto const RegUses = collectVirtualRegUses (MI, LIS, *MRI);
285
-
286
- // calc pressure at the MI (defs + uses)
287
- auto AtMIPressure = CurPressure;
288
- for (const auto &U : RegUses) {
289
- auto LiveMask = LiveRegs[U.RegUnit ];
290
- AtMIPressure.inc (U.RegUnit , LiveMask, LiveMask | U.LaneMask , *MRI);
291
- }
292
- // update max pressure
293
- MaxPressure = max (AtMIPressure, MaxPressure);
294
-
295
- for (const auto &MO : MI.all_defs ()) {
296
- if (!MO.getReg ().isVirtual () || MO.isDead ())
297
- continue ;
298
-
299
- auto Reg = MO.getReg ();
277
+ auto DecrementDef = [this ](const MachineOperand &MO) {
278
+ Register Reg = MO.getReg ();
300
279
auto I = LiveRegs.find (Reg);
301
280
if (I == LiveRegs.end ())
302
- continue ;
303
- auto &LiveMask = I->second ;
304
- auto PrevMask = LiveMask;
281
+ return ;
282
+
283
+ LaneBitmask &LiveMask = I->second ;
284
+ LaneBitmask PrevMask = LiveMask;
305
285
LiveMask &= ~getDefRegMask (MO, *MRI);
306
286
CurPressure.inc (Reg, PrevMask, LiveMask, *MRI);
307
287
if (LiveMask.none ())
308
288
LiveRegs.erase (I);
289
+ };
290
+
291
+ // Decrement non-early-clobber defs.
292
+ SmallVector<const MachineOperand *, 2 > EarlyClobberDefs;
293
+ for (const MachineOperand &MO : MI.all_defs ()) {
294
+ if (!MO.getReg ().isVirtual ())
295
+ continue ;
296
+ if (!MO.isEarlyClobber ())
297
+ DecrementDef (MO);
298
+ else
299
+ EarlyClobberDefs.push_back (&MO);
309
300
}
310
- for (const auto &U : RegUses) {
311
- auto &LiveMask = LiveRegs[U.RegUnit ];
312
- auto PrevMask = LiveMask;
301
+
302
+ // Increment uses.
303
+ SmallVector<RegisterMaskPair, 8 > RegUses;
304
+ collectVirtualRegUses (RegUses, MI, LIS, *MRI);
305
+ for (const RegisterMaskPair &U : RegUses) {
306
+ LaneBitmask &LiveMask = LiveRegs[U.RegUnit ];
307
+ LaneBitmask PrevMask = LiveMask;
313
308
LiveMask |= U.LaneMask ;
314
309
CurPressure.inc (U.RegUnit , PrevMask, LiveMask, *MRI);
315
310
}
311
+
312
+ // Point of maximum pressure: non-early-clobber defs are decremented and uses
313
+ // are incremented.
314
+ MaxPressure = max (CurPressure, MaxPressure);
315
+
316
+ // Now decrement early clobber defs.
317
+ for (const MachineOperand *MO : EarlyClobberDefs)
318
+ DecrementDef (*MO);
319
+
316
320
assert (CurPressure == getRegPressure (*MRI, LiveRegs));
317
321
}
318
322
323
+ // //////////////////////////////////////////////////////////////////////////////
324
+ // GCNDownwardRPTracker
325
+
319
326
bool GCNDownwardRPTracker::reset (const MachineInstr &MI,
320
327
const LiveRegSet *LiveRegsCopy) {
321
328
MRI = &MI.getParent ()->getParent ()->getRegInfo ();
@@ -562,15 +569,15 @@ bool GCNRegPressurePrinter::runOnMachineFunction(MachineFunction &MF) {
562
569
} else {
563
570
GCNUpwardRPTracker RPT (LIS);
564
571
RPT.reset (MRI, MBBEndSlot);
565
- RPT.moveMaxPressure (); // Clear max pressure.
566
572
567
573
LiveOut = RPT.getLiveRegs ();
568
574
RPAtMBBEnd = RPT.getPressure ();
569
575
570
576
for (auto &MI : reverse (MBB)) {
577
+ RPT.resetMaxPressure ();
571
578
RPT.recede (MI);
572
579
if (!MI.isDebugInstr ())
573
- RP.emplace_back (RPT.getPressure (), RPT.moveMaxPressure ());
580
+ RP.emplace_back (RPT.getPressure (), RPT.getMaxPressure ());
574
581
}
575
582
576
583
LiveIn = RPT.getLiveRegs ();
0 commit comments