9a72ff974b987233d502a1d2ed3b8990df7fdbf9
[oota-llvm.git] / include / llvm / CodeGen / TargetMachine.h
1 // $Id$ -*-c++-*-
2 //***************************************************************************
3 // File:
4 //      TargetMachine.h
5 // 
6 // Purpose:
7 //      
8 // History:
9 //      7/12/01  -  Vikram Adve  -  Created
10 //**************************************************************************/
11
12 #ifndef LLVM_CODEGEN_TARGETMACHINE_H
13 #define LLVM_CODEGEN_TARGETMACHINE_H
14
15 #include "llvm/CodeGen/TargetData.h"
16 #include "llvm/Support/NonCopyable.h"
17 #include "llvm/Support/DataTypes.h"
18 #include <string>
19 #include <hash_map>
20 #include <hash_set>
21 #include <algorithm>
22
23 class StructType;
24 struct MachineInstrDescriptor;
25 class TargetMachine;
26
27 //************************ Exported Data Types *****************************/
28
29 //---------------------------------------------------------------------------
30 // Data types used to define information about a single machine instruction
31 //---------------------------------------------------------------------------
32
33 typedef int MachineOpCode;
34 typedef int OpCodeMask;
35 typedef int InstrSchedClass;
36
37 static const unsigned MAX_OPCODE_SIZE = 16;
38
39 typedef long long cycles_t; 
40 const cycles_t HUGE_LATENCY = ~((unsigned long long) 1 << sizeof(cycles_t)-1);
41 const cycles_t INVALID_LATENCY = -HUGE_LATENCY; 
42
43
44 class OpCodePair {
45 public:
46   long val;                     // make long by concatenating two opcodes
47   OpCodePair(MachineOpCode op1, MachineOpCode op2)
48     : val((op1 < 0 || op2 < 0)?
49         -1 : (long)((((unsigned) op1) << MAX_OPCODE_SIZE) | (unsigned) op2)) {}
50   bool operator==(const OpCodePair& op) const {
51     return val == op.val;
52   }
53 private:
54   OpCodePair();                 // disable for now
55 };
56
57
58 template <> struct hash<OpCodePair> {
59   size_t operator()(const OpCodePair& pair) const {
60     return hash<long>()(pair.val);
61   }
62 };
63
64
65 // Global variable holding an array of descriptors for machine instructions.
66 // The actual object needs to be created separately for each target machine.
67 // This variable is initialized and reset by class MachineInstrInfo.
68 // 
69 extern const MachineInstrDescriptor* TargetInstrDescriptors;
70
71
72 //---------------------------------------------------------------------------
73 // struct MachineInstrDescriptor:
74 //      Predefined information about each machine instruction.
75 //      Designed to initialized statically.
76 // 
77 // class MachineInstructionInfo
78 //      Interface to description of machine instructions
79 // 
80 //---------------------------------------------------------------------------
81
82
83 const unsigned int      M_NOP_FLAG              = 1;
84 const unsigned int      M_BRANCH_FLAG           = 1 << 1;
85 const unsigned int      M_CALL_FLAG             = 1 << 2;
86 const unsigned int      M_RET_FLAG              = 1 << 3;
87 const unsigned int      M_ARITH_FLAG            = 1 << 4;
88 const unsigned int      M_CC_FLAG               = 1 << 6;
89 const unsigned int      M_LOGICAL_FLAG          = 1 << 6;
90 const unsigned int      M_INT_FLAG              = 1 << 7;
91 const unsigned int      M_FLOAT_FLAG            = 1 << 8;
92 const unsigned int      M_CONDL_FLAG            = 1 << 9;
93 const unsigned int      M_LOAD_FLAG             = 1 << 10;
94 const unsigned int      M_PREFETCH_FLAG         = 1 << 11;
95 const unsigned int      M_STORE_FLAG            = 1 << 12;
96 const unsigned int      M_DUMMY_PHI_FLAG        = 1 << 13;
97
98
99 struct MachineInstrDescriptor {
100   string        opCodeString;   // Assembly language mnemonic for the opcode.
101   int           numOperands;    // Number of args; -1 if variable #args
102   int           resultPos;      // Position of the result; -1 if no result
103   unsigned int  maxImmedConst;  // Largest +ve constant in IMMMED field or 0.
104   bool          immedIsSignExtended;    // Is IMMED field sign-extended? If so,
105                                 //   smallest -ve value is -(maxImmedConst+1).
106   unsigned int  numDelaySlots;  // Number of delay slots after instruction
107   unsigned int  latency;        // Latency in machine cycles
108   InstrSchedClass schedClass;   // enum  identifying instr sched class
109   unsigned int    iclass;       // flags identifying machine instr class
110 };
111
112
113 class MachineInstrInfo : public NonCopyableV {
114 protected:
115   const MachineInstrDescriptor* desc;   // raw array to allow static init'n
116   unsigned int descSize;                // number of entries in the desc array
117   unsigned int numRealOpCodes;          // number of non-dummy op codes
118   
119 public:
120   /*ctor*/              MachineInstrInfo(const MachineInstrDescriptor* _desc,
121                                          unsigned int _descSize,
122                                          unsigned int _numRealOpCodes);
123   /*dtor*/ virtual      ~MachineInstrInfo();
124   
125   unsigned int          getNumRealOpCodes() const {
126     return numRealOpCodes;
127   }
128   
129   unsigned int          getNumTotalOpCodes() const {
130     return descSize;
131   }
132   
133   const MachineInstrDescriptor& getDescriptor(MachineOpCode opCode) const {
134     assert(opCode >= 0 && opCode < (int) descSize);
135     return desc[opCode];
136   }
137   
138   int                   getNumOperands  (MachineOpCode opCode) const {
139     return getDescriptor(opCode).numOperands;
140   }
141   
142   int                   getResultPos    (MachineOpCode opCode) const {
143     return getDescriptor(opCode).resultPos;
144   }
145   
146   unsigned int          getNumDelaySlots(MachineOpCode opCode) const {
147     return getDescriptor(opCode).numDelaySlots;
148   }
149   
150   InstrSchedClass       getSchedClass   (MachineOpCode opCode) const {
151     return getDescriptor(opCode).schedClass;
152   }
153   
154   //
155   // Query instruction class flags according to the machine-independent
156   // flags listed above.
157   // 
158   unsigned int  getIClass               (MachineOpCode opCode) const {
159     return getDescriptor(opCode).iclass;
160   }
161   bool          isNop                   (MachineOpCode opCode) const {
162     return getDescriptor(opCode).iclass & M_NOP_FLAG;
163   }
164   bool          isBranch                (MachineOpCode opCode) const {
165     return getDescriptor(opCode).iclass & M_BRANCH_FLAG;
166   }
167   bool          isCall                  (MachineOpCode opCode) const {
168     return getDescriptor(opCode).iclass & M_CALL_FLAG;
169   }
170   bool          isReturn                (MachineOpCode opCode) const {
171     return getDescriptor(opCode).iclass & M_RET_FLAG;
172   }
173   bool          isControlFlow           (MachineOpCode opCode) const {
174     return getDescriptor(opCode).iclass & M_BRANCH_FLAG
175         || getDescriptor(opCode).iclass & M_CALL_FLAG
176         || getDescriptor(opCode).iclass & M_RET_FLAG;
177   }
178   bool          isArith                 (MachineOpCode opCode) const {
179     return getDescriptor(opCode).iclass & M_RET_FLAG;
180   }
181   bool          isCCInstr               (MachineOpCode opCode) const {
182     return getDescriptor(opCode).iclass & M_CC_FLAG;
183   }
184   bool          isLogical               (MachineOpCode opCode) const {
185     return getDescriptor(opCode).iclass & M_LOGICAL_FLAG;
186   }
187   bool          isIntInstr              (MachineOpCode opCode) const {
188     return getDescriptor(opCode).iclass & M_INT_FLAG;
189   }
190   bool          isFloatInstr            (MachineOpCode opCode) const {
191     return getDescriptor(opCode).iclass & M_FLOAT_FLAG;
192   }
193   bool          isConditional           (MachineOpCode opCode) const {
194     return getDescriptor(opCode).iclass & M_CONDL_FLAG;
195   }
196   bool          isLoad                  (MachineOpCode opCode) const {
197     return getDescriptor(opCode).iclass & M_LOAD_FLAG;
198   }
199   bool          isPrefetch              (MachineOpCode opCode) const {
200     return getDescriptor(opCode).iclass & M_PREFETCH_FLAG;
201   }
202   bool          isLoadOrPrefetch        (MachineOpCode opCode) const {
203     return getDescriptor(opCode).iclass & M_LOAD_FLAG
204         || getDescriptor(opCode).iclass & M_PREFETCH_FLAG;
205   }
206   bool          isStore                 (MachineOpCode opCode) const {
207     return getDescriptor(opCode).iclass & M_STORE_FLAG;
208   }
209   bool          isMemoryAccess          (MachineOpCode opCode) const {
210     return getDescriptor(opCode).iclass & M_LOAD_FLAG
211         || getDescriptor(opCode).iclass & M_PREFETCH_FLAG
212         || getDescriptor(opCode).iclass & M_STORE_FLAG;
213   }
214   bool          isDummyPhiInstr         (MachineOpCode opCode) const {
215     return getDescriptor(opCode).iclass & M_DUMMY_PHI_FLAG;
216   }
217
218
219   // delete this later *******
220   bool isPhi(MachineOpCode opCode) { return isDummyPhiInstr(opCode); }  
221   
222
223
224   // Check if an instruction can be issued before its operands are ready,
225   // or if a subsequent instruction that uses its result can be issued
226   // before the results are ready.
227   // Default to true since most instructions on many architectures allow this.
228   // 
229   virtual bool          hasOperandInterlock(MachineOpCode opCode) const {
230     return true;
231   }
232   
233   virtual bool          hasResultInterlock(MachineOpCode opCode) const {
234     return true;
235   }
236   
237   // 
238   // Latencies for individual instructions and instruction pairs
239   // 
240   virtual int           minLatency      (MachineOpCode opCode) const {
241     return getDescriptor(opCode).latency;
242   }
243   
244   virtual int           maxLatency      (MachineOpCode opCode) const {
245     return getDescriptor(opCode).latency;
246   }
247   
248   // Check if the specified constant fits in the immediate field
249   // of this machine instruction
250   // 
251   virtual bool          constantFitsInImmedField(MachineOpCode opCode,
252                                                  int64_t intValue) const;
253   
254   // Return the largest +ve constant that can be held in the IMMMED field
255   // of this machine instruction.
256   // isSignExtended is set to true if the value is sign-extended before use
257   // (this is true for all immediate fields in SPARC instructions).
258   // Return 0 if the instruction has no IMMED field.
259   // 
260   virtual uint64_t      maxImmedConstant(MachineOpCode opCode,
261                                          bool& isSignExtended) const {
262     isSignExtended = getDescriptor(opCode).immedIsSignExtended;
263     return getDescriptor(opCode).maxImmedConst;
264   }
265 };
266
267
268 //---------------------------------------------------------------------------
269 // class MachineResource 
270 // class CPUResource
271 // 
272 // Purpose:
273 //   Representation of a single machine resource used in specifying
274 //   resource usages of machine instructions for scheduling.
275 //---------------------------------------------------------------------------
276
277
278 typedef unsigned int resourceId_t;
279
280 class MachineResource {
281 public:
282   const string  rname;
283   resourceId_t  rid;
284   
285   /*ctor*/      MachineResource(const string& resourceName)
286                         : rname(resourceName), rid(nextId++) {}
287   
288 private:
289   static resourceId_t nextId;
290   MachineResource();                    // disable
291 };
292
293
294 class CPUResource : public MachineResource {
295 public:
296   int           maxNumUsers;            // MAXINT if no restriction
297   
298   /*ctor*/      CPUResource(const string& rname, int maxUsers)
299                         : MachineResource(rname), maxNumUsers(maxUsers) {}
300 };
301
302
303 //---------------------------------------------------------------------------
304 // struct InstrClassRUsage
305 // struct InstrRUsageDelta 
306 // struct InstrIssueDelta 
307 // struct InstrRUsage 
308 // 
309 // Purpose:
310 //   The first three are structures used to specify machine resource 
311 //   usages for each instruction in a machine description file:
312 //    InstrClassRUsage : resource usages common to all instrs. in a class
313 //    InstrRUsageDelta : add/delete resource usage for individual instrs. 
314 //    InstrIssueDelta  : add/delete instr. issue info for individual instrs 
315 //   
316 //   The last one (InstrRUsage) is the internal representation of
317 //   instruction resource usage constructed from the above three.
318 //---------------------------------------------------------------------------
319
320 const int MAX_NUM_SLOTS  = 32;
321 const int MAX_NUM_CYCLES = 32;
322
323 struct InstrClassRUsage {
324   InstrSchedClass schedClass;
325   int           totCycles;
326   
327   // Issue restrictions common to instructions in this class
328   unsigned int  maxNumIssue;
329   bool          isSingleIssue;
330   bool          breaksGroup;
331   cycles_t      numBubbles;
332   
333   // Feasible slots to use for instructions in this class.
334   // The size of vector S[] is `numSlots'.
335   unsigned int  numSlots;
336   unsigned int  feasibleSlots[MAX_NUM_SLOTS];
337   
338   // Resource usages common to instructions in this class.
339   // The size of vector V[] is `numRUEntries'.
340   unsigned int  numRUEntries;
341   struct {
342     resourceId_t resourceId;
343     unsigned int startCycle;
344     int          numCycles;
345   }             V[MAX_NUM_CYCLES];
346 };
347
348 struct InstrRUsageDelta {
349   MachineOpCode opCode;
350   resourceId_t  resourceId;
351   unsigned int  startCycle;
352   int           numCycles;
353 };
354
355 // Specify instruction issue restrictions for individual instructions
356 // that differ from the common rules for the class.
357 // 
358 struct InstrIssueDelta {
359   MachineOpCode opCode;
360   bool          isSingleIssue;
361   bool          breaksGroup;
362   cycles_t      numBubbles;
363 };
364
365
366 struct InstrRUsage {
367   /*ctor*/      InstrRUsage     () {}
368   /*ctor*/      InstrRUsage     (const InstrRUsage& instrRU);
369   InstrRUsage&  operator=       (const InstrRUsage& instrRU);
370   
371   bool          sameAsClass;
372   
373   // Issue restrictions for this instruction
374   bool          isSingleIssue;
375   bool          breaksGroup;
376   cycles_t      numBubbles;
377   
378   // Feasible slots to use for this instruction.
379   vector<bool>  feasibleSlots;
380   
381   // Resource usages for this instruction, with one resource vector per cycle.
382   cycles_t      numCycles;
383   vector<vector<resourceId_t> > resourcesByCycle;
384   
385 private:
386   // Conveniences for initializing this structure
387   InstrRUsage&  operator=       (const InstrClassRUsage& classRU);
388   void          addIssueDelta   (const InstrIssueDelta& delta);
389   void          addUsageDelta   (const InstrRUsageDelta& delta);
390   void          setMaxSlots     (int maxNumSlots);
391   
392   friend class MachineSchedInfo;        // give access to these functions
393 };
394
395
396 inline void
397 InstrRUsage::setMaxSlots(int maxNumSlots)
398 {
399   feasibleSlots.resize(maxNumSlots);
400 }
401
402 inline InstrRUsage&
403 InstrRUsage::operator=(const InstrRUsage& instrRU)
404 {
405   sameAsClass      = instrRU.sameAsClass;
406   isSingleIssue    = instrRU.isSingleIssue;
407   breaksGroup      = instrRU.breaksGroup; 
408   numBubbles       = instrRU.numBubbles;
409   feasibleSlots    = instrRU.feasibleSlots;
410   numCycles        = instrRU.numCycles;
411   resourcesByCycle = instrRU.resourcesByCycle;
412   return *this;
413 }
414
415 inline /*ctor*/
416 InstrRUsage::InstrRUsage(const InstrRUsage& instrRU)
417 {
418   *this = instrRU;
419 }
420
421 inline InstrRUsage&
422 InstrRUsage::operator=(const InstrClassRUsage& classRU)
423 {
424   sameAsClass   = true;
425   isSingleIssue = classRU.isSingleIssue;
426   breaksGroup   = classRU.breaksGroup; 
427   numBubbles    = classRU.numBubbles;
428   
429   for (unsigned i=0; i < classRU.numSlots; i++)
430     {
431       unsigned slot = classRU.feasibleSlots[i];
432       assert(slot < feasibleSlots.size() && "Invalid slot specified!");
433       this->feasibleSlots[slot] = true;
434     }
435   
436   this->numCycles   = classRU.totCycles;
437   this->resourcesByCycle.resize(this->numCycles);
438   
439   for (unsigned i=0; i < classRU.numRUEntries; i++)
440     for (unsigned c=classRU.V[i].startCycle, NC = c + classRU.V[i].numCycles;
441          c < NC; c++)
442       this->resourcesByCycle[c].push_back(classRU.V[i].resourceId);
443   
444   // Sort each resource usage vector by resourceId_t to speed up conflict checking
445   for (unsigned i=0; i < this->resourcesByCycle.size(); i++)
446     sort(resourcesByCycle[i].begin(), resourcesByCycle[i].end());
447   
448   return *this;
449 }
450
451
452 inline void
453 InstrRUsage::addIssueDelta(const InstrIssueDelta&  delta)
454 {
455   sameAsClass = false;
456   isSingleIssue = delta.isSingleIssue;
457   breaksGroup = delta.breaksGroup;
458   numBubbles = delta.numBubbles;
459 }
460
461
462 // Add the extra resource usage requirements specified in the delta.
463 // Note that a negative value of `numCycles' means one entry for that
464 // resource should be deleted for each cycle.
465 // 
466 inline void
467 InstrRUsage::addUsageDelta(const InstrRUsageDelta& delta)
468 {
469   int NC = delta.numCycles;
470     
471   this->sameAsClass = false;
472   
473   // resize the resources vector if more cycles are specified
474   unsigned maxCycles = this->numCycles;
475   maxCycles = max(maxCycles, delta.startCycle + abs(NC) - 1);
476   if (maxCycles > this->numCycles)
477     {
478       this->resourcesByCycle.resize(maxCycles);
479       this->numCycles = maxCycles;
480     }
481     
482   if (NC >= 0)
483     for (unsigned c=delta.startCycle, last=c+NC-1; c <= last; c++)
484       this->resourcesByCycle[c].push_back(delta.resourceId);
485   else
486     // Remove the resource from all NC cycles.
487     for (unsigned c=delta.startCycle, last=(c-NC)-1; c <= last; c++)
488       {
489         // Look for the resource backwards so we remove the last entry
490         // for that resource in each cycle.
491         vector<resourceId_t>& rvec = this->resourcesByCycle[c];
492         int r;
493         for (r = (int) rvec.size(); r >= 0; r--)
494           if (rvec[r] == delta.resourceId)
495             {// found last entry for the resource
496               rvec.erase(rvec.begin() + r);
497               break;
498             }
499         assert(r >= 0 && "Resource to remove was unused in cycle c!");
500       }
501 }
502
503
504 //---------------------------------------------------------------------------
505 // class MachineSchedInfo
506 //
507 // Purpose:
508 //   Common interface to machine information for instruction scheduling
509 //---------------------------------------------------------------------------
510
511 class MachineSchedInfo : public NonCopyableV {
512 public:
513   unsigned int  maxNumIssueTotal;
514   int   longestIssueConflict;
515   
516   int   branchMispredictPenalty;        // 4 for SPARC IIi
517   int   branchTargetUnknownPenalty;     // 2 for SPARC IIi
518   int   l1DCacheMissPenalty;            // 7 or 9 for SPARC IIi
519   int   l1ICacheMissPenalty;            // ? for SPARC IIi
520   
521   bool  inOrderLoads ;                  // true for SPARC IIi
522   bool  inOrderIssue;                   // true for SPARC IIi
523   bool  inOrderExec;                    // false for most architectures
524   bool  inOrderRetire;                  // true for most architectures
525   
526 protected:
527   inline const InstrRUsage& getInstrRUsage(MachineOpCode opCode) const {
528     assert(opCode >= 0 && opCode < (int) instrRUsages.size());
529     return instrRUsages[opCode];
530   }
531   inline const InstrClassRUsage&
532                         getClassRUsage(const InstrSchedClass& sc) const {
533     assert(sc >= 0 && sc < numSchedClasses);
534     return classRUsages[sc];
535   }
536   
537 public:
538   /*ctor*/         MachineSchedInfo     (int _numSchedClasses,
539                                          const MachineInstrInfo* _mii,
540                                          const InstrClassRUsage* _classRUsages,
541                                          const InstrRUsageDelta* _usageDeltas,
542                                          const InstrIssueDelta*  _issueDeltas,
543                                          unsigned int _numUsageDeltas,
544                                          unsigned int _numIssueDeltas);
545   /*dtor*/ virtual ~MachineSchedInfo    () {}
546   
547   inline const MachineInstrInfo& getInstrInfo() const {
548     return *mii;
549   }
550   
551   inline int            getNumSchedClasses()  const {
552     return numSchedClasses;
553   }  
554   
555   inline  unsigned int  getMaxNumIssueTotal() const {
556     return maxNumIssueTotal;
557   }
558   
559   inline  unsigned int  getMaxIssueForClass(const InstrSchedClass& sc) const {
560     assert(sc >= 0 && sc < numSchedClasses);
561     return classRUsages[sc].maxNumIssue;
562   }
563
564   inline InstrSchedClass getSchedClass  (MachineOpCode opCode) const {
565     return getInstrInfo().getSchedClass(opCode);
566   } 
567   
568   inline  bool  instrCanUseSlot         (MachineOpCode opCode,
569                                          unsigned s) const {
570     assert(s < getInstrRUsage(opCode).feasibleSlots.size() && "Invalid slot!");
571     return getInstrRUsage(opCode).feasibleSlots[s];
572   }
573   
574   inline int    getLongestIssueConflict () const {
575     return longestIssueConflict;
576   }
577   
578   inline  int   getMinIssueGap          (MachineOpCode fromOp,
579                                          MachineOpCode toOp)   const {
580     hash_map<OpCodePair,int>::const_iterator
581       I = issueGaps.find(OpCodePair(fromOp, toOp));
582     return (I == issueGaps.end())? 0 : (*I).second;
583   }
584   
585   inline const vector<MachineOpCode>*
586                 getConflictList(MachineOpCode opCode) const {
587     hash_map<MachineOpCode,vector<MachineOpCode> >::const_iterator
588       I = conflictLists.find(opCode);
589     return (I == conflictLists.end())? NULL : & (*I).second;
590   }
591   
592   inline  bool  isSingleIssue           (MachineOpCode opCode) const {
593     return getInstrRUsage(opCode).isSingleIssue;
594   }
595   
596   inline  bool  breaksIssueGroup        (MachineOpCode opCode) const {
597     return getInstrRUsage(opCode).breaksGroup;
598   }
599   
600   inline  unsigned int  numBubblesAfter (MachineOpCode opCode) const {
601     return getInstrRUsage(opCode).numBubbles;
602   }
603   
604 protected:
605   virtual void  initializeResources     ();
606   
607 private:
608   void computeInstrResources(const vector<InstrRUsage>& instrRUForClasses);
609   void computeIssueGaps(const vector<InstrRUsage>& instrRUForClasses);
610   
611 protected:
612   int                      numSchedClasses;
613   const MachineInstrInfo*  mii;
614   const InstrClassRUsage*  classRUsages;        // raw array by sclass
615   const InstrRUsageDelta*  usageDeltas;         // raw array [1:numUsageDeltas]
616   const InstrIssueDelta*   issueDeltas;         // raw array [1:numIssueDeltas]
617   unsigned int             numUsageDeltas;
618   unsigned int             numIssueDeltas;
619   
620   vector<InstrRUsage>      instrRUsages;        // indexed by opcode
621   hash_map<OpCodePair,int> issueGaps;           // indexed by opcode pair
622   hash_map<MachineOpCode,vector<MachineOpCode> >
623                            conflictLists;       // indexed by opcode
624 };
625
626
627
628 //-----------------------------------------------------------------------------
629 // class MachineRegClassInfo
630 // 
631 // Purpose:
632 //   Interface to description of machine register class (e.g., int reg class
633 //   float reg class etc)
634 // 
635 //--------------------------------------------------------------------------
636
637 class IGNode;
638
639
640 class MachineRegClassInfo {
641
642 protected:
643   
644   const unsigned RegClassID;        // integer ID of a reg class
645   const unsigned NumOfAvailRegs;    // # of avail for coloring -without SP etc.
646   const unsigned NumOfAllRegs;      // # of all registers -including SP,g0 etc.
647
648 public:
649   
650   inline unsigned getRegClassID() const { return RegClassID; }
651   inline unsigned getNumOfAvailRegs() const { return NumOfAvailRegs; }
652   inline unsigned getNumOfAllRegs() const { return NumOfAllRegs; }
653
654
655
656   // This method should find a color which is not used by neighbors
657   // (i.e., a false position in IsColorUsedArr) and 
658   virtual void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const = 0;
659
660
661   MachineRegClassInfo(const unsigned ID, const unsigned NVR, 
662                       const unsigned NAR): RegClassID(ID), NumOfAvailRegs(NVR),
663                                            NumOfAllRegs(NAR)
664   { }                         // empty constructor
665
666 };
667
668
669
670
671 //---------------------------------------------------------------------------
672 // class MachineRegInfo
673 // 
674 // Purpose:
675 //   Interface to register info of target machine
676 // 
677 //--------------------------------------------------------------------------
678
679 class LiveRangeInfo;
680 class Method;
681 class Instruction;
682 class LiveRange;
683 class AddedInstrns;
684 class MachineInstr;
685 typedef hash_map<const MachineInstr *, AddedInstrns *> AddedInstrMapType;
686
687 // A vector of all machine register classes
688 typedef vector<const MachineRegClassInfo *> MachineRegClassArrayType;
689
690
691 class MachineRegInfo : public NonCopyableV {
692
693 protected:
694
695   MachineRegClassArrayType MachineRegClassArr;    
696
697   
698 public:
699
700
701   inline unsigned int getNumOfRegClasses() const { 
702     return MachineRegClassArr.size(); 
703   }  
704
705   const MachineRegClassInfo *const getMachineRegClass(unsigned i) const { 
706     return MachineRegClassArr[i]; 
707   }
708
709
710   virtual unsigned getRegClassIDOfValue (const Value *const Val) const = 0;
711
712   virtual void colorArgs(const Method *const Meth, 
713                          LiveRangeInfo & LRI) const = 0;
714
715   virtual void colorCallArgs(vector<const Instruction *> & CallInstrList, 
716                              LiveRangeInfo& LRI, 
717                              AddedInstrMapType& AddedInstrMap ) const = 0 ;
718
719   virtual int getUnifiedRegNum(int RegClassID, int reg) const = 0;
720
721   virtual const string getUnifiedRegName(int reg) const = 0;
722
723   //virtual void printReg(const LiveRange *const LR) const =0;
724
725   MachineRegInfo() { }
726
727 };
728
729
730
731
732
733 //---------------------------------------------------------------------------
734 // class TargetMachine
735 // 
736 // Purpose:
737 //   Primary interface to machine description for the target machine.
738 // 
739 //---------------------------------------------------------------------------
740
741 class TargetMachine : public NonCopyableV {
742 public:
743   const string     TargetName;
744   const TargetData DataLayout;          // Calculates type size & alignment
745   int              optSizeForSubWordData;
746   int              minMemOpWordSize;
747   int              maxAtomicMemOpWordSize;
748   
749   // Register information.  This needs to be reorganized into a single class.
750   int           zeroRegNum;     // register that gives 0 if any (-1 if none)
751   
752 public:
753   TargetMachine(const string &targetname,
754                 unsigned char PtrSize = 8, unsigned char PtrAl = 8,
755                 unsigned char DoubleAl = 8, unsigned char FloatAl = 4,
756                 unsigned char LongAl = 8, unsigned char IntAl = 4,
757                 unsigned char ShortAl = 2, unsigned char ByteAl = 1)
758     : TargetName(targetname), DataLayout(targetname, PtrSize, PtrAl,
759                                          DoubleAl, FloatAl, LongAl, IntAl, 
760                                          ShortAl, ByteAl) { }
761   virtual ~TargetMachine() {}
762   
763   virtual const MachineInstrInfo& getInstrInfo() const = 0;
764   
765   virtual unsigned int  findOptimalStorageSize  (const Type* ty) const;
766   
767   // This really should be in the register info class
768   virtual bool          regsMayBeAliased        (unsigned int regNum1,
769                                                  unsigned int regNum2) const {
770     return (regNum1 == regNum2);
771   }
772   
773   // compileMethod - This does everything neccesary to compile a method into the
774   // built in representation.  This allows the target to have complete control
775   // over how it does compilation.  This does not emit assembly or output
776   // machine code however, this is done later.
777   //
778   virtual bool compileMethod(Method *M) = 0;
779
780   // emitAssembly - Output assembly language code (a .s file) for the specified
781   // method. The specified method must have been compiled before this may be
782   // used.
783   //
784   virtual void emitAssembly(Method *M, ostream &OutStr) {  /* todo */ }
785 };
786
787 #endif