llvm.org GIT mirror llvm / 412cd2f
misched: Use the TargetSchedModel interface wherever possible. Allows the new machine model to be used for NumMicroOps and OutputLatency. Allows the HazardRecognizer to be disabled along with itineraries. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165603 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Trick 7 years ago
12 changed file(s) with 128 addition(s) and 117 deletion(s). Raw diff Collapse all Expand all
3030 #include "llvm/CodeGen/RegisterPressure.h"
3131 #include "llvm/CodeGen/ScheduleDAGInstrs.h"
3232 #include "llvm/Target/TargetInstrInfo.h"
33 #include "llvm/MC/MCInstrItineraries.h"
3433
3534 namespace llvm {
3635
277276 return RegionCriticalPSets;
278277 }
279278
280 /// getIssueWidth - Return the max instructions per scheduling group.
281 unsigned getIssueWidth() const {
282 return (InstrItins && InstrItins->SchedModel)
283 ? InstrItins->SchedModel->IssueWidth : 1;
284 }
285
286 /// getNumMicroOps - Return the number of issue slots required for this MI.
287 unsigned getNumMicroOps(MachineInstr *MI) const {
288 if (!InstrItins) return 1;
289 int UOps = InstrItins->getNumMicroOps(MI->getDesc().getSchedClass());
290 return (UOps >= 0) ? UOps : TII->getNumMicroOps(InstrItins, MI);
291 }
292
293279 protected:
294280 // Top-Level entry points for the schedule() driver...
295281
569569 unsigned VerifyScheduledDAG(bool isBottomUp);
570570 #endif
571571
572 protected:
573 /// ComputeLatency - Compute node latency.
574 ///
575 virtual void computeLatency(SUnit *SU) = 0;
576
577572 private:
578573 // Return the MCInstrDesc of this SDNode or NULL.
579574 const MCInstrDesc *getNodeDesc(const SDNode *Node) const;
110110 const MachineLoopInfo &MLI;
111111 const MachineDominatorTree &MDT;
112112 const MachineFrameInfo *MFI;
113 const InstrItineraryData *InstrItins;
114113
115114 /// Live Intervals provides reaching defs in preRA scheduling.
116115 LiveIntervals *LIS;
185184 LiveIntervals *LIS = 0);
186185
187186 virtual ~ScheduleDAGInstrs() {}
187
188 /// \brief Get the machine model for instruction scheduling.
189 const TargetSchedModel *getSchedModel() const { return &SchedModel; }
188190
189191 /// begin - Return an iterator to the top of the current scheduling region.
190192 MachineBasicBlock::iterator begin() const { return RegionBegin; }
225227 /// are too high to be hidden by the branch or when the liveout registers
226228 /// used by instructions in the fallthrough block.
227229 void addSchedBarrierDeps();
228
229 /// computeLatency - Compute node latency.
230 ///
231 virtual void computeLatency(SUnit *SU);
232230
233231 /// schedule - Order nodes according to selected style, filling
234232 /// in the Sequence member.
5454 /// latency properties, but separate from the per-cycle itinerary data.
5555 bool hasInstrSchedModel() const;
5656
57 const MCSchedModel *getMCSchedModel() const { return &SchedModel; }
58
5759 /// \brief Return true if this machine model includes cycle-to-cycle itinerary
5860 /// data.
5961 ///
6062 /// This models scheduling at each stage in the processor pipeline.
6163 bool hasInstrItineraries() const;
64
65 const InstrItineraryData *getInstrItineraries() const {
66 if (hasInstrItineraries())
67 return &InstrItins;
68 return 0;
69 }
70
71 /// \brief Identify the processor corresponding to the current subtarget.
72 unsigned getProcessorID() const { return SchedModel.getProcessorID(); }
73
74 /// \brief Maximum number of micro-ops that may be scheduled per cycle.
75 unsigned getIssueWidth() const { return SchedModel.IssueWidth; }
76
77 /// \brief Return the number of issue slots required for this MI.
78 unsigned getNumMicroOps(MachineInstr *MI) const;
6279
6380 /// \brief Compute operand latency based on the available machine model.
6481 ///
8198 /// occasionally useful to help estimate instruction cost.
8299 unsigned computeInstrLatency(const MachineInstr *MI) const;
83100
84 /// \brief Identify the processor corresponding to the current subtarget.
85 unsigned getProcessorID() const { return SchedModel.getProcessorID(); }
101 /// \brief Output dependency latency of a pair of defs of the same register.
102 ///
103 /// This is typically one cycle.
104 unsigned computeOutputLatency(const MachineInstr *DefMI, unsigned DefIdx,
105 const MachineInstr *DepMI) const;
86106
87 /// \brief Maximum number of micro-ops that may be scheduled per cycle.
88 unsigned getIssueWidth() const { return SchedModel.IssueWidth; }
89107
90108 private:
91109 /// getDefLatency is a helper for computeOperandLatency. Return the
799799 const MachineInstr *DefMI, unsigned DefIdx,
800800 const MachineInstr *UseMI, unsigned UseIdx,
801801 bool FindMin = false) const;
802
803 /// getOutputLatency - Compute and return the output dependency latency of a
804 /// a given pair of defs which both target the same register. This is usually
805 /// one.
806 virtual unsigned getOutputLatency(const InstrItineraryData *ItinData,
807 const MachineInstr *DefMI, unsigned DefIdx,
808 const MachineInstr *DepMI) const {
809 return 1;
810 }
811802
812803 /// getInstrLatency - Compute the instruction latency of a given instruction.
813804 /// If the instruction has higher cost when predicated, it's returned via
651651 /// of "hazards" and other interlocks at the current cycle.
652652 struct SchedBoundary {
653653 ScheduleDAGMI *DAG;
654 const TargetSchedModel *SchedModel;
654655
655656 ReadyQueue Available;
656657 ReadyQueue Pending;
670671 /// Pending queues extend the ready queues with the same ID and the
671672 /// PendingFlag set.
672673 SchedBoundary(unsigned ID, const Twine &Name):
673 DAG(0), Available(ID, Name+".A"),
674 DAG(0), SchedModel(0), Available(ID, Name+".A"),
674675 Pending(ID << ConvergingScheduler::LogMaxQID, Name+".P"),
675676 CheckPending(false), HazardRec(0), CurrCycle(0), IssueCount(0),
676677 MinReadyCycle(UINT_MAX), MaxMinLatency(0) {}
677678
678679 ~SchedBoundary() { delete HazardRec; }
679680
681 void init(ScheduleDAGMI *dag, const TargetSchedModel *smodel) {
682 DAG = dag;
683 SchedModel = smodel;
684 }
685
680686 bool isTop() const {
681687 return Available.getID() == ConvergingScheduler::TopQID;
682688 }
697703 };
698704
699705 ScheduleDAGMI *DAG;
706 const TargetSchedModel *SchedModel;
700707 const TargetRegisterInfo *TRI;
701708
702709 // State of the top and bottom scheduled instruction boundaries.
712719 };
713720
714721 ConvergingScheduler():
715 DAG(0), TRI(0), Top(TopQID, "TopQ"), Bot(BotQID, "BotQ") {}
722 DAG(0), SchedModel(0), TRI(0), Top(TopQID, "TopQ"), Bot(BotQID, "BotQ") {}
716723
717724 virtual void initialize(ScheduleDAGMI *dag);
718725
739746
740747 void ConvergingScheduler::initialize(ScheduleDAGMI *dag) {
741748 DAG = dag;
749 SchedModel = DAG->getSchedModel();
742750 TRI = DAG->TRI;
743 Top.DAG = dag;
744 Bot.DAG = dag;
745
746 // Initialize the HazardRecognizers.
751 Top.init(DAG, SchedModel);
752 Bot.init(DAG, SchedModel);
753
754 // Initialize the HazardRecognizers. If itineraries don't exist, are empty, or
755 // are disabled, then these HazardRecs will be disabled.
756 const InstrItineraryData *Itin = SchedModel->getInstrItineraries();
747757 const TargetMachine &TM = DAG->MF.getTarget();
748 const InstrItineraryData *Itin = TM.getInstrItineraryData();
749758 Top.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG);
750759 Bot.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG);
751760
806815 if (HazardRec->isEnabled())
807816 return HazardRec->getHazardType(SU) != ScheduleHazardRecognizer::NoHazard;
808817
809 if (IssueCount + DAG->getNumMicroOps(SU->getInstr()) > DAG->getIssueWidth())
818 unsigned uops = SchedModel->getNumMicroOps(SU->getInstr());
819 if (IssueCount + uops > SchedModel->getIssueWidth())
810820 return true;
811821
812822 return false;
827837
828838 /// Move the boundary of scheduled code by one cycle.
829839 void ConvergingScheduler::SchedBoundary::bumpCycle() {
830 unsigned Width = DAG->getIssueWidth();
840 unsigned Width = SchedModel->getIssueWidth();
831841 IssueCount = (IssueCount <= Width) ? 0 : IssueCount - Width;
832842
833843 assert(MinReadyCycle < UINT_MAX && "MinReadyCycle uninitialized");
865875 }
866876 // Check the instruction group dispatch limit.
867877 // TODO: Check if this SU must end a dispatch group.
868 IssueCount += DAG->getNumMicroOps(SU->getInstr());
869 if (IssueCount >= DAG->getIssueWidth()) {
878 IssueCount += SchedModel->getNumMicroOps(SU->getInstr());
879 if (IssueCount >= SchedModel->getIssueWidth()) {
870880 DEBUG(dbgs() << "*** Max instrs at cycle " << CurrCycle << '\n');
871881 bumpCycle();
872882 }
4343 const MachineDominatorTree &mdt,
4444 bool IsPostRAFlag,
4545 LiveIntervals *lis)
46 : ScheduleDAG(mf), MLI(mli), MDT(mdt), MFI(mf.getFrameInfo()),
47 InstrItins(mf.getTarget().getInstrItineraryData()), LIS(lis),
46 : ScheduleDAG(mf), MLI(mli), MDT(mdt), MFI(mf.getFrameInfo()), LIS(lis),
4847 IsPostRA(IsPostRAFlag), CanHandleTerminators(false), FirstDbgValue(0) {
4948 assert((IsPostRA || LIS) && "PreRA scheduling requires LiveIntervals");
5049 DbgValues.clear();
291290 if (Kind == SDep::Anti)
292291 DefSU->addPred(SDep(SU, Kind, 0, /*Reg=*/*Alias));
293292 else {
294 unsigned AOLat = TII->getOutputLatency(InstrItins, MI, OperIdx,
295 DefSU->getInstr());
293 unsigned AOLat =
294 SchedModel.computeOutputLatency(MI, OperIdx, DefSU->getInstr());
296295 DefSU->addPred(SDep(SU, Kind, AOLat, /*Reg=*/*Alias));
297296 }
298297 }
362361 else {
363362 SUnit *DefSU = DefI->SU;
364363 if (DefSU != SU && DefSU != &ExitSU) {
365 unsigned OutLatency = TII->getOutputLatency(InstrItins, MI, OperIdx,
366 DefSU->getInstr());
364 unsigned OutLatency =
365 SchedModel.computeOutputLatency(MI, OperIdx, DefSU->getInstr());
367366 DefSU->addPred(SDep(SU, SDep::Output, OutLatency, Reg));
368367 }
369368 DefI->SU = SU;
649648 SU->isCommutable = MI->isCommutable();
650649
651650 // Assign the Latency field of SU using target-provided information.
652 computeLatency(SU);
651 SU->Latency = SchedModel.computeInstrLatency(SU->getInstr());
653652 }
654653 }
655654
910909 PendingLoads.clear();
911910 }
912911
913 void ScheduleDAGInstrs::computeLatency(SUnit *SU) {
914 // Compute the latency for the node. We only provide a default for missing
915 // itineraries. Empty itineraries still have latency properties.
916 if (!InstrItins) {
917 SU->Latency = 1;
918
919 // Simplistic target-independent heuristic: assume that loads take
920 // extra time.
921 if (SU->getInstr()->mayLoad())
922 SU->Latency += 2;
923 } else {
924 SU->Latency = TII->getInstrLatency(InstrItins, SU->getInstr());
925 }
926 }
927
928912 void ScheduleDAGInstrs::dumpNode(const SUnit *SU) const {
929913 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
930914 SU->getInstr()->dump();
1313
1414 #include "llvm/CodeGen/TargetSchedule.h"
1515 #include "llvm/Target/TargetInstrInfo.h"
16 #include "llvm/Target/TargetMachine.h"
1617 #include "llvm/Target/TargetRegisterInfo.h"
1718 #include "llvm/Target/TargetSubtargetInfo.h"
1819 #include "llvm/Support/CommandLine.h"
4142 STI = sti;
4243 TII = tii;
4344 STI->initInstrItins(InstrItins);
45 }
46
47 unsigned TargetSchedModel::getNumMicroOps(MachineInstr *MI) const {
48 if (hasInstrItineraries()) {
49 int UOps = InstrItins.getNumMicroOps(MI->getDesc().getSchedClass());
50 return (UOps >= 0) ? UOps : TII->getNumMicroOps(&InstrItins, MI);
51 }
52 if (hasInstrSchedModel())
53 return resolveSchedClass(MI)->NumMicroOps;
54
55 return 1;
4456 }
4557
4658 /// If we can determine the operand latency from the def only, without machine
208220 }
209221 return TII->defaultDefLatency(&SchedModel, MI);
210222 }
223
224 unsigned TargetSchedModel::
225 computeOutputLatency(const MachineInstr *DefMI, unsigned DefOperIdx,
226 const MachineInstr *DepMI) const {
227 // MinLatency == -1 is for in-order processors that always have unit
228 // MinLatency. MinLatency > 0 is for in-order processors with varying min
229 // latencies, but since this is not a RAW dep, we always use unit latency.
230 if (SchedModel.MinLatency != 0)
231 return 1;
232
233 // MinLatency == 0 indicates an out-of-order processor that can dispatch
234 // WAW dependencies in the same cycle.
235
236 // Treat predication as a data dependency for out-of-order cpus. In-order
237 // cpus do not need to treat predicated writes specially.
238 //
239 // TODO: The following hack exists because predication passes do not
240 // correctly append imp-use operands, and readsReg() strangely returns false
241 // for predicated defs.
242 unsigned Reg = DefMI->getOperand(DefOperIdx).getReg();
243 const MachineFunction &MF = *DefMI->getParent()->getParent();
244 const TargetRegisterInfo *TRI = MF.getTarget().getRegisterInfo();
245 if (!DepMI->readsRegister(Reg, TRI) && TII->isPredicated(DepMI))
246 return computeInstrLatency(DefMI);
247
248 // If we have a per operand scheduling model, check if this def is writing
249 // an unbuffered resource. If so, it treated like an in-order cpu.
250 if (hasInstrSchedModel()) {
251 const MCSchedClassDesc *SCDesc = resolveSchedClass(DefMI);
252 for (const MCWriteProcResEntry *PRI = STI->getWriteProcResBegin(SCDesc),
253 *PRE = STI->getWriteProcResEnd(SCDesc); PRI != PRE; ++PRI) {
254 if (!SchedModel.getProcResource(PRI->ProcResourceIdx)->IsBuffered)
255 return 1;
256 }
257 }
258 return 0;
259 }
35493549 return Latency;
35503550 }
35513551
3552 unsigned
3553 ARMBaseInstrInfo::getOutputLatency(const InstrItineraryData *ItinData,
3554 const MachineInstr *DefMI, unsigned DefIdx,
3555 const MachineInstr *DepMI) const {
3556 unsigned Reg = DefMI->getOperand(DefIdx).getReg();
3557 if (DepMI->readsRegister(Reg, &getRegisterInfo()) || !isPredicated(DepMI))
3558 return 1;
3559
3560 // If the second MI is predicated, then there is an implicit use dependency.
3561 return getInstrLatency(ItinData, DefMI);
3562 }
3563
35643552 unsigned ARMBaseInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
35653553 const MachineInstr *MI,
35663554 unsigned *PredCost) const {
227227 int getOperandLatency(const InstrItineraryData *ItinData,
228228 SDNode *DefNode, unsigned DefIdx,
229229 SDNode *UseNode, unsigned UseIdx) const;
230
231 virtual unsigned getOutputLatency(const InstrItineraryData *ItinData,
232 const MachineInstr *DefMI, unsigned DefIdx,
233 const MachineInstr *DepMI) const;
234230
235231 /// VFP/NEON execution domains.
236232 std::pair
127127
128128 // If packet is now full, reset the state so in the next cycle
129129 // we start fresh.
130 if (Packet.size() >= InstrItins->SchedModel->IssueWidth) {
130 if (Packet.size() >= SchedModel->getIssueWidth()) {
131131 ResourcesModel->clearResources();
132132 Packet.clear();
133133 TotalPackets++;
185185
186186 void ConvergingVLIWScheduler::initialize(ScheduleDAGMI *dag) {
187187 DAG = static_cast(dag);
188 SchedModel = DAG->getSchedModel();
188189 TRI = DAG->TRI;
189 Top.DAG = DAG;
190 Bot.DAG = DAG;
191
192 // Initialize the HazardRecognizers.
190 Top.init(DAG, SchedModel);
191 Bot.init(DAG, SchedModel);
192
193 // Initialize the HazardRecognizers. If itineraries don't exist, are empty, or
194 // are disabled, then these HazardRecs will be disabled.
195 const InstrItineraryData *Itin = DAG->getSchedModel()->getInstrItineraries();
193196 const TargetMachine &TM = DAG->MF.getTarget();
194 const InstrItineraryData *Itin = TM.getInstrItineraryData();
195197 Top.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG);
196198 Bot.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG);
197199
198 Top.ResourceModel = new VLIWResourceModel(TM);
199 Bot.ResourceModel = new VLIWResourceModel(TM);
200 Top.ResourceModel = new VLIWResourceModel(TM, DAG->getSchedModel());
201 Bot.ResourceModel = new VLIWResourceModel(TM, DAG->getSchedModel());
200202
201203 assert((!llvm::ForceTopDown || !llvm::ForceBottomUp) &&
202204 "-misched-topdown incompatible with -misched-bottomup");
255257 if (HazardRec->isEnabled())
256258 return HazardRec->getHazardType(SU) != ScheduleHazardRecognizer::NoHazard;
257259
258 if (IssueCount + DAG->getNumMicroOps(SU->getInstr()) > DAG->getIssueWidth())
260 unsigned uops = SchedModel->getNumMicroOps(SU->getInstr());
261 if (IssueCount + uops > SchedModel->getIssueWidth())
259262 return true;
260263
261264 return false;
277280
278281 /// Move the boundary of scheduled code by one cycle.
279282 void ConvergingVLIWScheduler::SchedBoundary::bumpCycle() {
280 unsigned Width = DAG->getIssueWidth();
283 unsigned Width = SchedModel->getIssueWidth();
281284 IssueCount = (IssueCount <= Width) ? 0 : IssueCount - Width;
282285
283286 assert(MinReadyCycle < UINT_MAX && "MinReadyCycle uninitialized");
320323
321324 // Check the instruction group dispatch limit.
322325 // TODO: Check if this SU must end a dispatch group.
323 IssueCount += DAG->getNumMicroOps(SU->getInstr());
326 IssueCount += SchedModel->getNumMicroOps(SU->getInstr());
324327 if (startNewCycle) {
325328 DEBUG(dbgs() << "*** Max instrs at cycle " << CurrCycle << '\n');
326329 bumpCycle();
4444 /// definition of DFA by a target.
4545 DFAPacketizer *ResourcesModel;
4646
47 const InstrItineraryData *InstrItins;
47 const TargetSchedModel *SchedModel;
4848
4949 /// Local packet/bundle model. Purely
5050 /// internal to the MI schedulre at the time.
5454 unsigned TotalPackets;
5555
5656 public:
57 VLIWResourceModel(MachineSchedContext *C, const InstrItineraryData *IID) :
58 InstrItins(IID), TotalPackets(0) {
59 const TargetMachine &TM = C->MF->getTarget();
57 VLIWResourceModel(const TargetMachine &TM, const TargetSchedModel *SM) :
58 SchedModel(SM), TotalPackets(0) {
6059 ResourcesModel = TM.getInstrInfo()->CreateTargetScheduleState(&TM,NULL);
6160
6261 // This hard requirement could be relaxed,
6362 // but for now do not let it proceed.
6463 assert(ResourcesModel && "Unimplemented CreateTargetScheduleState.");
6564
66 Packet.resize(InstrItins->SchedModel->IssueWidth);
67 Packet.clear();
68 ResourcesModel->clearResources();
69 }
70
71 VLIWResourceModel(const TargetMachine &TM) :
72 InstrItins(TM.getInstrItineraryData()), TotalPackets(0) {
73 ResourcesModel = TM.getInstrInfo()->CreateTargetScheduleState(&TM,NULL);
74
75 // This hard requirement could be relaxed,
76 // but for now do not let it proceed.
77 assert(ResourcesModel && "Unimplemented CreateTargetScheduleState.");
78
79 Packet.resize(InstrItins->SchedModel->IssueWidth);
65 Packet.resize(SchedModel->getIssueWidth());
8066 Packet.clear();
8167 ResourcesModel->clearResources();
8268 }
145131 /// of "hazards" and other interlocks at the current cycle.
146132 struct SchedBoundary {
147133 VLIWMachineScheduler *DAG;
134 const TargetSchedModel *SchedModel;
148135
149136 ReadyQueue Available;
150137 ReadyQueue Pending;
165152 /// Pending queues extend the ready queues with the same ID and the
166153 /// PendingFlag set.
167154 SchedBoundary(unsigned ID, const Twine &Name):
168 DAG(0), Available(ID, Name+".A"),
155 DAG(0), SchedModel(0), Available(ID, Name+".A"),
169156 Pending(ID << ConvergingVLIWScheduler::LogMaxQID, Name+".P"),
170157 CheckPending(false), HazardRec(0), ResourceModel(0),
171158 CurrCycle(0), IssueCount(0),
176163 delete HazardRec;
177164 }
178165
166 void init(VLIWMachineScheduler *dag, const TargetSchedModel *smodel) {
167 DAG = dag;
168 SchedModel = smodel;
169 }
170
179171 bool isTop() const {
180172 return Available.getID() == ConvergingVLIWScheduler::TopQID;
181173 }
196188 };
197189
198190 VLIWMachineScheduler *DAG;
191 const TargetSchedModel *SchedModel;
199192 const TargetRegisterInfo *TRI;
200193
201194 // State of the top and bottom scheduled instruction boundaries.
211204 };
212205
213206 ConvergingVLIWScheduler():
214 DAG(0), TRI(0), Top(TopQID, "TopQ"), Bot(BotQID, "BotQ") {}
207 DAG(0), SchedModel(0), TRI(0), Top(TopQID, "TopQ"), Bot(BotQID, "BotQ") {}
215208
216209 virtual void initialize(ScheduleDAGMI *dag);
217210