1 //===- Target/TargetSchedInfo.h - Target Instruction Sched Info --*- C++ -*-==//
3 // This file describes the target machine to the instruction scheduler.
5 //===----------------------------------------------------------------------===//
7 #ifndef LLVM_TARGET_TARGETSCHEDINFO_H
8 #define LLVM_TARGET_TARGETSCHEDINFO_H
10 #include "llvm/Target/TargetInstrInfo.h"
11 #include "Support/hash_map"
14 typedef long long cycles_t;
15 static const cycles_t HUGE_LATENCY = ~((long long) 1 << (sizeof(cycles_t)-2));
16 static const cycles_t INVALID_LATENCY = -HUGE_LATENCY;
17 static const unsigned MAX_OPCODE_SIZE = 16;
21 long val; // make long by concatenating two opcodes
22 OpCodePair(MachineOpCode op1, MachineOpCode op2)
23 : val((op1 < 0 || op2 < 0)?
24 -1 : (long)((((unsigned) op1) << MAX_OPCODE_SIZE) | (unsigned) op2)) {}
25 bool operator==(const OpCodePair& op) const {
29 OpCodePair(); // disable for now
32 namespace HASH_NAMESPACE {
33 template <> struct hash<OpCodePair> {
34 size_t operator()(const OpCodePair& pair) const {
35 return hash<long>()(pair.val);
40 //---------------------------------------------------------------------------
41 // class MachineResource
45 // Representation of a single machine resource used in specifying
46 // resource usages of machine instructions for scheduling.
47 //---------------------------------------------------------------------------
50 typedef unsigned resourceId_t;
52 struct MachineResource {
53 const std::string rname;
56 MachineResource(const std::string &resourceName)
57 : rname(resourceName), rid(nextId++) {}
60 static resourceId_t nextId;
61 MachineResource(); // disable
65 struct CPUResource : public MachineResource {
66 int maxNumUsers; // MAXINT if no restriction
68 CPUResource(const std::string& rname, int maxUsers)
69 : MachineResource(rname), maxNumUsers(maxUsers) {}
73 //---------------------------------------------------------------------------
74 // struct InstrClassRUsage
75 // struct InstrRUsageDelta
76 // struct InstrIssueDelta
80 // The first three are structures used to specify machine resource
81 // usages for each instruction in a machine description file:
82 // InstrClassRUsage : resource usages common to all instrs. in a class
83 // InstrRUsageDelta : add/delete resource usage for individual instrs.
84 // InstrIssueDelta : add/delete instr. issue info for individual instrs
86 // The last one (InstrRUsage) is the internal representation of
87 // instruction resource usage constructed from the above three.
88 //---------------------------------------------------------------------------
90 const int MAX_NUM_SLOTS = 32;
91 const int MAX_NUM_CYCLES = 32;
93 struct InstrClassRUsage {
94 InstrSchedClass schedClass;
97 // Issue restrictions common to instructions in this class
103 // Feasible slots to use for instructions in this class.
104 // The size of vector S[] is `numSlots'.
106 unsigned feasibleSlots[MAX_NUM_SLOTS];
108 // Resource usages common to instructions in this class.
109 // The size of vector V[] is `numRUEntries'.
110 unsigned numRUEntries;
112 resourceId_t resourceId;
118 struct InstrRUsageDelta {
119 MachineOpCode opCode;
120 resourceId_t resourceId;
125 // Specify instruction issue restrictions for individual instructions
126 // that differ from the common rules for the class.
128 struct InstrIssueDelta {
129 MachineOpCode opCode;
139 // Issue restrictions for this instruction
144 // Feasible slots to use for this instruction.
145 std::vector<bool> feasibleSlots;
147 // Resource usages for this instruction, with one resource vector per cycle.
149 std::vector<std::vector<resourceId_t> > resourcesByCycle;
152 // Conveniences for initializing this structure
153 void setTo(const InstrClassRUsage& classRU);
155 void addIssueDelta(const InstrIssueDelta& delta) {
157 isSingleIssue = delta.isSingleIssue;
158 breaksGroup = delta.breaksGroup;
159 numBubbles = delta.numBubbles;
162 void addUsageDelta (const InstrRUsageDelta& delta);
163 void setMaxSlots (int maxNumSlots) {
164 feasibleSlots.resize(maxNumSlots);
167 friend class TargetSchedInfo; // give access to these functions
171 //---------------------------------------------------------------------------
172 /// TargetSchedInfo - Common interface to machine information for
173 /// instruction scheduling
175 struct TargetSchedInfo {
176 const TargetMachine& target;
178 unsigned maxNumIssueTotal;
179 int longestIssueConflict;
181 int branchMispredictPenalty; // 4 for SPARC IIi
182 int branchTargetUnknownPenalty; // 2 for SPARC IIi
183 int l1DCacheMissPenalty; // 7 or 9 for SPARC IIi
184 int l1ICacheMissPenalty; // ? for SPARC IIi
186 bool inOrderLoads; // true for SPARC IIi
187 bool inOrderIssue; // true for SPARC IIi
188 bool inOrderExec; // false for most architectures
189 bool inOrderRetire; // true for most architectures
192 inline const InstrRUsage& getInstrRUsage(MachineOpCode opCode) const {
193 assert(opCode >= 0 && opCode < (int) instrRUsages.size());
194 return instrRUsages[opCode];
196 const InstrClassRUsage& getClassRUsage(const InstrSchedClass& sc) const {
197 assert(sc < numSchedClasses);
198 return classRUsages[sc];
202 TargetSchedInfo(const TargetSchedInfo &); // DO NOT IMPLEMENT
203 void operator=(const TargetSchedInfo &); // DO NOT IMPLEMENT
205 /*ctor*/ TargetSchedInfo (const TargetMachine& tgt,
206 int _numSchedClasses,
207 const InstrClassRUsage* _classRUsages,
208 const InstrRUsageDelta* _usageDeltas,
209 const InstrIssueDelta* _issueDeltas,
210 unsigned _numUsageDeltas,
211 unsigned _numIssueDeltas);
212 /*dtor*/ virtual ~TargetSchedInfo() {}
214 inline const TargetInstrInfo& getInstrInfo() const {
218 inline int getNumSchedClasses() const {
219 return numSchedClasses;
222 inline unsigned getMaxNumIssueTotal() const {
223 return maxNumIssueTotal;
226 inline unsigned getMaxIssueForClass(const InstrSchedClass& sc) const {
227 assert(sc < numSchedClasses);
228 return classRUsages[sc].maxNumIssue;
231 inline InstrSchedClass getSchedClass (MachineOpCode opCode) const {
232 return getInstrInfo().getSchedClass(opCode);
235 inline bool instrCanUseSlot (MachineOpCode opCode,
237 assert(s < getInstrRUsage(opCode).feasibleSlots.size() && "Invalid slot!");
238 return getInstrRUsage(opCode).feasibleSlots[s];
241 inline int getLongestIssueConflict () const {
242 return longestIssueConflict;
245 inline int getMinIssueGap (MachineOpCode fromOp,
246 MachineOpCode toOp) const {
247 assert(fromOp < (int) issueGaps.size());
248 const std::vector<int>& toGaps = issueGaps[fromOp];
249 return (toOp < (int) toGaps.size())? toGaps[toOp] : 0;
252 inline const std::vector<MachineOpCode>&
253 getConflictList(MachineOpCode opCode) const {
254 assert(opCode < (int) conflictLists.size());
255 return conflictLists[opCode];
258 inline bool isSingleIssue (MachineOpCode opCode) const {
259 return getInstrRUsage(opCode).isSingleIssue;
262 inline bool breaksIssueGroup (MachineOpCode opCode) const {
263 return getInstrRUsage(opCode).breaksGroup;
266 inline unsigned numBubblesAfter (MachineOpCode opCode) const {
267 return getInstrRUsage(opCode).numBubbles;
271 virtual void initializeResources ();
274 void computeInstrResources(const std::vector<InstrRUsage>& instrRUForClasses);
275 void computeIssueGaps(const std::vector<InstrRUsage>& instrRUForClasses);
277 void setGap(int gap, MachineOpCode fromOp, MachineOpCode toOp) {
278 std::vector<int>& toGaps = issueGaps[fromOp];
279 if (toOp >= (int) toGaps.size())
280 toGaps.resize(toOp+1);
285 unsigned numSchedClasses;
286 const TargetInstrInfo* mii;
287 const InstrClassRUsage* classRUsages; // raw array by sclass
288 const InstrRUsageDelta* usageDeltas; // raw array [1:numUsageDeltas]
289 const InstrIssueDelta* issueDeltas; // raw array [1:numIssueDeltas]
290 unsigned numUsageDeltas;
291 unsigned numIssueDeltas;
293 std::vector<InstrRUsage> instrRUsages; // indexed by opcode
294 std::vector<std::vector<int> > issueGaps; // indexed by [opcode1][opcode2]
295 std::vector<std::vector<MachineOpCode> >
296 conflictLists; // indexed by [opcode]