LLVM API Documentation

MachineOperand.h

Go to the documentation of this file.
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