1. Remove ranges from itinerary data.
[oota-llvm.git] / include / llvm / Target / TargetSchedInfo.h
1 //===- Target/TargetSchedInfo.h - Target Instruction Sched Info -*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
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.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the target machine to the instruction scheduler.
11 //
12 // NOTE: This file is currently sparc V9 specific.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_TARGET_TARGETSCHEDINFO_H
17 #define LLVM_TARGET_TARGETSCHEDINFO_H
18
19 #include "llvm/Target/TargetInstrInfo.h"
20 #include "llvm/ADT/hash_map"
21 #include <string>
22
23 namespace llvm {
24
25 typedef long long CycleCount_t;
26 static const CycleCount_t HUGE_LATENCY = ~((long long) 1 << (sizeof(CycleCount_t)-2));
27 static const CycleCount_t INVALID_LATENCY = -HUGE_LATENCY;
28
29 //---------------------------------------------------------------------------
30 // class MachineResource
31 // class CPUResource
32 //
33 // Purpose:
34 //   Representation of a single machine resource used in specifying
35 //   resource usages of machine instructions for scheduling.
36 //---------------------------------------------------------------------------
37
38
39 typedef unsigned resourceId_t;
40
41 struct CPUResource {
42   const std::string rname;
43   resourceId_t rid;
44   int maxNumUsers;   // MAXINT if no restriction
45
46   CPUResource(const std::string& resourceName, int maxUsers);
47   static CPUResource* getCPUResource(resourceId_t id);
48 private:
49   static resourceId_t nextId;
50 };
51
52
53 //---------------------------------------------------------------------------
54 // struct InstrClassRUsage
55 // struct InstrRUsageDelta
56 // struct InstrIssueDelta
57 // struct InstrRUsage
58 //
59 // Purpose:
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
65 //
66 //   The last one (InstrRUsage) is the internal representation of
67 //   instruction resource usage constructed from the above three.
68 //---------------------------------------------------------------------------
69
70 const int MAX_NUM_SLOTS  = 32;
71 const int MAX_NUM_CYCLES = 32;
72
73 struct InstrClassRUsage {
74   InstrSchedClass schedClass;
75   int             totCycles;
76
77   // Issue restrictions common to instructions in this class
78   unsigned      maxNumIssue;
79   bool          isSingleIssue;
80   bool          breaksGroup;
81   CycleCount_t  numBubbles;
82
83   // Feasible slots to use for instructions in this class.
84   // The size of vector S[] is `numSlots'.
85   unsigned      numSlots;
86   unsigned      feasibleSlots[MAX_NUM_SLOTS];
87
88   // Resource usages common to instructions in this class.
89   // The size of vector V[] is `numRUEntries'.
90   unsigned      numRUEntries;
91   struct {
92     resourceId_t resourceId;
93     unsigned    startCycle;
94     int         numCycles;
95   } V[MAX_NUM_CYCLES];
96 };
97
98 struct InstrRUsageDelta {
99   MachineOpCode opCode;
100   resourceId_t  resourceId;
101   unsigned      startCycle;
102   int  numCycles;
103 };
104
105 // Specify instruction issue restrictions for individual instructions
106 // that differ from the common rules for the class.
107 //
108 struct InstrIssueDelta {
109   MachineOpCode opCode;
110   bool isSingleIssue;
111   bool breaksGroup;
112   CycleCount_t numBubbles;
113 };
114
115
116 struct InstrRUsage {
117   bool  sameAsClass;
118
119   // Issue restrictions for this instruction
120   bool  isSingleIssue;
121   bool  breaksGroup;
122   CycleCount_t numBubbles;
123
124   // Feasible slots to use for this instruction.
125   std::vector<bool> feasibleSlots;
126
127   // Resource usages for this instruction, with one resource vector per cycle.
128   CycleCount_t numCycles;
129   std::vector<std::vector<resourceId_t> > resourcesByCycle;
130
131 private:
132   // Conveniences for initializing this structure
133   void setTo(const InstrClassRUsage& classRU);
134
135   void addIssueDelta(const InstrIssueDelta& delta) {
136     sameAsClass = false;
137     isSingleIssue = delta.isSingleIssue;
138     breaksGroup = delta.breaksGroup;
139     numBubbles = delta.numBubbles;
140   }
141
142   void addUsageDelta(const InstrRUsageDelta& delta);
143   void setMaxSlots(int maxNumSlots) {
144     feasibleSlots.resize(maxNumSlots);
145   }
146
147   friend class TargetSchedInfo; // give access to these functions
148 };
149
150
151 //---------------------------------------------------------------------------
152 /// TargetSchedInfo - Common interface to machine information for
153 /// instruction scheduling
154 ///
155 class TargetSchedInfo {
156 public:
157   const TargetMachine& target;
158
159   unsigned maxNumIssueTotal;
160   int longestIssueConflict;
161
162 protected:
163   inline const InstrRUsage& getInstrRUsage(MachineOpCode opCode) const {
164     assert(opCode >= 0 && opCode < (int) instrRUsages.size());
165     return instrRUsages[opCode];
166   }
167   const InstrClassRUsage& getClassRUsage(const InstrSchedClass& sc) const {
168     assert(sc < numSchedClasses);
169     return classRUsages[sc];
170   }
171
172 private:
173   TargetSchedInfo(const TargetSchedInfo &);  // DO NOT IMPLEMENT
174   void operator=(const TargetSchedInfo &);  // DO NOT IMPLEMENT
175 public:
176   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   virtual ~TargetSchedInfo() {}
184
185   inline const TargetInstrInfo& getInstrInfo() const {
186     return *mii;
187   }
188
189   inline int getNumSchedClasses()  const {
190     return numSchedClasses;
191   }
192
193   inline  unsigned getMaxNumIssueTotal() const {
194     return maxNumIssueTotal;
195   }
196
197   inline  unsigned getMaxIssueForClass(const InstrSchedClass& sc) const {
198     assert(sc < numSchedClasses);
199     return classRUsages[sc].maxNumIssue;
200   }
201
202   inline InstrSchedClass getSchedClass(MachineOpCode opCode) const {
203     return getInstrInfo().getSchedClass(opCode);
204   }
205
206   inline  bool instrCanUseSlot(MachineOpCode opCode,
207                                unsigned s) const {
208     assert(s < getInstrRUsage(opCode).feasibleSlots.size() && "Invalid slot!");
209     return getInstrRUsage(opCode).feasibleSlots[s];
210   }
211
212   inline int getLongestIssueConflict() const {
213     return longestIssueConflict;
214   }
215
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;
221   }
222
223   inline const std::vector<MachineOpCode>&
224     getConflictList(MachineOpCode opCode) const {
225     assert(opCode < (int) conflictLists.size());
226     return conflictLists[opCode];
227   }
228
229   inline  bool isSingleIssue(MachineOpCode opCode) const {
230     return getInstrRUsage(opCode).isSingleIssue;
231   }
232
233   inline  bool breaksIssueGroup(MachineOpCode opCode) const {
234     return getInstrRUsage(opCode).breaksGroup;
235   }
236
237   inline  unsigned numBubblesAfter(MachineOpCode opCode) const {
238     return getInstrRUsage(opCode).numBubbles;
239   }
240
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;
244     }
245     assert( 0&&"resource not found");
246     return 0;
247   }
248
249
250 protected:
251   virtual void initializeResources();
252
253 private:
254   void computeInstrResources(const std::vector<InstrRUsage>& instrRUForClasses);
255   void computeIssueGaps(const std::vector<InstrRUsage>& instrRUForClasses);
256
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);
261     toGaps[toOp] = gap;
262   }
263
264 public:
265   std::vector<std::pair<int,int> > resourceNumVector;
266
267 protected:
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;
275
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]
280
281
282   friend class ModuloSchedulingPass;
283   friend class ModuloSchedulingSBPass;
284   friend class MSSchedule;
285   friend class MSScheduleSB;
286   friend class MSchedGraphSB;
287
288 };
289
290 } // End llvm namespace
291
292 #endif