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