Be a bit more efficient when processing the active and inactive
[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 "Support/hash_map"
21 #include <string>
22
23 namespace llvm {
24
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; 
28 static const unsigned MAX_OPCODE_SIZE = 16;
29
30 class OpCodePair {
31 public:
32   long val;                     // make long by concatenating two opcodes
33   OpCodePair(MachineOpCode op1, MachineOpCode op2)
34     : val((op1 < 0 || op2 < 0)?
35         -1 : (long)((((unsigned) op1) << MAX_OPCODE_SIZE) | (unsigned) op2)) {}
36   bool operator==(const OpCodePair& op) const {
37     return val == op.val;
38   }
39 private:
40   OpCodePair();                 // disable for now
41 };
42
43 } // End llvm namespace
44
45 namespace HASH_NAMESPACE {
46   template <> struct hash<llvm::OpCodePair> {
47     size_t operator()(const llvm::OpCodePair& pair) const {
48       return hash<long>()(pair.val);
49     }
50   };
51 } // End HASH_NAMESPACE (a macro) namespace
52
53 namespace llvm {
54
55 //---------------------------------------------------------------------------
56 // class MachineResource 
57 // class CPUResource
58 // 
59 // Purpose:
60 //   Representation of a single machine resource used in specifying
61 //   resource usages of machine instructions for scheduling.
62 //---------------------------------------------------------------------------
63
64
65 typedef unsigned resourceId_t;
66
67 struct CPUResource {
68   const std::string rname;
69   resourceId_t rid;
70   int maxNumUsers;   // MAXINT if no restriction
71   
72   CPUResource(const std::string& resourceName, int maxUsers);
73   static CPUResource* getCPUResource(resourceId_t id);
74 private:
75   static resourceId_t nextId;
76 };
77
78
79 //---------------------------------------------------------------------------
80 // struct InstrClassRUsage
81 // struct InstrRUsageDelta 
82 // struct InstrIssueDelta 
83 // struct InstrRUsage 
84 // 
85 // Purpose:
86 //   The first three are structures used to specify machine resource 
87 //   usages for each instruction in a machine description file:
88 //    InstrClassRUsage : resource usages common to all instrs. in a class
89 //    InstrRUsageDelta : add/delete resource usage for individual instrs. 
90 //    InstrIssueDelta  : add/delete instr. issue info for individual instrs 
91 //   
92 //   The last one (InstrRUsage) is the internal representation of
93 //   instruction resource usage constructed from the above three.
94 //---------------------------------------------------------------------------
95
96 const int MAX_NUM_SLOTS  = 32;
97 const int MAX_NUM_CYCLES = 32;
98
99 struct InstrClassRUsage {
100   InstrSchedClass schedClass;
101   int           totCycles;
102   
103   // Issue restrictions common to instructions in this class
104   unsigned      maxNumIssue;
105   bool          isSingleIssue;
106   bool          breaksGroup;
107   cycles_t      numBubbles;
108   
109   // Feasible slots to use for instructions in this class.
110   // The size of vector S[] is `numSlots'.
111   unsigned      numSlots;
112   unsigned      feasibleSlots[MAX_NUM_SLOTS];
113   
114   // Resource usages common to instructions in this class.
115   // The size of vector V[] is `numRUEntries'.
116   unsigned      numRUEntries;
117   struct {
118     resourceId_t resourceId;
119     unsigned    startCycle;
120     int         numCycles;
121   } V[MAX_NUM_CYCLES];
122 };
123
124 struct InstrRUsageDelta {
125   MachineOpCode opCode;
126   resourceId_t  resourceId;
127   unsigned      startCycle;
128   int           numCycles;
129 };
130
131 // Specify instruction issue restrictions for individual instructions
132 // that differ from the common rules for the class.
133 // 
134 struct InstrIssueDelta {
135   MachineOpCode opCode;
136   bool          isSingleIssue;
137   bool          breaksGroup;
138   cycles_t      numBubbles;
139 };
140
141
142 struct InstrRUsage {
143   bool          sameAsClass;
144   
145   // Issue restrictions for this instruction
146   bool          isSingleIssue;
147   bool          breaksGroup;
148   cycles_t      numBubbles;
149   
150   // Feasible slots to use for this instruction.
151   std::vector<bool> feasibleSlots;
152   
153   // Resource usages for this instruction, with one resource vector per cycle.
154   cycles_t      numCycles;
155   std::vector<std::vector<resourceId_t> > resourcesByCycle;
156   
157 private:
158   // Conveniences for initializing this structure
159   void setTo(const InstrClassRUsage& classRU);
160
161   void addIssueDelta(const InstrIssueDelta& delta) {
162     sameAsClass = false;
163     isSingleIssue = delta.isSingleIssue;
164     breaksGroup = delta.breaksGroup;
165     numBubbles = delta.numBubbles;
166   }
167
168   void addUsageDelta    (const InstrRUsageDelta& delta);
169   void setMaxSlots      (int maxNumSlots) {
170     feasibleSlots.resize(maxNumSlots);
171   }
172   
173   friend class TargetSchedInfo; // give access to these functions
174 };
175
176
177 //---------------------------------------------------------------------------
178 /// TargetSchedInfo - Common interface to machine information for 
179 /// instruction scheduling
180 ///
181 struct TargetSchedInfo {
182   const TargetMachine& target;
183   
184   unsigned maxNumIssueTotal;
185   int   longestIssueConflict;
186   
187 protected:
188   inline const InstrRUsage& getInstrRUsage(MachineOpCode opCode) const {
189     assert(opCode >= 0 && opCode < (int) instrRUsages.size());
190     return instrRUsages[opCode];
191   }
192   const InstrClassRUsage& getClassRUsage(const InstrSchedClass& sc) const {
193     assert(sc < numSchedClasses);
194     return classRUsages[sc];
195   }
196
197 private:
198   TargetSchedInfo(const TargetSchedInfo &);  // DO NOT IMPLEMENT
199   void operator=(const TargetSchedInfo &);  // DO NOT IMPLEMENT
200 public:
201   /*ctor*/         TargetSchedInfo      (const TargetMachine& tgt,
202                                          int                  _numSchedClasses,
203                                          const InstrClassRUsage* _classRUsages,
204                                          const InstrRUsageDelta* _usageDeltas,
205                                          const InstrIssueDelta*  _issueDeltas,
206                                          unsigned _numUsageDeltas,
207                                          unsigned _numIssueDeltas);
208   /*dtor*/ virtual ~TargetSchedInfo() {}
209   
210   inline const TargetInstrInfo& getInstrInfo() const {
211     return *mii;
212   }
213   
214   inline int            getNumSchedClasses()  const {
215     return numSchedClasses;
216   }  
217   
218   inline  unsigned getMaxNumIssueTotal() const {
219     return maxNumIssueTotal;
220   }
221   
222   inline  unsigned getMaxIssueForClass(const InstrSchedClass& sc) const {
223     assert(sc < numSchedClasses);
224     return classRUsages[sc].maxNumIssue;
225   }
226
227   inline InstrSchedClass getSchedClass  (MachineOpCode opCode) const {
228     return getInstrInfo().getSchedClass(opCode);
229   } 
230   
231   inline  bool  instrCanUseSlot         (MachineOpCode opCode,
232                                          unsigned s) const {
233     assert(s < getInstrRUsage(opCode).feasibleSlots.size() && "Invalid slot!");
234     return getInstrRUsage(opCode).feasibleSlots[s];
235   }
236   
237   inline int    getLongestIssueConflict () const {
238     return longestIssueConflict;
239   }
240
241   inline  int   getMinIssueGap          (MachineOpCode fromOp,
242                                          MachineOpCode toOp)   const {
243     assert(fromOp < (int) issueGaps.size());
244     const std::vector<int>& toGaps = issueGaps[fromOp];
245     return (toOp < (int) toGaps.size())? toGaps[toOp] : 0;
246   }
247
248   inline const std::vector<MachineOpCode>&
249                 getConflictList(MachineOpCode opCode) const {
250     assert(opCode < (int) conflictLists.size());
251     return conflictLists[opCode];
252   }
253
254   inline  bool  isSingleIssue           (MachineOpCode opCode) const {
255     return getInstrRUsage(opCode).isSingleIssue;
256   }
257   
258   inline  bool  breaksIssueGroup        (MachineOpCode opCode) const {
259     return getInstrRUsage(opCode).breaksGroup;
260   }
261   
262   inline  unsigned numBubblesAfter      (MachineOpCode opCode) const {
263     return getInstrRUsage(opCode).numBubbles;
264   }
265   
266   inline unsigned getCPUResourceNum(int rd)const{
267     for(unsigned i=0;i<resourceNumVector.size();i++){
268       if(resourceNumVector[i].first == rd) return resourceNumVector[i].second;
269     }
270     assert( 0&&"resource not found");
271     return 0;
272   }
273   
274
275 protected:
276   virtual void  initializeResources     ();
277   
278 private:
279   void computeInstrResources(const std::vector<InstrRUsage>& instrRUForClasses);
280   void computeIssueGaps(const std::vector<InstrRUsage>& instrRUForClasses);
281   
282   void setGap(int gap, MachineOpCode fromOp, MachineOpCode toOp) {
283     std::vector<int>& toGaps = issueGaps[fromOp];
284     if (toOp >= (int) toGaps.size())
285       toGaps.resize(toOp+1);
286     toGaps[toOp] = gap;
287   }
288   
289 public:
290   std::vector<std::pair<int,int> > resourceNumVector;
291   
292 protected:
293   unsigned                 numSchedClasses;
294   const TargetInstrInfo*   mii;
295   const InstrClassRUsage*  classRUsages;        // raw array by sclass
296   const InstrRUsageDelta*  usageDeltas;         // raw array [1:numUsageDeltas]
297   const InstrIssueDelta*   issueDeltas;         // raw array [1:numIssueDeltas]
298   unsigned                 numUsageDeltas;
299   unsigned                 numIssueDeltas;
300   
301   std::vector<InstrRUsage> instrRUsages;    // indexed by opcode
302   std::vector<std::vector<int> > issueGaps; // indexed by [opcode1][opcode2]
303   std::vector<std::vector<MachineOpCode> >
304                            conflictLists;   // indexed by [opcode]
305
306
307   friend class ModuloSchedulingPass;
308   friend class MSSchedule;
309   
310 };
311
312 } // End llvm namespace
313
314 #endif