MachineInstr.h revision a995e6086deca9cbd9aab9d6e1e94b36964b66da
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
24template<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
63class MachineOperand {
64public:
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
74private:
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
90public:
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
120public:
121  friend ostream& operator<<(ostream& os, const MachineOperand& mop);
122
123
124private:
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
140public:
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
161inline
162MachineOperand::MachineOperand()
163  : opType(MO_VirtualRegister),
164    value(NULL),
165    regNum(0),
166    immedVal(0),
167    isDef(false)
168{}
169
170inline
171MachineOperand::MachineOperand(MachineOperandType operandType,
172			       Value* _val)
173  : opType(operandType),
174    value(_val),
175    regNum(0),
176    immedVal(0),
177    isDef(false)
178{}
179
180inline
181MachineOperand::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
196inline void
197MachineOperand::Initialize(MachineOperandType operandType,
198			   Value* _val)
199{
200  opType = operandType;
201  value = _val;
202}
203
204inline void
205MachineOperand::InitializeConst(MachineOperandType operandType,
206				int64_t intValue)
207{
208  opType = operandType;
209  value = NULL;
210  immedVal = intValue;
211}
212
213inline void
214MachineOperand::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
247class MachineInstr : public NonCopyable {
248private:
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
255public:
256  typedef ValOpIterator<const MachineInstr, const Value> val_op_const_iterator;
257  typedef ValOpIterator<const MachineInstr,       Value> val_op_iterator;
258
259public:
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
295public:
296  friend ostream& operator<<(ostream& os, const MachineInstr& minstr);
297  friend val_op_const_iterator;
298  friend val_op_iterator;
299
300public:
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
321inline MachineOperand&
322MachineInstr::getOperand(unsigned int i)
323{
324  assert(i < operands.size() && "getOperand() out of range!");
325  return operands[i];
326}
327
328inline const MachineOperand&
329MachineInstr::getOperand(unsigned int i) const
330{
331  assert(i < operands.size() && "getOperand() out of range!");
332  return operands[i];
333}
334
335inline bool
336MachineInstr::operandIsDefined(unsigned int i) const
337{
338  return getOperand(i).opIsDef();
339}
340
341inline bool
342MachineInstr::implicitRefIsDefined(unsigned int i) const
343{
344  assert(i < implicitIsDef.size() && "operand out of range!");
345  return implicitIsDef[i];
346}
347
348inline const Value*
349MachineInstr::getImplicitRef(unsigned int i) const
350{
351  assert(i < implicitRefs.size() && "getImplicitRef() out of range!");
352  return implicitRefs[i];
353}
354
355inline Value*
356MachineInstr::getImplicitRef(unsigned int i)
357{
358  assert(i < implicitRefs.size() && "getImplicitRef() out of range!");
359  return implicitRefs[i];
360}
361
362inline void
363MachineInstr::addImplicitRef(Value* val,
364                             bool isDef)
365{
366  implicitRefs.push_back(val);
367  implicitIsDef.push_back(isDef);
368}
369
370inline void
371MachineInstr::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
381template<class _MI, class _V>
382class ValOpIterator : public std::forward_iterator<_V, ptrdiff_t> {
383private:
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
396public:
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
435class MachineCodeForVMInstr: public vector<MachineInstr*>
436{
437private:
438  vector<Value*> tempVec;         // used by m/c instr but not VM instr
439
440public:
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
463inline
464MachineCodeForVMInstr::~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
485class MachineCodeForBasicBlock: public vector<MachineInstr*> {
486public:
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
497ostream& operator<<             (ostream& os, const MachineInstr& minstr);
498
499
500ostream& operator<<             (ostream& os, const MachineOperand& mop);
501
502
503void	PrintMachineInstructions(const Method *method);
504
505
506//**************************************************************************/
507
508#endif
509