MachineInstr.h revision 697954c15da58bd8b186dbafdedd8b06db770201
123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve// $Id$ -*-c++-*-
223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//***************************************************************************
323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve// File:
423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//	MachineInstr.h
523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve// Purpose:
723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve// Strategy:
1023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
1123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve// History:
1223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//	7/2/01	 -  Vikram Adve  -  Created
1323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//**************************************************************************/
1423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
1523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve#ifndef LLVM_CODEGEN_MACHINEINSTR_H
1623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve#define LLVM_CODEGEN_MACHINEINSTR_H
1723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
18360e17eaf1a2abda82b02235dc57d26d8f83c937Chris Lattner#include "Support/DataTypes.h"
19cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#include "Support/NonCopyable.h"
20cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#include "llvm/CodeGen/InstrForest.h"
214bc86976bb14ce66b734a534351a4e9fb027d17dVikram S. Adve#include "llvm/Target/MachineInstrInfo.h"
22be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve#include "llvm/Annotation.h"
23be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve#include "llvm/Method.h"
24cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#include <iterator>
25be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve#include <values.h>
2623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
276a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Advetemplate<class _MI, class _V> class ValOpIterator;
286a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve
296a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve
30be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve//************************** External Constants ****************************/
31be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve
32be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adveconst int INVALID_FRAME_OFFSET = MAXINT;
33be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve
34be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve
35be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve//*************************** External Classes *****************************/
36be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve
37be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve
3823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//---------------------------------------------------------------------------
3923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve// class MachineOperand
4023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
4123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve// Purpose:
4223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   Representation of each machine instruction operand.
4323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   This class is designed so that you can allocate a vector of operands
4423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   first and initialize each one later.
4523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
4623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   E.g, for this VM instruction:
4723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//		ptr = alloca type, numElements
4823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   we generate 2 machine instructions on the SPARC:
4923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
5023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//		mul Constant, Numelements -> Reg
5123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//		add %sp, Reg -> Ptr
5223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
5323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   Each instruction has 3 operands, listed above.  Of those:
5423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   -	Reg, NumElements, and Ptr are of operand type MO_Register.
5523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   -	Constant is of operand type MO_SignExtendedImmed on the SPARC.
5623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
5723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   For the register operands, the virtual register type is as follows:
5823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
5923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   -  Reg will be of virtual register type MO_MInstrVirtualReg.  The field
6023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//	MachineInstr* minstr will point to the instruction that computes reg.
6123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
6223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   -	%sp will be of virtual register type MO_MachineReg.
6323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//	The field regNum identifies the machine register.
6423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
6523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   -	NumElements will be of virtual register type MO_VirtualReg.
6623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//	The field Value* value identifies the value.
6723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
6823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   -	Ptr will also be of virtual register type MO_VirtualReg.
6923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//	Again, the field Value* value identifies the value.
7023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
7123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//---------------------------------------------------------------------------
7223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
731bf6d645cd8e167851660e841276dcc53be0e344Ruchira Sasanka
7423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adveclass MachineOperand {
7523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Advepublic:
7623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  enum MachineOperandType {
776a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve    MO_VirtualRegister,		// virtual register for *value
786a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve    MO_MachineRegister,		// pre-assigned machine register `regNum'
7923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve    MO_CCRegister,
8023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve    MO_SignExtendedImmed,
8123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve    MO_UnextendedImmed,
8223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve    MO_PCRelativeDisp,
8323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  };
8423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
856a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adveprivate:
866a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  MachineOperandType opType;
8723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
886a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  union {
896a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve    Value*	value;		// BasicBlockVal for a label operand.
9023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve				// ConstantVal for a non-address immediate.
916a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve				// Virtual register for an SSA operand,
926a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve				// including hidden operands required for
93427a5273113274ee35cff78534dba2ae812c79ceRuchira Sasanka				// the generated machine code.
946a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve    int64_t immedVal;		// constant value for an explicit constant
956a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  };
96773fc471bdc36a221ff9302a07e58f8f7210d87dRuchira Sasanka
9721721b63c3b5a314dfa0be14823b10273860787cRuchira Sasanka  int regNum;	                // register number for an explicit register
98427a5273113274ee35cff78534dba2ae812c79ceRuchira Sasanka                                // will be set for a value after reg allocation
9998f2f8053bebaad7683de074bfb74239364098d2Vikram S. Adve  bool isDef;                   // is this a defition for the value
10023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
1016a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Advepublic:
10223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  /*ctor*/		MachineOperand	();
10323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  /*ctor*/		MachineOperand	(MachineOperandType operandType,
10423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve					 Value* _val);
10523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  /*copy ctor*/		MachineOperand	(const MachineOperand&);
10623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  /*dtor*/		~MachineOperand	() {}
10723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
1086a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  // Accessor methods.  Caller is responsible for checking the
1096a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  // operand type before invoking the corresponding accessor.
1106a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  //
11198f2f8053bebaad7683de074bfb74239364098d2Vikram S. Adve  inline MachineOperandType getOperandType	() const {
1126a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve    return opType;
1136a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  }
11498f2f8053bebaad7683de074bfb74239364098d2Vikram S. Adve  inline Value*		getVRegValue	() const {
115746e0014a6c59f285ffefc30c722ef2cf69eb95dChris Lattner    assert(opType == MO_VirtualRegister || opType == MO_CCRegister ||
116746e0014a6c59f285ffefc30c722ef2cf69eb95dChris Lattner	   opType == MO_PCRelativeDisp);
1176a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve    return value;
1186a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  }
119df1c3b8398d1df253ebd389ac1068ec732a2f28fVikram S. Adve  inline int            getMachineRegNum() const {
1206a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve    assert(opType == MO_MachineRegister);
121df1c3b8398d1df253ebd389ac1068ec732a2f28fVikram S. Adve    return regNum;
1226a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  }
12398f2f8053bebaad7683de074bfb74239364098d2Vikram S. Adve  inline int64_t	getImmedValue	() const {
124dd52255e9a26fbc9b7e0cd22a2dd99b0b6bae991Vikram S. Adve    assert(opType == MO_SignExtendedImmed || opType == MO_UnextendedImmed);
1256a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve    return immedVal;
1266a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  }
12798f2f8053bebaad7683de074bfb74239364098d2Vikram S. Adve  inline bool		opIsDef		() const {
12898f2f8053bebaad7683de074bfb74239364098d2Vikram S. Adve    return isDef;
12998f2f8053bebaad7683de074bfb74239364098d2Vikram S. Adve  }
1306a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve
1316a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Advepublic:
132697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop);
13398f2f8053bebaad7683de074bfb74239364098d2Vikram S. Adve
1346a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve
1356a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adveprivate:
13623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  // These functions are provided so that a vector of operands can be
13723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  // statically allocated and individual ones can be initialized later.
1386a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  // Give class MachineInstr gets access to these functions.
13923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  //
14023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  void			Initialize	(MachineOperandType operandType,
14123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve					 Value* _val);
14223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  void			InitializeConst	(MachineOperandType operandType,
14323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve					 int64_t intValue);
144df1c3b8398d1df253ebd389ac1068ec732a2f28fVikram S. Adve  void			InitializeReg	(int regNum);
1456a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve
1466a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  friend class MachineInstr;
147136c9f4062b0fe6d864ebc2bc2b0cbada931a28eVikram S. Adve  friend class ValOpIterator<const MachineInstr, const Value>;
148136c9f4062b0fe6d864ebc2bc2b0cbada931a28eVikram S. Adve  friend class ValOpIterator<      MachineInstr,       Value>;
1497cd2ca13c1920e9db68695a364048cb6586bb324Ruchira Sasanka
1507cd2ca13c1920e9db68695a364048cb6586bb324Ruchira Sasanka
1517cd2ca13c1920e9db68695a364048cb6586bb324Ruchira Sasankapublic:
1527cd2ca13c1920e9db68695a364048cb6586bb324Ruchira Sasanka
1531876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve  // replaces the Value with its corresponding physical register after
154427a5273113274ee35cff78534dba2ae812c79ceRuchira Sasanka  // register allocation is complete
155eda6806f6aaec9a64707a8e5609ae21b15e1440aRuchira Sasanka  void setRegForValue(int reg) {
1561876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve    assert(opType == MO_VirtualRegister || opType == MO_CCRegister ||
1571876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve	   opType == MO_MachineRegister);
158427a5273113274ee35cff78534dba2ae812c79ceRuchira Sasanka    regNum = reg;
159427a5273113274ee35cff78534dba2ae812c79ceRuchira Sasanka  }
160427a5273113274ee35cff78534dba2ae812c79ceRuchira Sasanka
161475253b430649ccaf3c954714164821883aba9acRuchira Sasanka  // used to get the reg number if when one is allocted (must be
162475253b430649ccaf3c954714164821883aba9acRuchira Sasanka  // called only after reg alloc)
16321721b63c3b5a314dfa0be14823b10273860787cRuchira Sasanka  inline int  getAllocatedRegNum() const {
164475253b430649ccaf3c954714164821883aba9acRuchira Sasanka    assert(opType == MO_VirtualRegister || opType == MO_CCRegister ||
165475253b430649ccaf3c954714164821883aba9acRuchira Sasanka	   opType == MO_MachineRegister);
166475253b430649ccaf3c954714164821883aba9acRuchira Sasanka    return regNum;
167475253b430649ccaf3c954714164821883aba9acRuchira Sasanka  }
168475253b430649ccaf3c954714164821883aba9acRuchira Sasanka
169c866fe19492fc8958f7579c8462cde5bc03dc3b2Ruchira Sasanka
17023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve};
17123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
17223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
17323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adveinline
17423ee550765232e22d0daf6407141ecef4c55c06fVikram S. AdveMachineOperand::MachineOperand()
1756a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  : opType(MO_VirtualRegister),
176773fc471bdc36a221ff9302a07e58f8f7210d87dRuchira Sasanka    immedVal(0),
17721721b63c3b5a314dfa0be14823b10273860787cRuchira Sasanka    regNum(-1),
178773fc471bdc36a221ff9302a07e58f8f7210d87dRuchira Sasanka    isDef(false)
17923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve{}
18023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
18123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adveinline
18223ee550765232e22d0daf6407141ecef4c55c06fVikram S. AdveMachineOperand::MachineOperand(MachineOperandType operandType,
18323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve			       Value* _val)
1846a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  : opType(operandType),
185773fc471bdc36a221ff9302a07e58f8f7210d87dRuchira Sasanka    immedVal(0),
186618155f6c830af9b2abb587b6d1cb5bea3dcc4f9Ruchira Sasanka    regNum(-1),
187773fc471bdc36a221ff9302a07e58f8f7210d87dRuchira Sasanka    isDef(false)
18823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve{}
18923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
19023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adveinline
19123ee550765232e22d0daf6407141ecef4c55c06fVikram S. AdveMachineOperand::MachineOperand(const MachineOperand& mo)
192773fc471bdc36a221ff9302a07e58f8f7210d87dRuchira Sasanka  : opType(mo.opType),
193773fc471bdc36a221ff9302a07e58f8f7210d87dRuchira Sasanka    isDef(false)
19423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve{
1956a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  switch(opType) {
1966a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  case MO_VirtualRegister:
1976a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  case MO_CCRegister:		value = mo.value; break;
1986a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  case MO_MachineRegister:	regNum = mo.regNum; break;
1996a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  case MO_SignExtendedImmed:
2006a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  case MO_UnextendedImmed:
2016a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  case MO_PCRelativeDisp:	immedVal = mo.immedVal; break;
2026a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  default: assert(0);
2036a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  }
20423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve}
20523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
20623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adveinline void
20723ee550765232e22d0daf6407141ecef4c55c06fVikram S. AdveMachineOperand::Initialize(MachineOperandType operandType,
20823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve			   Value* _val)
20923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve{
2106a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  opType = operandType;
21123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  value = _val;
21233eb292e127a75d51587c390241817d8c355a18bRuchira Sasanka  regNum = -1;
21323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve}
21423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
21523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adveinline void
21623ee550765232e22d0daf6407141ecef4c55c06fVikram S. AdveMachineOperand::InitializeConst(MachineOperandType operandType,
21723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve				int64_t intValue)
21823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve{
2196a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  opType = operandType;
22023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  value = NULL;
22123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  immedVal = intValue;
22233eb292e127a75d51587c390241817d8c355a18bRuchira Sasanka  regNum = -1;
22323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve}
22423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
22523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adveinline void
226df1c3b8398d1df253ebd389ac1068ec732a2f28fVikram S. AdveMachineOperand::InitializeReg(int _regNum)
22723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve{
2286a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  opType = MO_MachineRegister;
22923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  value = NULL;
23021721b63c3b5a314dfa0be14823b10273860787cRuchira Sasanka  regNum = (int) _regNum;
23123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve}
23223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
23323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
23423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//---------------------------------------------------------------------------
23523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve// class MachineInstr
23623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
23723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve// Purpose:
23823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   Representation of each machine instruction.
23923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
24023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   MachineOpCode must be an enum, defined separately for each target.
24123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   E.g., It is defined in SparcInstructionSelection.h for the SPARC.
24223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
24323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   opCodeMask is used to record variants of an instruction.
24423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   E.g., each branch instruction on SPARC has 2 flags (i.e., 4 variants):
24523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//	ANNUL:		   if 1: Annul delay slot instruction.
24623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//	PREDICT-NOT-TAKEN: if 1: predict branch not taken.
24723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   Instead of creating 4 different opcodes for BNZ, we create a single
24823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   opcode and set bits in opCodeMask for each of these flags.
249a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve//
250a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve//  There are 2 kinds of operands:
251a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve//
252a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve//  (1) Explicit operands of the machine instruction in vector operands[]
253a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve//
254a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve//  (2) "Implicit operands" are values implicitly used or defined by the
255a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve//      machine instruction, such as arguments to a CALL, return value of
256a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve//      a CALL (if any), and return value of a RETURN.
25723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//---------------------------------------------------------------------------
25823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
2594bc3daaa3f3c9f22d5dd695e987e8d20f999791cChris Lattnerclass MachineInstr : public NonCopyable {
26023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adveprivate:
261a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  MachineOpCode         opCode;
262a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  OpCodeMask            opCodeMask;	// extra bits for variants of an opcode
263697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  std::vector<MachineOperand> operands;
264697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  std::vector<Value*>   implicitRefs;   // values implicitly referenced by this
265697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  std::vector<bool>     implicitIsDef;  // machine instruction (eg, call args)
2666a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve
2676a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Advepublic:
2687a1767520611d9ff6face702068de858e1cadf2cChris Lattner  typedef ValOpIterator<const MachineInstr, const Value> val_const_op_iterator;
269c866fe19492fc8958f7579c8462cde5bc03dc3b2Ruchira Sasanka  typedef ValOpIterator<const MachineInstr,       Value> val_op_iterator;
27023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
27123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Advepublic:
27223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  /*ctor*/		MachineInstr	(MachineOpCode _opCode,
27323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve					 OpCodeMask    _opCodeMask = 0x0);
2741885da4f49cf32efde2d4c840365c4333a0c8579Vikram S. Adve  /*ctor*/		MachineInstr	(MachineOpCode _opCode,
2751885da4f49cf32efde2d4c840365c4333a0c8579Vikram S. Adve					 unsigned	numOperands,
2761885da4f49cf32efde2d4c840365c4333a0c8579Vikram S. Adve					 OpCodeMask    _opCodeMask = 0x0);
2774bc3daaa3f3c9f22d5dd695e987e8d20f999791cChris Lattner  inline           	~MachineInstr	() {}
278704037f0248793be829df9e185bd889ca41beaf7Chris Lattner  const MachineOpCode	getOpCode	() const { return opCode; }
279da47526737c111128e34b9627a3beea1a68bd93eChris Lattner
280a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  //
281a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  // Information about explicit operands of the instruction
282a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  //
283704037f0248793be829df9e185bd889ca41beaf7Chris Lattner  unsigned int		getNumOperands	() const { return operands.size(); }
284a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve
285a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  bool			operandIsDefined(unsigned int i) const;
28623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
28723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  const MachineOperand& getOperand	(unsigned int i) const;
2886a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve        MachineOperand& getOperand	(unsigned int i);
28923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
290a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  //
291a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  // Information about implicit operands of the instruction
292a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  //
293a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  unsigned int		getNumImplicitRefs() const{return implicitRefs.size();}
294a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve
295a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  bool			implicitRefIsDefined(unsigned int i) const;
296136c9f4062b0fe6d864ebc2bc2b0cbada931a28eVikram S. Adve
297a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  const Value*          getImplicitRef  (unsigned int i) const;
298a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve        Value*          getImplicitRef  (unsigned int i);
299a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve
300a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  //
301a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  // Debugging support
302a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  //
3030b03c6a492a0e09049b6c0bd127bd0ede7732aa5Ruchira Sasanka  void			dump		(unsigned int indent = 0) const;
3047cd2ca13c1920e9db68695a364048cb6586bb324Ruchira Sasanka
30523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
30623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Advepublic:
307697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  friend std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr);
308697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  friend class val_const_op_iterator;
309697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  friend class val_op_iterator;
31023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
31123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Advepublic:
31223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  // Access to set the operands when building the machine instruction
31323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  void			SetMachineOperand(unsigned int i,
31423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve			      MachineOperand::MachineOperandType operandType,
315773fc471bdc36a221ff9302a07e58f8f7210d87dRuchira Sasanka			      Value* _val, bool isDef=false);
31623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  void			SetMachineOperand(unsigned int i,
31723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve			      MachineOperand::MachineOperandType operandType,
318773fc471bdc36a221ff9302a07e58f8f7210d87dRuchira Sasanka			      int64_t intValue, bool isDef=false);
31923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  void			SetMachineOperand(unsigned int i,
320df1c3b8398d1df253ebd389ac1068ec732a2f28fVikram S. Adve					  int regNum,
321773fc471bdc36a221ff9302a07e58f8f7210d87dRuchira Sasanka					  bool isDef=false);
32223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
323a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  void                  addImplicitRef	 (Value* val,
324a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve                                          bool isDef=false);
325a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve
326a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  void                  setImplicitRef	 (unsigned int i,
327a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve                                          Value* val,
328a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve                                          bool isDef=false);
329a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve};
33023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
33123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
3326a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adveinline MachineOperand&
3336a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. AdveMachineInstr::getOperand(unsigned int i)
3346a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve{
3351885da4f49cf32efde2d4c840365c4333a0c8579Vikram S. Adve  assert(i < operands.size() && "getOperand() out of range!");
3366a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  return operands[i];
3376a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve}
3386a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve
33923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adveinline const MachineOperand&
34023ee550765232e22d0daf6407141ecef4c55c06fVikram S. AdveMachineInstr::getOperand(unsigned int i) const
34123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve{
3421885da4f49cf32efde2d4c840365c4333a0c8579Vikram S. Adve  assert(i < operands.size() && "getOperand() out of range!");
34323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  return operands[i];
34423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve}
34523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
346136c9f4062b0fe6d864ebc2bc2b0cbada931a28eVikram S. Adveinline bool
347136c9f4062b0fe6d864ebc2bc2b0cbada931a28eVikram S. AdveMachineInstr::operandIsDefined(unsigned int i) const
348136c9f4062b0fe6d864ebc2bc2b0cbada931a28eVikram S. Adve{
349136c9f4062b0fe6d864ebc2bc2b0cbada931a28eVikram S. Adve  return getOperand(i).opIsDef();
350136c9f4062b0fe6d864ebc2bc2b0cbada931a28eVikram S. Adve}
351136c9f4062b0fe6d864ebc2bc2b0cbada931a28eVikram S. Adve
352a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adveinline bool
353a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. AdveMachineInstr::implicitRefIsDefined(unsigned int i) const
354a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve{
355a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  assert(i < implicitIsDef.size() && "operand out of range!");
356a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  return implicitIsDef[i];
357a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve}
358a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve
359a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adveinline const Value*
360a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. AdveMachineInstr::getImplicitRef(unsigned int i) const
361a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve{
362a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  assert(i < implicitRefs.size() && "getImplicitRef() out of range!");
363a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  return implicitRefs[i];
364a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve}
365a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve
366a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adveinline Value*
367a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. AdveMachineInstr::getImplicitRef(unsigned int i)
368a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve{
369a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  assert(i < implicitRefs.size() && "getImplicitRef() out of range!");
370a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  return implicitRefs[i];
371a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve}
372a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve
373a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adveinline void
374a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. AdveMachineInstr::addImplicitRef(Value* val,
375a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve                             bool isDef)
376a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve{
377a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  implicitRefs.push_back(val);
378a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  implicitIsDef.push_back(isDef);
379a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve}
380a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve
381a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adveinline void
382a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. AdveMachineInstr::setImplicitRef(unsigned int i,
383a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve                             Value* val,
384a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve                             bool isDef)
385a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve{
386a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  assert(i < implicitRefs.size() && "setImplicitRef() out of range!");
387a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  implicitRefs[i] = val;
388a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve  implicitIsDef[i] = isDef;
389a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve}
390a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve
39123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
3926a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Advetemplate<class _MI, class _V>
3936a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adveclass ValOpIterator : public std::forward_iterator<_V, ptrdiff_t> {
3946a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adveprivate:
3956a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  unsigned int i;
3966a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  int resultPos;
3974f01c1ee9920e25bb9695189439ed5e29fc9128dVikram S. Adve  _MI* minstr;
39898f2f8053bebaad7683de074bfb74239364098d2Vikram S. Adve
3996a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  inline void	skipToNextVal() {
40098f2f8053bebaad7683de074bfb74239364098d2Vikram S. Adve    while (i < minstr->getNumOperands() &&
40198f2f8053bebaad7683de074bfb74239364098d2Vikram S. Adve	   ! ((minstr->operands[i].opType == MachineOperand::MO_VirtualRegister
40298f2f8053bebaad7683de074bfb74239364098d2Vikram S. Adve	       || minstr->operands[i].opType == MachineOperand::MO_CCRegister)
40398f2f8053bebaad7683de074bfb74239364098d2Vikram S. Adve	      && minstr->operands[i].value != NULL))
4046a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve      ++i;
4056a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  }
4066a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve
4076a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Advepublic:
4086a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  typedef ValOpIterator<_MI, _V> _Self;
4096a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve
4106a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  inline ValOpIterator(_MI* _minstr) : i(0), minstr(_minstr) {
4116a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve    resultPos = TargetInstrDescriptors[minstr->opCode].resultPos;
4126a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve    skipToNextVal();
4136a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  };
4146a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve
4156a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  inline _V*	operator*()  const { return minstr->getOperand(i).getVRegValue();}
4161bf6d645cd8e167851660e841276dcc53be0e344Ruchira Sasanka
4171bf6d645cd8e167851660e841276dcc53be0e344Ruchira Sasanka  const MachineOperand & getMachineOperand() const { return minstr->getOperand(i);  }
4181bf6d645cd8e167851660e841276dcc53be0e344Ruchira Sasanka
4196a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  inline _V*	operator->() const { return operator*(); }
420773fc471bdc36a221ff9302a07e58f8f7210d87dRuchira Sasanka  //  inline bool	isDef	()   const { return (((int) i) == resultPos); }
42198f2f8053bebaad7683de074bfb74239364098d2Vikram S. Adve
422773fc471bdc36a221ff9302a07e58f8f7210d87dRuchira Sasanka  inline bool	isDef	()   const { return minstr->getOperand(i).isDef; }
4236a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  inline bool	done	()   const { return (i == minstr->getNumOperands()); }
4246a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve
4256a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  inline _Self& operator++()	   { i++; skipToNextVal(); return *this; }
4266a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve  inline _Self  operator++(int)	   { _Self tmp = *this; ++*this; return tmp; }
4276a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve};
4286a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve
4296a175e01eb164baac5cc16311c474ff644ce17c1Vikram S. Adve
43023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//---------------------------------------------------------------------------
431f6445837e9733e5657884f529879c5db2ca51f50Vikram S. Adve// class MachineCodeForVMInstr
43223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
43323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve// Purpose:
43423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//   Representation of the sequence of machine instructions created
4352a97dd1fc335cb8fd87c1fe6fada5f64006712c8Vikram S. Adve//   for a single VM instruction.  Additionally records information
436da47526737c111128e34b9627a3beea1a68bd93eChris Lattner//   about hidden and implicit values used by the machine instructions:
437a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve//   about hidden values used by the machine instructions:
4382a97dd1fc335cb8fd87c1fe6fada5f64006712c8Vikram S. Adve//
439a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve//   "Temporary values" are intermediate values used in the machine
440a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve//   instruction sequence, but not in the VM instruction
441a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve//   Note that such values should be treated as pure SSA values with
442a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve//   no interpretation of their operands (i.e., as a TmpInstruction
443a995e6086deca9cbd9aab9d6e1e94b36964b66daVikram S. Adve//   object which actually represents such a value).
44423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//
445da47526737c111128e34b9627a3beea1a68bd93eChris Lattner//   (2) "Implicit uses" are values used in the VM instruction but not in
446da47526737c111128e34b9627a3beea1a68bd93eChris Lattner//       the machine instruction sequence
447da47526737c111128e34b9627a3beea1a68bd93eChris Lattner//
44823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//---------------------------------------------------------------------------
44923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
450697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerclass MachineCodeForVMInstr: public std::vector<MachineInstr*>
45123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve{
45223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adveprivate:
453697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  std::vector<Value*> tempVec;         // used by m/c instr but not VM instr
45423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
45523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Advepublic:
45623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  /*ctor*/	MachineCodeForVMInstr	()	{}
45723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  /*ctor*/	~MachineCodeForVMInstr	();
45823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
459697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  const std::vector<Value*>& getTempValues  () const { return tempVec; }
460697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner        std::vector<Value*>& getTempValues  ()       { return tempVec; }
4612a97dd1fc335cb8fd87c1fe6fada5f64006712c8Vikram S. Adve
462593da4acc56d4c591ad688e6605b04d0825c867eVikram S. Adve  void    addTempValue  (Value* val)            { tempVec.push_back(val); }
46323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
46423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  // dropAllReferences() - This function drops all references within
46523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  // temporary (hidden) instructions created in implementing the original
46623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  // VM intruction.  This ensures there are no remaining "uses" within
46723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  // these hidden instructions, before the values of a method are freed.
46823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  //
46923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  // Make this inline because it has to be called from class Instruction
47023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  // and inlining it avoids a serious circurality in link order.
47123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  inline void dropAllReferences() {
47223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve    for (unsigned i=0, N=tempVec.size(); i < N; i++)
4739636a91649f168f41b477cba705287665e054f79Chris Lattner      if (Instruction *I = dyn_cast<Instruction>(tempVec[i]))
4742a97dd1fc335cb8fd87c1fe6fada5f64006712c8Vikram S. Adve        I->dropAllReferences();
47523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  }
47623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve};
47723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
47823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adveinline
47923ee550765232e22d0daf6407141ecef4c55c06fVikram S. AdveMachineCodeForVMInstr::~MachineCodeForVMInstr()
48023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve{
48123ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  // Free the Value objects created to hold intermediate values
48223ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  for (unsigned i=0, N=tempVec.size(); i < N; i++)
48323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve    delete tempVec[i];
48423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
48523ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  // Free the MachineInstr objects allocated, if any.
48623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve  for (unsigned i=0, N=this->size(); i < N; i++)
48723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve    delete (*this)[i];
48823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve}
48923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
490f6445837e9733e5657884f529879c5db2ca51f50Vikram S. Adve
491f6445837e9733e5657884f529879c5db2ca51f50Vikram S. Adve//---------------------------------------------------------------------------
492f6445837e9733e5657884f529879c5db2ca51f50Vikram S. Adve// class MachineCodeForBasicBlock
493f6445837e9733e5657884f529879c5db2ca51f50Vikram S. Adve//
494f6445837e9733e5657884f529879c5db2ca51f50Vikram S. Adve// Purpose:
495f6445837e9733e5657884f529879c5db2ca51f50Vikram S. Adve//   Representation of the sequence of machine instructions created
496f6445837e9733e5657884f529879c5db2ca51f50Vikram S. Adve//   for a basic block.
497f6445837e9733e5657884f529879c5db2ca51f50Vikram S. Adve//---------------------------------------------------------------------------
498f6445837e9733e5657884f529879c5db2ca51f50Vikram S. Adve
499f6445837e9733e5657884f529879c5db2ca51f50Vikram S. Adve
500697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerclass MachineCodeForBasicBlock: public std::vector<MachineInstr*> {
501f6445837e9733e5657884f529879c5db2ca51f50Vikram S. Advepublic:
502697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  typedef std::vector<MachineInstr*>::iterator iterator;
503697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  typedef std::vector<MachineInstr*>::const_iterator const_iterator;
504f6445837e9733e5657884f529879c5db2ca51f50Vikram S. Adve};
505f6445837e9733e5657884f529879c5db2ca51f50Vikram S. Adve
506f6445837e9733e5657884f529879c5db2ca51f50Vikram S. Adve
50723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//---------------------------------------------------------------------------
5081876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve// class MachineCodeForMethod
5091876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve//
5101876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve// Purpose:
5111876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve//   Collect native machine code information for a method.
5121876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve//   This allows target-specific information about the generated code
5131876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve//   to be stored with each method.
5141876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve//---------------------------------------------------------------------------
5151876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve
5161876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve
517be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve
518be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adveclass MachineCodeForMethod: public NonCopyable, private Annotation {
519be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adveprivate:
520be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  static AnnotationID AID;
5211876f92599b90f0a4b276aae413a1b965954174dVikram S. Adveprivate:
522be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  const Method* method;
5231876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve  bool          compiledAsLeaf;
5241876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve  unsigned	staticStackSize;
5251876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve  unsigned	automaticVarsSize;
5261876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve  unsigned	regSpillsSize;
527be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  unsigned	currentOptionalArgsSize;
528be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  unsigned	maxOptionalArgsSize;
529be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  unsigned	currentTmpValuesSize;
530697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  std::hash_set<const Constant*> constantsForConstPool;
531697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  std::hash_map<const Value*, int> offsets;
532be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  // hash_map<const Value*, int> offsetsFromSP;
5331876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve
5341876f92599b90f0a4b276aae413a1b965954174dVikram S. Advepublic:
535be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  /*ctor*/      MachineCodeForMethod(const Method* method,
536be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve                                     const TargetMachine& target);
537be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve
538be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  // The next two methods are used to construct and to retrieve
539be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  // the MachineCodeForMethod object for the given method.
540be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  // construct() -- Allocates and initializes for a given method and target
541be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  // get()       -- Returns a handle to the object.
542be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  //                This should not be called before "construct()"
543be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  //                for a given Method.
544be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  //
545be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  inline static MachineCodeForMethod& construct(const Method* method,
546be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve                                                const TargetMachine& target)
547be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  {
548be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve    assert(method->getAnnotation(MachineCodeForMethod::AID) == NULL &&
549be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve           "Object already exists for this method!");
550be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve    MachineCodeForMethod* mcInfo = new MachineCodeForMethod(method, target);
551be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve    method->addAnnotation(mcInfo);
552be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve    return *mcInfo;
553be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  }
554be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve
555be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  inline static MachineCodeForMethod& get(const Method* method)
556be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  {
557be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve    MachineCodeForMethod* mc = (MachineCodeForMethod*)
558be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve      method->getAnnotation(MachineCodeForMethod::AID);
559be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve    assert(mc && "Call construct() method first to allocate the object");
560be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve    return *mc;
561be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  }
562be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve
563be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  //
564be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  // Accessors for global information about generated code for a method.
565be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  //
566be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  inline bool     isCompiledAsLeafMethod() const { return compiledAsLeaf; }
567be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  inline unsigned getStaticStackSize()     const { return staticStackSize; }
568be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  inline unsigned getAutomaticVarsSize()   const { return automaticVarsSize; }
569be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  inline unsigned getRegSpillsSize()       const { return regSpillsSize; }
570be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  inline unsigned getMaxOptionalArgsSize() const { return maxOptionalArgsSize;}
571be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  inline unsigned getCurrentOptionalArgsSize() const
572be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve                                             { return currentOptionalArgsSize;}
573697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner  inline const std::hash_set<const Constant*>&
574dd52255e9a26fbc9b7e0cd22a2dd99b0b6bae991Vikram S. Adve                  getConstantPoolValues() const {return constantsForConstPool;}
575dd52255e9a26fbc9b7e0cd22a2dd99b0b6bae991Vikram S. Adve
576be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  //
577be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  // Modifiers used during code generation
578be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  //
579be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  void            initializeFrameLayout    (const TargetMachine& target);
580be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve
581e9bb2df410f7a22decad9a883f7139d5857c1520Chris Lattner  void            addToConstantPool        (const Constant* constVal)
582dd52255e9a26fbc9b7e0cd22a2dd99b0b6bae991Vikram S. Adve                                    { constantsForConstPool.insert(constVal); }
5831876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve
5841876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve  inline void     markAsLeafMethod()              { compiledAsLeaf = true; }
5851876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve
586be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  int             allocateLocalVar         (const TargetMachine& target,
587abf73cedd4f1100fae3e4bfe969649e1643e5254Vikram S. Adve                                            const Value* local,
588abf73cedd4f1100fae3e4bfe969649e1643e5254Vikram S. Adve                                            unsigned int size = 0);
5891876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve
590be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  int             allocateSpilledValue     (const TargetMachine& target,
591be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve                                            const Type* type);
5921876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve
593be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  int             allocateOptionalArg      (const TargetMachine& target,
594be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve                                            const Type* type);
5951876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve
596be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  void            resetOptionalArgs        (const TargetMachine& target);
5971876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve
598be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  int             pushTempValue            (const TargetMachine& target,
5991876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve                                            unsigned int size);
6001876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve
601be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  void            popAllTempValues         (const TargetMachine& target);
6021876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve
603be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  int             getOffset                (const Value* val) const;
604be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve
605be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  // int          getOffsetFromFP       (const Value* val) const;
6061876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve
6071876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve  void            dump                     () const;
608be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve
609be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adveprivate:
610be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  inline void     incrementAutomaticVarsSize(int incr) {
611be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve    automaticVarsSize+= incr;
612be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve    staticStackSize += incr;
613be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  }
614be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  inline void     incrementRegSpillsSize(int incr) {
615be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve    regSpillsSize+= incr;
616be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve    staticStackSize += incr;
617be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  }
618be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  inline void     incrementCurrentOptionalArgsSize(int incr) {
619be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve    currentOptionalArgsSize+= incr;     // stack size already includes this!
620be49526193c5d8856d0b3c2721dfa6a4c4010d6dVikram S. Adve  }
6211876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve};
6221876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve
6231876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve
6241876f92599b90f0a4b276aae413a1b965954174dVikram S. Adve//---------------------------------------------------------------------------
625593da4acc56d4c591ad688e6605b04d0825c867eVikram S. Adve// Debugging Support
62623ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//---------------------------------------------------------------------------
62723ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
62823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
629697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerstd::ostream& operator<<    (std::ostream& os, const MachineInstr& minstr);
630593da4acc56d4c591ad688e6605b04d0825c867eVikram S. Adve
631593da4acc56d4c591ad688e6605b04d0825c867eVikram S. Adve
632697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerstd::ostream& operator<<    (std::ostream& os, const MachineOperand& mop);
63323ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
63423ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
635593da4acc56d4c591ad688e6605b04d0825c867eVikram S. Advevoid	PrintMachineInstructions(const Method *method);
636136c9f4062b0fe6d864ebc2bc2b0cbada931a28eVikram S. Adve
637136c9f4062b0fe6d864ebc2bc2b0cbada931a28eVikram S. Adve
63823ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve//**************************************************************************/
63923ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve
64023ee550765232e22d0daf6407141ecef4c55c06fVikram S. Adve#endif
641