1 //===- Target/TargetSchedInfo.h - Target Instruction Sched Info -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the target machine to the instruction scheduler.
12 // NOTE: This file is currently sparc V9 specific.
14 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_TARGET_TARGETSCHEDINFO_H
17 #define LLVM_TARGET_TARGETSCHEDINFO_H
19 #include "llvm/Target/TargetInstrInfo.h"
20 #include "llvm/ADT/hash_map"
25 typedef long long cycles_t;
26 static const cycles_t HUGE_LATENCY = ~((long long) 1 << (sizeof(cycles_t)-2));
27 static const cycles_t INVALID_LATENCY = -HUGE_LATENCY;
28 static const unsigned MAX_OPCODE_SIZE = 16;
32 long val; // make long by concatenating two opcodes
33 OpCodePair(MachineOpCode op1, MachineOpCode op2)
34 : val((op1 < 0 || op2 < 0)?
35 -1 : (long)((((unsigned) op1) << MAX_OPCODE_SIZE) | (unsigned) op2)) {}
36 bool operator==(const OpCodePair& op) const {
40 OpCodePair(); // disable for now
43 } // End llvm namespace
45 namespace HASH_NAMESPACE {
46 template <> struct hash<llvm::OpCodePair> {
47 size_t operator()(const llvm::OpCodePair& pair) const {
48 return hash<long>()(pair.val);
51 } // End HASH_NAMESPACE (a macro) namespace
55 //---------------------------------------------------------------------------
56 // class MachineResource
60 // Representation of a single machine resource used in specifying
61 // resource usages of machine instructions for scheduling.
62 //---------------------------------------------------------------------------
65 typedef unsigned resourceId_t;
68 const std::string rname;
70 int maxNumUsers; // MAXINT if no restriction
72 CPUResource(const std::string& resourceName, int maxUsers);
73 static CPUResource* getCPUResource(resourceId_t id);
75 static resourceId_t nextId;
79 //---------------------------------------------------------------------------
80 // struct InstrClassRUsage
81 // struct InstrRUsageDelta
82 // struct InstrIssueDelta
86 // The first three are structures used to specify machine resource
87 // usages for each instruction in a machine description file:
88 // InstrClassRUsage : resource usages common to all instrs. in a class
89 // InstrRUsageDelta : add/delete resource usage for individual instrs.
90 // InstrIssueDelta : add/delete instr. issue info for individual instrs
92 // The last one (InstrRUsage) is the internal representation of
93 // instruction resource usage constructed from the above three.
94 //---------------------------------------------------------------------------
96 const int MAX_NUM_SLOTS = 32;
97 const int MAX_NUM_CYCLES = 32;
99 struct InstrClassRUsage {
100 InstrSchedClass schedClass;
103 // Issue restrictions common to instructions in this class
104 unsigned maxNumIssue;
109 // Feasible slots to use for instructions in this class.
110 // The size of vector S[] is `numSlots'.
112 unsigned feasibleSlots[MAX_NUM_SLOTS];
114 // Resource usages common to instructions in this class.
115 // The size of vector V[] is `numRUEntries'.
116 unsigned numRUEntries;
118 resourceId_t resourceId;
124 struct InstrRUsageDelta {
125 MachineOpCode opCode;
126 resourceId_t resourceId;
131 // Specify instruction issue restrictions for individual instructions
132 // that differ from the common rules for the class.
134 struct InstrIssueDelta {
135 MachineOpCode opCode;
145 // Issue restrictions for this instruction
150 // Feasible slots to use for this instruction.
151 std::vector<bool> feasibleSlots;
153 // Resource usages for this instruction, with one resource vector per cycle.
155 std::vector<std::vector<resourceId_t> > resourcesByCycle;
158 // Conveniences for initializing this structure
159 void setTo(const InstrClassRUsage& classRU);
161 void addIssueDelta(const InstrIssueDelta& delta) {
163 isSingleIssue = delta.isSingleIssue;
164 breaksGroup = delta.breaksGroup;
165 numBubbles = delta.numBubbles;
168 void addUsageDelta (const InstrRUsageDelta& delta);
169 void setMaxSlots (int maxNumSlots) {
170 feasibleSlots.resize(maxNumSlots);
173 friend class TargetSchedInfo; // give access to these functions
177 //---------------------------------------------------------------------------
178 /// TargetSchedInfo - Common interface to machine information for
179 /// instruction scheduling
181 struct TargetSchedInfo {
182 const TargetMachine& target;
184 unsigned maxNumIssueTotal;
185 int longestIssueConflict;
188 inline const InstrRUsage& getInstrRUsage(MachineOpCode opCode) const {
189 assert(opCode >= 0 && opCode < (int) instrRUsages.size());
190 return instrRUsages[opCode];
192 const InstrClassRUsage& getClassRUsage(const InstrSchedClass& sc) const {
193 assert(sc < numSchedClasses);
194 return classRUsages[sc];
198 TargetSchedInfo(const TargetSchedInfo &); // DO NOT IMPLEMENT
199 void operator=(const TargetSchedInfo &); // DO NOT IMPLEMENT
201 /*ctor*/ TargetSchedInfo (const TargetMachine& tgt,
202 int _numSchedClasses,
203 const InstrClassRUsage* _classRUsages,
204 const InstrRUsageDelta* _usageDeltas,
205 const InstrIssueDelta* _issueDeltas,
206 unsigned _numUsageDeltas,
207 unsigned _numIssueDeltas);
208 /*dtor*/ virtual ~TargetSchedInfo() {}
210 inline const TargetInstrInfo& getInstrInfo() const {
214 inline int getNumSchedClasses() const {
215 return numSchedClasses;
218 inline unsigned getMaxNumIssueTotal() const {
219 return maxNumIssueTotal;
222 inline unsigned getMaxIssueForClass(const InstrSchedClass& sc) const {
223 assert(sc < numSchedClasses);
224 return classRUsages[sc].maxNumIssue;
227 inline InstrSchedClass getSchedClass (MachineOpCode opCode) const {
228 return getInstrInfo().getSchedClass(opCode);
231 inline bool instrCanUseSlot (MachineOpCode opCode,
233 assert(s < getInstrRUsage(opCode).feasibleSlots.size() && "Invalid slot!");
234 return getInstrRUsage(opCode).feasibleSlots[s];
237 inline int getLongestIssueConflict () const {
238 return longestIssueConflict;
241 inline int getMinIssueGap (MachineOpCode fromOp,
242 MachineOpCode toOp) const {
243 assert(fromOp < (int) issueGaps.size());
244 const std::vector<int>& toGaps = issueGaps[fromOp];
245 return (toOp < (int) toGaps.size())? toGaps[toOp] : 0;
248 inline const std::vector<MachineOpCode>&
249 getConflictList(MachineOpCode opCode) const {
250 assert(opCode < (int) conflictLists.size());
251 return conflictLists[opCode];
254 inline bool isSingleIssue (MachineOpCode opCode) const {
255 return getInstrRUsage(opCode).isSingleIssue;
258 inline bool breaksIssueGroup (MachineOpCode opCode) const {
259 return getInstrRUsage(opCode).breaksGroup;
262 inline unsigned numBubblesAfter (MachineOpCode opCode) const {
263 return getInstrRUsage(opCode).numBubbles;
266 inline unsigned getCPUResourceNum(int rd)const{
267 for(unsigned i=0;i<resourceNumVector.size();i++){
268 if(resourceNumVector[i].first == rd) return resourceNumVector[i].second;
270 assert( 0&&"resource not found");
276 virtual void initializeResources ();
279 void computeInstrResources(const std::vector<InstrRUsage>& instrRUForClasses);
280 void computeIssueGaps(const std::vector<InstrRUsage>& instrRUForClasses);
282 void setGap(int gap, MachineOpCode fromOp, MachineOpCode toOp) {
283 std::vector<int>& toGaps = issueGaps[fromOp];
284 if (toOp >= (int) toGaps.size())
285 toGaps.resize(toOp+1);
290 std::vector<std::pair<int,int> > resourceNumVector;
293 unsigned numSchedClasses;
294 const TargetInstrInfo* mii;
295 const InstrClassRUsage* classRUsages; // raw array by sclass
296 const InstrRUsageDelta* usageDeltas; // raw array [1:numUsageDeltas]
297 const InstrIssueDelta* issueDeltas; // raw array [1:numIssueDeltas]
298 unsigned numUsageDeltas;
299 unsigned numIssueDeltas;
301 std::vector<InstrRUsage> instrRUsages; // indexed by opcode
302 std::vector<std::vector<int> > issueGaps; // indexed by [opcode1][opcode2]
303 std::vector<std::vector<MachineOpCode> >
304 conflictLists; // indexed by [opcode]
307 friend class ModuloSchedulingPass;
308 friend class MSSchedule;
312 } // End llvm namespace