LLVM: lib/CodeGen/SelectionDAG/ResourcePriorityQueue.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

30

31using namespace llvm;

32

33#define DEBUG_TYPE "scheduler"

34

37 cl::desc("Disable use of DFA during scheduling"));

38

41 cl::desc("Track reg pressure and switch priority to in-depth"));

42

44 : Picker(this), InstrItins(IS->MF->getSubtarget().getInstrItineraryData()) {

47 TLI = IS->TLI;

49 ResourcesModel.reset(TII->CreateTargetScheduleState(STI));

50

51

52 assert(ResourcesModel && "Unimplemented CreateTargetScheduleState.");

53

54 unsigned NumRC = TRI->getNumRegClasses();

55 RegLimit.resize(NumRC);

56 RegPressure.resize(NumRC);

60 RegLimit[RC->getID()] = TRI->getRegPressureLimit(RC, *IS->MF);

61

62 ParallelLiveRanges = 0;

63 HorizontalVerticalBalance = 0;

64}

65

67

68unsigned

69ResourcePriorityQueue::numberRCValPredInSU(SUnit *SU, unsigned RCId) {

70 unsigned NumberDeps = 0;

72 if (Pred.isCtrl())

73 continue;

74

75 SUnit *PredSU = Pred.getSUnit();

77

78 if (!ScegN)

79 continue;

80

81

82

84 default: break;

88 case ISD::INLINEASM: break;

89 case ISD::INLINEASM_BR: break;

90 }

92 continue;

93

94 for (unsigned i = 0, e = ScegN->getNumValues(); i != e; ++i) {

98 NumberDeps++;

99 break;

100 }

101 }

102 }

103 return NumberDeps;

104}

105

106unsigned ResourcePriorityQueue::numberRCValSuccInSU(SUnit *SU,

107 unsigned RCId) {

108 unsigned NumberDeps = 0;

109 for (const SDep &Succ : SU->Succs) {

111 continue;

112

113 SUnit *SuccSU = Succ.getSUnit();

114 const SDNode *ScegN = SuccSU->getNode();

115 if (!ScegN)

116 continue;

117

118

119

121 default: break;

125 case ISD::INLINEASM: break;

126 case ISD::INLINEASM_BR: break;

127 }

129 continue;

130

131 for (unsigned i = 0, e = ScegN->getNumOperands(); i != e; ++i) {

133 MVT VT = Op.getNode()->getSimpleValueType(Op.getResNo());

134 if (TLI->isTypeLegal(VT)

135 && (TLI->getRegClassFor(VT)->getID() == RCId)) {

136 NumberDeps++;

137 break;

138 }

139 }

140 }

141 return NumberDeps;

142}

143

145 unsigned NumberDeps = 0;

146 for (const SDep &Succ : SU->Succs)

148 NumberDeps++;

149

150 return NumberDeps;

151}

152

154 unsigned NumberDeps = 0;

156 if (Pred.isCtrl())

157 NumberDeps++;

158

159 return NumberDeps;

160}

161

162

163

164

166 SUnits = &sunits;

167 NumNodesSolelyBlocking.resize(SUnits->size(), 0);

168

169 for (SUnit &SU : *SUnits) {

172 }

173}

174

175

176

178

179

180

181 if (LHS->isScheduleHigh && !RHS->isScheduleHigh)

182 return false;

183

184 if (!LHS->isScheduleHigh && RHS->isScheduleHigh)

185 return true;

186

187 unsigned LHSNum = LHS->NodeNum;

188 unsigned RHSNum = RHS->NodeNum;

189

190

191 unsigned LHSLatency = PQ->getLatency(LHSNum);

192 unsigned RHSLatency = PQ->getLatency(RHSNum);

193 if (LHSLatency < RHSLatency) return true;

194 if (LHSLatency > RHSLatency) return false;

195

196

197

198 unsigned LHSBlocked = PQ->getNumSolelyBlockNodes(LHSNum);

199 unsigned RHSBlocked = PQ->getNumSolelyBlockNodes(RHSNum);

200 if (LHSBlocked < RHSBlocked) return true;

201 if (LHSBlocked > RHSBlocked) return false;

202

203

204

205 return LHSNum < RHSNum;

206}

207

208

209

210

211SUnit *ResourcePriorityQueue::getSingleUnscheduledPred(SUnit *SU) {

212 SUnit *OnlyAvailablePred = nullptr;

213 for (const SDep &Pred : SU->Preds) {

214 SUnit &PredSU = *Pred.getSUnit();

216

217

218 if (OnlyAvailablePred && OnlyAvailablePred != &PredSU)

219 return nullptr;

220 OnlyAvailablePred = &PredSU;

221 }

222 }

223 return OnlyAvailablePred;

224}

225

227

228

229 unsigned NumNodesBlocking = 0;

230 for (const SDep &Succ : SU->Succs)

231 if (getSingleUnscheduledPred(Succ.getSUnit()) == SU)

232 ++NumNodesBlocking;

233

234 NumNodesSolelyBlocking[SU->NodeNum] = NumNodesBlocking;

235 Queue.push_back(SU);

236}

237

238

239

241 if (!SU || !SU->getNode())

242 return false;

243

244

245

247 return true;

248

249

250

253 default:

254 if (!ResourcesModel->canReserveResources(&TII->get(

256 return false;

257 break;

258 case TargetOpcode::EXTRACT_SUBREG:

259 case TargetOpcode::INSERT_SUBREG:

260 case TargetOpcode::SUBREG_TO_REG:

261 case TargetOpcode::REG_SEQUENCE:

262 case TargetOpcode::IMPLICIT_DEF:

263 break;

264 }

265

266

267

268 for (const SUnit *S : Packet)

269 for (const SDep &Succ : S->Succs) {

270

271

273 continue;

274

276 return false;

277 }

278

279 return true;

280}

281

282

284

285

287 ResourcesModel->clearResources();

288 Packet.clear();

289 }

290

293 default:

294 ResourcesModel->reserveResources(&TII->get(

296 break;

297 case TargetOpcode::EXTRACT_SUBREG:

298 case TargetOpcode::INSERT_SUBREG:

299 case TargetOpcode::SUBREG_TO_REG:

300 case TargetOpcode::REG_SEQUENCE:

301 case TargetOpcode::IMPLICIT_DEF:

302 break;

303 }

304 Packet.push_back(SU);

305 }

306

307 else {

308 ResourcesModel->clearResources();

309 Packet.clear();

310 }

311

312

313

314 if (Packet.size() >= InstrItins->SchedModel.IssueWidth) {

315 ResourcesModel->clearResources();

316 Packet.clear();

317 }

318}

319

321 int RegBalance = 0;

322

324 return RegBalance;

325

326

329 if (TLI->isTypeLegal(VT)

330 && TLI->getRegClassFor(VT)

331 && TLI->getRegClassFor(VT)->getID() == RCId)

332 RegBalance += numberRCValSuccInSU(SU, RCId);

333 }

334

337 MVT VT = Op.getNode()->getSimpleValueType(Op.getResNo());

339 continue;

340

341 if (TLI->isTypeLegal(VT) && TLI->getRegClassFor(VT)

342 && TLI->getRegClassFor(VT)->getID() == RCId)

343 RegBalance -= numberRCValPredInSU(SU, RCId);

344 }

345 return RegBalance;

346}

347

348

349

350

351

352

353

355 int RegBalance = 0;

356

358 return RegBalance;

359

360 if (RawPressure) {

363 }

364 else {

366 if ((RegPressure[RC->getID()] +

368 (RegPressure[RC->getID()] +

371 }

372 }

373

374 return RegBalance;

375}

376

377

378

387

388

389

391

392 int ResCount = 1;

393

394

396 return ResCount;

397

398

401

402

403

404

406

408

409

412

413

414

416 }

417

418

419 else {

420

422

423 ResCount += (NumNodesSolelyBlocking[SU->NodeNum] * ScaleTwo);

424

425

428

430 }

431

432

433

434

436 if (N->isMachineOpcode()) {

437 const MCInstrDesc &TID = TII->get(N->getMachineOpcode());

440 }

441 else

442 switch (N->getOpcode()) {

443 default: break;

448 break;

449

450 case ISD::INLINEASM:

451 case ISD::INLINEASM_BR:

453 break;

454 }

455 }

456 return ResCount;

457}

458

459

460

462

463

464 if (!SU) {

465 ResourcesModel->clearResources();

466 Packet.clear();

467 return;

468 }

469

471

472

474

475 for (unsigned i = 0, e = ScegN->getNumValues(); i != e; ++i) {

477

478 if (TLI->isTypeLegal(VT)) {

480 if (RC)

481 RegPressure[RC->getID()] += numberRCValSuccInSU(SU, RC->getID());

482 }

483 }

484

485 for (unsigned i = 0, e = ScegN->getNumOperands(); i != e; ++i) {

487 MVT VT = Op.getNode()->getSimpleValueType(Op.getResNo());

488

489 if (TLI->isTypeLegal(VT)) {

491 if (RC) {

492 if (RegPressure[RC->getID()] >

493 (numberRCValPredInSU(SU, RC->getID())))

494 RegPressure[RC->getID()] -= numberRCValPredInSU(SU, RC->getID());

495 else RegPressure[RC->getID()] = 0;

496 }

497 }

498 }

500 if (Pred.isCtrl() || (Pred.getSUnit()->NumRegDefsLeft == 0))

501 continue;

502 --Pred.getSUnit()->NumRegDefsLeft;

503 }

504 }

505

506

508

509

510

511

512 unsigned NumberNonControlDeps = 0;

513

514 for (const SDep &Succ : SU->Succs) {

515 adjustPriorityOfUnscheduledPreds(Succ.getSUnit());

517 NumberNonControlDeps++;

518 }

519

520 if (!NumberNonControlDeps) {

521 if (ParallelLiveRanges >= SU->NumPreds)

522 ParallelLiveRanges -= SU->NumPreds;

523 else

524 ParallelLiveRanges = 0;

525

526 }

527 else

529

530

533}

534

536 unsigned NodeNumDefs = 0;

538 if (N->isMachineOpcode()) {

539 const MCInstrDesc &TID = TII->get(N->getMachineOpcode());

540

541 if (N->getMachineOpcode() == TargetOpcode::IMPLICIT_DEF) {

542 NodeNumDefs = 0;

543 break;

544 }

545 NodeNumDefs = std::min(N->getNumValues(), TID.getNumDefs());

546 }

547 else

548 switch(N->getOpcode()) {

549 default: break;

551 NodeNumDefs++;

552 break;

553 case ISD::INLINEASM:

554 case ISD::INLINEASM_BR:

555 NodeNumDefs++;

556 break;

557 }

558

560}

561

562

563

564

565

566

567

568void ResourcePriorityQueue::adjustPriorityOfUnscheduledPreds(SUnit *SU) {

569 if (SU->isAvailable) return;

570

571 SUnit *OnlyAvailablePred = getSingleUnscheduledPred(SU);

572 if (!OnlyAvailablePred || !OnlyAvailablePred->isAvailable)

573 return;

574

575

576

577 remove(OnlyAvailablePred);

578

579

580

581 push(OnlyAvailablePred);

582}

583

584

585

586

589 return nullptr;

590

591 std::vector<SUnit *>::iterator Best = Queue.begin();

594 for (auto I = std::next(Queue.begin()), E = Queue.end(); I != E; ++I) {

595

598 Best = I;

599 }

600 }

601 }

602

603 else {

604 for (auto I = std::next(Queue.begin()), E = Queue.end(); I != E; ++I)

605 if (Picker(*Best, *I))

606 Best = I;

607 }

608

609 SUnit *V = *Best;

610 if (Best != std::prev(Queue.end()))

612

613 Queue.pop_back();

614

615 return V;

616}

617

618

620 assert(!Queue.empty() && "Queue is empty!");

621 std::vector<SUnit *>::iterator I = find(Queue, SU);

622 if (I != std::prev(Queue.end()))

624

625 Queue.pop_back();

626}

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

static const unsigned PriorityTwo

Definition ResourcePriorityQueue.cpp:380

static const unsigned FactorOne

Definition ResourcePriorityQueue.cpp:386

static const unsigned PriorityThree

Definition ResourcePriorityQueue.cpp:381

static cl::opt< int > RegPressureThreshold("dfa-sched-reg-pressure-threshold", cl::Hidden, cl::init(5), cl::desc("Track reg pressure and switch priority to in-depth"))

static const unsigned ScaleOne

Definition ResourcePriorityQueue.cpp:383

static unsigned numberCtrlPredInSU(SUnit *SU)

Definition ResourcePriorityQueue.cpp:153

static const unsigned PriorityOne

Definition ResourcePriorityQueue.cpp:379

static unsigned numberCtrlDepsInSU(SUnit *SU)

Definition ResourcePriorityQueue.cpp:144

static cl::opt< bool > DisableDFASched("disable-dfa-sched", cl::Hidden, cl::desc("Disable use of DFA during scheduling"))

static const unsigned PriorityFour

Definition ResourcePriorityQueue.cpp:382

static const unsigned ScaleTwo

Definition ResourcePriorityQueue.cpp:384

static const unsigned ScaleThree

Definition ResourcePriorityQueue.cpp:385

This file describes how to lower LLVM code to machine code.

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

unsigned getNumDefs() const

Return the number of MachineOperands that are register definitions.

bool isCall() const

Return true if the instruction is a call.

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

void push(SUnit *U) override

Definition ResourcePriorityQueue.cpp:226

void scheduledNode(SUnit *SU) override

scheduledNode - Main resource tracking point.

Definition ResourcePriorityQueue.cpp:461

ResourcePriorityQueue(SelectionDAGISel *IS)

Definition ResourcePriorityQueue.cpp:43

void initNodes(std::vector< SUnit > &sunits) override

Initialize nodes.

Definition ResourcePriorityQueue.cpp:165

bool empty() const override

SUnit * pop() override

Main access point - returns next instructions to be placed in scheduling sequence.

Definition ResourcePriorityQueue.cpp:587

int rawRegPressureDelta(SUnit *SU, unsigned RCId)

Definition ResourcePriorityQueue.cpp:320

int regPressureDelta(SUnit *SU, bool RawPressure=false)

Estimates change in reg pressure from this SU.

Definition ResourcePriorityQueue.cpp:354

void remove(SUnit *SU) override

Definition ResourcePriorityQueue.cpp:619

~ResourcePriorityQueue() override

void reserveResources(SUnit *SU)

Keep track of available resources.

Definition ResourcePriorityQueue.cpp:283

int SUSchedulingCost(SUnit *SU)

Single cost function reflecting benefit of scheduling SU in the current cycle.

Definition ResourcePriorityQueue.cpp:390

void initNumRegDefsLeft(SUnit *SU)

InitNumRegDefsLeft - Determine the # of regs defined by this node.

Definition ResourcePriorityQueue.cpp:535

bool isResourceAvailable(SUnit *SU)

Check if scheduling of this SU is possible in the current packet.

Definition ResourcePriorityQueue.cpp:240

Represents one node in the SelectionDAG.

bool isMachineOpcode() const

Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.

unsigned getOpcode() const

Return the SelectionDAG opcode value for this node.

MVT getSimpleValueType(unsigned ResNo) const

Return the type of a specified result as a simple type.

unsigned getNumValues() const

Return the number of values defined/returned by this operator.

unsigned getNumOperands() const

Return the number of values used by this operation.

unsigned getMachineOpcode() const

This may only be called if isMachineOpcode returns true.

const SDValue & getOperand(unsigned Num) const

SDNode * getGluedNode() const

If this node has a glue operand, return the node to which the glue operand points.

Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.

bool isCtrl() const

Shorthand for getKind() != SDep::Data.

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

unsigned NodeQueueId

Queue id of node.

unsigned NodeNum

Entry # of node in the node vector.

unsigned getHeight() const

Returns the height of this node, which is the length of the maximum path down to any node which has n...

unsigned short NumRegDefsLeft

bool isScheduleHigh

True if preferable to schedule high.

bool isScheduled

True once scheduled.

bool isAvailable

True once available.

SmallVector< SDep, 4 > Succs

All sunit successors.

SDNode * getNode() const

Returns the representative SDNode for this SUnit.

SmallVector< SDep, 4 > Preds

All sunit predecessors.

SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...

const TargetLowering * TLI

virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const

Return the register class that should be used for the specified value type.

bool isTypeLegal(EVT VT) const

Return true if the target has native support for the specified value type.

unsigned getID() const

Return the register class ID number.

TargetSubtargetInfo - Generic base class for all target subtargets.

virtual const TargetInstrInfo * getInstrInfo() const

virtual const TargetRegisterInfo * getRegisterInfo() const =0

Return the target's register information.

@ CopyFromReg

CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...

@ CopyToReg

CopyToReg - This node has three operands: a chain, a register number to set to this value,...

@ TokenFactor

TokenFactor - This node takes multiple tokens as input and produces a single token result.

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

auto find(R &&Range, const T &Val)

Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.

void fill(R &&Range, T &&Value)

Provide wrappers to std::fill which take ranges instead of having to pass begin/end explicitly.

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

DWARFExpression::Operation Op

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.

bool operator()(const SUnit *LHS, const SUnit *RHS) const

This heuristic is used if DFA scheduling is not desired for some VLIW platform.

Definition ResourcePriorityQueue.cpp:177

ResourcePriorityQueue * PQ