Skip to content

Commit 3dc7da1

Browse files
committed
Settle for always using PressureDiffs when checking liveness.
1 parent 1914d53 commit 3dc7da1

File tree

2 files changed

+32
-126
lines changed

2 files changed

+32
-126
lines changed

llvm/lib/Target/SystemZ/SystemZMachineScheduler.cpp

Lines changed: 26 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,10 @@ static cl::opt<SystemZSched::LatencyReduction> PreRALatRed(
4141
"Use GenericSched cycle based decisions for reduction of "
4242
"scheduled latency.")));
4343

44-
// EXPERIMENTAL
45-
static cl::opt<bool>
46-
WITHPDIFFS("with-pdiffs", cl::init(false),
47-
cl::desc("Use SU PDiff instead of checking liveness of regs"));
48-
4944
static bool isRegDef(const MachineOperand &MO) {
5045
return MO.isReg() && MO.isDef();
5146
}
5247

53-
static bool isVirtRegDef(const MachineOperand &MO) {
54-
return isRegDef(MO) && MO.getReg().isVirtual();
55-
}
56-
5748
static bool isPhysRegDef(const MachineOperand &MO) {
5849
return isRegDef(MO) && MO.getReg().isPhysical();
5950
}
@@ -62,50 +53,6 @@ static bool isVirtRegUse(const MachineOperand &MO) {
6253
return MO.isReg() && MO.isUse() && MO.readsReg() && MO.getReg().isVirtual();
6354
}
6455

65-
void SystemZPreRASchedStrategy::initializePrioRegClasses(
66-
const TargetRegisterInfo *TRI) {
67-
if (WITHPDIFFS)
68-
return;
69-
for (const TargetRegisterClass *RC : TRI->regclasses()) {
70-
for (MVT VT : MVT::fp_valuetypes())
71-
if (TRI->isTypeLegalForClass(*RC, VT)) {
72-
PrioRegClasses.insert(RC->getID());
73-
break;
74-
}
75-
76-
// On SystemZ vector and FP registers overlap: add any vector RC.
77-
if (!PrioRegClasses.count(RC->getID()))
78-
for (MVT VT : MVT::fp_fixedlen_vector_valuetypes())
79-
if (TRI->isTypeLegalForClass(*RC, VT)) {
80-
PrioRegClasses.insert(RC->getID());
81-
break;
82-
}
83-
}
84-
}
85-
86-
void SystemZPreRASchedStrategy::initializePressureSets(
87-
const TargetRegisterInfo *TRI) {
88-
89-
// Based on the nature of the Vector/FP and GPR register classes, TableGen
90-
// defines a list of PressureSets that reflects the overlap of register
91-
// classes: FP regs affect both FP16Bit and VR16Bit PressureSets, while VR
92-
// regs affect only VR16Bit. Similarly, GR64 affects only GRX32Bit (with a
93-
// weight of 2), while GR32 affects both GR32Bit and GRX32Bit.
94-
//
95-
// When an instruction defines a register the question is if any used
96-
// registers will become live when scheduling it. This can be checked by
97-
// looking at the PressureSets that are shared between overlapping register
98-
// classes.
99-
//
100-
// misched-prera-pdiffs.mir tests against any future change in the
101-
// PressureSets, so simply hard-code them here:
102-
103-
if (!WITHPDIFFS)
104-
return;
105-
PrioPressureSet = SystemZ::VR16Bit;
106-
GPRPressureSet = SystemZ::GRX32Bit;
107-
}
108-
10956
bool SystemZPreRASchedStrategy::shouldReduceLatency(SchedBoundary *Zone) const {
11057
if (PreRALatRed == SystemZSched::Always)
11158
return true;
@@ -207,69 +154,56 @@ static int biasPhysRegExtra(const SUnit *SU) {
207154

208155
int SystemZPreRASchedStrategy::computeSULivenessScore(
209156
SchedCandidate &C, ScheduleDAGMILive *DAG, SchedBoundary *Zone) const {
210-
// Not all data deps are modelled around the SUnit - some data edges near
211-
// boundaries are missing: Look directly at the MI operands instead.
212157
const SUnit *SU = C.SU;
213158
const MachineInstr *MI = SU->getInstr();
214159
if (!MI->getNumOperands() || MI->isCopy())
215160
return 0;
216-
217161
const MachineOperand &MO0 = MI->getOperand(0);
218162
assert(!isPhysRegDef(MO0) && "Did not expect physreg def!");
219-
bool IsLoad = isRegDef(MO0) && !MO0.isDead() && !IsRedefining[SU->NodeNum];
220-
bool IsPrioLoad = IsLoad && isPrioVirtReg(MO0.getReg(), &DAG->MRI);
163+
221164
bool PreservesSchedLat = SU->getHeight() <= Zone->getScheduledLatency();
222165
const unsigned Cycles = 2;
223166
unsigned Margin = SchedModel->getIssueWidth() * (Cycles + SU->Latency - 1);
224167
bool HasDistToTop = NumLeft > Margin;
225-
bool IsKillingStore = isStoreOfVReg(MI) &&
226-
!DAG->getBotRPTracker().isRegLive(MO0.getReg());
227168

228169
// Before pulling down a load (to close the live range), the liveness of
229-
// the use operands is checked. This can be checked either by looking at
230-
// the operands of MI, or at the PDiff of the SU.
231-
bool UsesLivePrio = false, UsesLiveAll = false;
232-
if (!WITHPDIFFS) {
233-
// Find uses of registers that are not already live (kills).
234-
bool PrioKill = false;
235-
bool GPRKill = false;
236-
for (auto &MO : MI->explicit_uses())
237-
if (isVirtRegUse(MO) && !DAG->getBotRPTracker().isRegLive(MO.getReg()))
238-
(isPrioVirtReg(MO.getReg(), &DAG->MRI) ? PrioKill : GPRKill) = true;
239-
// Prioritize FP: Ignore GPR/Addr regs with an FP def.
240-
UsesLivePrio = !PrioKill && (IsPrioLoad || !GPRKill);
241-
UsesLiveAll = !PrioKill && !GPRKill;
242-
} else if (MO0.isReg() && MO0.getReg().isVirtual()) {
243-
int PrioPressureChange = 0;
170+
// the use operands is checked.
171+
bool UsesLiveVR = false, UsesLiveAll = false;
172+
if (isRegDef(MO0)) {
173+
// Extract the PressureChanges that all fp/vector or GR64/GR32/GRH32 regs
174+
// affect respectively. misched-prera-pdiffs.mir tests against any future
175+
// change in the PressureSets modelling, so simply hard-code them here.
176+
int VRPressureChange = 0;
244177
int GPRPressureChange = 0;
245178
const PressureDiff &PDiff = DAG->getPressureDiff(SU);
246179
for (const PressureChange &PC : PDiff) {
247180
if (!PC.isValid())
248181
break;
249-
if (PC.getPSet() == PrioPressureSet)
250-
PrioPressureChange += PC.getUnitInc();
251-
else if (PC.getPSet() == GPRPressureSet)
252-
GPRPressureChange += PC.getUnitInc();
182+
if (PC.getPSet() == SystemZ::VR16Bit)
183+
VRPressureChange = PC.getUnitInc();
184+
else if (PC.getPSet() == SystemZ::GRX32Bit)
185+
GPRPressureChange = PC.getUnitInc();
253186
}
254187
const TargetRegisterClass *RC = DAG->MRI.getRegClass(MO0.getReg());
255188
int RegWeight = TRI->getRegClassWeight(RC).RegWeight;
256-
if (IsLoad) {
257-
bool PrioDefNoKill = PrioPressureChange == -RegWeight;
258-
bool GPRDefNoKill = GPRPressureChange == -RegWeight;
259-
UsesLivePrio = (PrioDefNoKill || (!PrioPressureChange && GPRDefNoKill));
260-
UsesLiveAll = (PrioDefNoKill && !GPRPressureChange) ||
261-
(!PrioPressureChange && GPRDefNoKill);
262-
}
189+
bool VRDefNoKill = VRPressureChange == -RegWeight;
190+
bool GPRDefNoKill = GPRPressureChange == -RegWeight;
191+
UsesLiveVR = (VRDefNoKill || (!VRPressureChange && GPRDefNoKill));
192+
UsesLiveAll = (VRDefNoKill && !GPRPressureChange) ||
193+
(!VRPressureChange && GPRDefNoKill);
263194
}
264195

196+
bool IsKillingStore = isStoreOfVReg(MI) &&
197+
!DAG->getBotRPTracker().isRegLive(MO0.getReg());
198+
265199
// Pull down a defining SU if it preserves the scheduled latency while not
266-
// causing any (prioritized) register uses to become live. If however there
267-
// will be relatively many SUs scheduled above this one and all uses are
268-
// already live it should not be a problem to increase the scheduled
269-
// latency given the OOO execution.
200+
// causing any (vector) registers to become live. If however there will be
201+
// relatively many SUs scheduled above this one and all uses are already
202+
// live it should not be a problem to increase the scheduled latency given
203+
// the OOO execution.
270204
// TODO: Try scheduling small (DFSResult) subtrees as a unit.
271-
bool SchedLow = IsLoad && ((PreservesSchedLat && UsesLivePrio) ||
272-
(HasDistToTop && UsesLiveAll));
205+
bool SchedLow = (PreservesSchedLat && UsesLiveVR) ||
206+
(HasDistToTop && UsesLiveAll);
273207

274208
// This handles regions with many chained stores of the same depth at the
275209
// bottom in the input order (cactus). Push them upwards during scheduling.
@@ -419,18 +353,6 @@ void SystemZPreRASchedStrategy::initialize(ScheduleDAGMI *dag) {
419353
LLVM_DEBUG(dbgs() << "Latency scheduling " << (HasDataSequences ? "" : "not ")
420354
<< "enabled for data sequences.\n";);
421355

422-
// If MI uses the register it defines, record it one time here.
423-
IsRedefining = std::vector<bool>(DAG->SUnits.size(), false);
424-
if (!WITHPDIFFS) // This is not needed if using PressureDiffs.
425-
for (unsigned Idx = 0, End = DAG->SUnits.size(); Idx != End; ++Idx) {
426-
const MachineInstr *MI = DAG->SUnits[Idx].getInstr();
427-
if (MI->getNumOperands()) {
428-
const MachineOperand &DefMO = MI->getOperand(0);
429-
if (isVirtRegDef(DefMO))
430-
IsRedefining[Idx] = MI->readsVirtualRegister(DefMO.getReg());
431-
}
432-
}
433-
434356
initializeStoresGroup();
435357
LLVM_DEBUG(if (!StoresGroup.empty()) dbgs()
436358
<< "Has StoresGroup of " << StoresGroup.size() << " stores.\n";

llvm/lib/Target/SystemZ/SystemZMachineScheduler.h

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,10 @@ namespace llvm {
3636

3737
/// A MachineSchedStrategy implementation for SystemZ pre RA scheduling.
3838
class SystemZPreRASchedStrategy : public GenericScheduler {
39-
// The FP/Vector registers are prioritized during scheduling.
40-
std::set<unsigned> PrioRegClasses;
41-
void initializePrioRegClasses(const TargetRegisterInfo *TRI);
42-
bool isPrioVirtReg(Register Reg, const MachineRegisterInfo *MRI) const {
43-
return (Reg.isVirtual() &&
44-
PrioRegClasses.count(MRI->getRegClass(Reg)->getID()));
45-
}
46-
47-
unsigned PrioPressureSet;
48-
unsigned GPRPressureSet;
49-
void initializePressureSets(const TargetRegisterInfo *TRI);
50-
51-
// A TinyRegion has up to 10 instructions and is scheduled differently.
39+
// A TinyRegion has up to 10 instructions and is scheduled less
40+
// aggressively. Reordering these are more likely to disrupt copy /
41+
// comparison elimination while the potential benefit is less than in
42+
// bigger regions.
5243
bool TinyRegion;
5344

5445
// Num instructions left to schedule.
@@ -64,14 +55,11 @@ class SystemZPreRASchedStrategy : public GenericScheduler {
6455
// Return true if the scheduled latency should be minimized.
6556
bool shouldReduceLatency(SchedBoundary *Zone) const;
6657

67-
// True if MI is also using the register it defines.
68-
std::vector<bool> IsRedefining;
69-
7058
// Only call computeRemLatency() once before each scheduled node.
7159
mutable unsigned RemLat;
7260
unsigned getRemLat(SchedBoundary *Zone) const;
7361

74-
// A large group of stores at the bottom is spread upwards.
62+
// Make sure a large group of stores do not all end up at the bottom.
7563
std::set<const SUnit *> StoresGroup;
7664
bool FirstStoreInGroupScheduled;
7765
void initializeStoresGroup();
@@ -89,11 +77,7 @@ class SystemZPreRASchedStrategy : public GenericScheduler {
8977

9078
public:
9179
SystemZPreRASchedStrategy(const MachineSchedContext *C)
92-
: GenericScheduler(C) {
93-
const TargetRegisterInfo *TRI = C->MF->getRegInfo().getTargetRegisterInfo();
94-
initializePrioRegClasses(TRI);
95-
initializePressureSets(TRI);
96-
}
80+
: GenericScheduler(C) {}
9781

9882
void initPolicy(MachineBasicBlock::iterator Begin,
9983
MachineBasicBlock::iterator End,

0 commit comments

Comments
 (0)