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