LLVM: lib/CodeGen/VLIWMachineScheduler.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

33#include

34#include

35#include

36#include

37#include

38#include

39

40using namespace llvm;

41

42#define DEBUG_TYPE "machine-scheduler"

43

46

49

52

53

54

57

58

59

60

63 cl::desc("High register pressure threhold."));

64

67 : TII(STI.getInstrInfo()), SchedModel(SM) {

69

70

71

73

77}

78

82}

83

85

86

88 if (SUd->Succs.size() == 0)

89 return false;

90

91 for (const auto &S : SUd->Succs) {

92

93

94 if (S.isCtrl())

95 continue;

96

97 if (S.getSUnit() == SUu && S.getLatency() > 0)

98 return true;

99 }

100 return false;

101}

102

103

104

105

106

107

110 return false;

111

112

113

115 default:

117 return false;

118 break;

119 case TargetOpcode::EXTRACT_SUBREG:

120 case TargetOpcode::INSERT_SUBREG:

121 case TargetOpcode::SUBREG_TO_REG:

122 case TargetOpcode::REG_SEQUENCE:

123 case TargetOpcode::IMPLICIT_DEF:

124 case TargetOpcode::COPY:

125 case TargetOpcode::INLINEASM:

126 case TargetOpcode::INLINEASM_BR:

127 break;

128 }

129

130

131

132 if (IsTop) {

135 return false;

136 } else {

139 return false;

140 }

141 return true;

142}

143

144

146 bool startNewCycle = false;

147

148 if (!SU) {

151 return false;

152 }

153

154

159 startNewCycle = true;

160 }

161

163 default:

165 break;

166 case TargetOpcode::EXTRACT_SUBREG:

167 case TargetOpcode::INSERT_SUBREG:

168 case TargetOpcode::SUBREG_TO_REG:

169 case TargetOpcode::REG_SEQUENCE:

170 case TargetOpcode::IMPLICIT_DEF:

171 case TargetOpcode::KILL:

172 case TargetOpcode::CFI_INSTRUCTION:

173 case TargetOpcode::EH_LABEL:

174 case TargetOpcode::COPY:

175 case TargetOpcode::INLINEASM:

176 case TargetOpcode::INLINEASM_BR:

177 break;

178 }

179 Packet.push_back(SU);

180

181#ifndef NDEBUG

183 for (unsigned i = 0, e = Packet.size(); i != e; ++i) {

187 }

188#endif

189

190 return startNewCycle;

191}

192

196}

197

198

199

200

202 LLVM_DEBUG(dbgs() << "********** MI Converging Scheduling VLIW "

206

208

210

211

213

216

217

219

221 unsigned maxH = 0;

223 if (SU.getHeight() > maxH)

224 maxH = SU.getHeight();

225 dbgs() << "Max Height " << maxH << "\n";

226 });

228 unsigned maxD = 0;

230 if (SU.getDepth() > maxD)

231 maxD = SU.getDepth();

232 dbgs() << "Max Depth " << maxD << "\n";

233 });

237

239

240 bool IsTopNode = false;

241 while (true) {

243 dbgs() << "** VLIWMachineScheduler::schedule picking next node\n");

245 if (!SU)

246 break;

247

249 break;

250

252

253

254 SchedImpl->schedNode(SU, IsTopNode);

255

257 }

259

261

263 dbgs() << "*** Final schedule for "

266 dbgs() << '\n';

267 });

268}

269

273

276

277

278

286

291

292 const std::vector &MaxPressure =

295 for (unsigned i = 0, e = MaxPressure.size(); i < e; ++i) {

298 ((float)MaxPressure[i] > ((float)Limit * RPThreshold));

299 }

300}

301

305}

306

308 for (const SDep &PI : SU->Preds) {

310 unsigned MinLatency = PI.getLatency();

311#ifndef NDEBUG

313#endif

314 if (SU->TopReadyCycle < PredReadyCycle + MinLatency)

316 }

317

320}

321

323 assert(SU->getInstr() && "Scheduled SUnit must have instr");

324

326 ++I) {

327 unsigned SuccReadyCycle = I->getSUnit()->BotReadyCycle;

328 unsigned MinLatency = I->getLatency();

329#ifndef NDEBUG

331#endif

332 if (SU->BotReadyCycle < SuccReadyCycle + MinLatency)

334 }

335

338}

339

343}

344

345

346

347

348

349

350

351

352

353

354

355

356

357

359 if (HazardRec->isEnabled())

361

364 return true;

365

366 return false;

367}

368

370 SUnit *SU, unsigned ReadyCycle) {

371 if (ReadyCycle < MinReadyCycle)

372 MinReadyCycle = ReadyCycle;

373

374

375

376 if (ReadyCycle > CurrCycle || checkHazard(SU))

377

378 Pending.push(SU);

379 else

381}

382

383

386 IssueCount = (IssueCount <= Width) ? 0 : IssueCount - Width;

387

388 assert(MinReadyCycle < std::numeric_limits::max() &&

389 "MinReadyCycle uninitialized");

390 unsigned NextCycle = std::max(CurrCycle + 1, MinReadyCycle);

391

392 if (!HazardRec->isEnabled()) {

393

394 CurrCycle = NextCycle;

395 } else {

396

397 for (; CurrCycle != NextCycle; ++CurrCycle) {

398 if (isTop())

399 HazardRec->AdvanceCycle();

400 else

401 HazardRec->RecedeCycle();

402 }

403 }

404 CheckPending = true;

405

407 << CurrCycle << '\n');

408}

409

410

412 bool startNewCycle = false;

413

414

415 if (HazardRec->isEnabled()) {

416 if (!isTop() && SU->isCall) {

417

418

419 HazardRec->Reset();

420 }

421 HazardRec->EmitInstruction(SU);

422 }

423

424

425 startNewCycle = ResourceModel->reserveResources(SU, isTop());

426

427

428

430 if (startNewCycle) {

431 LLVM_DEBUG(dbgs() << "*** Max instrs at cycle " << CurrCycle << '\n');

432 bumpCycle();

433 } else

434 LLVM_DEBUG(dbgs() << "*** IssueCount " << IssueCount << " at cycle "

435 << CurrCycle << '\n');

436}

437

438

439

441

443 MinReadyCycle = std::numeric_limits::max();

444

445

446

447 for (unsigned i = 0, e = Pending.size(); i != e; ++i) {

448 SUnit *SU = *(Pending.begin() + i);

450

451 if (ReadyCycle < MinReadyCycle)

452 MinReadyCycle = ReadyCycle;

453

454 if (ReadyCycle > CurrCycle)

455 continue;

456

457 if (checkHazard(SU))

458 continue;

459

461 Pending.remove(Pending.begin() + i);

462 --i;

463 --e;

464 }

465 CheckPending = false;

466}

467

468

472 else {

473 assert(Pending.isInQueue(SU) && "bad ready count");

474 Pending.remove(Pending.find(SU));

475 }

476}

477

478

479

480

482 if (CheckPending)

483 releasePending();

484

485 auto AdvanceCycle = [this]() {

487 return true;

488 if (Available.size() == 1 && Pending.size() > 0)

489 return !ResourceModel->isResourceAvailable(*Available.begin(), isTop()) ||

491 return false;

492 };

493 for (unsigned i = 0; AdvanceCycle(); ++i) {

494 assert(i <= (HazardRec->getMaxLookAhead() + MaxMinLatency) &&

495 "permanent hazard");

496 (void)i;

497 ResourceModel->reserveResources(nullptr, isTop());

498 bumpCycle();

499 releasePending();

500 }

503 return nullptr;

504}

505

506#ifndef NDEBUG

510 dbgs() << Label << " " << Q.getName() << " ";

511 if (P.isValid())

513 << P.getUnitInc() << " ";

514 else

515 dbgs() << " ";

516 dbgs() << "cost(" << Cost << ")\t";

518}

519

520

525

532 std::stringstream dbgstr;

533 dbgstr << "SU(" << std::setw(3) << (*I)->NodeNum << ")";

534 dbgs() << dbgstr.str();

536 dbgs() << "\t";

537 (*I)->getInstr()->dump();

538 }

539 dbgs() << "\n";

540}

541#endif

542

543

544

547 return false;

548

549 for (auto &Pred : SU->Preds) {

550

551 if (!Pred.getSUnit()->isScheduled && (Pred.getSUnit() != SU2))

552 return false;

553 }

554

555 return true;

556}

557

558

559

562 return false;

563

564 for (auto &Succ : SU->Succs) {

565

566 if (!Succ.getSUnit()->isScheduled && (Succ.getSUnit() != SU2))

567 return false;

568 }

569 return true;

570}

571

572

573

574

575

576

579 for (const auto &P : PD) {

580 if (P.isValid())

581 continue;

582

583

584

586 return (isBotUp ? P.getUnitInc() : -P.getUnitInc());

587 }

588 return 0;

589}

590

591

592

596 bool verbose) {

597

598 int ResCount = 1;

599

600

602 return ResCount;

603

605 << ((Q.getID() == TopQID) ? "(top|" : "(bot|"));

606

610 }

611

612 unsigned IsAvailableAmt = 0;

613

618 }

619

621 std::stringstream dbgstr;

622 dbgstr << "h" << std::setw(3) << SU->getHeight() << "|";

623 dbgs() << dbgstr.str();

624 });

625

626

627

630 ResCount += IsAvailableAmt;

632 } else

634 } else {

638 }

639

641 std::stringstream dbgstr;

642 dbgstr << "d" << std::setw(3) << SU->getDepth() << "|";

643 dbgs() << dbgstr.str();

644 });

645

646

647

650 ResCount += IsAvailableAmt;

652 } else

654 }

655

656 unsigned NumNodesBlocking = 0;

658

659

660

661

665 ++NumNodesBlocking;

666 } else {

667

671 ++NumNodesBlocking;

672 }

673 ResCount += (NumNodesBlocking * ScaleTwo);

674

676 std::stringstream dbgstr;

677 dbgstr << "blk " << std::setw(2) << NumNodesBlocking << ")|";

678 dbgs() << dbgstr.str();

679 });

680

681

683

685

687

688

690

691

692

696 ResCount -= IsAvailableAmt;

701 });

702 }

703

704

705

707 for (const SDep &PI : SU->Preds) {

713 }

714 }

716 for (const SDep &SI : SU->Succs) {

717 if (!SI.getSUnit()->getInstr()->isPseudo() && SI.isAssignedRegDep() &&

718 SI.getLatency() == 0 &&

722 }

723 }

724 }

725

726

727

728

729

730

733 for (const auto &PI : SU->Preds) {

734 if (PI.getLatency() > 0 &&

738 }

739 }

740 } else {

741 for (const auto &SI : SU->Succs) {

742 if (SI.getLatency() > 0 &&

746 }

747 }

748 }

749 }

750

752 std::stringstream dbgstr;

753 dbgstr << "Total " << std::setw(4) << ResCount << ")";

754 dbgs() << dbgstr.str();

755 });

756

757 return ResCount;

758}

759

760

761

762

763

764

772 else Q.dump(););

773

774

776

777

781 TempTracker.getMaxPressureDelta((*I)->getInstr(), RPDelta,

784

785 int CurrentCost = SchedulingCost(Q, *I, Candidate, RPDelta, false);

786

787

788 if (!Candidate.SU) {

790 Candidate.SU = *I;

791 Candidate.RPDelta = RPDelta;

792 Candidate.SCost = CurrentCost;

794 continue;

795 }

796

797

798

799 if (CurrentCost < 0 && Candidate.SCost < 0) {

803 Candidate.SU = *I;

804 Candidate.RPDelta = RPDelta;

805 Candidate.SCost = CurrentCost;

807 }

808 continue;

809 }

810

811

812 if (CurrentCost > Candidate.SCost) {

814 Candidate.SU = *I;

815 Candidate.RPDelta = RPDelta;

816 Candidate.SCost = CurrentCost;

818 continue;

819 }

820

821

824 if (CurrWeak != CandWeak) {

825 if (CurrWeak < CandWeak) {

827 Candidate.SU = *I;

828 Candidate.RPDelta = RPDelta;

829 Candidate.SCost = CurrentCost;

830 FoundCandidate = Weak;

831 }

832 continue;

833 }

834

836 unsigned CurrSize, CandSize;

838 CurrSize = (*I)->Succs.size();

839 CandSize = Candidate.SU->Succs.size();

840 } else {

841 CurrSize = (*I)->Preds.size();

842 CandSize = Candidate.SU->Preds.size();

843 }

844 if (CurrSize > CandSize) {

846 Candidate.SU = *I;

847 Candidate.RPDelta = RPDelta;

848 Candidate.SCost = CurrentCost;

850 }

851

852

853 if (CurrSize != CandSize)

854 continue;

855 }

856

857

858

859

864 Candidate.SU = *I;

865 Candidate.RPDelta = RPDelta;

866 Candidate.SCost = CurrentCost;

868 continue;

869 }

870 }

871

872

873

874 if (FoundCandidate == NoCand)

875 continue;

876 }

877 return FoundCandidate;

878}

879

880

882

883

886 IsTopNode = false;

887 return SU;

888 }

891 IsTopNode = true;

892 return SU;

893 }

895

898 assert(BotResult != NoCand && "failed to find the first candidate");

899

900

901

902

903

904

905

906

909 IsTopNode = false;

910 return BotCand.SU;

911 }

912

916 assert(TopResult != NoCand && "failed to find the first candidate");

917

920 IsTopNode = true;

921 return TopCand.SU;

922 }

923

924

926 LLVM_DEBUG(dbgs() << "Prefered Bottom Node SingleMax\n");

927 IsTopNode = false;

928 return BotCand.SU;

929 }

931 LLVM_DEBUG(dbgs() << "Prefered Top Node SingleMax\n");

932 IsTopNode = true;

933 return TopCand.SU;

934 }

937 IsTopNode = true;

938 return TopCand.SU;

939 }

940

941 LLVM_DEBUG(dbgs() << "Prefered Bottom in Node order\n");

942 IsTopNode = false;

943 return BotCand.SU;

944}

945

946

951 return nullptr;

952 }

956 if (!SU) {

960 assert(TopResult != NoCand && "failed to find the first candidate");

961 (void)TopResult;

962 SU = TopCand.SU;

963 }

964 IsTopNode = true;

967 if (!SU) {

971 assert(BotResult != NoCand && "failed to find the first candidate");

972 (void)BotResult;

973 SU = BotCand.SU;

974 }

975 IsTopNode = false;

976 } else {

978 }

983

984 LLVM_DEBUG(dbgs() << "*** " << (IsTopNode ? "Top" : "Bottom")

985 << " Scheduling instruction in cycle "

989 return SU;

990}

991

992

993

994

995

997 if (IsTopNode) {

1000 } else {

1003 }

1004}

static const Function * getParent(const Value *V)

@ Available

We know the block is fully available. This is a fixpoint.

const HexagonInstrInfo * TII

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the SmallVector class.

static bool isSingleUnscheduledPred(SUnit *SU, SUnit *SU2)

isSingleUnscheduledPred - If SU2 is the only unscheduled predecessor of SU, return true (we may have ...

static cl::opt< bool > CheckEarlyAvail("check-early-avail", cl::Hidden, cl::init(true))

static cl::opt< bool > IgnoreBBRegPressure("ignore-bb-reg-pressure", cl::Hidden, cl::init(false))

static cl::opt< float > RPThreshold("vliw-misched-reg-pressure", cl::Hidden, cl::init(0.75f), cl::desc("High register pressure threhold."))

static cl::opt< bool > UseNewerCandidate("use-newer-candidate", cl::Hidden, cl::init(true))

static bool isSingleUnscheduledSucc(SUnit *SU, SUnit *SU2)

isSingleUnscheduledSucc - If SU2 is the only unscheduled successor of SU, return true (we may have du...

static cl::opt< unsigned > SchedDebugVerboseLevel("misched-verbose-level", cl::Hidden, cl::init(1))

VLIWMachineScheduler * DAG

void releaseBottomNode(SUnit *SU) override

When all successor dependencies have been resolved, free this node for bottom-up scheduling.

static constexpr unsigned PriorityOne

SUnit * pickNode(bool &IsTopNode) override

Pick the best node to balance the schedule. Implements MachineSchedStrategy.

virtual VLIWResourceModel * createVLIWResourceModel(const TargetSubtargetInfo &STI, const TargetSchedModel *SchedModel) const

int pressureChange(const SUnit *SU, bool isBotUp)

Check if the instruction changes the register pressure of a register in the high pressure set.

SmallVector< bool > HighPressureSets

List of pressure sets that have a high pressure level in the region.

static constexpr unsigned ScaleTwo

CandResult pickNodeFromQueue(VLIWSchedBoundary &Zone, const RegPressureTracker &RPTracker, SchedCandidate &Candidate)

Pick the best candidate from the top queue.

void schedNode(SUnit *SU, bool IsTopNode) override

Update the scheduler's state after scheduling a node.

void readyQueueVerboseDump(const RegPressureTracker &RPTracker, SchedCandidate &Candidate, ReadyQueue &Q)

void releaseTopNode(SUnit *SU) override

When all predecessor dependencies have been resolved, free this node for top-down scheduling.

SUnit * pickNodeBidrectional(bool &IsTopNode)

Pick the best candidate node from either the top or bottom queue.

static constexpr unsigned PriorityTwo

static constexpr unsigned PriorityThree

const TargetSchedModel * SchedModel

void initialize(ScheduleDAGMI *dag) override

Initialize the strategy after building the DAG for a new region.

virtual int SchedulingCost(ReadyQueue &Q, SUnit *SU, SchedCandidate &Candidate, RegPressureDelta &Delta, bool verbose)

Single point to compute overall scheduling cost.

void traceCandidate(const char *Label, const ReadyQueue &Q, SUnit *SU, int Cost, PressureChange P=PressureChange())

CandResult

Represent the type of SchedCandidate found within a single queue.

bool canReserveResources(const MCInstrDesc *MID)

void reserveResources(const MCInstrDesc *MID)

Itinerary data supplied by a subtarget to be used by a target.

unsigned getLoopDepth(const BlockT *BB) const

Return the loop nesting level of the specified block.

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

StringRef getName() const

Return the name of the corresponding LLVM basic block, or an empty string.

const TargetSubtargetInfo & getSubtarget() const

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

StringRef getName() const

getName - Return the name of the corresponding LLVM function.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

bool isPseudo(QueryType Type=IgnoreBundle) const

Return true if this is a pseudo instruction that doesn't correspond to a real machine instruction.

Capture a change in pressure for a single pressure set.

List of PressureChanges in order of increasing, unique PSetID.

Helpers for implementing custom MachineSchedStrategy classes.

std::vector< SUnit * >::iterator iterator

StringRef getName() const

Track the current register pressure at some position in the instruction stream, and remember the high...

void getMaxPressureDelta(const MachineInstr *MI, RegPressureDelta &Delta, ArrayRef< PressureChange > CriticalPSets, ArrayRef< unsigned > MaxPressureLimit)

Find the pressure set with the most change beyond its pressure limit after traversing this instructio...

unsigned getRegPressureSetLimit(unsigned Idx) const

Get the register unit limit for the given pressure set index.

unsigned getLatency() const

Returns the latency value for this edge, which roughly means the minimum number of cycles that must e...

bool isAssignedRegDep() const

Tests if this is a Data dependence that is associated with a register.

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

bool isCall

Is a function call.

unsigned TopReadyCycle

Cycle relative to start when node is ready.

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...

bool isScheduleHigh

True if preferable to schedule high.

unsigned getDepth() const

Returns the depth of this node, which is the length of the maximum path up to any node which has no p...

bool isScheduled

True once scheduled.

unsigned BotReadyCycle

Cycle relative to end when node is ready.

SmallVector< SDep, 4 > Succs

All sunit successors.

bool isBottomReady() const

SmallVector< SDep, 4 > Preds

All sunit predecessors.

SmallVectorImpl< SDep >::iterator succ_iterator

MachineInstr * getInstr() const

Returns the representative MachineInstr for this SUnit.

MachineBasicBlock * BB

The block in which to insert instructions.

const TargetSchedModel * getSchedModel() const

Gets the machine model for instruction scheduling.

ScheduleDAGTopologicalSort Topo

Topo - A topological ordering for SUnits which permits fast IsReachable and similar queries.

void dumpNode(const SUnit &SU) const override

MachineBasicBlock::iterator begin() const

Returns an iterator to the top of the current scheduling region.

const MachineLoopInfo * MLI

void scheduleMI(SUnit *SU, bool IsTopNode)

Move an instruction and update register pressure.

PressureDiff & getPressureDiff(const SUnit *SU)

void initQueues(ArrayRef< SUnit * > TopRoots, ArrayRef< SUnit * > BotRoots)

Release ExitSU predecessors and setup scheduler queues.

void buildDAGWithRegPressure()

Call ScheduleDAGInstrs::buildSchedGraph with register pressure tracking enabled.

const RegPressureTracker & getBotRPTracker() const

const RegPressureTracker & getTopRPTracker() const

const IntervalPressure & getRegPressure() const

Get register pressure for the entire scheduling region before scheduling.

void dump() const override

const std::vector< PressureChange > & getRegionCriticalPSets() const

ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply schedules machine instructions ac...

void dumpSchedule() const

dump the scheduled Sequence.

std::unique_ptr< MachineSchedStrategy > SchedImpl

void postProcessDAG()

Apply each ScheduleDAGMutation step in order.

MachineBasicBlock::iterator top() const

void findRootsAndBiasEdges(SmallVectorImpl< SUnit * > &TopRoots, SmallVectorImpl< SUnit * > &BotRoots)

MachineBasicBlock::iterator bottom() const

MachineBasicBlock::iterator CurrentBottom

The bottom of the unscheduled zone.

void viewGraph() override

Out-of-line implementation with no arguments is handy for gdb.

void updateQueues(SUnit *SU, bool IsTopNode)

Update scheduler DAG and queues after scheduling an instruction.

void placeDebugValues()

Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues.

MachineBasicBlock::iterator CurrentTop

The top of the unscheduled zone.

void InitDAGTopologicalSorting()

Creates the initial topological ordering from the DAG to be scheduled.

std::vector< SUnit > SUnits

The scheduling units.

const TargetRegisterInfo * TRI

Target processor register info.

MachineFunction & MF

Machine function.

void assign(size_type NumElts, ValueParamT Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

TargetInstrInfo - Interface to description of machine instruction set.

virtual DFAPacketizer * CreateTargetScheduleState(const TargetSubtargetInfo &) const

Create machine specific model for scheduling.

virtual const char * getRegPressureSetName(unsigned Idx) const =0

Get the name of this register unit pressure set.

Provide an instruction scheduling machine model to CodeGen passes.

unsigned getIssueWidth() const

Maximum number of micro-ops that may be scheduled per cycle.

unsigned getNumMicroOps(const MachineInstr *MI, const MCSchedClassDesc *SC=nullptr) const

Return the number of issue slots required for this MI.

const InstrItineraryData * getInstrItineraries() const

TargetSubtargetInfo - Generic base class for all target subtargets.

virtual const TargetInstrInfo * getInstrInfo() const

Extend the standard ScheduleDAGMILive to provide more context and override the top-level schedule() d...

RegisterClassInfo * getRegClassInfo()

void schedule() override

Schedule - This is called back from ScheduleDAGInstrs::Run() when it's time to do some work.

unsigned TotalPackets

Total packets created.

virtual ~VLIWResourceModel()

virtual bool hasDependence(const SUnit *SUd, const SUnit *SUu)

Return true if there is a dependence between SUd and SUu.

virtual DFAPacketizer * createPacketizer(const TargetSubtargetInfo &STI) const

virtual bool reserveResources(SUnit *SU, bool IsTop)

Keep track of available resources.

bool isInPacket(SUnit *SU) const

DFAPacketizer * ResourcesModel

ResourcesModel - Represents VLIW state.

SmallVector< SUnit * > Packet

Local packet/bundle model.

const TargetSchedModel * SchedModel

VLIWResourceModel(const TargetSubtargetInfo &STI, const TargetSchedModel *SM)

virtual bool isResourceAvailable(SUnit *SU, bool IsTop)

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

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)

unsigned getWeakLeft(const SUnit *SU, bool isTop)

cl::opt< bool > ViewMISchedDAGs

raw_ostream & dbgs()

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

cl::opt< MISched::Direction > PreRADirection

Printable printMBBReference(const MachineBasicBlock &MBB)

Prints a machine basic block reference.

Store the state used by ConvergingVLIWScheduler heuristics, required for the lifetime of one invocati...

Each Scheduling boundary is associated with ready queues.

bool isLatencyBound(SUnit *SU)

void releaseNode(SUnit *SU, unsigned ReadyCycle)

void removeReady(SUnit *SU)

Remove SU from the ready set for this boundary.

ScheduleHazardRecognizer * HazardRec

void bumpNode(SUnit *SU)

Move the boundary of scheduled code by one SUnit.

VLIWResourceModel * ResourceModel

void releasePending()

Release pending ready nodes in to the available queue.

SUnit * pickOnlyChoice()

If this queue only has one ready candidate, return it.

void init(VLIWMachineScheduler *dag, const TargetSchedModel *smodel)

void bumpCycle()

Move the boundary of scheduled code by one cycle.

bool checkHazard(SUnit *SU)

Does this SU have a hazard within the current instruction group.

Store the effects of a change in pressure on things that MI scheduler cares about.

PressureChange CriticalMax

PressureChange CurrentMax

std::vector< unsigned > MaxSetPressure

Map of max reg pressure indexed by pressure set ID, not class ID.