MachineInstr.h revision b6bb7e1ffe7a1324e70ec410b3a06f008f37b072
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 <vector> 22#include <cassert> 23 24namespace llvm { 25 26class Value; 27class Function; 28class MachineBasicBlock; 29class TargetMachine; 30class GlobalValue; 31 32template <typename T> struct ilist_traits; 33template <typename T> struct ilist; 34 35//===----------------------------------------------------------------------===// 36// class MachineOperand 37// 38// Representation of each machine instruction operand. 39// 40struct MachineOperand { 41 enum MachineOperandType { 42 MO_Register, // Register operand. 43 MO_Immediate, // Immediate Operand 44 MO_MachineBasicBlock, // MachineBasicBlock reference 45 MO_FrameIndex, // Abstract Stack Frame Index 46 MO_ConstantPoolIndex, // Address of indexed Constant in Constant Pool 47 MO_JumpTableIndex, // Address of indexed Jump Table for switch 48 MO_ExternalSymbol, // Name of external global symbol 49 MO_GlobalAddress // Address of a global value 50 }; 51 52private: 53 union { 54 GlobalValue *GV; // For MO_GlobalAddress. 55 MachineBasicBlock *MBB; // For MO_MachineBasicBlock. 56 const char *SymbolName; // For MO_ExternalSymbol. 57 unsigned RegNo; // For MO_Register. 58 int64_t immedVal; // For MO_Immediate and MO_*Index. 59 } contents; 60 61 MachineOperandType opType:8; // Discriminate the union. 62 bool IsDef : 1; // True if this is a def, false if this is a use. 63 64 /// offset - Offset to address of global or external, only valid for 65 /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex 66 int offset; 67 68 MachineOperand() {} 69public: 70 MachineOperand(const MachineOperand &M) { 71 *this = M; 72 } 73 74 ~MachineOperand() {} 75 76 const MachineOperand &operator=(const MachineOperand &MO) { 77 contents = MO.contents; 78 IsDef = MO.IsDef; 79 opType = MO.opType; 80 offset = MO.offset; 81 return *this; 82 } 83 84 /// getType - Returns the MachineOperandType for this operand. 85 /// 86 MachineOperandType getType() const { return opType; } 87 88 /// Accessors that tell you what kind of MachineOperand you're looking at. 89 /// 90 bool isReg() const { return opType == MO_Register; } 91 bool isImm() const { return opType == MO_Immediate; } 92 bool isMBB() const { return opType == MO_MachineBasicBlock; } 93 94 bool isRegister() const { return opType == MO_Register; } 95 bool isImmediate() const { return opType == MO_Immediate; } 96 bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; } 97 bool isFrameIndex() const { return opType == MO_FrameIndex; } 98 bool isConstantPoolIndex() const { return opType == MO_ConstantPoolIndex; } 99 bool isJumpTableIndex() const { return opType == MO_JumpTableIndex; } 100 bool isGlobalAddress() const { return opType == MO_GlobalAddress; } 101 bool isExternalSymbol() const { return opType == MO_ExternalSymbol; } 102 103 int64_t getImm() const { 104 assert(isImm() && "Wrong MachineOperand accessor"); 105 return contents.immedVal; 106 } 107 108 int64_t getImmedValue() const { 109 assert(isImm() && "Wrong MachineOperand accessor"); 110 return contents.immedVal; 111 } 112 MachineBasicBlock *getMachineBasicBlock() const { 113 assert(isMachineBasicBlock() && "Wrong MachineOperand accessor"); 114 return contents.MBB; 115 } 116 void setMachineBasicBlock(MachineBasicBlock *MBB) { 117 assert(isMachineBasicBlock() && "Wrong MachineOperand accessor"); 118 contents.MBB = MBB; 119 } 120 int getFrameIndex() const { 121 assert(isFrameIndex() && "Wrong MachineOperand accessor"); 122 return (int)contents.immedVal; 123 } 124 unsigned getConstantPoolIndex() const { 125 assert(isConstantPoolIndex() && "Wrong MachineOperand accessor"); 126 return (unsigned)contents.immedVal; 127 } 128 unsigned getJumpTableIndex() const { 129 assert(isJumpTableIndex() && "Wrong MachineOperand accessor"); 130 return (unsigned)contents.immedVal; 131 } 132 GlobalValue *getGlobal() const { 133 assert(isGlobalAddress() && "Wrong MachineOperand accessor"); 134 return contents.GV; 135 } 136 int getOffset() const { 137 assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) && 138 "Wrong MachineOperand accessor"); 139 return offset; 140 } 141 const char *getSymbolName() const { 142 assert(isExternalSymbol() && "Wrong MachineOperand accessor"); 143 return contents.SymbolName; 144 } 145 146 bool isUse() const { 147 assert(isRegister() && "Wrong MachineOperand accessor"); 148 return !IsDef; 149 } 150 bool isDef() const { 151 assert(isRegister() && "Wrong MachineOperand accessor"); 152 return IsDef; 153 } 154 void setIsUse() { 155 assert(isRegister() && "Wrong MachineOperand accessor"); 156 IsDef = false; 157 } 158 void setIsDef() { 159 assert(isRegister() && "Wrong MachineOperand accessor"); 160 IsDef = true; 161 } 162 163 /// getReg - Returns the register number. 164 /// 165 unsigned getReg() const { 166 assert(isRegister() && "This is not a register operand!"); 167 return contents.RegNo; 168 } 169 170 /// MachineOperand mutators. 171 /// 172 void setReg(unsigned Reg) { 173 assert(isRegister() && "This is not a register operand!"); 174 contents.RegNo = Reg; 175 } 176 177 void setImmedValue(int64_t immVal) { 178 assert(isImm() && "Wrong MachineOperand mutator"); 179 contents.immedVal = immVal; 180 } 181 void setImm(int64_t immVal) { 182 assert(isImm() && "Wrong MachineOperand mutator"); 183 contents.immedVal = immVal; 184 } 185 186 void setOffset(int Offset) { 187 assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() || 188 isJumpTableIndex()) && 189 "Wrong MachineOperand accessor"); 190 offset = Offset; 191 } 192 void setConstantPoolIndex(unsigned Idx) { 193 assert(isConstantPoolIndex() && "Wrong MachineOperand accessor"); 194 contents.immedVal = Idx; 195 } 196 197 198 /// ChangeToImmediate - Replace this operand with a new immediate operand of 199 /// the specified value. If an operand is known to be an immediate already, 200 /// the setImmedValue method should be used. 201 void ChangeToImmediate(int64_t ImmVal) { 202 opType = MO_Immediate; 203 contents.immedVal = ImmVal; 204 } 205 206 /// ChangeToRegister - Replace this operand with a new register operand of 207 /// the specified value. If an operand is known to be an register already, 208 /// the setReg method should be used. 209 void ChangeToRegister(unsigned Reg, bool isDef) { 210 opType = MO_Register; 211 contents.RegNo = Reg; 212 IsDef = isDef; 213 } 214 215 friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop); 216 217 friend class MachineInstr; 218}; 219 220 221//===----------------------------------------------------------------------===// 222/// MachineInstr - Representation of each machine instruction. 223/// 224class MachineInstr { 225 short Opcode; // the opcode 226 std::vector<MachineOperand> Operands; // the operands 227 MachineInstr* prev, *next; // links for our intrusive list 228 MachineBasicBlock* parent; // pointer to the owning basic block 229 230 // OperandComplete - Return true if it's illegal to add a new operand 231 bool OperandsComplete() const; 232 233 MachineInstr(const MachineInstr&); 234 void operator=(const MachineInstr&); // DO NOT IMPLEMENT 235 236 // Intrusive list support 237 // 238 friend struct ilist_traits<MachineInstr>; 239 240public: 241 /// MachineInstr ctor - This constructor reserve's space for numOperand 242 /// operands. 243 MachineInstr(short Opcode, unsigned numOperands); 244 245 /// MachineInstr ctor - Work exactly the same as the ctor above, except that 246 /// the MachineInstr is created and added to the end of the specified basic 247 /// block. 248 /// 249 MachineInstr(MachineBasicBlock *MBB, short Opcode, unsigned numOps); 250 251 ~MachineInstr(); 252 253 const MachineBasicBlock* getParent() const { return parent; } 254 MachineBasicBlock* getParent() { return parent; } 255 256 /// getOpcode - Returns the opcode of this MachineInstr. 257 /// 258 const int getOpcode() const { return Opcode; } 259 260 /// Access to explicit operands of the instruction. 261 /// 262 unsigned getNumOperands() const { return Operands.size(); } 263 264 const MachineOperand& getOperand(unsigned i) const { 265 assert(i < getNumOperands() && "getOperand() out of range!"); 266 return Operands[i]; 267 } 268 MachineOperand& getOperand(unsigned i) { 269 assert(i < getNumOperands() && "getOperand() out of range!"); 270 return Operands[i]; 271 } 272 273 274 /// clone - Create a copy of 'this' instruction that is identical in 275 /// all ways except the the instruction has no parent, prev, or next. 276 MachineInstr* clone() const { return new MachineInstr(*this); } 277 278 /// removeFromParent - This method unlinks 'this' from the containing basic 279 /// block, and returns it, but does not delete it. 280 MachineInstr *removeFromParent(); 281 282 /// eraseFromParent - This method unlinks 'this' from the containing basic 283 /// block and deletes it. 284 void eraseFromParent() { 285 delete removeFromParent(); 286 } 287 288 // 289 // Debugging support 290 // 291 void print(std::ostream &OS, const TargetMachine *TM) const; 292 void dump() const; 293 friend std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr); 294 295 //===--------------------------------------------------------------------===// 296 // Accessors to add operands when building up machine instructions. 297 // 298 299 /// addRegOperand - Add a register operand. 300 /// 301 void addRegOperand(unsigned Reg, bool IsDef) { 302 MachineOperand &Op = AddNewOperand(); 303 Op.opType = MachineOperand::MO_Register; 304 Op.IsDef = IsDef; 305 Op.contents.RegNo = Reg; 306 Op.offset = 0; 307 } 308 309 /// addImmOperand - Add a zero extended constant argument to the 310 /// machine instruction. 311 /// 312 void addImmOperand(int64_t Val) { 313 MachineOperand &Op = AddNewOperand(); 314 Op.opType = MachineOperand::MO_Immediate; 315 Op.contents.immedVal = Val; 316 Op.offset = 0; 317 } 318 319 void addMachineBasicBlockOperand(MachineBasicBlock *MBB) { 320 MachineOperand &Op = AddNewOperand(); 321 Op.opType = MachineOperand::MO_MachineBasicBlock; 322 Op.contents.MBB = MBB; 323 Op.offset = 0; 324 } 325 326 /// addFrameIndexOperand - Add an abstract frame index to the instruction 327 /// 328 void addFrameIndexOperand(unsigned Idx) { 329 MachineOperand &Op = AddNewOperand(); 330 Op.opType = MachineOperand::MO_FrameIndex; 331 Op.contents.immedVal = Idx; 332 Op.offset = 0; 333 } 334 335 /// addConstantPoolndexOperand - Add a constant pool object index to the 336 /// instruction. 337 /// 338 void addConstantPoolIndexOperand(unsigned Idx, int Offset) { 339 MachineOperand &Op = AddNewOperand(); 340 Op.opType = MachineOperand::MO_ConstantPoolIndex; 341 Op.contents.immedVal = Idx; 342 Op.offset = Offset; 343 } 344 345 /// addJumpTableIndexOperand - Add a jump table object index to the 346 /// instruction. 347 /// 348 void addJumpTableIndexOperand(unsigned Idx) { 349 MachineOperand &Op = AddNewOperand(); 350 Op.opType = MachineOperand::MO_JumpTableIndex; 351 Op.contents.immedVal = Idx; 352 Op.offset = 0; 353 } 354 355 void addGlobalAddressOperand(GlobalValue *GV, int Offset) { 356 MachineOperand &Op = AddNewOperand(); 357 Op.opType = MachineOperand::MO_GlobalAddress; 358 Op.contents.GV = GV; 359 Op.offset = Offset; 360 } 361 362 /// addExternalSymbolOperand - Add an external symbol operand to this instr 363 /// 364 void addExternalSymbolOperand(const char *SymName) { 365 MachineOperand &Op = AddNewOperand(); 366 Op.opType = MachineOperand::MO_ExternalSymbol; 367 Op.contents.SymbolName = SymName; 368 Op.offset = 0; 369 } 370 371 //===--------------------------------------------------------------------===// 372 // Accessors used to modify instructions in place. 373 // 374 375 /// setOpcode - Replace the opcode of the current instruction with a new one. 376 /// 377 void setOpcode(unsigned Op) { Opcode = Op; } 378 379 /// RemoveOperand - Erase an operand from an instruction, leaving it with one 380 /// fewer operand than it started with. 381 /// 382 void RemoveOperand(unsigned i) { 383 Operands.erase(Operands.begin()+i); 384 } 385private: 386 MachineOperand &AddNewOperand() { 387 assert(!OperandsComplete() && 388 "Trying to add an operand to a machine instr that is already done!"); 389 Operands.push_back(MachineOperand()); 390 return Operands.back(); 391 } 392}; 393 394//===----------------------------------------------------------------------===// 395// Debugging Support 396 397std::ostream& operator<<(std::ostream &OS, const MachineInstr &MI); 398std::ostream& operator<<(std::ostream &OS, const MachineOperand &MO); 399 400} // End llvm namespace 401 402#endif 403