Fixed friend class name for ModuloScheduling.
[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 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_TARGET_TARGETSCHEDINFO_H
15 #define LLVM_TARGET_TARGETSCHEDINFO_H
16
17 #include "llvm/Target/TargetInstrInfo.h"
18 #include "Support/hash_map"
19 #include <string>
20
21 namespace llvm {
22
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;
27
28 class OpCodePair {
29 public:
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 {
35     return val == op.val;
36   }
37 private:
38   OpCodePair();                 // disable for now
39 };
40
41 } // End llvm namespace
42
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);
47     }
48   };
49 } // End HASH_NAMESPACE (a macro) namespace
50
51 namespace llvm {
52
53 //---------------------------------------------------------------------------
54 // class MachineResource 
55 // class CPUResource
56 // 
57 // Purpose:
58 //   Representation of a single machine resource used in specifying
59 //   resource usages of machine instructions for scheduling.
60 //---------------------------------------------------------------------------
61
62
63 typedef unsigned resourceId_t;
64
65 struct CPUResource {
66   const std::string rname;
67   resourceId_t rid;
68   int maxNumUsers;   // MAXINT if no restriction
69   
70   CPUResource(const std::string& resourceName, int maxUsers);
71
72 private:
73   static resourceId_t nextId;
74 };
75
76
77 //---------------------------------------------------------------------------
78 // struct InstrClassRUsage
79 // struct InstrRUsageDelta 
80 // struct InstrIssueDelta 
81 // struct InstrRUsage 
82 // 
83 // Purpose:
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 
89 //   
90 //   The last one (InstrRUsage) is the internal representation of
91 //   instruction resource usage constructed from the above three.
92 //---------------------------------------------------------------------------
93
94 const int MAX_NUM_SLOTS  = 32;
95 const int MAX_NUM_CYCLES = 32;
96
97 struct InstrClassRUsage {
98   InstrSchedClass schedClass;
99   int           totCycles;
100   
101   // Issue restrictions common to instructions in this class
102   unsigned      maxNumIssue;
103   bool          isSingleIssue;
104   bool          breaksGroup;
105   cycles_t      numBubbles;
106   
107   // Feasible slots to use for instructions in this class.
108   // The size of vector S[] is `numSlots'.
109   unsigned      numSlots;
110   unsigned      feasibleSlots[MAX_NUM_SLOTS];
111   
112   // Resource usages common to instructions in this class.
113   // The size of vector V[] is `numRUEntries'.
114   unsigned      numRUEntries;
115   struct {
116     resourceId_t resourceId;
117     unsigned    startCycle;
118     int         numCycles;
119   } V[MAX_NUM_CYCLES];
120 };
121
122 struct InstrRUsageDelta {
123   MachineOpCode opCode;
124   resourceId_t  resourceId;
125   unsigned      startCycle;
126   int           numCycles;
127 };
128
129 // Specify instruction issue restrictions for individual instructions
130 // that differ from the common rules for the class.
131 // 
132 struct InstrIssueDelta {
133   MachineOpCode opCode;
134   bool          isSingleIssue;
135   bool          breaksGroup;
136   cycles_t      numBubbles;
137 };
138
139
140 struct InstrRUsage {
141   bool          sameAsClass;
142   
143   // Issue restrictions for this instruction
144   bool          isSingleIssue;
145   bool          breaksGroup;
146   cycles_t      numBubbles;
147   
148   // Feasible slots to use for this instruction.
149   std::vector<bool> feasibleSlots;
150   
151   // Resource usages for this instruction, with one resource vector per cycle.
152   cycles_t      numCycles;
153   std::vector<std::vector<resourceId_t> > resourcesByCycle;
154   
155 private:
156   // Conveniences for initializing this structure
157   void setTo(const InstrClassRUsage& classRU);
158
159   void addIssueDelta(const InstrIssueDelta& delta) {
160     sameAsClass = false;
161     isSingleIssue = delta.isSingleIssue;
162     breaksGroup = delta.breaksGroup;
163     numBubbles = delta.numBubbles;
164   }
165
166   void addUsageDelta    (const InstrRUsageDelta& delta);
167   void setMaxSlots      (int maxNumSlots) {
168     feasibleSlots.resize(maxNumSlots);
169   }
170   
171   friend class TargetSchedInfo; // give access to these functions
172 };
173
174
175 //---------------------------------------------------------------------------
176 /// TargetSchedInfo - Common interface to machine information for 
177 /// instruction scheduling
178 ///
179 struct TargetSchedInfo {
180   const TargetMachine& target;
181   
182   unsigned maxNumIssueTotal;
183   int   longestIssueConflict;
184   
185 protected:
186   inline const InstrRUsage& getInstrRUsage(MachineOpCode opCode) const {
187     assert(opCode >= 0 && opCode < (int) instrRUsages.size());
188     return instrRUsages[opCode];
189   }
190   const InstrClassRUsage& getClassRUsage(const InstrSchedClass& sc) const {
191     assert(sc < numSchedClasses);
192     return classRUsages[sc];
193   }
194
195 private:
196   TargetSchedInfo(const TargetSchedInfo &);  // DO NOT IMPLEMENT
197   void operator=(const TargetSchedInfo &);  // DO NOT IMPLEMENT
198 public:
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() {}
207   
208   inline const TargetInstrInfo& getInstrInfo() const {
209     return *mii;
210   }
211   
212   inline int            getNumSchedClasses()  const {
213     return numSchedClasses;
214   }  
215   
216   inline  unsigned getMaxNumIssueTotal() const {
217     return maxNumIssueTotal;
218   }
219   
220   inline  unsigned getMaxIssueForClass(const InstrSchedClass& sc) const {
221     assert(sc < numSchedClasses);
222     return classRUsages[sc].maxNumIssue;
223   }
224
225   inline InstrSchedClass getSchedClass  (MachineOpCode opCode) const {
226     return getInstrInfo().getSchedClass(opCode);
227   } 
228   
229   inline  bool  instrCanUseSlot         (MachineOpCode opCode,
230                                          unsigned s) const {
231     assert(s < getInstrRUsage(opCode).feasibleSlots.size() && "Invalid slot!");
232     return getInstrRUsage(opCode).feasibleSlots[s];
233   }
234   
235   inline int    getLongestIssueConflict () const {
236     return longestIssueConflict;
237   }
238
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;
244   }
245
246   inline const std::vector<MachineOpCode>&
247                 getConflictList(MachineOpCode opCode) const {
248     assert(opCode < (int) conflictLists.size());
249     return conflictLists[opCode];
250   }
251
252   inline  bool  isSingleIssue           (MachineOpCode opCode) const {
253     return getInstrRUsage(opCode).isSingleIssue;
254   }
255   
256   inline  bool  breaksIssueGroup        (MachineOpCode opCode) const {
257     return getInstrRUsage(opCode).breaksGroup;
258   }
259   
260   inline  unsigned numBubblesAfter      (MachineOpCode opCode) const {
261     return getInstrRUsage(opCode).numBubbles;
262   }
263   
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;
267     }
268     assert( 0&&"resource not found");
269     return 0;
270   }
271   
272
273 protected:
274   virtual void  initializeResources     ();
275   
276 private:
277   void computeInstrResources(const std::vector<InstrRUsage>& instrRUForClasses);
278   void computeIssueGaps(const std::vector<InstrRUsage>& instrRUForClasses);
279   
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);
284     toGaps[toOp] = gap;
285   }
286   
287 public:
288   std::vector<std::pair<int,int> > resourceNumVector;
289   
290 protected:
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;
298   
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]
303
304
305   friend class ModuloSchedGraph;
306   friend class ModuloSchedulingPass;
307   
308 };
309
310 } // End llvm namespace
311
312 #endif