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 class TargetSchedInfo {
157 const TargetMachine& target;
159 unsigned maxNumIssueTotal;
160 int longestIssueConflict;
163 inline const InstrRUsage& getInstrRUsage(MachineOpCode opCode) const {
164 assert(opCode >= 0 && opCode < (int) instrRUsages.size());
165 return instrRUsages[opCode];
167 const InstrClassRUsage& getClassRUsage(const InstrSchedClass& sc) const {
168 assert(sc < numSchedClasses);
169 return classRUsages[sc];
173 TargetSchedInfo(const TargetSchedInfo &); // DO NOT IMPLEMENT
174 void operator=(const TargetSchedInfo &); // DO NOT IMPLEMENT
176 /*ctor*/ TargetSchedInfo (const TargetMachine& tgt,
177 int _numSchedClasses,
178 const InstrClassRUsage* _classRUsages,
179 const InstrRUsageDelta* _usageDeltas,
180 const InstrIssueDelta* _issueDeltas,
181 unsigned _numUsageDeltas,
182 unsigned _numIssueDeltas);
183 /*dtor*/ virtual ~TargetSchedInfo() {}
185 inline const TargetInstrInfo& getInstrInfo() const {
189 inline int getNumSchedClasses() const {
190 return numSchedClasses;
193 inline unsigned getMaxNumIssueTotal() const {
194 return maxNumIssueTotal;
197 inline unsigned getMaxIssueForClass(const InstrSchedClass& sc) const {
198 assert(sc < numSchedClasses);
199 return classRUsages[sc].maxNumIssue;
202 inline InstrSchedClass getSchedClass (MachineOpCode opCode) const {
203 return getInstrInfo().getSchedClass(opCode);
206 inline bool instrCanUseSlot (MachineOpCode opCode,
208 assert(s < getInstrRUsage(opCode).feasibleSlots.size() && "Invalid slot!");
209 return getInstrRUsage(opCode).feasibleSlots[s];
212 inline int getLongestIssueConflict () const {
213 return longestIssueConflict;
216 inline int getMinIssueGap (MachineOpCode fromOp,
217 MachineOpCode toOp) const {
218 assert(fromOp < (int) issueGaps.size());
219 const std::vector<int>& toGaps = issueGaps[fromOp];
220 return (toOp < (int) toGaps.size())? toGaps[toOp] : 0;
223 inline const std::vector<MachineOpCode>&
224 getConflictList(MachineOpCode opCode) const {
225 assert(opCode < (int) conflictLists.size());
226 return conflictLists[opCode];
229 inline bool isSingleIssue (MachineOpCode opCode) const {
230 return getInstrRUsage(opCode).isSingleIssue;
233 inline bool breaksIssueGroup (MachineOpCode opCode) const {
234 return getInstrRUsage(opCode).breaksGroup;
237 inline unsigned numBubblesAfter (MachineOpCode opCode) const {
238 return getInstrRUsage(opCode).numBubbles;
241 inline unsigned getCPUResourceNum(int rd)const{
242 for(unsigned i=0;i<resourceNumVector.size();i++){
243 if(resourceNumVector[i].first == rd) return resourceNumVector[i].second;
245 assert( 0&&"resource not found");
251 virtual void initializeResources ();
254 void computeInstrResources(const std::vector<InstrRUsage>& instrRUForClasses);
255 void computeIssueGaps(const std::vector<InstrRUsage>& instrRUForClasses);
257 void setGap(int gap, MachineOpCode fromOp, MachineOpCode toOp) {
258 std::vector<int>& toGaps = issueGaps[fromOp];
259 if (toOp >= (int) toGaps.size())
260 toGaps.resize(toOp+1);
265 std::vector<std::pair<int,int> > resourceNumVector;
268 unsigned numSchedClasses;
269 const TargetInstrInfo* mii;
270 const InstrClassRUsage* classRUsages; // raw array by sclass
271 const InstrRUsageDelta* usageDeltas; // raw array [1:numUsageDeltas]
272 const InstrIssueDelta* issueDeltas; // raw array [1:numIssueDeltas]
273 unsigned numUsageDeltas;
274 unsigned numIssueDeltas;
276 std::vector<InstrRUsage> instrRUsages; // indexed by opcode
277 std::vector<std::vector<int> > issueGaps; // indexed by [opcode1][opcode2]
278 std::vector<std::vector<MachineOpCode> >
279 conflictLists; // indexed by [opcode]
282 friend class ModuloSchedulingPass;
283 friend class MSSchedule;
287 } // End llvm namespace