blob: e2af0222799919257a93606bf54ed87bd88f3cd2 [file] [log] [blame]
Jonas Paulsson8010b632016-10-20 08:27:16 +00001//=-- SystemZHazardRecognizer.h - SystemZ Hazard Recognizer -----*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Jonas Paulsson8010b632016-10-20 08:27:16 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file defines a hazard recognizer for the SystemZ scheduler.
10//
11// This class is used by the SystemZ scheduling strategy to maintain
12// the state during scheduling, and provide cost functions for
13// scheduling candidates. This includes:
14//
15// * Decoder grouping. A decoder group can maximally hold 3 uops, and
16// instructions that always begin a new group should be scheduled when
17// the current decoder group is empty.
18// * Processor resources usage. It is beneficial to balance the use of
19// resources.
20//
Jonas Paulsson57a705d2017-08-17 08:33:44 +000021// A goal is to consider all instructions, also those outside of any
22// scheduling region. Such instructions are "advanced" past and include
23// single instructions before a scheduling region, branches etc.
24//
25// A block that has only one predecessor continues scheduling with the state
26// of it (which may be updated by emitting branches).
27//
Jonas Paulsson8010b632016-10-20 08:27:16 +000028// ===---------------------------------------------------------------------===//
29
30#include "SystemZHazardRecognizer.h"
31#include "llvm/ADT/Statistic.h"
32
33using namespace llvm;
34
Evandro Menezes0cd23f562017-07-11 22:08:28 +000035#define DEBUG_TYPE "machine-scheduler"
Jonas Paulsson8010b632016-10-20 08:27:16 +000036
37// This is the limit of processor resource usage at which the
38// scheduler should try to look for other instructions (not using the
39// critical resource).
Benjamin Kramerffd37152016-11-19 20:44:26 +000040static cl::opt<int> ProcResCostLim("procres-cost-lim", cl::Hidden,
41 cl::desc("The OOO window for processor "
42 "resources during scheduling."),
43 cl::init(8));
Jonas Paulsson8010b632016-10-20 08:27:16 +000044
Jonas Paulsson8010b632016-10-20 08:27:16 +000045unsigned SystemZHazardRecognizer::
46getNumDecoderSlots(SUnit *SU) const {
Jonas Paulsson57a705d2017-08-17 08:33:44 +000047 const MCSchedClassDesc *SC = getSchedClass(SU);
Jonas Paulsson8010b632016-10-20 08:27:16 +000048 if (!SC->isValid())
49 return 0; // IMPLICIT_DEF / KILL -- will not make impact in output.
50
Jonas Paulssonf107b722018-08-03 10:43:05 +000051 assert((SC->NumMicroOps != 2 || (SC->BeginGroup && !SC->EndGroup)) &&
52 "Only cracked instruction can have 2 uops.");
53 assert((SC->NumMicroOps < 3 || (SC->BeginGroup && SC->EndGroup)) &&
54 "Expanded instructions always group alone.");
55 assert((SC->NumMicroOps < 3 || (SC->NumMicroOps % 3 == 0)) &&
56 "Expanded instructions fill the group(s).");
Fangrui Songf78650a2018-07-30 19:41:25 +000057
Jonas Paulssonf107b722018-08-03 10:43:05 +000058 return SC->NumMicroOps;
Jonas Paulsson8010b632016-10-20 08:27:16 +000059}
60
Jonas Paulsson9b0f28f2018-03-07 08:54:32 +000061unsigned SystemZHazardRecognizer::getCurrCycleIdx(SUnit *SU) const {
Jonas Paulsson8010b632016-10-20 08:27:16 +000062 unsigned Idx = CurrGroupSize;
63 if (GrpCount % 2)
64 Idx += 3;
Jonas Paulsson9b0f28f2018-03-07 08:54:32 +000065
66 if (SU != nullptr && !fitsIntoCurrentGroup(SU)) {
67 if (Idx == 1 || Idx == 2)
68 Idx = 3;
69 else if (Idx == 4 || Idx == 5)
70 Idx = 0;
71 }
72
Jonas Paulsson8010b632016-10-20 08:27:16 +000073 return Idx;
74}
75
76ScheduleHazardRecognizer::HazardType SystemZHazardRecognizer::
77getHazardType(SUnit *m, int Stalls) {
78 return (fitsIntoCurrentGroup(m) ? NoHazard : Hazard);
79}
80
81void SystemZHazardRecognizer::Reset() {
82 CurrGroupSize = 0;
Jonas Paulsson2f12e452018-07-31 13:00:42 +000083 CurrGroupHas4RegOps = false;
Jonas Paulsson8010b632016-10-20 08:27:16 +000084 clearProcResCounters();
85 GrpCount = 0;
86 LastFPdOpCycleIdx = UINT_MAX;
Jonas Paulsson57a705d2017-08-17 08:33:44 +000087 LastEmittedMI = nullptr;
Nicola Zaghend34e60c2018-05-14 12:53:11 +000088 LLVM_DEBUG(CurGroupDbg = "";);
Jonas Paulsson8010b632016-10-20 08:27:16 +000089}
90
91bool
92SystemZHazardRecognizer::fitsIntoCurrentGroup(SUnit *SU) const {
Jonas Paulsson57a705d2017-08-17 08:33:44 +000093 const MCSchedClassDesc *SC = getSchedClass(SU);
Jonas Paulsson8010b632016-10-20 08:27:16 +000094 if (!SC->isValid())
95 return true;
96
97 // A cracked instruction only fits into schedule if the current
98 // group is empty.
99 if (SC->BeginGroup)
100 return (CurrGroupSize == 0);
101
Jonas Paulsson2f12e452018-07-31 13:00:42 +0000102 // An instruction with 4 register operands will not fit in last slot.
Jonas Paulsson590b1fc2018-07-31 19:58:42 +0000103 assert ((CurrGroupSize < 2 || !CurrGroupHas4RegOps) &&
Jonas Paulsson2f12e452018-07-31 13:00:42 +0000104 "Current decoder group is already full!");
105 if (CurrGroupSize == 2 && has4RegOps(SU->getInstr()))
106 return false;
107
Jonas Paulsson8010b632016-10-20 08:27:16 +0000108 // Since a full group is handled immediately in EmitInstruction(),
109 // SU should fit into current group. NumSlots should be 1 or 0,
110 // since it is not a cracked or expanded instruction.
111 assert ((getNumDecoderSlots(SU) <= 1) && (CurrGroupSize < 3) &&
112 "Expected normal instruction to fit in non-full group!");
113
114 return true;
115}
116
Jonas Paulsson2f12e452018-07-31 13:00:42 +0000117bool SystemZHazardRecognizer::has4RegOps(const MachineInstr *MI) const {
118 const MachineFunction &MF = *MI->getParent()->getParent();
119 const TargetRegisterInfo *TRI = &TII->getRegisterInfo();
120 const MCInstrDesc &MID = MI->getDesc();
121 unsigned Count = 0;
122 for (unsigned OpIdx = 0; OpIdx < MID.getNumOperands(); OpIdx++) {
123 const TargetRegisterClass *RC = TII->getRegClass(MID, OpIdx, TRI, MF);
124 if (RC == nullptr)
125 continue;
126 if (OpIdx >= MID.getNumDefs() &&
127 MID.getOperandConstraint(OpIdx, MCOI::TIED_TO) != -1)
128 continue;
129 Count++;
130 }
131 return Count >= 4;
132}
133
Jonas Paulsson61fbcf52018-03-07 08:39:00 +0000134void SystemZHazardRecognizer::nextGroup() {
135 if (CurrGroupSize == 0)
136 return;
Jonas Paulsson8010b632016-10-20 08:27:16 +0000137
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000138 LLVM_DEBUG(dumpCurrGroup("Completed decode group"));
139 LLVM_DEBUG(CurGroupDbg = "";);
Jonas Paulsson8010b632016-10-20 08:27:16 +0000140
Jonas Paulssonf107b722018-08-03 10:43:05 +0000141 int NumGroups = ((CurrGroupSize > 3) ? (CurrGroupSize / 3) : 1);
142 assert((CurrGroupSize <= 3 || CurrGroupSize % 3 == 0) &&
143 "Current decoder group bad.");
Jonas Paulsson8010b632016-10-20 08:27:16 +0000144
Jonas Paulsson61fbcf52018-03-07 08:39:00 +0000145 // Reset counter for next group.
146 CurrGroupSize = 0;
Jonas Paulsson2f12e452018-07-31 13:00:42 +0000147 CurrGroupHas4RegOps = false;
Jonas Paulsson8010b632016-10-20 08:27:16 +0000148
Jonas Paulssonf107b722018-08-03 10:43:05 +0000149 GrpCount += ((unsigned) NumGroups);
150
Jonas Paulsson5438f1d2018-08-07 13:48:09 +0000151 // Decrease counters for execution units.
Jonas Paulsson61fbcf52018-03-07 08:39:00 +0000152 for (unsigned i = 0; i < SchedModel->getNumProcResourceKinds(); ++i)
Jonas Paulsson25cbfdd2018-08-07 13:44:11 +0000153 ProcResourceCounters[i] = ((ProcResourceCounters[i] > NumGroups)
154 ? (ProcResourceCounters[i] - NumGroups)
155 : 0);
Jonas Paulsson8010b632016-10-20 08:27:16 +0000156
Jonas Paulsson61fbcf52018-03-07 08:39:00 +0000157 // Clear CriticalResourceIdx if it is now below the threshold.
158 if (CriticalResourceIdx != UINT_MAX &&
159 (ProcResourceCounters[CriticalResourceIdx] <=
160 ProcResCostLim))
161 CriticalResourceIdx = UINT_MAX;
162
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000163 LLVM_DEBUG(dumpState(););
Jonas Paulsson8010b632016-10-20 08:27:16 +0000164}
165
166#ifndef NDEBUG // Debug output
167void SystemZHazardRecognizer::dumpSU(SUnit *SU, raw_ostream &OS) const {
168 OS << "SU(" << SU->NodeNum << "):";
Jonas Paulsson57a705d2017-08-17 08:33:44 +0000169 OS << TII->getName(SU->getInstr()->getOpcode());
Jonas Paulsson8010b632016-10-20 08:27:16 +0000170
Jonas Paulsson57a705d2017-08-17 08:33:44 +0000171 const MCSchedClassDesc *SC = getSchedClass(SU);
Jonas Paulsson8010b632016-10-20 08:27:16 +0000172 if (!SC->isValid())
173 return;
Fangrui Songf78650a2018-07-30 19:41:25 +0000174
Jonas Paulsson8010b632016-10-20 08:27:16 +0000175 for (TargetSchedModel::ProcResIter
176 PI = SchedModel->getWriteProcResBegin(SC),
177 PE = SchedModel->getWriteProcResEnd(SC); PI != PE; ++PI) {
178 const MCProcResourceDesc &PRD =
179 *SchedModel->getProcResource(PI->ProcResourceIdx);
180 std::string FU(PRD.Name);
181 // trim e.g. Z13_FXaUnit -> FXa
182 FU = FU.substr(FU.find("_") + 1);
Jonas Paulsson59c94be2018-07-23 15:08:35 +0000183 size_t Pos = FU.find("Unit");
184 if (Pos != std::string::npos)
185 FU.resize(Pos);
186 if (FU == "LS") // LSUnit -> LSU
187 FU = "LSU";
Jonas Paulsson8010b632016-10-20 08:27:16 +0000188 OS << "/" << FU;
189
190 if (PI->Cycles > 1)
191 OS << "(" << PI->Cycles << "cyc)";
192 }
193
194 if (SC->NumMicroOps > 1)
195 OS << "/" << SC->NumMicroOps << "uops";
196 if (SC->BeginGroup && SC->EndGroup)
197 OS << "/GroupsAlone";
198 else if (SC->BeginGroup)
199 OS << "/BeginsGroup";
200 else if (SC->EndGroup)
201 OS << "/EndsGroup";
202 if (SU->isUnbuffered)
203 OS << "/Unbuffered";
Jonas Paulsson2f12e452018-07-31 13:00:42 +0000204 if (has4RegOps(SU->getInstr()))
205 OS << "/4RegOps";
Jonas Paulsson8010b632016-10-20 08:27:16 +0000206}
207
208void SystemZHazardRecognizer::dumpCurrGroup(std::string Msg) const {
Jonas Paulsson61fbcf52018-03-07 08:39:00 +0000209 dbgs() << "++ " << Msg;
Jonas Paulsson8010b632016-10-20 08:27:16 +0000210 dbgs() << ": ";
211
212 if (CurGroupDbg.empty())
213 dbgs() << " <empty>\n";
214 else {
215 dbgs() << "{ " << CurGroupDbg << " }";
216 dbgs() << " (" << CurrGroupSize << " decoder slot"
217 << (CurrGroupSize > 1 ? "s":"")
Jonas Paulsson2f12e452018-07-31 13:00:42 +0000218 << (CurrGroupHas4RegOps ? ", 4RegOps" : "")
Jonas Paulsson8010b632016-10-20 08:27:16 +0000219 << ")\n";
220 }
221}
222
223void SystemZHazardRecognizer::dumpProcResourceCounters() const {
224 bool any = false;
225
226 for (unsigned i = 0; i < SchedModel->getNumProcResourceKinds(); ++i)
227 if (ProcResourceCounters[i] > 0) {
228 any = true;
229 break;
230 }
231
232 if (!any)
233 return;
234
Jonas Paulsson61fbcf52018-03-07 08:39:00 +0000235 dbgs() << "++ | Resource counters: ";
Jonas Paulsson8010b632016-10-20 08:27:16 +0000236 for (unsigned i = 0; i < SchedModel->getNumProcResourceKinds(); ++i)
Jonas Paulsson61fbcf52018-03-07 08:39:00 +0000237 if (ProcResourceCounters[i] > 0)
238 dbgs() << SchedModel->getProcResource(i)->Name
239 << ":" << ProcResourceCounters[i] << " ";
240 dbgs() << "\n";
241
242 if (CriticalResourceIdx != UINT_MAX)
243 dbgs() << "++ | Critical resource: "
244 << SchedModel->getProcResource(CriticalResourceIdx)->Name
245 << "\n";
Jonas Paulsson8010b632016-10-20 08:27:16 +0000246}
Jonas Paulsson61fbcf52018-03-07 08:39:00 +0000247
248void SystemZHazardRecognizer::dumpState() const {
249 dumpCurrGroup("| Current decoder group");
250 dbgs() << "++ | Current cycle index: "
251 << getCurrCycleIdx() << "\n";
252 dumpProcResourceCounters();
253 if (LastFPdOpCycleIdx != UINT_MAX)
254 dbgs() << "++ | Last FPd cycle index: " << LastFPdOpCycleIdx << "\n";
255}
256
Jonas Paulsson8010b632016-10-20 08:27:16 +0000257#endif //NDEBUG
258
259void SystemZHazardRecognizer::clearProcResCounters() {
260 ProcResourceCounters.assign(SchedModel->getNumProcResourceKinds(), 0);
261 CriticalResourceIdx = UINT_MAX;
262}
263
Jonas Paulsson57a705d2017-08-17 08:33:44 +0000264static inline bool isBranchRetTrap(MachineInstr *MI) {
265 return (MI->isBranch() || MI->isReturn() ||
266 MI->getOpcode() == SystemZ::CondTrap);
267}
268
Jonas Paulsson8010b632016-10-20 08:27:16 +0000269// Update state with SU as the next scheduled unit.
270void SystemZHazardRecognizer::
271EmitInstruction(SUnit *SU) {
Jonas Paulsson57a705d2017-08-17 08:33:44 +0000272 const MCSchedClassDesc *SC = getSchedClass(SU);
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000273 LLVM_DEBUG(dbgs() << "++ HazardRecognizer emitting "; dumpSU(SU, dbgs());
274 dbgs() << "\n";);
275 LLVM_DEBUG(dumpCurrGroup("Decode group before emission"););
Jonas Paulsson8010b632016-10-20 08:27:16 +0000276
277 // If scheduling an SU that must begin a new decoder group, move on
278 // to next group.
279 if (!fitsIntoCurrentGroup(SU))
280 nextGroup();
281
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000282 LLVM_DEBUG(raw_string_ostream cgd(CurGroupDbg);
283 if (CurGroupDbg.length()) cgd << ", "; dumpSU(SU, cgd););
Jonas Paulsson8010b632016-10-20 08:27:16 +0000284
Jonas Paulsson57a705d2017-08-17 08:33:44 +0000285 LastEmittedMI = SU->getInstr();
286
Jonas Paulsson8010b632016-10-20 08:27:16 +0000287 // After returning from a call, we don't know much about the state.
Jonas Paulsson57a705d2017-08-17 08:33:44 +0000288 if (SU->isCall) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000289 LLVM_DEBUG(dbgs() << "++ Clearing state after call.\n";);
Jonas Paulsson91c853a2018-03-07 08:57:09 +0000290 Reset();
291 LastEmittedMI = SU->getInstr();
Jonas Paulsson8010b632016-10-20 08:27:16 +0000292 return;
293 }
294
295 // Increase counter for execution unit(s).
296 for (TargetSchedModel::ProcResIter
297 PI = SchedModel->getWriteProcResBegin(SC),
298 PE = SchedModel->getWriteProcResEnd(SC); PI != PE; ++PI) {
299 // Don't handle FPd together with the other resources.
300 if (SchedModel->getProcResource(PI->ProcResourceIdx)->BufferSize == 1)
301 continue;
302 int &CurrCounter =
303 ProcResourceCounters[PI->ProcResourceIdx];
304 CurrCounter += PI->Cycles;
305 // Check if this is now the new critical resource.
306 if ((CurrCounter > ProcResCostLim) &&
307 (CriticalResourceIdx == UINT_MAX ||
308 (PI->ProcResourceIdx != CriticalResourceIdx &&
309 CurrCounter >
310 ProcResourceCounters[CriticalResourceIdx]))) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000311 LLVM_DEBUG(
312 dbgs() << "++ New critical resource: "
313 << SchedModel->getProcResource(PI->ProcResourceIdx)->Name
314 << "\n";);
Jonas Paulsson8010b632016-10-20 08:27:16 +0000315 CriticalResourceIdx = PI->ProcResourceIdx;
316 }
317 }
318
319 // Make note of an instruction that uses a blocking resource (FPd).
320 if (SU->isUnbuffered) {
Jonas Paulsson9b0f28f2018-03-07 08:54:32 +0000321 LastFPdOpCycleIdx = getCurrCycleIdx(SU);
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000322 LLVM_DEBUG(dbgs() << "++ Last FPd cycle index: " << LastFPdOpCycleIdx
323 << "\n";);
Jonas Paulsson8010b632016-10-20 08:27:16 +0000324 }
325
326 // Insert SU into current group by increasing number of slots used
327 // in current group.
328 CurrGroupSize += getNumDecoderSlots(SU);
Jonas Paulsson2f12e452018-07-31 13:00:42 +0000329 CurrGroupHas4RegOps |= has4RegOps(SU->getInstr());
Jonas Paulssonf107b722018-08-03 10:43:05 +0000330 unsigned GroupLim = (CurrGroupHas4RegOps ? 2 : 3);
331 assert((CurrGroupSize <= GroupLim || CurrGroupSize == getNumDecoderSlots(SU))
332 && "SU does not fit into decoder group!");
Jonas Paulsson8010b632016-10-20 08:27:16 +0000333
334 // Check if current group is now full/ended. If so, move on to next
335 // group to be ready to evaluate more candidates.
Jonas Paulssonf107b722018-08-03 10:43:05 +0000336 if (CurrGroupSize >= GroupLim || SC->EndGroup)
Jonas Paulsson8010b632016-10-20 08:27:16 +0000337 nextGroup();
338}
339
340int SystemZHazardRecognizer::groupingCost(SUnit *SU) const {
Jonas Paulsson57a705d2017-08-17 08:33:44 +0000341 const MCSchedClassDesc *SC = getSchedClass(SU);
Jonas Paulsson8010b632016-10-20 08:27:16 +0000342 if (!SC->isValid())
343 return 0;
Fangrui Songf78650a2018-07-30 19:41:25 +0000344
Jonas Paulsson8010b632016-10-20 08:27:16 +0000345 // If SU begins new group, it can either break a current group early
346 // or fit naturally if current group is empty (negative cost).
347 if (SC->BeginGroup) {
348 if (CurrGroupSize)
349 return 3 - CurrGroupSize;
350 return -1;
351 }
352
353 // Similarly, a group-ending SU may either fit well (last in group), or
354 // end the group prematurely.
355 if (SC->EndGroup) {
356 unsigned resultingGroupSize =
357 (CurrGroupSize + getNumDecoderSlots(SU));
358 if (resultingGroupSize < 3)
359 return (3 - resultingGroupSize);
360 return -1;
361 }
362
Jonas Paulsson2f12e452018-07-31 13:00:42 +0000363 // An instruction with 4 register operands will not fit in last slot.
364 if (CurrGroupSize == 2 && has4RegOps(SU->getInstr()))
365 return 1;
366
Jonas Paulsson8010b632016-10-20 08:27:16 +0000367 // Most instructions can be placed in any decoder slot.
368 return 0;
369}
370
Jonas Paulsson9b0f28f2018-03-07 08:54:32 +0000371bool SystemZHazardRecognizer::isFPdOpPreferred_distance(SUnit *SU) const {
Jonas Paulsson8010b632016-10-20 08:27:16 +0000372 assert (SU->isUnbuffered);
373 // If this is the first FPd op, it should be scheduled high.
374 if (LastFPdOpCycleIdx == UINT_MAX)
375 return true;
376 // If this is not the first PFd op, it should go into the other side
377 // of the processor to use the other FPd unit there. This should
378 // generally happen if two FPd ops are placed with 2 other
379 // instructions between them (modulo 6).
Jonas Paulsson9b0f28f2018-03-07 08:54:32 +0000380 unsigned SUCycleIdx = getCurrCycleIdx(SU);
381 if (LastFPdOpCycleIdx > SUCycleIdx)
382 return ((LastFPdOpCycleIdx - SUCycleIdx) == 3);
383 return ((SUCycleIdx - LastFPdOpCycleIdx) == 3);
Jonas Paulsson8010b632016-10-20 08:27:16 +0000384}
385
386int SystemZHazardRecognizer::
387resourcesCost(SUnit *SU) {
388 int Cost = 0;
389
Jonas Paulsson57a705d2017-08-17 08:33:44 +0000390 const MCSchedClassDesc *SC = getSchedClass(SU);
Jonas Paulsson8010b632016-10-20 08:27:16 +0000391 if (!SC->isValid())
392 return 0;
393
394 // For a FPd op, either return min or max value as indicated by the
395 // distance to any prior FPd op.
396 if (SU->isUnbuffered)
397 Cost = (isFPdOpPreferred_distance(SU) ? INT_MIN : INT_MAX);
398 // For other instructions, give a cost to the use of the critical resource.
399 else if (CriticalResourceIdx != UINT_MAX) {
400 for (TargetSchedModel::ProcResIter
401 PI = SchedModel->getWriteProcResBegin(SC),
402 PE = SchedModel->getWriteProcResEnd(SC); PI != PE; ++PI)
403 if (PI->ProcResourceIdx == CriticalResourceIdx)
404 Cost = PI->Cycles;
405 }
406
407 return Cost;
408}
409
Jonas Paulsson57a705d2017-08-17 08:33:44 +0000410void SystemZHazardRecognizer::emitInstruction(MachineInstr *MI,
411 bool TakenBranch) {
412 // Make a temporary SUnit.
413 SUnit SU(MI, 0);
414
415 // Set interesting flags.
416 SU.isCall = MI->isCall();
417
418 const MCSchedClassDesc *SC = SchedModel->resolveSchedClass(MI);
419 for (const MCWriteProcResEntry &PRE :
420 make_range(SchedModel->getWriteProcResBegin(SC),
421 SchedModel->getWriteProcResEnd(SC))) {
422 switch (SchedModel->getProcResource(PRE.ProcResourceIdx)->BufferSize) {
423 case 0:
424 SU.hasReservedResource = true;
425 break;
426 case 1:
427 SU.isUnbuffered = true;
428 break;
429 default:
430 break;
431 }
432 }
433
Jonas Paulssone18dbeb2018-03-07 08:45:09 +0000434 unsigned GroupSizeBeforeEmit = CurrGroupSize;
Jonas Paulsson57a705d2017-08-17 08:33:44 +0000435 EmitInstruction(&SU);
436
Jonas Paulssone18dbeb2018-03-07 08:45:09 +0000437 if (!TakenBranch && isBranchRetTrap(MI)) {
438 // NT Branch on second slot ends group.
439 if (GroupSizeBeforeEmit == 1)
440 nextGroup();
441 }
442
Jonas Paulsson57a705d2017-08-17 08:33:44 +0000443 if (TakenBranch && CurrGroupSize > 0)
Jonas Paulsson61fbcf52018-03-07 08:39:00 +0000444 nextGroup();
Jonas Paulsson57a705d2017-08-17 08:33:44 +0000445
446 assert ((!MI->isTerminator() || isBranchRetTrap(MI)) &&
447 "Scheduler: unhandled terminator!");
448}
449
450void SystemZHazardRecognizer::
451copyState(SystemZHazardRecognizer *Incoming) {
452 // Current decoder group
453 CurrGroupSize = Incoming->CurrGroupSize;
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000454 LLVM_DEBUG(CurGroupDbg = Incoming->CurGroupDbg;);
Jonas Paulsson57a705d2017-08-17 08:33:44 +0000455
456 // Processor resources
457 ProcResourceCounters = Incoming->ProcResourceCounters;
458 CriticalResourceIdx = Incoming->CriticalResourceIdx;
459
460 // FPd
461 LastFPdOpCycleIdx = Incoming->LastFPdOpCycleIdx;
462 GrpCount = Incoming->GrpCount;
463}