llvm.org GIT mirror llvm / 7ae51be
Add "blocked" heuristic to the Hexagon MI scheduler. Improve AQ instruction selection in the Hexagon MI scheduler. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163523 91177308-0d34-0410-b5e6-96231b3b80d8 Sergei Larin 8 years ago
2 changed file(s) with 321 addition(s) and 229 deletion(s). Raw diff Collapse all Expand all
189189 std::vector RegionPressure = RPTracker.getPressure().MaxSetPressure;
190190 for (unsigned i = 0, e = RegionPressure.size(); i < e; ++i) {
191191 unsigned Limit = TRI->getRegPressureSetLimit(i);
192 DEBUG(dbgs() << TRI->getRegPressureSetName(i)
193 << "Limit " << Limit
194 << " Actual " << RegionPressure[i] << "\n");
192195 if (RegionPressure[i] > Limit)
193196 RegionCriticalPSets.push_back(PressureElement(i, 0));
194197 }
198201 RegionCriticalPSets[i].PSetID) << " ";
199202 dbgs() << "\n");
200203
201 // Reset resource state.
202 TopResourceModel->resetPacketState();
203 TopResourceModel->resetDFA();
204 BotResourceModel->resetPacketState();
205 BotResourceModel->resetDFA();
206204 TotalPackets = 0;
207205 }
208206
263261 }
264262
265263 /// Keep track of available resources.
266 void VLIWResourceModel::reserveResources(SUnit *SU) {
264 bool VLIWResourceModel::reserveResources(SUnit *SU) {
265 bool startNewCycle = false;
267266 // If this SU does not fit in the packet
268267 // start a new one.
269268 if (!isResourceAvailable(SU)) {
270269 ResourcesModel->clearResources();
271270 Packet.clear();
272271 TotalPackets++;
272 startNewCycle = true;
273273 }
274274
275275 switch (SU->getInstr()->getOpcode()) {
294294 DEBUG(dbgs() << "Packet[" << TotalPackets << "]:\n");
295295 for (unsigned i = 0, e = Packet.size(); i != e; ++i) {
296296 DEBUG(dbgs() << "\t[" << i << "] SU(");
297 DEBUG(dbgs() << Packet[i]->NodeNum << ")\n");
297 DEBUG(dbgs() << Packet[i]->NodeNum << ")\t");
298 DEBUG(Packet[i]->getInstr()->dump());
298299 }
299300 #endif
300301
304305 ResourcesModel->clearResources();
305306 Packet.clear();
306307 TotalPackets++;
307 }
308 startNewCycle = true;
309 }
310
311 return startNewCycle;
308312 }
309313
310314 // Release all DAG roots for scheduling.
351355 // Initialize top/bottom trackers after computing region pressure.
352356 initRegPressure();
353357
358 // To view Height/Depth correctly, they should be accessed at least once.
359 DEBUG(unsigned maxH = 0;
360 for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
361 if (SUnits[su].getHeight() > maxH)
362 maxH = SUnits[su].getHeight();
363 dbgs() << "Max Height " << maxH << "\n";);
364 DEBUG(unsigned maxD = 0;
365 for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
366 if (SUnits[su].getDepth() > maxD)
367 maxD = SUnits[su].getDepth();
368 dbgs() << "Max Depth " << maxD << "\n";);
354369 DEBUG(for (unsigned su = 0, e = SUnits.size(); su != e; ++su)
355370 SUnits[su].dumpAll(this));
356371
389404 assert(TopRPTracker.getPos() == CurrentTop && "out of sync");
390405 updateScheduledPressure(TopRPTracker.getPressure().MaxSetPressure);
391406
392 // Update DFA state.
393 TopResourceModel->reserveResources(SU);
394
395407 // Release dependent instructions for scheduling.
396408 releaseSuccessors(SU);
397 }
398 else {
409 } else {
399410 assert(SU->isBottomReady() && "node still has unscheduled dependencies");
400411 MachineBasicBlock::iterator priorII =
401412 priorNonDebug(CurrentBottom, CurrentTop);
414425 assert(BotRPTracker.getPos() == CurrentBottom && "out of sync");
415426 updateScheduledPressure(BotRPTracker.getPressure().MaxSetPressure);
416427
417 // Update DFA state.
418 BotResourceModel->reserveResources(SU);
419
420428 // Release dependent instructions for scheduling.
421429 releasePredecessors(SU);
422430 }
424432 SchedImpl->schedNode(SU, IsTopNode);
425433 }
426434 assert(CurrentTop == CurrentBottom && "Nonempty unscheduled zone.");
427
428 DEBUG(dbgs() << "Final schedule has " << TopResourceModel->getTotalPackets() +
429 BotResourceModel->getTotalPackets()<< "packets.\n");
430435
431436 placeDebugValues();
432437 }
463468 const InstrItineraryData *Itin = TM.getInstrItineraryData();
464469 Top.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG);
465470 Bot.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG);
471
472 Top.ResourceModel = new VLIWResourceModel(TM);
473 Bot.ResourceModel = new VLIWResourceModel(TM);
466474
467475 assert((!ForceTopDown || !ForceBottomUp) &&
468476 "-misched-topdown incompatible with -misched-bottomup");
552560 if (!HazardRec->isEnabled()) {
553561 // Bypass HazardRec virtual calls.
554562 CurrCycle = NextCycle;
555 }
556 else {
563 } else {
557564 // Bypass getHazardType calls in case of long latency.
558565 for (; CurrCycle != NextCycle; ++CurrCycle) {
559566 if (isTop())
570577
571578 /// Move the boundary of scheduled code by one SUnit.
572579 void ConvergingVLIWScheduler::SchedBoundary::bumpNode(SUnit *SU) {
580 bool startNewCycle = false;
573581
574582 // Update the reservation table.
575583 if (HazardRec->isEnabled()) {
580588 }
581589 HazardRec->EmitInstruction(SU);
582590 }
591
592 // Update DFA model.
593 startNewCycle = ResourceModel->reserveResources(SU);
594
583595 // Check the instruction group dispatch limit.
584596 // TODO: Check if this SU must end a dispatch group.
585597 IssueCount += DAG->getNumMicroOps(SU->getInstr());
586 if (IssueCount >= DAG->getIssueWidth()) {
598 if (startNewCycle) {
587599 DEBUG(dbgs() << "*** Max instrs at cycle " << CurrCycle << '\n');
588600 bumpCycle();
589601 }
602 else
603 DEBUG(dbgs() << "*** IssueCount " << IssueCount
604 << " at cycle " << CurrCycle << '\n');
590605 }
591606
592607 /// Release pending ready nodes in to the available queue. This makes them
647662 }
648663
649664 #ifndef NDEBUG
650 void ConvergingVLIWScheduler::traceCandidate(const char *Label, const ReadyQueue &Q,
651 SUnit *SU, PressureElement P) {
665 void ConvergingVLIWScheduler::traceCandidate(const char *Label,
666 const ReadyQueue &Q,
667 SUnit *SU, PressureElement P) {
652668 dbgs() << Label << " " << Q.getName() << " ";
653669 if (P.isValid())
654670 dbgs() << TRI->getRegPressureSetName(P.PSetID) << ":" << P.UnitIncrease
659675 }
660676 #endif
661677
678 /// getSingleUnscheduledPred - If there is exactly one unscheduled predecessor
679 /// of SU, return it, otherwise return null.
680 static SUnit *getSingleUnscheduledPred(SUnit *SU) {
681 SUnit *OnlyAvailablePred = 0;
682 for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
683 I != E; ++I) {
684 SUnit &Pred = *I->getSUnit();
685 if (!Pred.isScheduled) {
686 // We found an available, but not scheduled, predecessor. If it's the
687 // only one we have found, keep track of it... otherwise give up.
688 if (OnlyAvailablePred && OnlyAvailablePred != &Pred)
689 return 0;
690 OnlyAvailablePred = &Pred;
691 }
692 }
693 return OnlyAvailablePred;
694 }
695
696 /// getSingleUnscheduledSucc - If there is exactly one unscheduled successor
697 /// of SU, return it, otherwise return null.
698 static SUnit *getSingleUnscheduledSucc(SUnit *SU) {
699 SUnit *OnlyAvailableSucc = 0;
700 for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
701 I != E; ++I) {
702 SUnit &Succ = *I->getSUnit();
703 if (!Succ.isScheduled) {
704 // We found an available, but not scheduled, successor. If it's the
705 // only one we have found, keep track of it... otherwise give up.
706 if (OnlyAvailableSucc && OnlyAvailableSucc != &Succ)
707 return 0;
708 OnlyAvailableSucc = &Succ;
709 }
710 }
711 return OnlyAvailableSucc;
712 }
713
662714 // Constants used to denote relative importance of
663715 // heuristic components for cost computation.
664716 static const unsigned PriorityOne = 200;
717 static const unsigned PriorityTwo = 100;
665718 static const unsigned PriorityThree = 50;
719 static const unsigned PriorityFour = 20;
666720 static const unsigned ScaleTwo = 10;
667721 static const unsigned FactorOne = 2;
668722
684738 ResCount += PriorityOne;
685739
686740 // Critical path first.
687 if (Q.getID() == TopQID)
741 if (Q.getID() == TopQID) {
688742 ResCount += (SU->getHeight() * ScaleTwo);
689 else
743
744 // If resources are available for it, multiply the
745 // chance of scheduling.
746 if (Top.ResourceModel->isResourceAvailable(SU))
747 ResCount <<= FactorOne;
748 } else {
690749 ResCount += (SU->getDepth() * ScaleTwo);
691750
692 // If resources are available for it, multiply the
693 // chance of scheduling.
694 if (DAG->getTopResourceModel()->isResourceAvailable(SU))
695 ResCount <<= FactorOne;
751 // If resources are available for it, multiply the
752 // chance of scheduling.
753 if (Bot.ResourceModel->isResourceAvailable(SU))
754 ResCount <<= FactorOne;
755 }
756
757 unsigned NumNodesBlocking = 0;
758 if (Q.getID() == TopQID) {
759 // How many SUs does it block from scheduling?
760 // Look at all of the successors of this node.
761 // Count the number of nodes that
762 // this node is the sole unscheduled node for.
763 for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end();
764 I != E; ++I)
765 if (getSingleUnscheduledPred(I->getSUnit()) == SU)
766 ++NumNodesBlocking;
767 } else {
768 // How many unscheduled predecessors block this node?
769 for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
770 I != E; ++I)
771 if (getSingleUnscheduledSucc(I->getSUnit()) == SU)
772 ++NumNodesBlocking;
773 }
774 ResCount += (NumNodesBlocking * ScaleTwo);
696775
697776 // Factor in reg pressure as a heuristic.
698 ResCount -= (Delta.Excess.UnitIncrease * PriorityThree);
699 ResCount -= (Delta.CriticalMax.UnitIncrease * PriorityThree);
777 ResCount -= (Delta.Excess.UnitIncrease*PriorityThree);
778 ResCount -= (Delta.CriticalMax.UnitIncrease*PriorityThree);
700779
701780 DEBUG(if (verbose) dbgs() << " Total(" << ResCount << ")");
702781
734813 FoundCandidate = NodeOrder;
735814 continue;
736815 }
737
738816
739817 // Best cost.
740818 if (CurrentCost > Candidate.SCost) {
858936 }
859937
860938 /// Update the scheduler's state after scheduling a node. This is the same node
861 /// that was just returned by pickNode(). However, VLIWMachineScheduler needs to update
862 /// it's state based on the current cycle before MachineSchedStrategy does.
939 /// that was just returned by pickNode(). However, VLIWMachineScheduler needs
940 /// to update it's state based on the current cycle before MachineSchedStrategy
941 /// does.
863942 void ConvergingVLIWScheduler::schedNode(SUnit *SU, bool IsTopNode) {
864943 if (IsTopNode) {
865944 SU->TopReadyCycle = Top.CurrCycle;
866945 Top.bumpNode(SU);
867 }
868 else {
946 } else {
869947 SU->BotReadyCycle = Bot.CurrCycle;
870948 Bot.bumpNode(SU);
871949 }
3939 namespace llvm {
4040 class VLIWMachineScheduler;
4141
42 /// MachineSchedStrategy - Interface used by VLIWMachineScheduler to drive the selected
43 /// scheduling algorithm.
42 /// MachineSchedStrategy - Interface used by VLIWMachineScheduler to drive
43 /// the selected scheduling algorithm.
4444 ///
45 /// If this works well and targets wish to reuse VLIWMachineScheduler, we may expose it
46 /// in ScheduleDAGInstrs.h
45 /// TODO: Move this to ScheduleDAGInstrs.h
4746 class MachineSchedStrategy {
4847 public:
4948 virtual ~MachineSchedStrategy() {}
5655 /// be scheduled at the bottom.
5756 virtual SUnit *pickNode(bool &IsTopNode) = 0;
5857
59 /// Notify MachineSchedStrategy that VLIWMachineScheduler has scheduled a node.
58 /// Notify MachineSchedStrategy that VLIWMachineScheduler has
59 /// scheduled a node.
6060 virtual void schedNode(SUnit *SU, bool IsTopNode) = 0;
6161
6262 /// When all predecessor dependencies have been resolved, free this node for
6868 };
6969
7070 //===----------------------------------------------------------------------===//
71 // ConvergingVLIWScheduler - Implementation of the standard MachineSchedStrategy.
71 // ConvergingVLIWScheduler - Implementation of the standard
72 // MachineSchedStrategy.
7273 //===----------------------------------------------------------------------===//
7374
7475 /// ReadyQueue encapsulates vector of "ready" SUnits with basic convenience
122123 }
123124 };
124125
125 /// ConvergingVLIWScheduler shrinks the unscheduled zone using heuristics to balance
126 /// the schedule.
126 class VLIWResourceModel {
127 /// ResourcesModel - Represents VLIW state.
128 /// Not limited to VLIW targets per say, but assumes
129 /// definition of DFA by a target.
130 DFAPacketizer *ResourcesModel;
131
132 const InstrItineraryData *InstrItins;
133
134 /// Local packet/bundle model. Purely
135 /// internal to the MI schedulre at the time.
136 std::vector Packet;
137
138 /// Total packets created.
139 unsigned TotalPackets;
140
141 public:
142 VLIWResourceModel(MachineSchedContext *C, const InstrItineraryData *IID) :
143 InstrItins(IID), TotalPackets(0) {
144 const TargetMachine &TM = C->MF->getTarget();
145 ResourcesModel = TM.getInstrInfo()->CreateTargetScheduleState(&TM,NULL);
146
147 // This hard requirement could be relaxed,
148 // but for now do not let it proceed.
149 assert(ResourcesModel && "Unimplemented CreateTargetScheduleState.");
150
151 Packet.resize(InstrItins->SchedModel->IssueWidth);
152 Packet.clear();
153 ResourcesModel->clearResources();
154 }
155
156 VLIWResourceModel(const TargetMachine &TM) :
157 InstrItins(TM.getInstrItineraryData()), TotalPackets(0) {
158 ResourcesModel = TM.getInstrInfo()->CreateTargetScheduleState(&TM,NULL);
159
160 // This hard requirement could be relaxed,
161 // but for now do not let it proceed.
162 assert(ResourcesModel && "Unimplemented CreateTargetScheduleState.");
163
164 Packet.resize(InstrItins->SchedModel->IssueWidth);
165 Packet.clear();
166 ResourcesModel->clearResources();
167 }
168
169 ~VLIWResourceModel() {
170 delete ResourcesModel;
171 }
172
173 void resetPacketState() {
174 Packet.clear();
175 }
176
177 void resetDFA() {
178 ResourcesModel->clearResources();
179 }
180
181 void reset() {
182 Packet.clear();
183 ResourcesModel->clearResources();
184 }
185
186 bool isResourceAvailable(SUnit *SU);
187 bool reserveResources(SUnit *SU);
188 unsigned getTotalPackets() const { return TotalPackets; }
189 };
190
191 class VLIWMachineScheduler : public ScheduleDAGInstrs {
192 /// AA - AliasAnalysis for making memory reference queries.
193 AliasAnalysis *AA;
194
195 RegisterClassInfo *RegClassInfo;
196 MachineSchedStrategy *SchedImpl;
197
198 MachineBasicBlock::iterator LiveRegionEnd;
199
200 /// Register pressure in this region computed by buildSchedGraph.
201 IntervalPressure RegPressure;
202 RegPressureTracker RPTracker;
203
204 /// List of pressure sets that exceed the target's pressure limit before
205 /// scheduling, listed in increasing set ID order. Each pressure set is paired
206 /// with its max pressure in the currently scheduled regions.
207 std::vector RegionCriticalPSets;
208
209 /// The top of the unscheduled zone.
210 MachineBasicBlock::iterator CurrentTop;
211 IntervalPressure TopPressure;
212 RegPressureTracker TopRPTracker;
213
214 /// The bottom of the unscheduled zone.
215 MachineBasicBlock::iterator CurrentBottom;
216 IntervalPressure BotPressure;
217 RegPressureTracker BotRPTracker;
218
219 #ifndef NDEBUG
220 /// The number of instructions scheduled so far. Used to cut off the
221 /// scheduler at the point determined by misched-cutoff.
222 unsigned NumInstrsScheduled;
223 #endif
224
225 /// Total packets in the region.
226 unsigned TotalPackets;
227
228 const MachineLoopInfo *MLI;
229 public:
230 VLIWMachineScheduler(MachineSchedContext *C, MachineSchedStrategy *S):
231 ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
232 AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S),
233 RPTracker(RegPressure), CurrentTop(), TopRPTracker(TopPressure),
234 CurrentBottom(), BotRPTracker(BotPressure), MLI(C->MLI) {
235 #ifndef NDEBUG
236 NumInstrsScheduled = 0;
237 #endif
238 TotalPackets = 0;
239 }
240
241 virtual ~VLIWMachineScheduler() {
242 delete SchedImpl;
243 }
244
245 MachineBasicBlock::iterator top() const { return CurrentTop; }
246 MachineBasicBlock::iterator bottom() const { return CurrentBottom; }
247
248 /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
249 /// region. This covers all instructions in a block, while schedule() may only
250 /// cover a subset.
251 void enterRegion(MachineBasicBlock *bb,
252 MachineBasicBlock::iterator begin,
253 MachineBasicBlock::iterator end,
254 unsigned endcount);
255
256 /// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's
257 /// time to do some work.
258 void schedule();
259
260 unsigned CurCycle;
261
262 /// Get current register pressure for the top scheduled instructions.
263 const IntervalPressure &getTopPressure() const { return TopPressure; }
264 const RegPressureTracker &getTopRPTracker() const { return TopRPTracker; }
265
266 /// Get current register pressure for the bottom scheduled instructions.
267 const IntervalPressure &getBotPressure() const { return BotPressure; }
268 const RegPressureTracker &getBotRPTracker() const { return BotRPTracker; }
269
270 /// Get register pressure for the entire scheduling region before scheduling.
271 const IntervalPressure &getRegPressure() const { return RegPressure; }
272
273 const std::vector &getRegionCriticalPSets() const {
274 return RegionCriticalPSets;
275 }
276
277 /// getIssueWidth - Return the max instructions per scheduling group.
278 unsigned getIssueWidth() const {
279 return (InstrItins && InstrItins->SchedModel)
280 ? InstrItins->SchedModel->IssueWidth : 1;
281 }
282
283 /// getNumMicroOps - Return the number of issue slots required for this MI.
284 unsigned getNumMicroOps(MachineInstr *MI) const {
285 return 1;
286 //if (!InstrItins) return 1;
287 //int UOps = InstrItins->getNumMicroOps(MI->getDesc().getSchedClass());
288 //return (UOps >= 0) ? UOps : TII->getNumMicroOps(InstrItins, MI);
289 }
290
291 private:
292 void scheduleNodeTopDown(SUnit *SU);
293 void listScheduleTopDown();
294
295 void initRegPressure();
296 void updateScheduledPressure(std::vector NewMaxPressure);
297
298 void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
299 bool checkSchedLimit();
300
301 void releaseRoots();
302
303 void releaseSucc(SUnit *SU, SDep *SuccEdge);
304 void releaseSuccessors(SUnit *SU);
305 void releasePred(SUnit *SU, SDep *PredEdge);
306 void releasePredecessors(SUnit *SU);
307
308 void placeDebugValues();
309 };
310
311 /// ConvergingVLIWScheduler shrinks the unscheduled zone using heuristics
312 /// to balance the schedule.
127313 class ConvergingVLIWScheduler : public MachineSchedStrategy {
128314
129 /// Store the state used by ConvergingVLIWScheduler heuristics, required for the
130 /// lifetime of one invocation of pickNode().
315 /// Store the state used by ConvergingVLIWScheduler heuristics, required
316 /// for the lifetime of one invocation of pickNode().
131317 struct SchedCandidate {
132318 // The best SUnit candidate.
133319 SUnit *SU;
156342 bool CheckPending;
157343
158344 ScheduleHazardRecognizer *HazardRec;
345 VLIWResourceModel *ResourceModel;
159346
160347 unsigned CurrCycle;
161348 unsigned IssueCount;
171358 SchedBoundary(unsigned ID, const Twine &Name):
172359 DAG(0), Available(ID, Name+".A"),
173360 Pending(ID << ConvergingVLIWScheduler::LogMaxQID, Name+".P"),
174 CheckPending(false), HazardRec(0), CurrCycle(0), IssueCount(0),
361 CheckPending(false), HazardRec(0), ResourceModel(0),
362 CurrCycle(0), IssueCount(0),
175363 MinReadyCycle(UINT_MAX), MaxMinLatency(0) {}
176364
177 ~SchedBoundary() { delete HazardRec; }
365 ~SchedBoundary() {
366 delete ResourceModel;
367 delete HazardRec;
368 }
178369
179370 bool isTop() const {
180371 return Available.getID() == ConvergingVLIWScheduler::TopQID;
239430 #endif
240431 };
241432
242 class VLIWResourceModel {
243 /// ResourcesModel - Represents VLIW state.
244 /// Not limited to VLIW targets per say, but assumes
245 /// definition of DFA by a target.
246 DFAPacketizer *ResourcesModel;
247
248 const InstrItineraryData *InstrItins;
249
250 /// Local packet/bundle model. Purely
251 /// internal to the MI schedulre at the time.
252 std::vector Packet;
253
254 /// Total packets created.
255 unsigned TotalPackets;
256
257 public:
258 VLIWResourceModel(MachineSchedContext *C, const InstrItineraryData *IID) :
259 InstrItins(IID), TotalPackets(0) {
260 const TargetMachine &TM = C->MF->getTarget();
261 ResourcesModel = TM.getInstrInfo()->CreateTargetScheduleState(&TM,NULL);
262
263 // This hard requirement could be relaxed, but for now do not let it proceed.
264 assert(ResourcesModel && "Unimplemented CreateTargetScheduleState.");
265
266 Packet.resize(InstrItins->SchedModel->IssueWidth);
267 Packet.clear();
268 ResourcesModel->clearResources();
269 }
270
271 ~VLIWResourceModel() {
272 delete ResourcesModel;
273 }
274
275 void resetPacketState() {
276 Packet.clear();
277 }
278
279 void resetDFA() {
280 ResourcesModel->clearResources();
281 }
282
283 bool isResourceAvailable(SUnit *SU);
284 void reserveResources(SUnit *SU);
285 unsigned getTotalPackets() const { return TotalPackets; }
286 };
287
288 class VLIWMachineScheduler : public ScheduleDAGInstrs {
289 /// AA - AliasAnalysis for making memory reference queries.
290 AliasAnalysis *AA;
291
292 RegisterClassInfo *RegClassInfo;
293 MachineSchedStrategy *SchedImpl;
294
295 /// state separatly for top/bottom sectioins.
296 VLIWResourceModel *TopResourceModel;
297 VLIWResourceModel *BotResourceModel;
298
299 MachineBasicBlock::iterator LiveRegionEnd;
300
301 /// Register pressure in this region computed by buildSchedGraph.
302 IntervalPressure RegPressure;
303 RegPressureTracker RPTracker;
304
305 /// List of pressure sets that exceed the target's pressure limit before
306 /// scheduling, listed in increasing set ID order. Each pressure set is paired
307 /// with its max pressure in the currently scheduled regions.
308 std::vector RegionCriticalPSets;
309
310 /// The top of the unscheduled zone.
311 MachineBasicBlock::iterator CurrentTop;
312 IntervalPressure TopPressure;
313 RegPressureTracker TopRPTracker;
314
315 /// The bottom of the unscheduled zone.
316 MachineBasicBlock::iterator CurrentBottom;
317 IntervalPressure BotPressure;
318 RegPressureTracker BotRPTracker;
319
320 #ifndef NDEBUG
321 /// The number of instructions scheduled so far. Used to cut off the
322 /// scheduler at the point determined by misched-cutoff.
323 unsigned NumInstrsScheduled;
433 } // namespace
434
435
324436 #endif
325
326 /// Total packets in the region.
327 unsigned TotalPackets;
328
329 const MachineLoopInfo *MLI;
330 public:
331 VLIWMachineScheduler(MachineSchedContext *C, MachineSchedStrategy *S):
332 ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
333 AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S),
334 RPTracker(RegPressure), CurrentTop(), TopRPTracker(TopPressure),
335 CurrentBottom(), BotRPTracker(BotPressure), MLI(C->MLI) {
336
337 TopResourceModel = new VLIWResourceModel(C, InstrItins);
338 BotResourceModel = new VLIWResourceModel(C, InstrItins);
339
340 #ifndef NDEBUG
341 NumInstrsScheduled = 0;
342 #endif
343 TotalPackets = 0;
344 }
345
346 virtual ~VLIWMachineScheduler() {
347 delete SchedImpl;
348 delete TopResourceModel;
349 delete BotResourceModel;
350 }
351
352 MachineBasicBlock::iterator top() const { return CurrentTop; }
353 MachineBasicBlock::iterator bottom() const { return CurrentBottom; }
354
355 /// Implement the ScheduleDAGInstrs interface for handling the next scheduling
356 /// region. This covers all instructions in a block, while schedule() may only
357 /// cover a subset.
358 void enterRegion(MachineBasicBlock *bb,
359 MachineBasicBlock::iterator begin,
360 MachineBasicBlock::iterator end,
361 unsigned endcount);
362
363 /// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's
364 /// time to do some work.
365 void schedule();
366
367 unsigned CurCycle;
368
369 /// Get current register pressure for the top scheduled instructions.
370 const IntervalPressure &getTopPressure() const { return TopPressure; }
371 const RegPressureTracker &getTopRPTracker() const { return TopRPTracker; }
372
373 /// Get current register pressure for the bottom scheduled instructions.
374 const IntervalPressure &getBotPressure() const { return BotPressure; }
375 const RegPressureTracker &getBotRPTracker() const { return BotRPTracker; }
376
377 /// Get register pressure for the entire scheduling region before scheduling.
378 const IntervalPressure &getRegPressure() const { return RegPressure; }
379
380 const std::vector &getRegionCriticalPSets() const {
381 return RegionCriticalPSets;
382 }
383
384 VLIWResourceModel *getTopResourceModel() { return TopResourceModel; }
385 VLIWResourceModel *getBotResourceModel() { return BotResourceModel; }
386
387 /// getIssueWidth - Return the max instructions per scheduling group.
388 unsigned getIssueWidth() const {
389 return (InstrItins && InstrItins->SchedModel)
390 ? InstrItins->SchedModel->IssueWidth : 1;
391 }
392
393 /// getNumMicroOps - Return the number of issue slots required for this MI.
394 unsigned getNumMicroOps(MachineInstr *MI) const {
395 if (!InstrItins) return 1;
396 int UOps = InstrItins->getNumMicroOps(MI->getDesc().getSchedClass());
397 return (UOps >= 0) ? UOps : TII->getNumMicroOps(InstrItins, MI);
398 }
399
400 private:
401 void scheduleNodeTopDown(SUnit *SU);
402 void listScheduleTopDown();
403
404 void initRegPressure();
405 void updateScheduledPressure(std::vector NewMaxPressure);
406
407 void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
408 bool checkSchedLimit();
409
410 void releaseRoots();
411
412 void releaseSucc(SUnit *SU, SDep *SuccEdge);
413 void releaseSuccessors(SUnit *SU);
414 void releasePred(SUnit *SU, SDep *PredEdge);
415 void releasePredecessors(SUnit *SU);
416
417 void placeDebugValues();
418 };
419 } // namespace
420
421
422 #endif