dc68904e3c1486439b00d447fe16f5f8182cd824
[oota-llvm.git] / include / llvm / CodeGen / MachineInstr.h
1 // $Id$ -*-c++-*-
2 //***************************************************************************
3 // File:
4 //      MachineInstr.h
5 // 
6 // Purpose:
7 //      
8 // 
9 // Strategy:
10 // 
11 // History:
12 //      7/2/01   -  Vikram Adve  -  Created
13 //**************************************************************************/
14
15 #ifndef LLVM_CODEGEN_MACHINEINSTR_H
16 #define LLVM_CODEGEN_MACHINEINSTR_H
17
18 #include <iterator>
19 #include "llvm/CodeGen/InstrForest.h"
20 #include "llvm/Support/DataTypes.h"
21 #include "llvm/Support/NonCopyable.h"
22 #include "llvm/Target/MachineInstrInfo.h"
23 #include <hash_map>
24 #include <hash_set>
25
26 template<class _MI, class _V> class ValOpIterator;
27
28
29 //---------------------------------------------------------------------------
30 // class MachineOperand 
31 // 
32 // Purpose:
33 //   Representation of each machine instruction operand.
34 //   This class is designed so that you can allocate a vector of operands
35 //   first and initialize each one later.
36 //
37 //   E.g, for this VM instruction:
38 //              ptr = alloca type, numElements
39 //   we generate 2 machine instructions on the SPARC:
40 // 
41 //              mul Constant, Numelements -> Reg
42 //              add %sp, Reg -> Ptr
43 // 
44 //   Each instruction has 3 operands, listed above.  Of those:
45 //   -  Reg, NumElements, and Ptr are of operand type MO_Register.
46 //   -  Constant is of operand type MO_SignExtendedImmed on the SPARC.
47 //      
48 //   For the register operands, the virtual register type is as follows:
49 //      
50 //   -  Reg will be of virtual register type MO_MInstrVirtualReg.  The field
51 //      MachineInstr* minstr will point to the instruction that computes reg.
52 // 
53 //   -  %sp will be of virtual register type MO_MachineReg.
54 //      The field regNum identifies the machine register.
55 // 
56 //   -  NumElements will be of virtual register type MO_VirtualReg.
57 //      The field Value* value identifies the value.
58 // 
59 //   -  Ptr will also be of virtual register type MO_VirtualReg.
60 //      Again, the field Value* value identifies the value.
61 // 
62 //---------------------------------------------------------------------------
63
64
65 class MachineOperand {
66 public:
67   enum MachineOperandType {
68     MO_VirtualRegister,         // virtual register for *value
69     MO_MachineRegister,         // pre-assigned machine register `regNum'
70     MO_CCRegister,
71     MO_SignExtendedImmed,
72     MO_UnextendedImmed,
73     MO_PCRelativeDisp,
74   };
75   
76 private:
77   MachineOperandType opType;
78   
79   union {
80     Value*      value;          // BasicBlockVal for a label operand.
81                                 // ConstantVal for a non-address immediate.
82                                 // Virtual register for an SSA operand,
83                                 // including hidden operands required for
84                                 // the generated machine code.     
85     int64_t immedVal;           // constant value for an explicit constant
86   };
87
88   int regNum;                   // register number for an explicit register
89                                 // will be set for a value after reg allocation
90   bool isDef;                   // is this a defition for the value
91   
92 public:
93   /*ctor*/              MachineOperand  ();
94   /*ctor*/              MachineOperand  (MachineOperandType operandType,
95                                          Value* _val);
96   /*copy ctor*/         MachineOperand  (const MachineOperand&);
97   /*dtor*/              ~MachineOperand () {}
98   
99   // Accessor methods.  Caller is responsible for checking the
100   // operand type before invoking the corresponding accessor.
101   // 
102   inline MachineOperandType getOperandType      () const {
103     return opType;
104   }
105   inline Value*         getVRegValue    () const {
106     assert(opType == MO_VirtualRegister || opType == MO_CCRegister || 
107            opType == MO_PCRelativeDisp);
108     return value;
109   }
110   inline int            getMachineRegNum() const {
111     assert(opType == MO_MachineRegister);
112     return regNum;
113   }
114   inline int64_t        getImmedValue   () const {
115     assert(opType == MO_SignExtendedImmed || opType == MO_UnextendedImmed);
116     return immedVal;
117   }
118   inline bool           opIsDef         () const {
119     return isDef;
120   }
121   
122 public:
123   friend ostream& operator<<(ostream& os, const MachineOperand& mop);
124
125   
126 private:
127   // These functions are provided so that a vector of operands can be
128   // statically allocated and individual ones can be initialized later.
129   // Give class MachineInstr gets access to these functions.
130   // 
131   void                  Initialize      (MachineOperandType operandType,
132                                          Value* _val);
133   void                  InitializeConst (MachineOperandType operandType,
134                                          int64_t intValue);
135   void                  InitializeReg   (int regNum);
136
137   friend class MachineInstr;
138   friend class ValOpIterator<const MachineInstr, const Value>;
139   friend class ValOpIterator<      MachineInstr,       Value>;
140
141
142 public:
143
144   // replaces the Value with its corresponding physical register after
145   // register allocation is complete
146   void setRegForValue(int reg) {
147     assert(opType == MO_VirtualRegister || opType == MO_CCRegister || 
148            opType == MO_MachineRegister);
149     regNum = reg;
150   }
151
152   // used to get the reg number if when one is allocted (must be
153   // called only after reg alloc)
154   inline int  getAllocatedRegNum() const {
155     assert(opType == MO_VirtualRegister || opType == MO_CCRegister || 
156            opType == MO_MachineRegister);
157     return regNum;
158   }
159
160  
161 };
162
163
164 inline
165 MachineOperand::MachineOperand()
166   : opType(MO_VirtualRegister),
167     immedVal(0),
168     regNum(-1),
169     isDef(false)
170 {}
171
172 inline
173 MachineOperand::MachineOperand(MachineOperandType operandType,
174                                Value* _val)
175   : opType(operandType),
176     immedVal(0),
177     regNum(-1),
178     value(_val),
179     isDef(false)
180 {}
181
182 inline
183 MachineOperand::MachineOperand(const MachineOperand& mo)
184   : opType(mo.opType),
185     isDef(false)
186 {
187   switch(opType) {
188   case MO_VirtualRegister:
189   case MO_CCRegister:           value = mo.value; break;
190   case MO_MachineRegister:      regNum = mo.regNum; break;
191   case MO_SignExtendedImmed:
192   case MO_UnextendedImmed:
193   case MO_PCRelativeDisp:       immedVal = mo.immedVal; break;
194   default: assert(0);
195   }
196 }
197
198 inline void
199 MachineOperand::Initialize(MachineOperandType operandType,
200                            Value* _val)
201 {
202   opType = operandType;
203   value = _val;
204   regNum = -1;
205 }
206
207 inline void
208 MachineOperand::InitializeConst(MachineOperandType operandType,
209                                 int64_t intValue)
210 {
211   opType = operandType;
212   value = NULL;
213   immedVal = intValue;
214   regNum = -1;
215 }
216
217 inline void
218 MachineOperand::InitializeReg(int _regNum)
219 {
220   opType = MO_MachineRegister;
221   value = NULL;
222   regNum = (int) _regNum;
223 }
224
225
226 //---------------------------------------------------------------------------
227 // class MachineInstr 
228 // 
229 // Purpose:
230 //   Representation of each machine instruction.
231 // 
232 //   MachineOpCode must be an enum, defined separately for each target.
233 //   E.g., It is defined in SparcInstructionSelection.h for the SPARC.
234 // 
235 //   opCodeMask is used to record variants of an instruction.
236 //   E.g., each branch instruction on SPARC has 2 flags (i.e., 4 variants):
237 //      ANNUL:             if 1: Annul delay slot instruction.
238 //      PREDICT-NOT-TAKEN: if 1: predict branch not taken.
239 //   Instead of creating 4 different opcodes for BNZ, we create a single
240 //   opcode and set bits in opCodeMask for each of these flags.
241 //
242 //  There are 2 kinds of operands:
243 // 
244 //  (1) Explicit operands of the machine instruction in vector operands[] 
245 // 
246 //  (2) "Implicit operands" are values implicitly used or defined by the
247 //      machine instruction, such as arguments to a CALL, return value of
248 //      a CALL (if any), and return value of a RETURN.
249 //---------------------------------------------------------------------------
250
251 class MachineInstr : public NonCopyable {
252 private:
253   MachineOpCode         opCode;
254   OpCodeMask            opCodeMask;     // extra bits for variants of an opcode
255   vector<MachineOperand> operands;
256   vector<Value*>        implicitRefs;   // values implicitly referenced by this
257   vector<bool>          implicitIsDef;  // machine instruction (eg, call args)
258   
259 public:
260   typedef ValOpIterator<const MachineInstr, const Value> val_op_const_iterator;
261   typedef ValOpIterator<const MachineInstr,       Value> val_op_iterator;
262   
263 public:
264   /*ctor*/              MachineInstr    (MachineOpCode _opCode,
265                                          OpCodeMask    _opCodeMask = 0x0);
266   /*ctor*/              MachineInstr    (MachineOpCode _opCode,
267                                          unsigned       numOperands,
268                                          OpCodeMask    _opCodeMask = 0x0);
269   inline                ~MachineInstr   () {}
270   const MachineOpCode   getOpCode       () const { return opCode; }
271
272   //
273   // Information about explicit operands of the instruction
274   // 
275   unsigned int          getNumOperands  () const { return operands.size(); }
276   
277   bool                  operandIsDefined(unsigned int i) const;
278   
279   const MachineOperand& getOperand      (unsigned int i) const;
280         MachineOperand& getOperand      (unsigned int i);
281   
282   //
283   // Information about implicit operands of the instruction
284   // 
285   unsigned int          getNumImplicitRefs() const{return implicitRefs.size();}
286   
287   bool                  implicitRefIsDefined(unsigned int i) const;
288   
289   const Value*          getImplicitRef  (unsigned int i) const;
290         Value*          getImplicitRef  (unsigned int i);
291   
292   //
293   // Debugging support
294   // 
295   void                  dump            (unsigned int indent = 0) const;
296
297   
298 public:
299   friend ostream& operator<<(ostream& os, const MachineInstr& minstr);
300   friend val_op_const_iterator;
301   friend val_op_iterator;
302
303 public:
304   // Access to set the operands when building the machine instruction
305   void                  SetMachineOperand(unsigned int i,
306                               MachineOperand::MachineOperandType operandType,
307                               Value* _val, bool isDef=false);
308   void                  SetMachineOperand(unsigned int i,
309                               MachineOperand::MachineOperandType operandType,
310                               int64_t intValue, bool isDef=false);
311   void                  SetMachineOperand(unsigned int i,
312                                           int regNum, 
313                                           bool isDef=false);
314
315   void                  addImplicitRef   (Value* val, 
316                                           bool isDef=false);
317   
318   void                  setImplicitRef   (unsigned int i,
319                                           Value* val, 
320                                           bool isDef=false);
321 };
322
323
324 inline MachineOperand&
325 MachineInstr::getOperand(unsigned int i)
326 {
327   assert(i < operands.size() && "getOperand() out of range!");
328   return operands[i];
329 }
330
331 inline const MachineOperand&
332 MachineInstr::getOperand(unsigned int i) const
333 {
334   assert(i < operands.size() && "getOperand() out of range!");
335   return operands[i];
336 }
337
338 inline bool
339 MachineInstr::operandIsDefined(unsigned int i) const
340 {
341   return getOperand(i).opIsDef();
342 }
343
344 inline bool
345 MachineInstr::implicitRefIsDefined(unsigned int i) const
346 {
347   assert(i < implicitIsDef.size() && "operand out of range!");
348   return implicitIsDef[i];
349 }
350
351 inline const Value*
352 MachineInstr::getImplicitRef(unsigned int i) const
353 {
354   assert(i < implicitRefs.size() && "getImplicitRef() out of range!");
355   return implicitRefs[i];
356 }
357
358 inline Value*
359 MachineInstr::getImplicitRef(unsigned int i)
360 {
361   assert(i < implicitRefs.size() && "getImplicitRef() out of range!");
362   return implicitRefs[i];
363 }
364
365 inline void
366 MachineInstr::addImplicitRef(Value* val, 
367                              bool isDef)
368 {
369   implicitRefs.push_back(val);
370   implicitIsDef.push_back(isDef);
371 }
372
373 inline void
374 MachineInstr::setImplicitRef(unsigned int i,
375                              Value* val, 
376                              bool isDef)
377 {
378   assert(i < implicitRefs.size() && "setImplicitRef() out of range!");
379   implicitRefs[i] = val;
380   implicitIsDef[i] = isDef;
381 }
382
383
384 template<class _MI, class _V>
385 class ValOpIterator : public std::forward_iterator<_V, ptrdiff_t> {
386 private:
387   unsigned int i;
388   int resultPos;
389   _MI* minstr;
390   
391   inline void   skipToNextVal() {
392     while (i < minstr->getNumOperands() &&
393            ! ((minstr->operands[i].opType == MachineOperand::MO_VirtualRegister
394                || minstr->operands[i].opType == MachineOperand::MO_CCRegister)
395               && minstr->operands[i].value != NULL))
396       ++i;
397   }
398   
399 public:
400   typedef ValOpIterator<_MI, _V> _Self;
401   
402   inline ValOpIterator(_MI* _minstr) : i(0), minstr(_minstr) {
403     resultPos = TargetInstrDescriptors[minstr->opCode].resultPos;
404     skipToNextVal();
405   };
406   
407   inline _V*    operator*()  const { return minstr->getOperand(i).getVRegValue();}
408
409   const MachineOperand & getMachineOperand() const { return minstr->getOperand(i);  }
410
411   inline _V*    operator->() const { return operator*(); }
412   //  inline bool       isDef   ()   const { return (((int) i) == resultPos); }
413   
414   inline bool   isDef   ()   const { return minstr->getOperand(i).isDef; } 
415   inline bool   done    ()   const { return (i == minstr->getNumOperands()); }
416   
417   inline _Self& operator++()       { i++; skipToNextVal(); return *this; }
418   inline _Self  operator++(int)    { _Self tmp = *this; ++*this; return tmp; }
419 };
420
421
422 //---------------------------------------------------------------------------
423 // class MachineCodeForVMInstr
424 // 
425 // Purpose:
426 //   Representation of the sequence of machine instructions created
427 //   for a single VM instruction.  Additionally records information
428 //   about hidden and implicit values used by the machine instructions:
429 //   about hidden values used by the machine instructions:
430 // 
431 //   "Temporary values" are intermediate values used in the machine
432 //   instruction sequence, but not in the VM instruction
433 //   Note that such values should be treated as pure SSA values with
434 //   no interpretation of their operands (i.e., as a TmpInstruction
435 //   object which actually represents such a value).
436 // 
437 //   (2) "Implicit uses" are values used in the VM instruction but not in
438 //       the machine instruction sequence
439 // 
440 //---------------------------------------------------------------------------
441
442 class MachineCodeForVMInstr: public vector<MachineInstr*>
443 {
444 private:
445   vector<Value*> tempVec;         // used by m/c instr but not VM instr
446   
447 public:
448   /*ctor*/      MachineCodeForVMInstr   ()      {}
449   /*ctor*/      ~MachineCodeForVMInstr  ();
450   
451   const vector<Value*>& getTempValues  () const { return tempVec; }
452         vector<Value*>& getTempValues  ()       { return tempVec; }
453   
454   void    addTempValue  (Value* val)            { tempVec.push_back(val); }
455   
456   // dropAllReferences() - This function drops all references within
457   // temporary (hidden) instructions created in implementing the original
458   // VM intruction.  This ensures there are no remaining "uses" within
459   // these hidden instructions, before the values of a method are freed.
460   //
461   // Make this inline because it has to be called from class Instruction
462   // and inlining it avoids a serious circurality in link order.
463   inline void dropAllReferences() {
464     for (unsigned i=0, N=tempVec.size(); i < N; i++)
465       if (Instruction *I = dyn_cast<Instruction>(tempVec[i]))
466         I->dropAllReferences();
467   }
468 };
469
470 inline
471 MachineCodeForVMInstr::~MachineCodeForVMInstr()
472 {
473   // Free the Value objects created to hold intermediate values
474   for (unsigned i=0, N=tempVec.size(); i < N; i++)
475     delete tempVec[i];
476   
477   // Free the MachineInstr objects allocated, if any.
478   for (unsigned i=0, N=this->size(); i < N; i++)
479     delete (*this)[i];
480 }
481
482
483 //---------------------------------------------------------------------------
484 // class MachineCodeForBasicBlock
485 // 
486 // Purpose:
487 //   Representation of the sequence of machine instructions created
488 //   for a basic block.
489 //---------------------------------------------------------------------------
490
491
492 class MachineCodeForBasicBlock: public vector<MachineInstr*> {
493 public:
494   typedef vector<MachineInstr*>::iterator iterator;
495   typedef vector<const MachineInstr*>::const_iterator const_iterator;
496 };
497
498
499 //---------------------------------------------------------------------------
500 // class MachineCodeForMethod
501 // 
502 // Purpose:
503 //   Collect native machine code information for a method.
504 //   This allows target-specific information about the generated code
505 //   to be stored with each method.
506 //---------------------------------------------------------------------------
507
508
509 class MachineCodeForMethod: public NonCopyable {
510 private:
511   Method*       method;
512   bool          compiledAsLeaf;
513   unsigned      staticStackSize;
514   unsigned      automaticVarsSize;
515   unsigned      regSpillsSize;
516   unsigned      optionalOutgoingArgsSize;
517   hash_set<const ConstPoolVal*> constantsForConstPool;
518   hash_map<const Value*, int> offsetsFromFP;
519   hash_map<const Value*, int> offsetsFromSP;
520   
521   inline void     incrementAutomaticVarsSize(int incr)
522                                                   { automaticVarsSize+= incr;
523                                                     staticStackSize += incr; }
524   
525 public:
526   /*ctor*/      MachineCodeForMethod(Method* _M)
527     : method(_M), compiledAsLeaf(false), staticStackSize(0),
528       automaticVarsSize(0), regSpillsSize(0), optionalOutgoingArgsSize(0) {}
529   
530   inline bool     isCompiledAsLeafMethod() const  { return compiledAsLeaf; }
531   inline unsigned getStaticStackSize()     const  { return staticStackSize; }
532   inline unsigned getAutomaticVarsSize()   const  { return automaticVarsSize; }
533   inline unsigned getRegSpillsSize()       const  { return regSpillsSize; }
534   inline unsigned getOptionalOutgoingArgsSize() const
535                                            { return optionalOutgoingArgsSize; }
536   inline const hash_set<const ConstPoolVal*>&
537                   getConstantPoolValues() const {return constantsForConstPool;}
538   
539   void            addToConstantPool        (const ConstPoolVal* constVal)
540                                     { constantsForConstPool.insert(constVal); }
541   
542   inline void     markAsLeafMethod()              { compiledAsLeaf = true; }
543   
544   inline void     incrementStackSize(int incr)    { staticStackSize += incr; }
545   
546   inline void     incrementRegSpillsSize(int incr)
547                                                   { regSpillsSize+= incr;
548                                                     staticStackSize += incr; }
549   
550   inline void     incrementOptionalOutgoingArgsSize(int incr)
551                                           { optionalOutgoingArgsSize+= incr;
552                                                     staticStackSize += incr; }
553   
554   void            putLocalVarAtOffsetFromFP(const Value* local,
555                                             int offset,
556                                             unsigned int size);
557   
558   void            putLocalVarAtOffsetFromSP(const Value* local,
559                                             int offset,
560                                             unsigned int size);
561   
562   int             getOffsetFromFP          (const Value* local) const;
563   
564   int             getOffsetFromSP          (const Value* local) const;
565   
566   void            dump                     () const;
567 };
568
569
570 //---------------------------------------------------------------------------
571 // Debugging Support
572 //---------------------------------------------------------------------------
573
574
575 ostream& operator<<             (ostream& os, const MachineInstr& minstr);
576
577
578 ostream& operator<<             (ostream& os, const MachineOperand& mop);
579                                          
580
581 void    PrintMachineInstructions(const Method *method);
582
583
584 //**************************************************************************/
585
586 #endif