MachineInstr.h revision 9636a91649f168f41b477cba705287665e054f79
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
239class MachineInstr : public NonCopyable {
240private:
241  MachineOpCode	opCode;
242  OpCodeMask	opCodeMask;		// extra bits for variants of an opcode
243  vector<MachineOperand> operands;
244
245public:
246  typedef ValOpIterator<const MachineInstr, const Value> val_op_const_iterator;
247  typedef ValOpIterator<const MachineInstr,       Value> val_op_iterator;
248
249public:
250  /*ctor*/		MachineInstr	(MachineOpCode _opCode,
251					 OpCodeMask    _opCodeMask = 0x0);
252  /*ctor*/		MachineInstr	(MachineOpCode _opCode,
253					 unsigned	numOperands,
254					 OpCodeMask    _opCodeMask = 0x0);
255  inline           	~MachineInstr	() {}
256
257  const MachineOpCode	getOpCode	() const;
258
259  unsigned int		getNumOperands	() const;
260
261  const MachineOperand& getOperand	(unsigned int i) const;
262        MachineOperand& getOperand	(unsigned int i);
263
264  bool			operandIsDefined(unsigned int i) const;
265
266  void			dump		(unsigned int indent = 0) const;
267
268
269
270
271
272public:
273  friend ostream& operator<<(ostream& os, const MachineInstr& minstr);
274  friend val_op_const_iterator;
275  friend val_op_iterator;
276
277public:
278  // Access to set the operands when building the machine instruction
279  void			SetMachineOperand(unsigned int i,
280			      MachineOperand::MachineOperandType operandType,
281			      Value* _val, bool isDef=false);
282  void			SetMachineOperand(unsigned int i,
283			      MachineOperand::MachineOperandType operandType,
284			      int64_t intValue, bool isDef=false);
285  void			SetMachineOperand(unsigned int i,
286					  unsigned int regNum,
287					  bool isDef=false);
288};
289
290inline const MachineOpCode
291MachineInstr::getOpCode() const
292{
293  return opCode;
294}
295
296inline unsigned int
297MachineInstr::getNumOperands() const
298{
299  return operands.size();
300}
301
302inline MachineOperand&
303MachineInstr::getOperand(unsigned int i)
304{
305  assert(i < operands.size() && "getOperand() out of range!");
306  return operands[i];
307}
308
309inline const MachineOperand&
310MachineInstr::getOperand(unsigned int i) const
311{
312  assert(i < operands.size() && "getOperand() out of range!");
313  return operands[i];
314}
315
316inline bool
317MachineInstr::operandIsDefined(unsigned int i) const
318{
319  return getOperand(i).opIsDef();
320}
321
322
323template<class _MI, class _V>
324class ValOpIterator : public std::forward_iterator<_V, ptrdiff_t> {
325private:
326  unsigned int i;
327  int resultPos;
328  _MI* minstr;
329
330  inline void	skipToNextVal() {
331    while (i < minstr->getNumOperands() &&
332	   ! ((minstr->operands[i].opType == MachineOperand::MO_VirtualRegister
333	       || minstr->operands[i].opType == MachineOperand::MO_CCRegister)
334	      && minstr->operands[i].value != NULL))
335      ++i;
336  }
337
338public:
339  typedef ValOpIterator<_MI, _V> _Self;
340
341  inline ValOpIterator(_MI* _minstr) : i(0), minstr(_minstr) {
342    resultPos = TargetInstrDescriptors[minstr->opCode].resultPos;
343    skipToNextVal();
344  };
345
346  inline _V*	operator*()  const { return minstr->getOperand(i).getVRegValue();}
347
348  const MachineOperand & getMachineOperand() const { return minstr->getOperand(i);  }
349
350  inline _V*	operator->() const { return operator*(); }
351  //  inline bool	isDef	()   const { return (((int) i) == resultPos); }
352
353  inline bool	isDef	()   const { return minstr->getOperand(i).isDef; }
354  inline bool	done	()   const { return (i == minstr->getNumOperands()); }
355
356  inline _Self& operator++()	   { i++; skipToNextVal(); return *this; }
357  inline _Self  operator++(int)	   { _Self tmp = *this; ++*this; return tmp; }
358};
359
360
361//---------------------------------------------------------------------------
362// class MachineCodeForVMInstr
363//
364// Purpose:
365//   Representation of the sequence of machine instructions created
366//   for a single VM instruction.  Additionally records information
367//   about hidden and implicit values used by the machine instructions:
368//
369//   (1) "Temporary values" are intermediate values used in the machine
370//       instruction sequence, but not in the VM instruction
371//       Note that such values should be treated as pure SSA values with
372//       no interpretation of their operands (i.e., as a TmpInstruction
373//       object which actually represents such a value).
374//
375//   (2) "Implicit uses" are values used in the VM instruction but not in
376//       the machine instruction sequence
377//
378//---------------------------------------------------------------------------
379
380class MachineCodeForVMInstr: public vector<MachineInstr*>
381{
382private:
383  vector<      Value*> tempVec;         // used by m/c instr but not VM instr
384  vector<const Value*> implicitUses;    // used by VM instr but not m/c instr
385
386public:
387  /*ctor*/	MachineCodeForVMInstr	()	{}
388  /*ctor*/	~MachineCodeForVMInstr	();
389
390  const vector<      Value*>& getTempValues  () const { return tempVec; }
391  const vector<const Value*>& getImplicitUses() const { return implicitUses; }
392
393  void    addTempValue  (      Value* val)      { tempVec.push_back(val); }
394  void    addImplicitUse(const Value* val)      { implicitUses.push_back(val);}
395
396  // dropAllReferences() - This function drops all references within
397  // temporary (hidden) instructions created in implementing the original
398  // VM intruction.  This ensures there are no remaining "uses" within
399  // these hidden instructions, before the values of a method are freed.
400  //
401  // Make this inline because it has to be called from class Instruction
402  // and inlining it avoids a serious circurality in link order.
403  inline void dropAllReferences() {
404    for (unsigned i=0, N=tempVec.size(); i < N; i++)
405      if (Instruction *I = dyn_cast<Instruction>(tempVec[i]))
406        I->dropAllReferences();
407  }
408};
409
410inline
411MachineCodeForVMInstr::~MachineCodeForVMInstr()
412{
413  // Free the Value objects created to hold intermediate values
414  for (unsigned i=0, N=tempVec.size(); i < N; i++)
415    delete tempVec[i];
416
417  // Free the MachineInstr objects allocated, if any.
418  for (unsigned i=0, N=this->size(); i < N; i++)
419    delete (*this)[i];
420}
421
422
423//---------------------------------------------------------------------------
424// class MachineCodeForBasicBlock
425//
426// Purpose:
427//   Representation of the sequence of machine instructions created
428//   for a basic block.
429//---------------------------------------------------------------------------
430
431
432class MachineCodeForBasicBlock: public vector<MachineInstr*> {
433public:
434  typedef vector<MachineInstr*>::iterator iterator;
435  typedef vector<const MachineInstr*>::const_iterator const_iterator;
436};
437
438
439//---------------------------------------------------------------------------
440// Target-independent utility routines for creating machine instructions
441//---------------------------------------------------------------------------
442
443
444//------------------------------------------------------------------------
445// Function Set2OperandsFromInstr
446// Function Set3OperandsFromInstr
447//
448// For the common case of 2- and 3-operand arithmetic/logical instructions,
449// set the m/c instr. operands directly from the VM instruction's operands.
450// Check whether the first or second operand is 0 and can use a dedicated
451// "0" register.
452// Check whether the second operand should use an immediate field or register.
453// (First and third operands are never immediates for such instructions.)
454//
455// Arguments:
456// canDiscardResult: Specifies that the result operand can be discarded
457//		     by using the dedicated "0"
458//
459// op1position, op2position and resultPosition: Specify in which position
460//		     in the machine instruction the 3 operands (arg1, arg2
461//		     and result) should go.
462//
463// RETURN VALUE: unsigned int flags, where
464//	flags & 0x01	=> operand 1 is constant and needs a register
465//	flags & 0x02	=> operand 2 is constant and needs a register
466//------------------------------------------------------------------------
467
468void		Set2OperandsFromInstr	(MachineInstr* minstr,
469					 InstructionNode* vmInstrNode,
470					 const TargetMachine& targetMachine,
471					 bool canDiscardResult = false,
472					 int op1Position = 0,
473					 int resultPosition = 1);
474
475void		Set3OperandsFromInstr	(MachineInstr* minstr,
476					 InstructionNode* vmInstrNode,
477					 const TargetMachine& targetMachine,
478					 bool canDiscardResult = false,
479					 int op1Position = 0,
480					 int op2Position = 1,
481					 int resultPosition = 2);
482
483MachineOperand::MachineOperandType
484		ChooseRegOrImmed(Value* val,
485				 MachineOpCode opCode,
486				 const TargetMachine& targetMachine,
487				 bool canUseImmed,
488				 unsigned int& getMachineRegNum,
489				 int64_t& getImmedValue);
490
491
492ostream& operator<<(ostream& os, const MachineInstr& minstr);
493
494
495ostream& operator<<(ostream& os, const MachineOperand& mop);
496
497
498void	PrintMachineInstructions	(const Method *method);
499
500
501//**************************************************************************/
502
503#endif
504