MachineInstr.h revision faa510726f4b40aa4495e60e4d341c6467e3fb01
1//===-- llvm/CodeGen/MachineInstr.h - MachineInstr class --------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains the declaration of the MachineInstr class, which is the 11// basic representation for all target dependent machine instructions used by 12// the back end. 13// 14//===----------------------------------------------------------------------===// 15 16#ifndef LLVM_CODEGEN_MACHINEINSTR_H 17#define LLVM_CODEGEN_MACHINEINSTR_H 18 19#include "llvm/ADT/iterator" 20#include "llvm/Support/DataTypes.h" 21#include "llvm/Support/Streams.h" 22#include <vector> 23#include <cassert> 24#include <iosfwd> 25 26namespace llvm { 27 28class Value; 29class Function; 30class MachineBasicBlock; 31class TargetInstrDescriptor; 32class TargetMachine; 33class GlobalValue; 34 35template <typename T> struct ilist_traits; 36template <typename T> struct ilist; 37 38//===----------------------------------------------------------------------===// 39// class MachineOperand 40// 41// Representation of each machine instruction operand. 42// 43struct MachineOperand { 44 enum MachineOperandType { 45 MO_Register, // Register operand. 46 MO_Immediate, // Immediate Operand 47 MO_MachineBasicBlock, // MachineBasicBlock reference 48 MO_FrameIndex, // Abstract Stack Frame Index 49 MO_ConstantPoolIndex, // Address of indexed Constant in Constant Pool 50 MO_JumpTableIndex, // Address of indexed Jump Table for switch 51 MO_ExternalSymbol, // Name of external global symbol 52 MO_GlobalAddress // Address of a global value 53 }; 54 55private: 56 union { 57 GlobalValue *GV; // For MO_GlobalAddress. 58 MachineBasicBlock *MBB; // For MO_MachineBasicBlock. 59 const char *SymbolName; // For MO_ExternalSymbol. 60 unsigned RegNo; // For MO_Register. 61 int64_t immedVal; // For MO_Immediate and MO_*Index. 62 } contents; 63 64 MachineOperandType opType:8; // Discriminate the union. 65 bool IsDef : 1; // True if this is a def, false if this is a use. 66 bool IsImp : 1; // True if this is an implicit def or use. 67 68 bool IsKill : 1; // True if this is a reg use and the reg is dead 69 // immediately after the read. 70 bool IsDead : 1; // True if this is a reg def and the reg is dead 71 // immediately after the write. i.e. A register 72 // that is defined but never used. 73 74 /// offset - Offset to address of global or external, only valid for 75 /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex 76 int offset; 77 78 MachineOperand() {} 79 80 void print(std::ostream &os) const; 81 void print(std::ostream *os) const { if (os) print(*os); } 82 83public: 84 MachineOperand(const MachineOperand &M) { 85 *this = M; 86 } 87 88 ~MachineOperand() {} 89 90 static MachineOperand CreateImm(int64_t Val) { 91 MachineOperand Op; 92 Op.opType = MachineOperand::MO_Immediate; 93 Op.contents.immedVal = Val; 94 Op.IsDef = false; 95 Op.IsImp = false; 96 Op.IsKill = false; 97 Op.IsDead = false; 98 Op.offset = 0; 99 return Op; 100 } 101 102 const MachineOperand &operator=(const MachineOperand &MO) { 103 contents = MO.contents; 104 IsDef = MO.IsDef; 105 IsImp = MO.IsImp; 106 IsKill = MO.IsKill; 107 IsDead = MO.IsDead; 108 opType = MO.opType; 109 offset = MO.offset; 110 return *this; 111 } 112 113 /// getType - Returns the MachineOperandType for this operand. 114 /// 115 MachineOperandType getType() const { return opType; } 116 117 /// Accessors that tell you what kind of MachineOperand you're looking at. 118 /// 119 bool isReg() const { return opType == MO_Register; } 120 bool isImm() const { return opType == MO_Immediate; } 121 bool isMBB() const { return opType == MO_MachineBasicBlock; } 122 123 bool isRegister() const { return opType == MO_Register; } 124 bool isImmediate() const { return opType == MO_Immediate; } 125 bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; } 126 bool isFrameIndex() const { return opType == MO_FrameIndex; } 127 bool isConstantPoolIndex() const { return opType == MO_ConstantPoolIndex; } 128 bool isJumpTableIndex() const { return opType == MO_JumpTableIndex; } 129 bool isGlobalAddress() const { return opType == MO_GlobalAddress; } 130 bool isExternalSymbol() const { return opType == MO_ExternalSymbol; } 131 132 int64_t getImm() const { 133 assert(isImm() && "Wrong MachineOperand accessor"); 134 return contents.immedVal; 135 } 136 137 int64_t getImmedValue() const { 138 assert(isImm() && "Wrong MachineOperand accessor"); 139 return contents.immedVal; 140 } 141 MachineBasicBlock *getMBB() const { 142 assert(isMachineBasicBlock() && "Wrong MachineOperand accessor"); 143 return contents.MBB; 144 } 145 MachineBasicBlock *getMachineBasicBlock() const { 146 assert(isMachineBasicBlock() && "Wrong MachineOperand accessor"); 147 return contents.MBB; 148 } 149 void setMachineBasicBlock(MachineBasicBlock *MBB) { 150 assert(isMachineBasicBlock() && "Wrong MachineOperand accessor"); 151 contents.MBB = MBB; 152 } 153 int getFrameIndex() const { 154 assert(isFrameIndex() && "Wrong MachineOperand accessor"); 155 return (int)contents.immedVal; 156 } 157 unsigned getConstantPoolIndex() const { 158 assert(isConstantPoolIndex() && "Wrong MachineOperand accessor"); 159 return (unsigned)contents.immedVal; 160 } 161 unsigned getJumpTableIndex() const { 162 assert(isJumpTableIndex() && "Wrong MachineOperand accessor"); 163 return (unsigned)contents.immedVal; 164 } 165 GlobalValue *getGlobal() const { 166 assert(isGlobalAddress() && "Wrong MachineOperand accessor"); 167 return contents.GV; 168 } 169 int getOffset() const { 170 assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) && 171 "Wrong MachineOperand accessor"); 172 return offset; 173 } 174 const char *getSymbolName() const { 175 assert(isExternalSymbol() && "Wrong MachineOperand accessor"); 176 return contents.SymbolName; 177 } 178 179 bool isUse() const { 180 assert(isRegister() && "Wrong MachineOperand accessor"); 181 return !IsDef; 182 } 183 bool isDef() const { 184 assert(isRegister() && "Wrong MachineOperand accessor"); 185 return IsDef; 186 } 187 void setIsUse() { 188 assert(isRegister() && "Wrong MachineOperand accessor"); 189 IsDef = false; 190 } 191 void setIsDef() { 192 assert(isRegister() && "Wrong MachineOperand accessor"); 193 IsDef = true; 194 } 195 196 bool isImplicit() const { 197 assert(isRegister() && "Wrong MachineOperand accessor"); 198 return IsImp; 199 } 200 void setImplicit() { 201 assert(isRegister() && "Wrong MachineOperand accessor"); 202 IsImp = true; 203 } 204 205 bool isKill() const { 206 assert(isRegister() && "Wrong MachineOperand accessor"); 207 return IsKill; 208 } 209 bool isDead() const { 210 assert(isRegister() && "Wrong MachineOperand accessor"); 211 return IsDead; 212 } 213 void setIsKill() { 214 assert(isRegister() && !IsDef && "Wrong MachineOperand accessor"); 215 IsKill = true; 216 } 217 void setIsDead() { 218 assert(isRegister() && IsDef && "Wrong MachineOperand accessor"); 219 IsDead = true; 220 } 221 void unsetIsKill() { 222 assert(isRegister() && !IsDef && "Wrong MachineOperand accessor"); 223 IsKill = false; 224 } 225 void unsetIsDead() { 226 assert(isRegister() && IsDef && "Wrong MachineOperand accessor"); 227 IsDead = false; 228 } 229 230 /// getReg - Returns the register number. 231 /// 232 unsigned getReg() const { 233 assert(isRegister() && "This is not a register operand!"); 234 return contents.RegNo; 235 } 236 237 /// MachineOperand mutators. 238 /// 239 void setReg(unsigned Reg) { 240 assert(isRegister() && "This is not a register operand!"); 241 contents.RegNo = Reg; 242 } 243 244 void setImmedValue(int64_t immVal) { 245 assert(isImm() && "Wrong MachineOperand mutator"); 246 contents.immedVal = immVal; 247 } 248 void setImm(int64_t immVal) { 249 assert(isImm() && "Wrong MachineOperand mutator"); 250 contents.immedVal = immVal; 251 } 252 253 void setOffset(int Offset) { 254 assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() || 255 isJumpTableIndex()) && 256 "Wrong MachineOperand accessor"); 257 offset = Offset; 258 } 259 void setConstantPoolIndex(unsigned Idx) { 260 assert(isConstantPoolIndex() && "Wrong MachineOperand accessor"); 261 contents.immedVal = Idx; 262 } 263 void setJumpTableIndex(unsigned Idx) { 264 assert(isJumpTableIndex() && "Wrong MachineOperand accessor"); 265 contents.immedVal = Idx; 266 } 267 268 /// isIdenticalTo - Return true if this operand is identical to the specified 269 /// operand. Note: This method ignores isKill and isDead properties. 270 bool isIdenticalTo(const MachineOperand &Other) const; 271 272 /// ChangeToImmediate - Replace this operand with a new immediate operand of 273 /// the specified value. If an operand is known to be an immediate already, 274 /// the setImmedValue method should be used. 275 void ChangeToImmediate(int64_t ImmVal) { 276 opType = MO_Immediate; 277 contents.immedVal = ImmVal; 278 } 279 280 /// ChangeToRegister - Replace this operand with a new register operand of 281 /// the specified value. If an operand is known to be an register already, 282 /// the setReg method should be used. 283 void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false, 284 bool isKill = false, bool isDead = false) { 285 opType = MO_Register; 286 contents.RegNo = Reg; 287 IsDef = isDef; 288 IsImp = isImp; 289 IsKill = isKill; 290 IsDead = isDead; 291 } 292 293 friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop) { 294 mop.print(os); 295 return os; 296 } 297 298 friend class MachineInstr; 299}; 300 301 302//===----------------------------------------------------------------------===// 303/// MachineInstr - Representation of each machine instruction. 304/// 305class MachineInstr { 306 const TargetInstrDescriptor *TID; // Instruction descriptor. 307 unsigned short NumImplicitOps; // Number of implicit operands (which 308 // are determined at construction time). 309 310 std::vector<MachineOperand> Operands; // the operands 311 MachineInstr* prev, *next; // links for our intrusive list 312 MachineBasicBlock* parent; // pointer to the owning basic block 313 314 // OperandComplete - Return true if it's illegal to add a new operand 315 bool OperandsComplete() const; 316 317 MachineInstr(const MachineInstr&); 318 void operator=(const MachineInstr&); // DO NOT IMPLEMENT 319 320 // Intrusive list support 321 // 322 friend struct ilist_traits<MachineInstr>; 323 324public: 325 /// MachineInstr ctor - This constructor creates a dummy MachineInstr with 326 /// TID NULL and no operands. 327 MachineInstr(); 328 329 /// MachineInstr ctor - This constructor create a MachineInstr and add the 330 /// implicit operands. It reserves space for number of operands specified by 331 /// TargetInstrDescriptor. 332 MachineInstr(const TargetInstrDescriptor &TID); 333 334 /// MachineInstr ctor - Work exactly the same as the ctor above, except that 335 /// the MachineInstr is created and added to the end of the specified basic 336 /// block. 337 /// 338 MachineInstr(MachineBasicBlock *MBB, const TargetInstrDescriptor &TID); 339 340 ~MachineInstr(); 341 342 const MachineBasicBlock* getParent() const { return parent; } 343 MachineBasicBlock* getParent() { return parent; } 344 345 /// getInstrDescriptor - Returns the target instruction descriptor of this 346 /// MachineInstr. 347 const TargetInstrDescriptor *getInstrDescriptor() const { return TID; } 348 349 /// getOpcode - Returns the opcode of this MachineInstr. 350 /// 351 const int getOpcode() const; 352 353 /// Access to explicit operands of the instruction. 354 /// 355 unsigned getNumOperands() const { return Operands.size(); } 356 357 const MachineOperand& getOperand(unsigned i) const { 358 assert(i < getNumOperands() && "getOperand() out of range!"); 359 return Operands[i]; 360 } 361 MachineOperand& getOperand(unsigned i) { 362 assert(i < getNumOperands() && "getOperand() out of range!"); 363 return Operands[i]; 364 } 365 366 367 /// isIdenticalTo - Return true if this instruction is identical to (same 368 /// opcode and same operands as) the specified instruction. 369 bool isIdenticalTo(const MachineInstr *Other) const { 370 if (Other->getOpcode() != getOpcode() || 371 Other->getNumOperands() != getNumOperands()) 372 return false; 373 for (unsigned i = 0, e = getNumOperands(); i != e; ++i) 374 if (!getOperand(i).isIdenticalTo(Other->getOperand(i))) 375 return false; 376 return true; 377 } 378 379 /// clone - Create a copy of 'this' instruction that is identical in 380 /// all ways except the the instruction has no parent, prev, or next. 381 MachineInstr* clone() const { return new MachineInstr(*this); } 382 383 /// removeFromParent - This method unlinks 'this' from the containing basic 384 /// block, and returns it, but does not delete it. 385 MachineInstr *removeFromParent(); 386 387 /// eraseFromParent - This method unlinks 'this' from the containing basic 388 /// block and deletes it. 389 void eraseFromParent() { 390 delete removeFromParent(); 391 } 392 393 /// findRegisterUseOperandIdx() - Returns the operand index that is a use of 394 /// the specific register or -1 if it is not found. It further tightening 395 /// the search criteria to a use that kills the register if isKill is true. 396 int findRegisterUseOperandIdx(unsigned Reg, bool isKill = false); 397 398 /// findRegisterDefOperand() - Returns the MachineOperand that is a def of 399 /// the specific register or NULL if it is not found. 400 MachineOperand *findRegisterDefOperand(unsigned Reg); 401 402 /// copyKillDeadInfo - Copies kill / dead operand properties from MI. 403 /// 404 void copyKillDeadInfo(const MachineInstr *MI); 405 406 // 407 // Debugging support 408 // 409 void print(std::ostream *OS, const TargetMachine *TM) const { 410 if (OS) print(*OS, TM); 411 } 412 void print(std::ostream &OS, const TargetMachine *TM) const; 413 void print(std::ostream &OS) const; 414 void print(std::ostream *OS) const { if (OS) print(*OS); } 415 void dump() const; 416 friend std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr){ 417 minstr.print(os); 418 return os; 419 } 420 421 //===--------------------------------------------------------------------===// 422 // Accessors to add operands when building up machine instructions. 423 // 424 425 /// addRegOperand - Add a register operand. 426 /// 427 void addRegOperand(unsigned Reg, bool IsDef, bool IsImp = false, 428 bool IsKill = false, bool IsDead = false) { 429 MachineOperand &Op = AddNewOperand(IsImp); 430 Op.opType = MachineOperand::MO_Register; 431 Op.IsDef = IsDef; 432 Op.IsImp = IsImp; 433 Op.IsKill = IsKill; 434 Op.IsDead = IsDead; 435 Op.contents.RegNo = Reg; 436 Op.offset = 0; 437 } 438 439 /// addImmOperand - Add a zero extended constant argument to the 440 /// machine instruction. 441 /// 442 void addImmOperand(int64_t Val) { 443 MachineOperand &Op = AddNewOperand(); 444 Op.opType = MachineOperand::MO_Immediate; 445 Op.contents.immedVal = Val; 446 Op.offset = 0; 447 } 448 449 void addMachineBasicBlockOperand(MachineBasicBlock *MBB) { 450 MachineOperand &Op = AddNewOperand(); 451 Op.opType = MachineOperand::MO_MachineBasicBlock; 452 Op.contents.MBB = MBB; 453 Op.offset = 0; 454 } 455 456 /// addFrameIndexOperand - Add an abstract frame index to the instruction 457 /// 458 void addFrameIndexOperand(unsigned Idx) { 459 MachineOperand &Op = AddNewOperand(); 460 Op.opType = MachineOperand::MO_FrameIndex; 461 Op.contents.immedVal = Idx; 462 Op.offset = 0; 463 } 464 465 /// addConstantPoolndexOperand - Add a constant pool object index to the 466 /// instruction. 467 /// 468 void addConstantPoolIndexOperand(unsigned Idx, int Offset) { 469 MachineOperand &Op = AddNewOperand(); 470 Op.opType = MachineOperand::MO_ConstantPoolIndex; 471 Op.contents.immedVal = Idx; 472 Op.offset = Offset; 473 } 474 475 /// addJumpTableIndexOperand - Add a jump table object index to the 476 /// instruction. 477 /// 478 void addJumpTableIndexOperand(unsigned Idx) { 479 MachineOperand &Op = AddNewOperand(); 480 Op.opType = MachineOperand::MO_JumpTableIndex; 481 Op.contents.immedVal = Idx; 482 Op.offset = 0; 483 } 484 485 void addGlobalAddressOperand(GlobalValue *GV, int Offset) { 486 MachineOperand &Op = AddNewOperand(); 487 Op.opType = MachineOperand::MO_GlobalAddress; 488 Op.contents.GV = GV; 489 Op.offset = Offset; 490 } 491 492 /// addExternalSymbolOperand - Add an external symbol operand to this instr 493 /// 494 void addExternalSymbolOperand(const char *SymName) { 495 MachineOperand &Op = AddNewOperand(); 496 Op.opType = MachineOperand::MO_ExternalSymbol; 497 Op.contents.SymbolName = SymName; 498 Op.offset = 0; 499 } 500 501 //===--------------------------------------------------------------------===// 502 // Accessors used to modify instructions in place. 503 // 504 505 /// setInstrDescriptor - Replace the instruction descriptor (thus opcode) of 506 /// the current instruction with a new one. 507 /// 508 void setInstrDescriptor(const TargetInstrDescriptor &tid) { TID = &tid; } 509 510 /// RemoveOperand - Erase an operand from an instruction, leaving it with one 511 /// fewer operand than it started with. 512 /// 513 void RemoveOperand(unsigned i) { 514 Operands.erase(Operands.begin()+i); 515 } 516private: 517 MachineOperand &AddNewOperand(bool IsImp = false) { 518 assert((IsImp || !OperandsComplete()) && 519 "Trying to add an operand to a machine instr that is already done!"); 520 if (IsImp || NumImplicitOps == 0) { // This is true most of the time. 521 Operands.push_back(MachineOperand()); 522 return Operands.back(); 523 } 524 return *Operands.insert(Operands.begin()+Operands.size()-NumImplicitOps, 525 MachineOperand()); 526 } 527 528 /// addImplicitDefUseOperands - Add all implicit def and use operands to 529 /// this instruction. 530 void addImplicitDefUseOperands(); 531}; 532 533//===----------------------------------------------------------------------===// 534// Debugging Support 535 536std::ostream& operator<<(std::ostream &OS, const MachineInstr &MI); 537std::ostream& operator<<(std::ostream &OS, const MachineOperand &MO); 538 539} // End llvm namespace 540 541#endif 542