LLVM API Documentation
00001 //===-- llvm/CodeGen/MachineOperand.h - MachineOperand class ----*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the declaration of the MachineOperand class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CODEGEN_MACHINEOPERAND_H 00015 #define LLVM_CODEGEN_MACHINEOPERAND_H 00016 00017 #include "llvm/Support/DataTypes.h" 00018 #include <cassert> 00019 #include <iosfwd> 00020 00021 namespace llvm { 00022 00023 class ConstantFP; 00024 class MachineBasicBlock; 00025 class GlobalValue; 00026 class MachineInstr; 00027 class TargetMachine; 00028 class MachineRegisterInfo; 00029 class raw_ostream; 00030 00031 /// MachineOperand class - Representation of each machine instruction operand. 00032 /// 00033 class MachineOperand { 00034 public: 00035 enum MachineOperandType { 00036 MO_Register, ///< Register operand. 00037 MO_Immediate, ///< Immediate operand 00038 MO_FPImmediate, ///< Floating-point immediate operand 00039 MO_MachineBasicBlock, ///< MachineBasicBlock reference 00040 MO_FrameIndex, ///< Abstract Stack Frame Index 00041 MO_ConstantPoolIndex, ///< Address of indexed Constant in Constant Pool 00042 MO_JumpTableIndex, ///< Address of indexed Jump Table for switch 00043 MO_ExternalSymbol, ///< Name of external global symbol 00044 MO_GlobalAddress ///< Address of a global value 00045 }; 00046 00047 private: 00048 /// OpKind - Specify what kind of operand this is. This discriminates the 00049 /// union. 00050 MachineOperandType OpKind : 8; 00051 00052 /// IsDef/IsImp/IsKill/IsDead flags - These are only valid for MO_Register 00053 /// operands. 00054 00055 /// IsDef - True if this is a def, false if this is a use of the register. 00056 /// 00057 bool IsDef : 1; 00058 00059 /// IsImp - True if this is an implicit def or use, false if it is explicit. 00060 /// 00061 bool IsImp : 1; 00062 00063 /// IsKill - True if this instruction is the last use of the register on this 00064 /// path through the function. This is only valid on uses of registers. 00065 bool IsKill : 1; 00066 00067 /// IsDead - True if this register is never used by a subsequent instruction. 00068 /// This is only valid on definitions of registers. 00069 bool IsDead : 1; 00070 00071 /// IsEarlyClobber - True if this MO_Register 'def' operand is written to 00072 /// by the MachineInstr before all input registers are read. This is used to 00073 /// model the GCC inline asm '&' constraint modifier. 00074 bool IsEarlyClobber : 1; 00075 00076 /// SubReg - Subregister number, only valid for MO_Register. A value of 0 00077 /// indicates the MO_Register has no subReg. 00078 unsigned char SubReg; 00079 00080 /// ParentMI - This is the instruction that this operand is embedded into. 00081 /// This is valid for all operand types, when the operand is in an instr. 00082 MachineInstr *ParentMI; 00083 00084 /// Contents union - This contains the payload for the various operand types. 00085 union { 00086 MachineBasicBlock *MBB; // For MO_MachineBasicBlock. 00087 const ConstantFP *CFP; // For MO_FPImmediate. 00088 int64_t ImmVal; // For MO_Immediate. 00089 00090 struct { // For MO_Register. 00091 unsigned RegNo; 00092 MachineOperand **Prev; // Access list for register. 00093 MachineOperand *Next; 00094 } Reg; 00095 00096 /// OffsetedInfo - This struct contains the offset and an object identifier. 00097 /// this represent the object as with an optional offset from it. 00098 struct { 00099 union { 00100 int Index; // For MO_*Index - The index itself. 00101 const char *SymbolName; // For MO_ExternalSymbol. 00102 GlobalValue *GV; // For MO_GlobalAddress. 00103 } Val; 00104 int64_t Offset; // An offset from the object. 00105 } OffsetedInfo; 00106 } Contents; 00107 00108 explicit MachineOperand(MachineOperandType K) : OpKind(K), ParentMI(0) {} 00109 public: 00110 MachineOperand(const MachineOperand &M) { 00111 *this = M; 00112 } 00113 00114 ~MachineOperand() {} 00115 00116 /// getType - Returns the MachineOperandType for this operand. 00117 /// 00118 MachineOperandType getType() const { return OpKind; } 00119 00120 /// getParent - Return the instruction that this operand belongs to. 00121 /// 00122 MachineInstr *getParent() { return ParentMI; } 00123 const MachineInstr *getParent() const { return ParentMI; } 00124 00125 void print(std::ostream &os, const TargetMachine *TM = 0) const; 00126 void print(raw_ostream &os, const TargetMachine *TM = 0) const; 00127 00128 //===--------------------------------------------------------------------===// 00129 // Accessors that tell you what kind of MachineOperand you're looking at. 00130 //===--------------------------------------------------------------------===// 00131 00132 /// isReg - Tests if this is a MO_Register operand. 00133 bool isReg() const { return OpKind == MO_Register; } 00134 /// isImm - Tests if this is a MO_Immediate operand. 00135 bool isImm() const { return OpKind == MO_Immediate; } 00136 /// isFPImm - Tests if this is a MO_FPImmediate operand. 00137 bool isFPImm() const { return OpKind == MO_FPImmediate; } 00138 /// isMBB - Tests if this is a MO_MachineBasicBlock operand. 00139 bool isMBB() const { return OpKind == MO_MachineBasicBlock; } 00140 /// isFI - Tests if this is a MO_FrameIndex operand. 00141 bool isFI() const { return OpKind == MO_FrameIndex; } 00142 /// isCPI - Tests if this is a MO_ConstantPoolIndex operand. 00143 bool isCPI() const { return OpKind == MO_ConstantPoolIndex; } 00144 /// isJTI - Tests if this is a MO_JumpTableIndex operand. 00145 bool isJTI() const { return OpKind == MO_JumpTableIndex; } 00146 /// isGlobal - Tests if this is a MO_GlobalAddress operand. 00147 bool isGlobal() const { return OpKind == MO_GlobalAddress; } 00148 /// isSymbol - Tests if this is a MO_ExternalSymbol operand. 00149 bool isSymbol() const { return OpKind == MO_ExternalSymbol; } 00150 00151 //===--------------------------------------------------------------------===// 00152 // Accessors for Register Operands 00153 //===--------------------------------------------------------------------===// 00154 00155 /// getReg - Returns the register number. 00156 unsigned getReg() const { 00157 assert(isReg() && "This is not a register operand!"); 00158 return Contents.Reg.RegNo; 00159 } 00160 00161 unsigned getSubReg() const { 00162 assert(isReg() && "Wrong MachineOperand accessor"); 00163 return (unsigned)SubReg; 00164 } 00165 00166 bool isUse() const { 00167 assert(isReg() && "Wrong MachineOperand accessor"); 00168 return !IsDef; 00169 } 00170 00171 bool isDef() const { 00172 assert(isReg() && "Wrong MachineOperand accessor"); 00173 return IsDef; 00174 } 00175 00176 bool isImplicit() const { 00177 assert(isReg() && "Wrong MachineOperand accessor"); 00178 return IsImp; 00179 } 00180 00181 bool isDead() const { 00182 assert(isReg() && "Wrong MachineOperand accessor"); 00183 return IsDead; 00184 } 00185 00186 bool isKill() const { 00187 assert(isReg() && "Wrong MachineOperand accessor"); 00188 return IsKill; 00189 } 00190 00191 bool isEarlyClobber() const { 00192 assert(isReg() && "Wrong MachineOperand accessor"); 00193 return IsEarlyClobber; 00194 } 00195 00196 /// getNextOperandForReg - Return the next MachineOperand in the function that 00197 /// uses or defines this register. 00198 MachineOperand *getNextOperandForReg() const { 00199 assert(isReg() && "This is not a register operand!"); 00200 return Contents.Reg.Next; 00201 } 00202 00203 //===--------------------------------------------------------------------===// 00204 // Mutators for Register Operands 00205 //===--------------------------------------------------------------------===// 00206 00207 /// Change the register this operand corresponds to. 00208 /// 00209 void setReg(unsigned Reg); 00210 00211 void setSubReg(unsigned subReg) { 00212 assert(isReg() && "Wrong MachineOperand accessor"); 00213 SubReg = (unsigned char)subReg; 00214 } 00215 00216 void setIsUse(bool Val = true) { 00217 assert(isReg() && "Wrong MachineOperand accessor"); 00218 IsDef = !Val; 00219 } 00220 00221 void setIsDef(bool Val = true) { 00222 assert(isReg() && "Wrong MachineOperand accessor"); 00223 IsDef = Val; 00224 } 00225 00226 void setImplicit(bool Val = true) { 00227 assert(isReg() && "Wrong MachineOperand accessor"); 00228 IsImp = Val; 00229 } 00230 00231 void setIsKill(bool Val = true) { 00232 assert(isReg() && !IsDef && "Wrong MachineOperand accessor"); 00233 IsKill = Val; 00234 } 00235 00236 void setIsDead(bool Val = true) { 00237 assert(isReg() && IsDef && "Wrong MachineOperand accessor"); 00238 IsDead = Val; 00239 } 00240 00241 void setIsEarlyClobber(bool Val = true) { 00242 assert(isReg() && IsDef && "Wrong MachineOperand accessor"); 00243 IsEarlyClobber = Val; 00244 } 00245 00246 //===--------------------------------------------------------------------===// 00247 // Accessors for various operand types. 00248 //===--------------------------------------------------------------------===// 00249 00250 int64_t getImm() const { 00251 assert(isImm() && "Wrong MachineOperand accessor"); 00252 return Contents.ImmVal; 00253 } 00254 00255 const ConstantFP *getFPImm() const { 00256 assert(isFPImm() && "Wrong MachineOperand accessor"); 00257 return Contents.CFP; 00258 } 00259 00260 MachineBasicBlock *getMBB() const { 00261 assert(isMBB() && "Wrong MachineOperand accessor"); 00262 return Contents.MBB; 00263 } 00264 00265 int getIndex() const { 00266 assert((isFI() || isCPI() || isJTI()) && 00267 "Wrong MachineOperand accessor"); 00268 return Contents.OffsetedInfo.Val.Index; 00269 } 00270 00271 GlobalValue *getGlobal() const { 00272 assert(isGlobal() && "Wrong MachineOperand accessor"); 00273 return Contents.OffsetedInfo.Val.GV; 00274 } 00275 00276 int64_t getOffset() const { 00277 assert((isGlobal() || isSymbol() || isCPI()) && 00278 "Wrong MachineOperand accessor"); 00279 return Contents.OffsetedInfo.Offset; 00280 } 00281 00282 const char *getSymbolName() const { 00283 assert(isSymbol() && "Wrong MachineOperand accessor"); 00284 return Contents.OffsetedInfo.Val.SymbolName; 00285 } 00286 00287 //===--------------------------------------------------------------------===// 00288 // Mutators for various operand types. 00289 //===--------------------------------------------------------------------===// 00290 00291 void setImm(int64_t immVal) { 00292 assert(isImm() && "Wrong MachineOperand mutator"); 00293 Contents.ImmVal = immVal; 00294 } 00295 00296 void setOffset(int64_t Offset) { 00297 assert((isGlobal() || isSymbol() || isCPI()) && 00298 "Wrong MachineOperand accessor"); 00299 Contents.OffsetedInfo.Offset = Offset; 00300 } 00301 00302 void setIndex(int Idx) { 00303 assert((isFI() || isCPI() || isJTI()) && 00304 "Wrong MachineOperand accessor"); 00305 Contents.OffsetedInfo.Val.Index = Idx; 00306 } 00307 00308 void setMBB(MachineBasicBlock *MBB) { 00309 assert(isMBB() && "Wrong MachineOperand accessor"); 00310 Contents.MBB = MBB; 00311 } 00312 00313 //===--------------------------------------------------------------------===// 00314 // Other methods. 00315 //===--------------------------------------------------------------------===// 00316 00317 /// isIdenticalTo - Return true if this operand is identical to the specified 00318 /// operand. Note: This method ignores isKill and isDead properties. 00319 bool isIdenticalTo(const MachineOperand &Other) const; 00320 00321 /// ChangeToImmediate - Replace this operand with a new immediate operand of 00322 /// the specified value. If an operand is known to be an immediate already, 00323 /// the setImm method should be used. 00324 void ChangeToImmediate(int64_t ImmVal); 00325 00326 /// ChangeToRegister - Replace this operand with a new register operand of 00327 /// the specified value. If an operand is known to be an register already, 00328 /// the setReg method should be used. 00329 void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false, 00330 bool isKill = false, bool isDead = false); 00331 00332 //===--------------------------------------------------------------------===// 00333 // Construction methods. 00334 //===--------------------------------------------------------------------===// 00335 00336 static MachineOperand CreateImm(int64_t Val) { 00337 MachineOperand Op(MachineOperand::MO_Immediate); 00338 Op.setImm(Val); 00339 return Op; 00340 } 00341 00342 static MachineOperand CreateFPImm(const ConstantFP *CFP) { 00343 MachineOperand Op(MachineOperand::MO_FPImmediate); 00344 Op.Contents.CFP = CFP; 00345 return Op; 00346 } 00347 00348 static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp = false, 00349 bool isKill = false, bool isDead = false, 00350 unsigned SubReg = 0, 00351 bool isEarlyClobber = false) { 00352 MachineOperand Op(MachineOperand::MO_Register); 00353 Op.IsDef = isDef; 00354 Op.IsImp = isImp; 00355 Op.IsKill = isKill; 00356 Op.IsDead = isDead; 00357 Op.IsEarlyClobber = isEarlyClobber; 00358 Op.Contents.Reg.RegNo = Reg; 00359 Op.Contents.Reg.Prev = 0; 00360 Op.Contents.Reg.Next = 0; 00361 Op.SubReg = SubReg; 00362 return Op; 00363 } 00364 static MachineOperand CreateMBB(MachineBasicBlock *MBB) { 00365 MachineOperand Op(MachineOperand::MO_MachineBasicBlock); 00366 Op.setMBB(MBB); 00367 return Op; 00368 } 00369 static MachineOperand CreateFI(unsigned Idx) { 00370 MachineOperand Op(MachineOperand::MO_FrameIndex); 00371 Op.setIndex(Idx); 00372 return Op; 00373 } 00374 static MachineOperand CreateCPI(unsigned Idx, int Offset) { 00375 MachineOperand Op(MachineOperand::MO_ConstantPoolIndex); 00376 Op.setIndex(Idx); 00377 Op.setOffset(Offset); 00378 return Op; 00379 } 00380 static MachineOperand CreateJTI(unsigned Idx) { 00381 MachineOperand Op(MachineOperand::MO_JumpTableIndex); 00382 Op.setIndex(Idx); 00383 return Op; 00384 } 00385 static MachineOperand CreateGA(GlobalValue *GV, int64_t Offset) { 00386 MachineOperand Op(MachineOperand::MO_GlobalAddress); 00387 Op.Contents.OffsetedInfo.Val.GV = GV; 00388 Op.setOffset(Offset); 00389 return Op; 00390 } 00391 static MachineOperand CreateES(const char *SymName, int64_t Offset = 0) { 00392 MachineOperand Op(MachineOperand::MO_ExternalSymbol); 00393 Op.Contents.OffsetedInfo.Val.SymbolName = SymName; 00394 Op.setOffset(Offset); 00395 return Op; 00396 } 00397 const MachineOperand &operator=(const MachineOperand &MO) { 00398 OpKind = MO.OpKind; 00399 IsDef = MO.IsDef; 00400 IsImp = MO.IsImp; 00401 IsKill = MO.IsKill; 00402 IsDead = MO.IsDead; 00403 IsEarlyClobber = MO.IsEarlyClobber; 00404 SubReg = MO.SubReg; 00405 ParentMI = MO.ParentMI; 00406 Contents = MO.Contents; 00407 return *this; 00408 } 00409 00410 friend class MachineInstr; 00411 friend class MachineRegisterInfo; 00412 private: 00413 //===--------------------------------------------------------------------===// 00414 // Methods for handling register use/def lists. 00415 //===--------------------------------------------------------------------===// 00416 00417 /// isOnRegUseList - Return true if this operand is on a register use/def list 00418 /// or false if not. This can only be called for register operands that are 00419 /// part of a machine instruction. 00420 bool isOnRegUseList() const { 00421 assert(isReg() && "Can only add reg operand to use lists"); 00422 return Contents.Reg.Prev != 0; 00423 } 00424 00425 /// AddRegOperandToRegInfo - Add this register operand to the specified 00426 /// MachineRegisterInfo. If it is null, then the next/prev fields should be 00427 /// explicitly nulled out. 00428 void AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo); 00429 00430 void RemoveRegOperandFromRegInfo() { 00431 assert(isOnRegUseList() && "Reg operand is not on a use list"); 00432 // Unlink this from the doubly linked list of operands. 00433 MachineOperand *NextOp = Contents.Reg.Next; 00434 *Contents.Reg.Prev = NextOp; 00435 if (NextOp) { 00436 assert(NextOp->getReg() == getReg() && "Corrupt reg use/def chain!"); 00437 NextOp->Contents.Reg.Prev = Contents.Reg.Prev; 00438 } 00439 Contents.Reg.Prev = 0; 00440 Contents.Reg.Next = 0; 00441 } 00442 }; 00443 00444 inline std::ostream &operator<<(std::ostream &OS, const MachineOperand &MO) { 00445 MO.print(OS, 0); 00446 return OS; 00447 } 00448 00449 inline raw_ostream &operator<<(raw_ostream &OS, const MachineOperand& MO) { 00450 MO.print(OS, 0); 00451 return OS; 00452 } 00453 00454 } // End llvm namespace 00455 00456 #endif