LLVM API Documentation
00001 //===-- llvm/CodeGen/MachineInstr.h - MachineInstr class --------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the declaration of the MachineInstr class, which is the 00011 // basic representation for all target dependent machine instructions used by 00012 // the back end. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #ifndef LLVM_CODEGEN_MACHINEINSTR_H 00017 #define LLVM_CODEGEN_MACHINEINSTR_H 00018 00019 #include "llvm/ADT/iterator" 00020 #include "llvm/Support/DataTypes.h" 00021 #include <vector> 00022 #include <cassert> 00023 00024 namespace llvm { 00025 00026 class Value; 00027 class Function; 00028 class MachineBasicBlock; 00029 class TargetMachine; 00030 class GlobalValue; 00031 00032 template <typename T> struct ilist_traits; 00033 template <typename T> struct ilist; 00034 00035 //===----------------------------------------------------------------------===// 00036 // class MachineOperand 00037 // 00038 // Representation of each machine instruction operand. 00039 // 00040 struct MachineOperand { 00041 private: 00042 // Bit fields of the flags variable used for different operand properties 00043 enum { 00044 DEFFLAG = 0x01, // this is a def of the operand 00045 USEFLAG = 0x02 // this is a use of the operand 00046 }; 00047 00048 public: 00049 // UseType - This enum describes how the machine operand is used by 00050 // the instruction. Note that the MachineInstr/Operator class 00051 // currently uses bool arguments to represent this information 00052 // instead of an enum. Eventually this should change over to use 00053 // this _easier to read_ representation instead. 00054 // 00055 enum UseType { 00056 Use = USEFLAG, /// only read 00057 Def = DEFFLAG, /// only written 00058 UseAndDef = Use | Def /// read AND written 00059 }; 00060 00061 enum MachineOperandType { 00062 MO_Register, // Register operand. 00063 MO_Immediate, // Immediate Operand 00064 MO_MachineBasicBlock, // MachineBasicBlock reference 00065 MO_FrameIndex, // Abstract Stack Frame Index 00066 MO_ConstantPoolIndex, // Address of indexed Constant in Constant Pool 00067 MO_JumpTableIndex, // Address of indexed Jump Table for switch 00068 MO_ExternalSymbol, // Name of external global symbol 00069 MO_GlobalAddress // Address of a global value 00070 }; 00071 00072 private: 00073 union { 00074 GlobalValue *GV; // For MO_GlobalAddress. 00075 MachineBasicBlock *MBB; // For MO_MachineBasicBlock. 00076 const char *SymbolName; // For MO_ExternalSymbol. 00077 unsigned RegNo; // For MO_Register. 00078 int64_t immedVal; // For MO_Immediate and MO_*Index. 00079 } contents; 00080 00081 char flags; // see bit field definitions above 00082 MachineOperandType opType:8; // Pack into 8 bits efficiently after flags. 00083 00084 /// offset - Offset to address of global or external, only valid for 00085 /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex 00086 int offset; 00087 00088 MachineOperand() {} 00089 public: 00090 MachineOperand(const MachineOperand &M) { 00091 *this = M; 00092 } 00093 00094 ~MachineOperand() {} 00095 00096 const MachineOperand &operator=(const MachineOperand &MO) { 00097 contents = MO.contents; 00098 flags = MO.flags; 00099 opType = MO.opType; 00100 offset = MO.offset; 00101 return *this; 00102 } 00103 00104 /// getType - Returns the MachineOperandType for this operand. 00105 /// 00106 MachineOperandType getType() const { return opType; } 00107 00108 /// getUseType - Returns the MachineOperandUseType of this operand. 00109 /// 00110 UseType getUseType() const { return UseType(flags & (USEFLAG|DEFFLAG)); } 00111 00112 /// Accessors that tell you what kind of MachineOperand you're looking at. 00113 /// 00114 bool isRegister() const { return opType == MO_Register; } 00115 bool isImmediate() const { return opType == MO_Immediate; } 00116 bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; } 00117 bool isFrameIndex() const { return opType == MO_FrameIndex; } 00118 bool isConstantPoolIndex() const { return opType == MO_ConstantPoolIndex; } 00119 bool isJumpTableIndex() const { return opType == MO_JumpTableIndex; } 00120 bool isGlobalAddress() const { return opType == MO_GlobalAddress; } 00121 bool isExternalSymbol() const { return opType == MO_ExternalSymbol; } 00122 00123 int64_t getImmedValue() const { 00124 assert(isImmediate() && "Wrong MachineOperand accessor"); 00125 return contents.immedVal; 00126 } 00127 MachineBasicBlock *getMachineBasicBlock() const { 00128 assert(isMachineBasicBlock() && "Wrong MachineOperand accessor"); 00129 return contents.MBB; 00130 } 00131 void setMachineBasicBlock(MachineBasicBlock *MBB) { 00132 assert(isMachineBasicBlock() && "Wrong MachineOperand accessor"); 00133 contents.MBB = MBB; 00134 } 00135 int getFrameIndex() const { 00136 assert(isFrameIndex() && "Wrong MachineOperand accessor"); 00137 return (int)contents.immedVal; 00138 } 00139 unsigned getConstantPoolIndex() const { 00140 assert(isConstantPoolIndex() && "Wrong MachineOperand accessor"); 00141 return (unsigned)contents.immedVal; 00142 } 00143 unsigned getJumpTableIndex() const { 00144 assert(isJumpTableIndex() && "Wrong MachineOperand accessor"); 00145 return (unsigned)contents.immedVal; 00146 } 00147 GlobalValue *getGlobal() const { 00148 assert(isGlobalAddress() && "Wrong MachineOperand accessor"); 00149 return contents.GV; 00150 } 00151 int getOffset() const { 00152 assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) && 00153 "Wrong MachineOperand accessor"); 00154 return offset; 00155 } 00156 const char *getSymbolName() const { 00157 assert(isExternalSymbol() && "Wrong MachineOperand accessor"); 00158 return contents.SymbolName; 00159 } 00160 00161 /// MachineOperand methods for testing that work on any kind of 00162 /// MachineOperand... 00163 /// 00164 bool isUse () const { return flags & USEFLAG; } 00165 MachineOperand& setUse () { flags |= USEFLAG; return *this; } 00166 bool isDef () const { return flags & DEFFLAG; } 00167 MachineOperand& setDef () { flags |= DEFFLAG; return *this; } 00168 00169 /// getReg - Returns the register number. 00170 /// 00171 unsigned getReg() const { 00172 assert(isRegister() && "This is not a register operand!"); 00173 return contents.RegNo; 00174 } 00175 00176 /// MachineOperand mutators. 00177 /// 00178 void setReg(unsigned Reg) { 00179 assert(isRegister() && "This is not a register operand!"); 00180 contents.RegNo = Reg; 00181 } 00182 00183 void setImmedValue(int64_t immVal) { 00184 assert(isImmediate() && "Wrong MachineOperand mutator"); 00185 contents.immedVal = immVal; 00186 } 00187 00188 void setOffset(int Offset) { 00189 assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() || 00190 isJumpTableIndex()) && 00191 "Wrong MachineOperand accessor"); 00192 offset = Offset; 00193 } 00194 00195 /// ChangeToImmediate - Replace this operand with a new immediate operand of 00196 /// the specified value. If an operand is known to be an immediate already, 00197 /// the setImmedValue method should be used. 00198 void ChangeToImmediate(int64_t ImmVal) { 00199 opType = MO_Immediate; 00200 contents.immedVal = ImmVal; 00201 } 00202 00203 /// ChangeToRegister - Replace this operand with a new register operand of 00204 /// the specified value. If an operand is known to be an register already, 00205 /// the setReg method should be used. 00206 void ChangeToRegister(unsigned Reg) { 00207 opType = MO_Register; 00208 contents.RegNo = Reg; 00209 } 00210 00211 friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop); 00212 00213 friend class MachineInstr; 00214 }; 00215 00216 00217 //===----------------------------------------------------------------------===// 00218 /// MachineInstr - Representation of each machine instruction. 00219 /// 00220 class MachineInstr { 00221 short Opcode; // the opcode 00222 std::vector<MachineOperand> Operands; // the operands 00223 MachineInstr* prev, *next; // links for our intrusive list 00224 MachineBasicBlock* parent; // pointer to the owning basic block 00225 00226 // OperandComplete - Return true if it's illegal to add a new operand 00227 bool OperandsComplete() const; 00228 00229 MachineInstr(const MachineInstr&); 00230 void operator=(const MachineInstr&); // DO NOT IMPLEMENT 00231 00232 // Intrusive list support 00233 // 00234 friend struct ilist_traits<MachineInstr>; 00235 00236 public: 00237 /// MachineInstr ctor - This constructor reserve's space for numOperand 00238 /// operands. 00239 MachineInstr(short Opcode, unsigned numOperands); 00240 00241 /// MachineInstr ctor - Work exactly the same as the ctor above, except that 00242 /// the MachineInstr is created and added to the end of the specified basic 00243 /// block. 00244 /// 00245 MachineInstr(MachineBasicBlock *MBB, short Opcode, unsigned numOps); 00246 00247 ~MachineInstr(); 00248 00249 const MachineBasicBlock* getParent() const { return parent; } 00250 MachineBasicBlock* getParent() { return parent; } 00251 00252 /// getOpcode - Returns the opcode of this MachineInstr. 00253 /// 00254 const int getOpcode() const { return Opcode; } 00255 00256 /// Access to explicit operands of the instruction. 00257 /// 00258 unsigned getNumOperands() const { return Operands.size(); } 00259 00260 const MachineOperand& getOperand(unsigned i) const { 00261 assert(i < getNumOperands() && "getOperand() out of range!"); 00262 return Operands[i]; 00263 } 00264 MachineOperand& getOperand(unsigned i) { 00265 assert(i < getNumOperands() && "getOperand() out of range!"); 00266 return Operands[i]; 00267 } 00268 00269 00270 /// clone - Create a copy of 'this' instruction that is identical in 00271 /// all ways except the the instruction has no parent, prev, or next. 00272 MachineInstr* clone() const { return new MachineInstr(*this); } 00273 00274 /// removeFromParent - This method unlinks 'this' from the containing basic 00275 /// block, and returns it, but does not delete it. 00276 MachineInstr *removeFromParent(); 00277 00278 /// eraseFromParent - This method unlinks 'this' from the containing basic 00279 /// block and deletes it. 00280 void eraseFromParent() { 00281 delete removeFromParent(); 00282 } 00283 00284 // 00285 // Debugging support 00286 // 00287 void print(std::ostream &OS, const TargetMachine *TM) const; 00288 void dump() const; 00289 friend std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr); 00290 00291 //===--------------------------------------------------------------------===// 00292 // Accessors to add operands when building up machine instructions. 00293 // 00294 00295 /// addRegOperand - Add a register operand. 00296 /// 00297 void addRegOperand(unsigned Reg, 00298 MachineOperand::UseType UTy = MachineOperand::Use) { 00299 MachineOperand &Op = AddNewOperand(); 00300 Op.opType = MachineOperand::MO_Register; 00301 Op.flags = UTy; 00302 Op.contents.RegNo = Reg; 00303 Op.offset = 0; 00304 } 00305 00306 /// addImmOperand - Add a zero extended constant argument to the 00307 /// machine instruction. 00308 /// 00309 void addImmOperand(int64_t Val) { 00310 MachineOperand &Op = AddNewOperand(); 00311 Op.opType = MachineOperand::MO_Immediate; 00312 Op.flags = 0; 00313 Op.contents.immedVal = Val; 00314 Op.offset = 0; 00315 } 00316 00317 void addMachineBasicBlockOperand(MachineBasicBlock *MBB) { 00318 MachineOperand &Op = AddNewOperand(); 00319 Op.opType = MachineOperand::MO_MachineBasicBlock; 00320 Op.flags = 0; 00321 Op.contents.MBB = MBB; 00322 Op.offset = 0; 00323 } 00324 00325 /// addFrameIndexOperand - Add an abstract frame index to the instruction 00326 /// 00327 void addFrameIndexOperand(unsigned Idx) { 00328 MachineOperand &Op = AddNewOperand(); 00329 Op.opType = MachineOperand::MO_FrameIndex; 00330 Op.flags = 0; 00331 Op.contents.immedVal = Idx; 00332 Op.offset = 0; 00333 } 00334 00335 /// addConstantPoolndexOperand - Add a constant pool object index to the 00336 /// instruction. 00337 /// 00338 void addConstantPoolIndexOperand(unsigned Idx, int Offset) { 00339 MachineOperand &Op = AddNewOperand(); 00340 Op.opType = MachineOperand::MO_ConstantPoolIndex; 00341 Op.flags = 0; 00342 Op.contents.immedVal = Idx; 00343 Op.offset = Offset; 00344 } 00345 00346 /// addJumpTableIndexOperand - Add a jump table object index to the 00347 /// instruction. 00348 /// 00349 void addJumpTableIndexOperand(unsigned Idx) { 00350 MachineOperand &Op = AddNewOperand(); 00351 Op.opType = MachineOperand::MO_JumpTableIndex; 00352 Op.flags = 0; 00353 Op.contents.immedVal = Idx; 00354 Op.offset = 0; 00355 } 00356 00357 void addGlobalAddressOperand(GlobalValue *GV, int Offset) { 00358 MachineOperand &Op = AddNewOperand(); 00359 Op.opType = MachineOperand::MO_GlobalAddress; 00360 Op.flags = 0; 00361 Op.contents.GV = GV; 00362 Op.offset = Offset; 00363 } 00364 00365 /// addExternalSymbolOperand - Add an external symbol operand to this instr 00366 /// 00367 void addExternalSymbolOperand(const char *SymName) { 00368 MachineOperand &Op = AddNewOperand(); 00369 Op.opType = MachineOperand::MO_ExternalSymbol; 00370 Op.flags = 0; 00371 Op.contents.SymbolName = SymName; 00372 Op.offset = 0; 00373 } 00374 00375 //===--------------------------------------------------------------------===// 00376 // Accessors used to modify instructions in place. 00377 // 00378 00379 /// setOpcode - Replace the opcode of the current instruction with a new one. 00380 /// 00381 void setOpcode(unsigned Op) { Opcode = Op; } 00382 00383 /// RemoveOperand - Erase an operand from an instruction, leaving it with one 00384 /// fewer operand than it started with. 00385 /// 00386 void RemoveOperand(unsigned i) { 00387 Operands.erase(Operands.begin()+i); 00388 } 00389 private: 00390 MachineOperand &AddNewOperand() { 00391 assert(!OperandsComplete() && 00392 "Trying to add an operand to a machine instr that is already done!"); 00393 Operands.push_back(MachineOperand()); 00394 return Operands.back(); 00395 } 00396 }; 00397 00398 //===----------------------------------------------------------------------===// 00399 // Debugging Support 00400 00401 std::ostream& operator<<(std::ostream &OS, const MachineInstr &MI); 00402 std::ostream& operator<<(std::ostream &OS, const MachineOperand &MO); 00403 00404 } // End llvm namespace 00405 00406 #endif