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;
29 //---------------------------------------------------------------------------
30 // class MachineResource
34 // Representation of a single machine resource used in specifying
35 // resource usages of machine instructions for scheduling.
36 //---------------------------------------------------------------------------
39 typedef unsigned resourceId_t;
42 const std::string rname;
44 int maxNumUsers; // MAXINT if no restriction
46 CPUResource(const std::string& resourceName, int maxUsers);
47 static CPUResource* getCPUResource(resourceId_t id);
49 static resourceId_t nextId;
53 //---------------------------------------------------------------------------
54 // struct InstrClassRUsage
55 // struct InstrRUsageDelta
56 // struct InstrIssueDelta
60 // The first three are structures used to specify machine resource
61 // usages for each instruction in a machine description file:
62 // InstrClassRUsage : resource usages common to all instrs. in a class
63 // InstrRUsageDelta : add/delete resource usage for individual instrs.
64 // InstrIssueDelta : add/delete instr. issue info for individual instrs
66 // The last one (InstrRUsage) is the internal representation of
67 // instruction resource usage constructed from the above three.
68 //---------------------------------------------------------------------------
70 const int MAX_NUM_SLOTS = 32;
71 const int MAX_NUM_CYCLES = 32;
73 struct InstrClassRUsage {
74 InstrSchedClass schedClass;
77 // Issue restrictions common to instructions in this class
83 // Feasible slots to use for instructions in this class.
84 // The size of vector S[] is `numSlots'.
86 unsigned feasibleSlots[MAX_NUM_SLOTS];
88 // Resource usages common to instructions in this class.
89 // The size of vector V[] is `numRUEntries'.
90 unsigned numRUEntries;
92 resourceId_t resourceId;
98 struct InstrRUsageDelta {
100 resourceId_t resourceId;
105 // Specify instruction issue restrictions for individual instructions
106 // that differ from the common rules for the class.
108 struct InstrIssueDelta {
109 MachineOpCode opCode;
119 // Issue restrictions for this instruction
124 // Feasible slots to use for this instruction.
125 std::vector<bool> feasibleSlots;
127 // Resource usages for this instruction, with one resource vector per cycle.
129 std::vector<std::vector<resourceId_t> > resourcesByCycle;
132 // Conveniences for initializing this structure
133 void setTo(const InstrClassRUsage& classRU);
135 void addIssueDelta(const InstrIssueDelta& delta) {
137 isSingleIssue = delta.isSingleIssue;
138 breaksGroup = delta.breaksGroup;
139 numBubbles = delta.numBubbles;
142 void addUsageDelta (const InstrRUsageDelta& delta);
143 void setMaxSlots (int maxNumSlots) {
144 feasibleSlots.resize(maxNumSlots);
147 friend class TargetSchedInfo; // give access to these functions
151 //---------------------------------------------------------------------------
152 /// TargetSchedInfo - Common interface to machine information for
153 /// instruction scheduling
155 struct TargetSchedInfo {
156 const TargetMachine& target;
158 unsigned maxNumIssueTotal;
159 int longestIssueConflict;
162 inline const InstrRUsage& getInstrRUsage(MachineOpCode opCode) const {
163 assert(opCode >= 0 && opCode < (int) instrRUsages.size());
164 return instrRUsages[opCode];
166 const InstrClassRUsage& getClassRUsage(const InstrSchedClass& sc) const {
167 assert(sc < numSchedClasses);
168 return classRUsages[sc];
172 TargetSchedInfo(const TargetSchedInfo &); // DO NOT IMPLEMENT
173 void operator=(const TargetSchedInfo &); // DO NOT IMPLEMENT
175 /*ctor*/ TargetSchedInfo (const TargetMachine& tgt,
176 int _numSchedClasses,
177 const InstrClassRUsage* _classRUsages,
178 const InstrRUsageDelta* _usageDeltas,
179 const InstrIssueDelta* _issueDeltas,
180 unsigned _numUsageDeltas,
181 unsigned _numIssueDeltas);
182 /*dtor*/ virtual ~TargetSchedInfo() {}
184 inline const TargetInstrInfo& getInstrInfo() const {
188 inline int getNumSchedClasses() const {
189 return numSchedClasses;
192 inline unsigned getMaxNumIssueTotal() const {
193 return maxNumIssueTotal;
196 inline unsigned getMaxIssueForClass(const InstrSchedClass& sc) const {
197 assert(sc < numSchedClasses);
198 return classRUsages[sc].maxNumIssue;
201 inline InstrSchedClass getSchedClass (MachineOpCode opCode) const {
202 return getInstrInfo().getSchedClass(opCode);
205 inline bool instrCanUseSlot (MachineOpCode opCode,
207 assert(s < getInstrRUsage(opCode).feasibleSlots.size() && "Invalid slot!");
208 return getInstrRUsage(opCode).feasibleSlots[s];
211 inline int getLongestIssueConflict () const {
212 return longestIssueConflict;
215 inline int getMinIssueGap (MachineOpCode fromOp,
216 MachineOpCode toOp) const {
217 assert(fromOp < (int) issueGaps.size());
218 const std::vector<int>& toGaps = issueGaps[fromOp];
219 return (toOp < (int) toGaps.size())? toGaps[toOp] : 0;
222 inline const std::vector<MachineOpCode>&
223 getConflictList(MachineOpCode opCode) const {
224 assert(opCode < (int) conflictLists.size());
225 return conflictLists[opCode];
228 inline bool isSingleIssue (MachineOpCode opCode) const {
229 return getInstrRUsage(opCode).isSingleIssue;
232 inline bool breaksIssueGroup (MachineOpCode opCode) const {
233 return getInstrRUsage(opCode).breaksGroup;
236 inline unsigned numBubblesAfter (MachineOpCode opCode) const {
237 return getInstrRUsage(opCode).numBubbles;
240 inline unsigned getCPUResourceNum(int rd)const{
241 for(unsigned i=0;i<resourceNumVector.size();i++){
242 if(resourceNumVector[i].first == rd) return resourceNumVector[i].second;
244 assert( 0&&"resource not found");
250 virtual void initializeResources ();
253 void computeInstrResources(const std::vector<InstrRUsage>& instrRUForClasses);
254 void computeIssueGaps(const std::vector<InstrRUsage>& instrRUForClasses);
256 void setGap(int gap, MachineOpCode fromOp, MachineOpCode toOp) {
257 std::vector<int>& toGaps = issueGaps[fromOp];
258 if (toOp >= (int) toGaps.size())
259 toGaps.resize(toOp+1);
264 std::vector<std::pair<int,int> > resourceNumVector;
267 unsigned numSchedClasses;
268 const TargetInstrInfo* mii;
269 const InstrClassRUsage* classRUsages; // raw array by sclass
270 const InstrRUsageDelta* usageDeltas; // raw array [1:numUsageDeltas]
271 const InstrIssueDelta* issueDeltas; // raw array [1:numIssueDeltas]
272 unsigned numUsageDeltas;
273 unsigned numIssueDeltas;
275 std::vector<InstrRUsage> instrRUsages; // indexed by opcode
276 std::vector<std::vector<int> > issueGaps; // indexed by [opcode1][opcode2]
277 std::vector<std::vector<MachineOpCode> >
278 conflictLists; // indexed by [opcode]
281 friend class ModuloSchedulingPass;
282 friend class MSSchedule;
286 } // End llvm namespace