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