LLVM: lib/Target/SystemZ/SystemZHazardRecognizer.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

32

33using namespace llvm;

34

35#define DEBUG_TYPE "machine-scheduler"

36

37

38

39

41 cl::desc("The OOO window for processor "

42 "resources during scheduling."),

44

45unsigned SystemZHazardRecognizer::

46getNumDecoderSlots(SUnit *SU) const {

49 return 0;

50

52 "Only cracked instruction can have 2 uops.");

54 "Expanded instructions always group alone.");

56 "Expanded instructions fill the group(s).");

57

59}

60

61unsigned SystemZHazardRecognizer::getCurrCycleIdx(SUnit *SU) const {

62 unsigned Idx = CurrGroupSize;

63 if (GrpCount % 2)

64 Idx += 3;

65

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

73 return Idx;

74}

75

80

82 CurrGroupSize = 0;

83 CurrGroupHas4RegOps = false;

84 clearProcResCounters();

85 GrpCount = 0;

86 LastFPdOpCycleIdx = UINT_MAX;

87 LastEmittedMI = nullptr;

89}

90

91bool

92SystemZHazardRecognizer::fitsIntoCurrentGroup(SUnit *SU) const {

95 return true;

96

97

98

100 return (CurrGroupSize == 0);

101

102

103 assert ((CurrGroupSize < 2 || !CurrGroupHas4RegOps) &&

104 "Current decoder group is already full!");

105 if (CurrGroupSize == 2 && has4RegOps(SU->getInstr()))

106 return false;

107

108

109

110

111 assert ((getNumDecoderSlots(SU) <= 1) && (CurrGroupSize < 3) &&

112 "Expected normal instruction to fit in non-full group!");

113

114 return true;

115}

116

117bool SystemZHazardRecognizer::has4RegOps(const MachineInstr *MI) const {

119 unsigned Count = 0;

122 if (RC == nullptr)

123 continue;

126 continue;

128 }

129 return Count >= 4;

130}

131

132void SystemZHazardRecognizer::nextGroup() {

133 if (CurrGroupSize == 0)

134 return;

135

138

139 int NumGroups = ((CurrGroupSize > 3) ? (CurrGroupSize / 3) : 1);

140 assert((CurrGroupSize <= 3 || CurrGroupSize % 3 == 0) &&

141 "Current decoder group bad.");

142

143

144 CurrGroupSize = 0;

145 CurrGroupHas4RegOps = false;

146

147 GrpCount += ((unsigned) NumGroups);

148

149

150 for (unsigned i = 0; i < SchedModel->getNumProcResourceKinds(); ++i)

151 ProcResourceCounters[i] = ((ProcResourceCounters[i] > NumGroups)

152 ? (ProcResourceCounters[i] - NumGroups)

153 : 0);

154

155

156 if (CriticalResourceIdx != UINT_MAX &&

157 (ProcResourceCounters[CriticalResourceIdx] <=

159 CriticalResourceIdx = UINT_MAX;

160

162}

163

164#ifndef NDEBUG

166 OS << "SU(" << SU->NodeNum << "):";

168

171 return;

172

174 PI = SchedModel->getWriteProcResBegin(SC),

175 PE = SchedModel->getWriteProcResEnd(SC); PI != PE; ++PI) {

177 *SchedModel->getProcResource(PI->ProcResourceIdx);

178 std::string FU(PRD.Name);

179

180 FU = FU.substr(FU.find('_') + 1);

181 size_t Pos = FU.find("Unit");

182 if (Pos != std:🧵:npos)

183 FU.resize(Pos);

184 if (FU == "LS")

185 FU = "LSU";

186 OS << "/" << FU;

187

188 if (PI->ReleaseAtCycle> 1)

189 OS << "(" << PI->ReleaseAtCycle << "cyc)";

190 }

191

195 OS << "/GroupsAlone";

197 OS << "/BeginsGroup";

199 OS << "/EndsGroup";

201 OS << "/Unbuffered";

202 if (has4RegOps(SU->getInstr()))

203 OS << "/4RegOps";

204}

205

207 dbgs() << "++ " << Msg;

208 dbgs() << ": ";

209

211 dbgs() << " \n";

212 else {

214 dbgs() << " (" << CurrGroupSize << " decoder slot"

215 << (CurrGroupSize > 1 ? "s":"")

216 << (CurrGroupHas4RegOps ? ", 4RegOps" : "")

217 << ")\n";

218 }

219}

220

222 bool any = false;

223

224 for (unsigned i = 0; i < SchedModel->getNumProcResourceKinds(); ++i)

225 if (ProcResourceCounters[i] > 0) {

226 any = true;

227 break;

228 }

229

230 if (!any)

231 return;

232

233 dbgs() << "++ | Resource counters: ";

234 for (unsigned i = 0; i < SchedModel->getNumProcResourceKinds(); ++i)

235 if (ProcResourceCounters[i] > 0)

236 dbgs() << SchedModel->getProcResource(i)->Name

237 << ":" << ProcResourceCounters[i] << " ";

238 dbgs() << "\n";

239

240 if (CriticalResourceIdx != UINT_MAX)

241 dbgs() << "++ | Critical resource: "

242 << SchedModel->getProcResource(CriticalResourceIdx)->Name

243 << "\n";

244}

245

248 dbgs() << "++ | Current cycle index: "

249 << getCurrCycleIdx() << "\n";

251 if (LastFPdOpCycleIdx != UINT_MAX)

252 dbgs() << "++ | Last FPd cycle index: " << LastFPdOpCycleIdx << "\n";

253}

254

255#endif

256

257void SystemZHazardRecognizer::clearProcResCounters() {

259 CriticalResourceIdx = UINT_MAX;

260}

261

263 return (MI->isBranch() || MI->isReturn() ||

264 MI->getOpcode() == SystemZ::CondTrap);

265}

266

267

272 dbgs() << "\n";);

274

275

276

277 if (!fitsIntoCurrentGroup(SU))

278 nextGroup();

279

282

283 LastEmittedMI = SU->getInstr();

284

285

287 LLVM_DEBUG(dbgs() << "++ Clearing state after call.\n";);

289 LastEmittedMI = SU->getInstr();

290 return;

291 }

292

293

295 PI = SchedModel->getWriteProcResBegin(SC),

296 PE = SchedModel->getWriteProcResEnd(SC); PI != PE; ++PI) {

297

298 if (SchedModel->getProcResource(PI->ProcResourceIdx)->BufferSize == 1)

299 continue;

300 int &CurrCounter =

301 ProcResourceCounters[PI->ProcResourceIdx];

302 CurrCounter += PI->ReleaseAtCycle;

303

305 (CriticalResourceIdx == UINT_MAX ||

306 (PI->ProcResourceIdx != CriticalResourceIdx &&

307 CurrCounter >

308 ProcResourceCounters[CriticalResourceIdx]))) {

310 dbgs() << "++ New critical resource: "

311 << SchedModel->getProcResource(PI->ProcResourceIdx)->Name

312 << "\n";);

313 CriticalResourceIdx = PI->ProcResourceIdx;

314 }

315 }

316

317

319 LastFPdOpCycleIdx = getCurrCycleIdx(SU);

320 LLVM_DEBUG(dbgs() << "++ Last FPd cycle index: " << LastFPdOpCycleIdx

321 << "\n";);

322 }

323

324

325

326 CurrGroupSize += getNumDecoderSlots(SU);

327 CurrGroupHas4RegOps |= has4RegOps(SU->getInstr());

328 unsigned GroupLim = (CurrGroupHas4RegOps ? 2 : 3);

329 assert((CurrGroupSize <= GroupLim || CurrGroupSize == getNumDecoderSlots(SU))

330 && "SU does not fit into decoder group!");

331

332

333

334 if (CurrGroupSize >= GroupLim || SC->EndGroup)

335 nextGroup();

336}

337

341 return 0;

342

343

344

346 if (CurrGroupSize)

347 return 3 - CurrGroupSize;

348 return -1;

349 }

350

351

352

354 unsigned ResultingGroupSize = (CurrGroupSize + getNumDecoderSlots(SU));

355 if (ResultingGroupSize < 3)

356 return (3 - ResultingGroupSize);

357 return -1;

358 }

359

360

361 if (CurrGroupSize == 2 && has4RegOps(SU->getInstr()))

362 return 1;

363

364

365 return 0;

366}

367

368bool SystemZHazardRecognizer::isFPdOpPreferred_distance(SUnit *SU) const {

370

371 if (LastFPdOpCycleIdx == UINT_MAX)

372 return true;

373

374

375

376

377 unsigned SUCycleIdx = getCurrCycleIdx(SU);

378 if (LastFPdOpCycleIdx > SUCycleIdx)

379 return ((LastFPdOpCycleIdx - SUCycleIdx) == 3);

380 return ((SUCycleIdx - LastFPdOpCycleIdx) == 3);

381}

382

385 int Cost = 0;

386

389 return 0;

390

391

392

394 Cost = (isFPdOpPreferred_distance(SU) ? INT_MIN : INT_MAX);

395

396 else if (CriticalResourceIdx != UINT_MAX) {

398 PI = SchedModel->getWriteProcResBegin(SC),

399 PE = SchedModel->getWriteProcResEnd(SC); PI != PE; ++PI)

400 if (PI->ProcResourceIdx == CriticalResourceIdx)

401 Cost = PI->ReleaseAtCycle;

402 }

403

405}

406

408 bool TakenBranch) {

409

411

412

414

417 make_range(SchedModel->getWriteProcResBegin(SC),

418 SchedModel->getWriteProcResEnd(SC))) {

419 switch (SchedModel->getProcResource(PRE.ProcResourceIdx)->BufferSize) {

420 case 0:

422 break;

423 case 1:

425 break;

426 default:

427 break;

428 }

429 }

430

431 unsigned GroupSizeBeforeEmit = CurrGroupSize;

433

435

436 if (GroupSizeBeforeEmit == 1)

437 nextGroup();

438 }

439

440 if (TakenBranch && CurrGroupSize > 0)

441 nextGroup();

442

444 "Scheduler: unhandled terminator!");

445}

446

449

450 CurrGroupSize = Incoming->CurrGroupSize;

452

453

454 ProcResourceCounters = Incoming->ProcResourceCounters;

455 CriticalResourceIdx = Incoming->CriticalResourceIdx;

456

457

458 LastFPdOpCycleIdx = Incoming->LastFPdOpCycleIdx;

459 GrpCount = Incoming->GrpCount;

460}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

const HexagonInstrInfo * TII

MachineInstr unsigned OpIdx

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

static bool isBranchRetTrap(MachineInstr *MI)

Definition SystemZHazardRecognizer.cpp:262

static cl::opt< int > ProcResCostLim("procres-cost-lim", cl::Hidden, cl::desc("The OOO window for processor " "resources during scheduling."), cl::init(8))

Describe properties that are true of each instruction in the target description file.

unsigned getNumOperands() const

Return the number of declared MachineOperands for this MachineInstruction.

unsigned getNumDefs() const

Return the number of MachineOperands that are register definitions.

int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const

Returns the value of the specified operand constraint if it is present.

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

Scheduling unit. This is a node in the scheduling DAG.

bool isCall

Is a function call.

unsigned NodeNum

Entry # of node in the node vector.

bool isUnbuffered

Uses an unbuffered resource.

bool hasReservedResource

Uses a reserved resource.

MachineInstr * getInstr() const

Returns the representative MachineInstr for this SUnit.

void assign(size_type NumElts, ValueParamT Elt)

int groupingCost(SUnit *SU) const

Return the cost of decoder grouping for SU.

Definition SystemZHazardRecognizer.cpp:338

void dumpProcResourceCounters() const

Definition SystemZHazardRecognizer.cpp:221

void emitInstruction(MachineInstr *MI, bool TakenBranch=false)

Wrap a non-scheduled instruction in an SU and emit it.

Definition SystemZHazardRecognizer.cpp:407

const MCSchedClassDesc * getSchedClass(SUnit *SU) const

Resolves and cache a resolved scheduling class for an SUnit.

void copyState(SystemZHazardRecognizer *Incoming)

Copy counters from end of single predecessor.

Definition SystemZHazardRecognizer.cpp:448

void Reset() override

Reset - This callback is invoked when a new block of instructions is about to be schedule.

Definition SystemZHazardRecognizer.cpp:81

void dumpSU(SUnit *SU, raw_ostream &OS) const

Definition SystemZHazardRecognizer.cpp:165

HazardType getHazardType(SUnit *SU, int Stalls=0) override

getHazardType - Return the hazard type of emitting this node.

Definition SystemZHazardRecognizer.cpp:77

void dumpCurrGroup(std::string Msg="") const

Definition SystemZHazardRecognizer.cpp:206

int resourcesCost(SUnit *SU)

Return the cost of SU in regards to processor resources usage.

Definition SystemZHazardRecognizer.cpp:384

void dumpState() const

Definition SystemZHazardRecognizer.cpp:246

void EmitInstruction(SUnit *SU) override

EmitInstruction - This callback is invoked when an instruction is emitted, to advance the hazard stat...

Definition SystemZHazardRecognizer.cpp:269

SystemZHazardRecognizer(const SystemZInstrInfo *tii, const TargetSchedModel *SM)

const MCWriteProcResEntry * ProcResIter

unsigned getNumProcResourceKinds() const

Get the number of kinds of resources for this target.

This class implements an extremely fast bulk output stream that can only output to a stream.

A raw_ostream that writes to an std::string.

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

iterator_range< T > make_range(T x, T y)

Convenience function for iterating over sub-ranges.

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

FunctionAddr VTableAddr Count

Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...

Define a kind of processor resource that will be modeled by the scheduler.

Summarize the scheduling resources required for an instruction of a particular scheduling class.

Identify one of the processor resource kinds consumed by a particular scheduling class for the specif...