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 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_TARGET_TARGETSCHEDINFO_H
15 #define LLVM_TARGET_TARGETSCHEDINFO_H
17 #include "llvm/Target/TargetInstrInfo.h"
18 #include "Support/hash_map"
23 typedef long long cycles_t;
24 static const cycles_t HUGE_LATENCY = ~((long long) 1 << (sizeof(cycles_t)-2));
25 static const cycles_t INVALID_LATENCY = -HUGE_LATENCY;
26 static const unsigned MAX_OPCODE_SIZE = 16;
30 long val; // make long by concatenating two opcodes
31 OpCodePair(MachineOpCode op1, MachineOpCode op2)
32 : val((op1 < 0 || op2 < 0)?
33 -1 : (long)((((unsigned) op1) << MAX_OPCODE_SIZE) | (unsigned) op2)) {}
34 bool operator==(const OpCodePair& op) const {
38 OpCodePair(); // disable for now
41 } // End llvm namespace
43 namespace HASH_NAMESPACE {
44 template <> struct hash<llvm::OpCodePair> {
45 size_t operator()(const llvm::OpCodePair& pair) const {
46 return hash<long>()(pair.val);
49 } // End HASH_NAMESPACE (a macro) namespace
53 //---------------------------------------------------------------------------
54 // class MachineResource
58 // Representation of a single machine resource used in specifying
59 // resource usages of machine instructions for scheduling.
60 //---------------------------------------------------------------------------
63 typedef unsigned resourceId_t;
66 const std::string rname;
68 int maxNumUsers; // MAXINT if no restriction
70 CPUResource(const std::string& resourceName, int maxUsers);
73 static resourceId_t nextId;
77 //---------------------------------------------------------------------------
78 // struct InstrClassRUsage
79 // struct InstrRUsageDelta
80 // struct InstrIssueDelta
84 // The first three are structures used to specify machine resource
85 // usages for each instruction in a machine description file:
86 // InstrClassRUsage : resource usages common to all instrs. in a class
87 // InstrRUsageDelta : add/delete resource usage for individual instrs.
88 // InstrIssueDelta : add/delete instr. issue info for individual instrs
90 // The last one (InstrRUsage) is the internal representation of
91 // instruction resource usage constructed from the above three.
92 //---------------------------------------------------------------------------
94 const int MAX_NUM_SLOTS = 32;
95 const int MAX_NUM_CYCLES = 32;
97 struct InstrClassRUsage {
98 InstrSchedClass schedClass;
101 // Issue restrictions common to instructions in this class
102 unsigned maxNumIssue;
107 // Feasible slots to use for instructions in this class.
108 // The size of vector S[] is `numSlots'.
110 unsigned feasibleSlots[MAX_NUM_SLOTS];
112 // Resource usages common to instructions in this class.
113 // The size of vector V[] is `numRUEntries'.
114 unsigned numRUEntries;
116 resourceId_t resourceId;
122 struct InstrRUsageDelta {
123 MachineOpCode opCode;
124 resourceId_t resourceId;
129 // Specify instruction issue restrictions for individual instructions
130 // that differ from the common rules for the class.
132 struct InstrIssueDelta {
133 MachineOpCode opCode;
143 // Issue restrictions for this instruction
148 // Feasible slots to use for this instruction.
149 std::vector<bool> feasibleSlots;
151 // Resource usages for this instruction, with one resource vector per cycle.
153 std::vector<std::vector<resourceId_t> > resourcesByCycle;
156 // Conveniences for initializing this structure
157 void setTo(const InstrClassRUsage& classRU);
159 void addIssueDelta(const InstrIssueDelta& delta) {
161 isSingleIssue = delta.isSingleIssue;
162 breaksGroup = delta.breaksGroup;
163 numBubbles = delta.numBubbles;
166 void addUsageDelta (const InstrRUsageDelta& delta);
167 void setMaxSlots (int maxNumSlots) {
168 feasibleSlots.resize(maxNumSlots);
171 friend class TargetSchedInfo; // give access to these functions
175 //---------------------------------------------------------------------------
176 /// TargetSchedInfo - Common interface to machine information for
177 /// instruction scheduling
179 struct TargetSchedInfo {
180 const TargetMachine& target;
182 unsigned maxNumIssueTotal;
183 int longestIssueConflict;
186 inline const InstrRUsage& getInstrRUsage(MachineOpCode opCode) const {
187 assert(opCode >= 0 && opCode < (int) instrRUsages.size());
188 return instrRUsages[opCode];
190 const InstrClassRUsage& getClassRUsage(const InstrSchedClass& sc) const {
191 assert(sc < numSchedClasses);
192 return classRUsages[sc];
196 TargetSchedInfo(const TargetSchedInfo &); // DO NOT IMPLEMENT
197 void operator=(const TargetSchedInfo &); // DO NOT IMPLEMENT
199 /*ctor*/ TargetSchedInfo (const TargetMachine& tgt,
200 int _numSchedClasses,
201 const InstrClassRUsage* _classRUsages,
202 const InstrRUsageDelta* _usageDeltas,
203 const InstrIssueDelta* _issueDeltas,
204 unsigned _numUsageDeltas,
205 unsigned _numIssueDeltas);
206 /*dtor*/ virtual ~TargetSchedInfo() {}
208 inline const TargetInstrInfo& getInstrInfo() const {
212 inline int getNumSchedClasses() const {
213 return numSchedClasses;
216 inline unsigned getMaxNumIssueTotal() const {
217 return maxNumIssueTotal;
220 inline unsigned getMaxIssueForClass(const InstrSchedClass& sc) const {
221 assert(sc < numSchedClasses);
222 return classRUsages[sc].maxNumIssue;
225 inline InstrSchedClass getSchedClass (MachineOpCode opCode) const {
226 return getInstrInfo().getSchedClass(opCode);
229 inline bool instrCanUseSlot (MachineOpCode opCode,
231 assert(s < getInstrRUsage(opCode).feasibleSlots.size() && "Invalid slot!");
232 return getInstrRUsage(opCode).feasibleSlots[s];
235 inline int getLongestIssueConflict () const {
236 return longestIssueConflict;
239 inline int getMinIssueGap (MachineOpCode fromOp,
240 MachineOpCode toOp) const {
241 assert(fromOp < (int) issueGaps.size());
242 const std::vector<int>& toGaps = issueGaps[fromOp];
243 return (toOp < (int) toGaps.size())? toGaps[toOp] : 0;
246 inline const std::vector<MachineOpCode>&
247 getConflictList(MachineOpCode opCode) const {
248 assert(opCode < (int) conflictLists.size());
249 return conflictLists[opCode];
252 inline bool isSingleIssue (MachineOpCode opCode) const {
253 return getInstrRUsage(opCode).isSingleIssue;
256 inline bool breaksIssueGroup (MachineOpCode opCode) const {
257 return getInstrRUsage(opCode).breaksGroup;
260 inline unsigned numBubblesAfter (MachineOpCode opCode) const {
261 return getInstrRUsage(opCode).numBubbles;
264 inline unsigned getCPUResourceNum(int rd)const{
265 for(unsigned i=0;i<resourceNumVector.size();i++){
266 if(resourceNumVector[i].first == rd) return resourceNumVector[i].second;
268 assert( 0&&"resource not found");
274 virtual void initializeResources ();
277 void computeInstrResources(const std::vector<InstrRUsage>& instrRUForClasses);
278 void computeIssueGaps(const std::vector<InstrRUsage>& instrRUForClasses);
280 void setGap(int gap, MachineOpCode fromOp, MachineOpCode toOp) {
281 std::vector<int>& toGaps = issueGaps[fromOp];
282 if (toOp >= (int) toGaps.size())
283 toGaps.resize(toOp+1);
288 std::vector<std::pair<int,int> > resourceNumVector;
291 unsigned numSchedClasses;
292 const TargetInstrInfo* mii;
293 const InstrClassRUsage* classRUsages; // raw array by sclass
294 const InstrRUsageDelta* usageDeltas; // raw array [1:numUsageDeltas]
295 const InstrIssueDelta* issueDeltas; // raw array [1:numIssueDeltas]
296 unsigned numUsageDeltas;
297 unsigned numIssueDeltas;
299 std::vector<InstrRUsage> instrRUsages; // indexed by opcode
300 std::vector<std::vector<int> > issueGaps; // indexed by [opcode1][opcode2]
301 std::vector<std::vector<MachineOpCode> >
302 conflictLists; // indexed by [opcode]
305 friend class ModuloSchedGraph;
306 friend class ModuloSchedulingPass;
310 } // End llvm namespace