LLVM: lib/Target/PowerPC/PPCHazardRecognizers.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

20using namespace llvm;

21

22#define DEBUG_TYPE "pre-RA-sched"

23

24bool PPCDispatchGroupSBHazardRecognizer::isLoadAfterStore(SUnit *SU) {

25

26 if (isBCTRAfterSet(SU))

27 return true;

28

31 return false;

32

33 if (MCID->mayLoad())

34 return false;

35

36

37

38 for (unsigned i = 0, ie = (unsigned) SU->Preds.size(); i != ie; ++i) {

40 if (!PredMCID || !PredMCID->mayStore())

41 continue;

42

43 if (!SU->Preds[i].isNormalMemory() && !SU->Preds[i].isBarrier())

44 continue;

45

46 for (unsigned j = 0, je = CurGroup.size(); j != je; ++j)

47 if (SU->Preds[i].getSUnit() == CurGroup[j])

48 return true;

49 }

50

51 return false;

52}

53

54bool PPCDispatchGroupSBHazardRecognizer::isBCTRAfterSet(SUnit *SU) {

55 const MCInstrDesc *MCID = DAG->getInstrDesc(SU);

56 if (!MCID)

57 return false;

58

60 return false;

61

62

63

64 for (unsigned i = 0, ie = (unsigned) SU->Preds.size(); i != ie; ++i) {

65 const MCInstrDesc *PredMCID = DAG->getInstrDesc(SU->Preds[i].getSUnit());

66 if (!PredMCID || PredMCID->getSchedClass() != PPC::Sched::IIC_SprMTSPR)

67 continue;

68

69 if (SU->Preds[i].isCtrl())

70 continue;

71

72 for (unsigned j = 0, je = CurGroup.size(); j != je; ++j)

73 if (SU->Preds[i].getSUnit() == CurGroup[j])

74 return true;

75 }

76

77 return false;

78}

79

80

82

83

84

85bool PPCDispatchGroupSBHazardRecognizer::mustComeFirst(const MCInstrDesc *MCID,

86 unsigned &NSlots) {

87

88

89

90 unsigned IIC = MCID->getSchedClass();

91 switch (IIC) {

92 default:

93 NSlots = 1;

94 break;

95 case PPC::Sched::IIC_IntDivW:

96 case PPC::Sched::IIC_IntDivD:

97 case PPC::Sched::IIC_LdStLoadUpd:

98 case PPC::Sched::IIC_LdStLDU:

99 case PPC::Sched::IIC_LdStLFDU:

100 case PPC::Sched::IIC_LdStLFDUX:

101 case PPC::Sched::IIC_LdStLHA:

102 case PPC::Sched::IIC_LdStLHAU:

103 case PPC::Sched::IIC_LdStLWA:

104 case PPC::Sched::IIC_LdStSTU:

105 case PPC::Sched::IIC_LdStSTFDU:

106 NSlots = 2;

107 break;

108 case PPC::Sched::IIC_LdStLoadUpdX:

109 case PPC::Sched::IIC_LdStLDUX:

110 case PPC::Sched::IIC_LdStLHAUX:

111 case PPC::Sched::IIC_LdStLWARX:

112 case PPC::Sched::IIC_LdStLDARX:

113 case PPC::Sched::IIC_LdStSTUX:

114 case PPC::Sched::IIC_LdStSTDCX:

115 case PPC::Sched::IIC_LdStSTWCX:

116 case PPC::Sched::IIC_BrMCRX:

117

118 NSlots = 4;

119 break;

120 }

121

122

124 NSlots = 2;

125

126 switch (IIC) {

127 default:

128

129 return NSlots > 1;

130 case PPC::Sched::IIC_BrCR:

131 case PPC::Sched::IIC_SprMFCR:

132 case PPC::Sched::IIC_SprMFCRF:

133 case PPC::Sched::IIC_SprMTSPR:

134 return true;

135 }

136}

137

140 if (Stalls == 0 && isLoadAfterStore(SU))

142

144}

145

148 unsigned NSlots;

149 if (MCID && mustComeFirst(MCID, NSlots) && CurSlots)

150 return true;

151

153}

154

156

157

158

159 if (isLoadAfterStore(SU) && CurSlots < 6) {

161 DAG->MF.getSubtarget<PPCSubtarget>().getCPUDirective();

162

163

166 return 1;

167

168 return 5 - CurSlots;

169 }

170

172}

173

177 if (CurSlots == 5 || (MCID->isBranch() && CurBranches == 1)) {

178 CurGroup.clear();

179 CurSlots = CurBranches = 0;

180 } else {

181 LLVM_DEBUG(dbgs() << "**** Adding to dispatch group: ");

183

184 unsigned NSlots;

185 bool MustBeFirst = mustComeFirst(MCID, NSlots);

186

187

188

189 if (MustBeFirst && CurSlots) {

190 CurSlots = CurBranches = 0;

191 CurGroup.clear();

192 }

193

194 CurSlots += NSlots;

195 CurGroup.push_back(SU);

196

197 if (MCID->isBranch())

198 ++CurBranches;

199 }

200 }

201

203}

204

208

212

214 CurGroup.clear();

215 CurSlots = CurBranches = 0;

217}

218

221 DAG->MF.getSubtarget<PPCSubtarget>().getCPUDirective();

222

223

224

227 CurSlots == 6) {

228 CurGroup.clear();

229 CurSlots = CurBranches = 0;

230 } else {

231 CurGroup.push_back(nullptr);

232 ++CurSlots;

233 }

234}

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

263 : DAG(DAG) {

264 EndDispatchGroup();

265}

266

267void PPCHazardRecognizer970::EndDispatchGroup() {

268 LLVM_DEBUG(errs() << "=== Start of dispatch group\n");

269 NumIssued = 0;

270

271

272 HasCTRSet = false;

273 NumStores = 0;

274}

275

276

278PPCHazardRecognizer970::GetInstrType(unsigned Opcode,

279 bool &isFirst, bool &isSingle,

280 bool &isCracked,

283

286

288

293}

294

295

296

297bool PPCHazardRecognizer970::

298isLoadOfStoredAddress(uint64_t LoadSize, int64_t LoadOffset,

299 const Value *LoadValue) const {

300 for (unsigned i = 0, e = NumStores; i != e; ++i) {

301

302 if (LoadValue == StoreValue[i] && LoadOffset == StoreOffset[i])

303 return true;

304

305

306

307 if (StoreValue[i] == LoadValue) {

308

309

310 if (StoreOffset[i] < LoadOffset) {

311 if (int64_t(StoreOffset[i]+StoreSize[i]) > LoadOffset) return true;

312 } else {

313 if (int64_t(LoadOffset+LoadSize) > StoreOffset[i]) return true;

314 }

315 }

316 }

317 return false;

318}

319

320

321

322

323

326 assert(Stalls == 0 && "PPC hazards don't support scoreboard lookahead");

327

329

330 if (MI->isDebugInstr())

332

333 unsigned Opcode = MI->getOpcode();

334 bool isFirst, isSingle, isCracked, isLoad, isStore;

336 GetInstrType(Opcode, isFirst, isSingle, isCracked,

339

340

341

342 if (NumIssued != 0 && (isFirst || isSingle))

344

345

346

347

348 if (isCracked && NumIssued > 2)

350

358

359 if (NumIssued == 4) return Hazard;

360 break;

362

363 if (NumIssued >= 2) return Hazard;

364 break;

366 break;

367 }

368

369

370 if (HasCTRSet && Opcode == PPC::BCTRL)

372

373

374

375 if (isLoad && NumStores && MI->memoperands_empty()) {

381 }

382

384}

385

388

389 if (MI->isDebugInstr())

390 return;

391

392 unsigned Opcode = MI->getOpcode();

393 bool isFirst, isSingle, isCracked, isLoad, isStore;

395 GetInstrType(Opcode, isFirst, isSingle, isCracked,

398

399

400 if (Opcode == PPC::MTCTR || Opcode == PPC::MTCTR8) HasCTRSet = true;

401

402

403 if (isStore && NumStores < 4 && !MI->memoperands_empty() &&

404 (*MI->memoperands_begin())->getSize().hasValue()) {

407 StoreOffset[NumStores] = MO->getOffset();

408 StoreValue[NumStores] = MO->getValue();

409 ++NumStores;

410 }

411

413 NumIssued = 4;

414 ++NumIssued;

415

416

417

418 if (isCracked)

419 ++NumIssued;

420

421 if (NumIssued == 5)

422 EndDispatchGroup();

423}

424

426 assert(NumIssued < 5 && "Illegal dispatch group!");

427 ++NumIssued;

428 if (NumIssued == 5)

429 EndDispatchGroup();

430}

431

433 EndDispatchGroup();

434}

435

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

static bool isLoad(int Opcode)

static bool isStore(int Opcode)

TypeSize getValue() const

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

unsigned getSchedClass() const

Return the scheduling class for this instruction.

bool mayStore() const

Return true if this instruction could possibly modify memory.

bool isBranch() const

Returns true if this is a conditional, unconditional, or indirect branch.

const MCInstrDesc & get(unsigned Opcode) const

Return the machine instruction descriptor that corresponds to the specified instruction opcode.

Representation of each machine instruction.

A description of a memory reference used in the backend.

LocationSize getSize() const

Return the size in bytes of the memory reference.

const Value * getValue() const

Return the base address of the memory access.

int64_t getOffset() const

For normal values, this is a byte offset added to the base address.

HazardType getHazardType(SUnit *SU, int Stalls) override

getHazardType - Return the hazard type of emitting this node.

Definition PPCHazardRecognizers.cpp:139

void AdvanceCycle() override

AdvanceCycle - This callback is invoked whenever the next top-down instruction to be scheduled cannot...

Definition PPCHazardRecognizers.cpp:205

unsigned PreEmitNoops(SUnit *SU) override

PreEmitNoops - This callback is invoked prior to emitting an instruction.

Definition PPCHazardRecognizers.cpp:155

void RecedeCycle() override

RecedeCycle - This callback is invoked whenever the next bottom-up instruction to be scheduled cannot...

Definition PPCHazardRecognizers.cpp:209

bool ShouldPreferAnother(SUnit *SU) override

ShouldPreferAnother - This callback may be invoked if getHazardType returns NoHazard.

Definition PPCHazardRecognizers.cpp:146

void EmitNoop() override

EmitNoop - This callback is invoked when a noop was added to the instruction stream.

Definition PPCHazardRecognizers.cpp:219

void Reset() override

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

Definition PPCHazardRecognizers.cpp:213

void EmitInstruction(SUnit *SU) override

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

Definition PPCHazardRecognizers.cpp:174

void AdvanceCycle() override

AdvanceCycle - This callback is invoked whenever the next top-down instruction to be scheduled cannot...

Definition PPCHazardRecognizers.cpp:425

PPCHazardRecognizer970(const ScheduleDAG &DAG)

Definition PPCHazardRecognizers.cpp:262

HazardType getHazardType(SUnit *SU, int Stalls) override

getHazardType - We return hazard for any non-branch instruction that would terminate the dispatch gro...

Definition PPCHazardRecognizers.cpp:325

void Reset() override

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

Definition PPCHazardRecognizers.cpp:432

void EmitInstruction(SUnit *SU) override

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

Definition PPCHazardRecognizers.cpp:386

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

SmallVector< SDep, 4 > Preds

All sunit predecessors.

MachineInstr * getInstr() const

Returns the representative MachineInstr for this SUnit.

const MCInstrDesc * getInstrDesc(const SUnit *SU) const

Returns the MCInstrDesc of this SUnit.

const TargetInstrInfo * TII

Target instruction information.

virtual bool ShouldPreferAnother(SUnit *)

ShouldPreferAnother - This callback may be invoked if getHazardType returns NoHazard.

virtual unsigned PreEmitNoops(SUnit *)

PreEmitNoops - This callback is invoked prior to emitting an instruction.

void Reset() override

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

void EmitInstruction(SUnit *SU) override

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

HazardType getHazardType(SUnit *SU, int Stalls) override

getHazardType - Return the hazard type of emitting this node.

void AdvanceCycle() override

AdvanceCycle - This callback is invoked whenever the next top-down instruction to be scheduled cannot...

LLVM Value Representation.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

InstrType

This represents what is and is not supported when finding similarity in Instructions.

@ PPC970_Pseudo

These are the various PPC970 execution unit pipelines.

@ PPC970_First

PPC970_First - This instruction starts a new dispatch group, so it will always be the first one in th...

@ PPC970_Cracked

PPC970_Cracked - This instruction is cracked into two pieces, requiring two dispatch pipes to be avai...

@ PPC970_Single

PPC970_Single - This instruction starts a new dispatch group and terminates it, so it will be the sol...

Define some predicates that are used for node matching.

int getNonRecordFormOpcode(uint16_t)

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI raw_ostream & dbgs()

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

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.