llvm.org GIT mirror llvm / 8d4abb2
misched: TargetSchedule interface for machine resources. Expose the processor resources defined by the machine model to the scheduler and other clients through the TargetSchedule interface. Normalize each resource count with respect to other kinds of resources. This allows scheduling heuristics to balance resources against other kinds of resources and latency. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167444 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Trick 7 years ago
5 changed file(s) with 105 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
3030 class MachineFunction;
3131 class MachineRegisterInfo;
3232 class MachineInstr;
33 struct MCSchedClassDesc;
3334 class TargetRegisterInfo;
3435 class ScheduleDAG;
3536 class SDNode;
247248 SUnit *OrigNode; // If not this, the node from which
248249 // this node was cloned.
249250 // (SD scheduling only)
251
252 const MCSchedClassDesc *SchedClass; // NULL or resolved SchedClass.
250253
251254 // Preds/Succs - The SUnits before/after us in the graph.
252255 SmallVector Preds; // All sunit predecessors.
295298 /// SUnit - Construct an SUnit for pre-regalloc scheduling to represent
296299 /// an SDNode and any nodes flagged to it.
297300 SUnit(SDNode *node, unsigned nodenum)
298 : Node(node), Instr(0), OrigNode(0), NodeNum(nodenum),
301 : Node(node), Instr(0), OrigNode(0), SchedClass(0), NodeNum(nodenum),
299302 NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
300303 NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0),
301304 isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false),
309312 /// SUnit - Construct an SUnit for post-regalloc scheduling to represent
310313 /// a MachineInstr.
311314 SUnit(MachineInstr *instr, unsigned nodenum)
312 : Node(0), Instr(instr), OrigNode(0), NodeNum(nodenum),
315 : Node(0), Instr(instr), OrigNode(0), SchedClass(0), NodeNum(nodenum),
313316 NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
314317 NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0),
315318 isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false),
322325
323326 /// SUnit - Construct a placeholder SUnit.
324327 SUnit()
325 : Node(0), Instr(0), OrigNode(0), NodeNum(~0u),
328 : Node(0), Instr(0), OrigNode(0), SchedClass(0), NodeNum(~0u),
326329 NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
327330 NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0),
328331 isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false),
188188 /// \brief Get the machine model for instruction scheduling.
189189 const TargetSchedModel *getSchedModel() const { return &SchedModel; }
190190
191 /// \brief Resolve and cache a resolved scheduling class for an SUnit.
192 const MCSchedClassDesc *getSchedClass(SUnit *SU) const {
193 if (!SU->SchedClass)
194 SU->SchedClass = SchedModel.resolveSchedClass(SU->getInstr());
195 return SU->SchedClass;
196 }
197
191198 /// begin - Return an iterator to the top of the current scheduling region.
192199 MachineBasicBlock::iterator begin() const { return RegionBegin; }
193200
1515 #ifndef LLVM_TARGET_TARGETSCHEDMODEL_H
1616 #define LLVM_TARGET_TARGETSCHEDMODEL_H
1717
18 #include "llvm/Target/TargetSubtargetInfo.h"
1819 #include "llvm/MC/MCSchedule.h"
1920 #include "llvm/MC/MCInstrItineraries.h"
21 #include "llvm/ADT/SmallVector.h"
2022
2123 namespace llvm {
2224
3335 InstrItineraryData InstrItins;
3436 const TargetSubtargetInfo *STI;
3537 const TargetInstrInfo *TII;
38
39 SmallVector ResourceFactors;
40 unsigned MicroOpFactor; // Multiply to normalize microops to resource units.
41 unsigned ResourceLCM; // Resource units per cycle. Latency normalization factor.
3642 public:
3743 TargetSchedModel(): STI(0), TII(0) {}
3844
4349 /// dynamic properties.
4450 void init(const MCSchedModel &sm, const TargetSubtargetInfo *sti,
4551 const TargetInstrInfo *tii);
52
53 /// Return the MCSchedClassDesc for this instruction.
54 const MCSchedClassDesc *resolveSchedClass(const MachineInstr *MI) const;
4655
4756 /// \brief TargetInstrInfo getter.
4857 const TargetInstrInfo *getInstrInfo() const { return TII; }
7584 unsigned getIssueWidth() const { return SchedModel.IssueWidth; }
7685
7786 /// \brief Return the number of issue slots required for this MI.
78 unsigned getNumMicroOps(MachineInstr *MI) const;
87 unsigned getNumMicroOps(const MachineInstr *MI,
88 const MCSchedClassDesc *SC = 0) const;
89
90 /// \brief Get the number of kinds of resources for this target.
91 unsigned getNumProcResourceKinds() const {
92 return SchedModel.getNumProcResourceKinds();
93 }
94
95 /// \brief Get a processor resource by ID for convenience.
96 const MCProcResourceDesc *getProcResource(unsigned PIdx) const {
97 return SchedModel.getProcResource(PIdx);
98 }
99
100 typedef const MCWriteProcResEntry *ProcResIter;
101
102 // \brief Get an iterator into the processor resources consumed by this
103 // scheduling class.
104 ProcResIter getWriteProcResBegin(const MCSchedClassDesc *SC) const {
105 // The subtarget holds a single resource table for all processors.
106 return STI->getWriteProcResBegin(SC);
107 }
108 ProcResIter getWriteProcResEnd(const MCSchedClassDesc *SC) const {
109 return STI->getWriteProcResEnd(SC);
110 }
111
112 /// \brief Multiply the number of units consumed for a resource by this factor
113 /// to normalize it relative to other resources.
114 unsigned getResourceFactor(unsigned ResIdx) const {
115 return ResourceFactors[ResIdx];
116 }
117
118 /// \brief Multiply number of micro-ops by this factor to normalize it
119 /// relative to other resources.
120 unsigned getMicroOpFactor() const {
121 return MicroOpFactor;
122 }
123
124 /// \brief Multiply cycle count by this factor to normalize it relative to
125 /// other resources. This is the number of resource units per cycle.
126 unsigned getLatencyFactor() const {
127 return ResourceLCM;
128 }
79129
80130 /// \brief Compute operand latency based on the available machine model.
81131 ///
104154 unsigned computeOutputLatency(const MachineInstr *DefMI, unsigned DefIdx,
105155 const MachineInstr *DepMI) const;
106156
107
108157 private:
109158 /// getDefLatency is a helper for computeOperandLatency. Return the
110159 /// instruction's latency if operand lookup is not required.
111160 /// Otherwise return -1.
112161 int getDefLatency(const MachineInstr *DefMI, bool FindMin) const;
113
114 /// Return the MCSchedClassDesc for this instruction.
115 const MCSchedClassDesc *resolveSchedClass(const MachineInstr *MI) const;
116162 };
117163
118164 } // namespace llvm
218218 /// Does this machine model include instruction-level scheduling.
219219 bool hasInstrSchedModel() const { return SchedClassTable; }
220220
221 unsigned getNumProcResourceKinds() const {
222 return NumProcResourceKinds;
223 }
224
221225 const MCProcResourceDesc *getProcResource(unsigned ProcResourceIdx) const {
222226 assert(hasInstrSchedModel() && "No scheduling machine model");
223227
3535 return EnableSchedItins && !InstrItins.isEmpty();
3636 }
3737
38 static unsigned gcd(unsigned Dividend, unsigned Divisor) {
39 // Dividend and Divisor will be naturally swapped as needed.
40 while(Divisor) {
41 unsigned Rem = Dividend % Divisor;
42 Dividend = Divisor;
43 Divisor = Rem;
44 };
45 return Dividend;
46 }
47 static unsigned lcm(unsigned A, unsigned B) {
48 unsigned LCM = (uint64_t(A) * B) / gcd(A, B);
49 assert((LCM >= A && LCM >= B) && "LCM overflow");
50 return LCM;
51 }
52
3853 void TargetSchedModel::init(const MCSchedModel &sm,
3954 const TargetSubtargetInfo *sti,
4055 const TargetInstrInfo *tii) {
4257 STI = sti;
4358 TII = tii;
4459 STI->initInstrItins(InstrItins);
45 }
46
47 unsigned TargetSchedModel::getNumMicroOps(MachineInstr *MI) const {
60
61 unsigned NumRes = SchedModel.getNumProcResourceKinds();
62 ResourceFactors.resize(NumRes);
63 ResourceLCM = SchedModel.IssueWidth;
64 for (unsigned Idx = 0; Idx < NumRes; ++Idx) {
65 unsigned NumUnits = SchedModel.getProcResource(Idx)->NumUnits;
66 if (NumUnits > 0)
67 ResourceLCM = lcm(ResourceLCM, NumUnits);
68 }
69 MicroOpFactor = ResourceLCM / SchedModel.IssueWidth;
70 for (unsigned Idx = 0; Idx < NumRes; ++Idx) {
71 unsigned NumUnits = SchedModel.getProcResource(Idx)->NumUnits;
72 ResourceFactors[Idx] = NumUnits ? (ResourceLCM / NumUnits) : 0;
73 }
74 }
75
76 unsigned TargetSchedModel::getNumMicroOps(const MachineInstr *MI,
77 const MCSchedClassDesc *SC) const {
4878 if (hasInstrItineraries()) {
4979 int UOps = InstrItins.getNumMicroOps(MI->getDesc().getSchedClass());
5080 return (UOps >= 0) ? UOps : TII->getNumMicroOps(&InstrItins, MI);
5181 }
5282 if (hasInstrSchedModel()) {
53 const MCSchedClassDesc *SCDesc = resolveSchedClass(MI);
54 if (SCDesc->isValid())
55 return SCDesc->NumMicroOps;
83 if (!SC)
84 SC = resolveSchedClass(MI);
85 if (SC->isValid())
86 return SC->NumMicroOps;
5687 }
5788 return MI->isTransient() ? 0 : 1;
5889 }