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