| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 //===- subzero/src/IceOperand.h - High-level operands -----------*- C++ -*-===// | 
|  | 2 // | 
|  | 3 //                        The Subzero Code Generator | 
|  | 4 // | 
|  | 5 // This file is distributed under the University of Illinois Open Source | 
|  | 6 // License. See LICENSE.TXT for details. | 
|  | 7 // | 
|  | 8 //===----------------------------------------------------------------------===// | 
|  | 9 // | 
|  | 10 // This file declares the IceOperand class and its target-independent | 
|  | 11 // subclasses.  The main classes are IceVariable, which represents an | 
|  | 12 // LLVM variable that is either register- or stack-allocated, and the | 
|  | 13 // IceConstant hierarchy, which represents integer, floating-point, | 
|  | 14 // and/or symbolic constants. | 
|  | 15 // | 
|  | 16 //===----------------------------------------------------------------------===// | 
|  | 17 | 
|  | 18 #ifndef SUBZERO_SRC_ICEOPERAND_H | 
|  | 19 #define SUBZERO_SRC_ICEOPERAND_H | 
|  | 20 | 
|  | 21 #include "IceDefs.h" | 
|  | 22 #include "IceTypes.h" | 
|  | 23 | 
|  | 24 class IceOperand { | 
|  | 25 public: | 
|  | 26   enum OperandKind { | 
|  | 27     Constant, | 
|  | 28     ConstantInteger, | 
|  | 29     ConstantFloat, | 
|  | 30     ConstantDouble, | 
|  | 31     ConstantRelocatable, | 
|  | 32     Constant_Num, | 
|  | 33     Variable, | 
|  | 34     // Target-specific operand classes use Target as the starting | 
|  | 35     // point for their Kind enum space. | 
|  | 36     Target | 
|  | 37   }; | 
|  | 38   OperandKind getKind() const { return Kind; } | 
|  | 39   IceType getType() const { return Type; } | 
|  | 40 | 
|  | 41   // Every IceOperand keeps an array of the IceVariables referenced in | 
|  | 42   // the operand.  This is so that the liveness operations can get | 
|  | 43   // quick access to the variables of interest, without having to dig | 
|  | 44   // so far into the operand. | 
|  | 45   uint32_t getNumVars() const { return NumVars; } | 
|  | 46   IceVariable *getVar(uint32_t I) const { | 
|  | 47     assert(I < getNumVars()); | 
|  | 48     return Vars[I]; | 
|  | 49   } | 
|  | 50   virtual void setUse(const IceInst *Inst, const IceCfgNode *Node) {} | 
|  | 51   virtual void dump(IceOstream &Str) const; | 
|  | 52 | 
|  | 53   virtual ~IceOperand() {} | 
|  | 54 | 
|  | 55 protected: | 
|  | 56   IceOperand(IceCfg *Cfg, OperandKind Kind, IceType Type) | 
|  | 57       : Type(Type), Kind(Kind) {} | 
|  | 58   const IceType Type; | 
|  | 59   const OperandKind Kind; | 
|  | 60   // Vars and NumVars are initialized by the derived class. | 
|  | 61   uint32_t NumVars; | 
|  | 62   IceVariable **Vars; | 
|  | 63 }; | 
|  | 64 | 
|  | 65 IceOstream &operator<<(IceOstream &Str, const IceOperand *O); | 
|  | 66 | 
|  | 67 // IceConstant is the abstract base class for constants. | 
|  | 68 // TODO: better design of a minimal per-module constant pool, | 
|  | 69 // including synchronized access for parallel translation. | 
|  | 70 class IceConstant : public IceOperand { | 
|  | 71 public: | 
|  | 72   virtual void dump(IceOstream &Str) const = 0; | 
|  | 73 | 
|  | 74   static bool classof(const IceOperand *Operand) { | 
|  | 75     OperandKind Kind = Operand->getKind(); | 
|  | 76     return Kind >= Constant && Kind <= Constant_Num; | 
|  | 77   } | 
|  | 78 | 
|  | 79 protected: | 
|  | 80   IceConstant(IceCfg *Cfg, OperandKind Kind, IceType Type) | 
|  | 81       : IceOperand(Cfg, Kind, Type) { | 
|  | 82     Vars = NULL; | 
|  | 83     NumVars = 0; | 
|  | 84   } | 
|  | 85 }; | 
|  | 86 | 
|  | 87 // IceConstantPrimitive<> wraps a primitive type. | 
|  | 88 template <typename T, IceOperand::OperandKind K> | 
|  | 89 class IceConstantPrimitive : public IceConstant { | 
|  | 90 public: | 
|  | 91   static IceConstantPrimitive *create(IceCfg *Cfg, IceType Type, T Value) { | 
|  | 92     return new IceConstantPrimitive(Cfg, Type, Value); | 
|  | 93   } | 
|  | 94   T getValue() const { return Value; } | 
|  | 95   virtual void dump(IceOstream &Str) const { Str << getValue(); } | 
|  | 96 | 
|  | 97   static bool classof(const IceOperand *Operand) { | 
|  | 98     return Operand->getKind() == K; | 
|  | 99   } | 
|  | 100 | 
|  | 101 private: | 
|  | 102   IceConstantPrimitive(IceCfg *Cfg, IceType Type, T Value) | 
|  | 103       : IceConstant(Cfg, K, Type), Value(Value) {} | 
|  | 104   const T Value; | 
|  | 105 }; | 
|  | 106 | 
|  | 107 typedef IceConstantPrimitive<uint64_t, IceOperand::ConstantInteger> | 
|  | 108 IceConstantInteger; | 
|  | 109 typedef IceConstantPrimitive<float, IceOperand::ConstantFloat> IceConstantFloat; | 
|  | 110 typedef IceConstantPrimitive<double, IceOperand::ConstantDouble> | 
|  | 111 IceConstantDouble; | 
|  | 112 | 
|  | 113 // IceConstantRelocatable represents a symbolic constant combined with | 
|  | 114 // a fixed offset. | 
|  | 115 class IceConstantRelocatable : public IceConstant { | 
|  | 116 public: | 
|  | 117   static IceConstantRelocatable *create(IceCfg *Cfg, uint32_t CPIndex, | 
|  | 118                                         IceType Type, const void *Handle, | 
|  | 119                                         int64_t Offset, | 
|  | 120                                         const IceString &Name = "") { | 
|  | 121     return new IceConstantRelocatable(Cfg, Type, Handle, Offset, Name, CPIndex); | 
|  | 122   } | 
|  | 123   uint32_t getCPIndex() const { return CPIndex; } | 
|  | 124   const void *getHandle() const { return Handle; } | 
|  | 125   int64_t getOffset() const { return Offset; } | 
|  | 126   IceString getName() const { return Name; } | 
|  | 127   void setSuppressMangling(bool Value) { SuppressMangling = Value; } | 
|  | 128   bool getSuppressMangling() const { return SuppressMangling; } | 
|  | 129   virtual void dump(IceOstream &Str) const; | 
|  | 130 | 
|  | 131   static bool classof(const IceOperand *Operand) { | 
|  | 132     OperandKind Kind = Operand->getKind(); | 
|  | 133     return Kind == ConstantRelocatable; | 
|  | 134   } | 
|  | 135 | 
|  | 136 private: | 
|  | 137   IceConstantRelocatable(IceCfg *Cfg, IceType Type, const void *Handle, | 
|  | 138                          int64_t Offset, const IceString &Name, | 
|  | 139                          uint32_t CPIndex) | 
|  | 140       : IceConstant(Cfg, ConstantRelocatable, Type), CPIndex(CPIndex), | 
|  | 141         Handle(Handle), Offset(Offset), Name(Name), SuppressMangling(false) {} | 
|  | 142   const uint32_t CPIndex;   // index into ICE constant pool | 
|  | 143   const void *const Handle; // opaque handle e.g. to LLVM | 
|  | 144   const int64_t Offset;     // fixed offset to add | 
|  | 145   const IceString Name;     // optional for debug/dump | 
|  | 146   bool SuppressMangling; | 
|  | 147 }; | 
|  | 148 | 
|  | 149 // IceVariable represents an operand that is register-allocated or | 
|  | 150 // stack-allocated.  If it is register-allocated, it will ultimately | 
|  | 151 // have a non-negative RegNum field. | 
|  | 152 class IceVariable : public IceOperand { | 
|  | 153 public: | 
|  | 154   static IceVariable *create(IceCfg *Cfg, IceType Type, const IceCfgNode *Node, | 
|  | 155                              uint32_t Index, const IceString &Name) { | 
|  | 156     return new IceVariable(Cfg, Type, Node, Index, Name); | 
|  | 157   } | 
|  | 158 | 
|  | 159   uint32_t getIndex() const { return Number; } | 
|  | 160   IceString getName() const; | 
|  | 161 | 
|  | 162   IceInst *getDefinition() const { return DefInst; } | 
|  | 163   void setDefinition(IceInst *Inst, const IceCfgNode *Node); | 
|  | 164   void replaceDefinition(IceInst *Inst, const IceCfgNode *Node); | 
|  | 165 | 
|  | 166   const IceCfgNode *getLocalUseNode() const { return DefNode; } | 
|  | 167   bool isMultiblockLife() const { return (DefNode == NULL); } | 
|  | 168   void setUse(const IceInst *Inst, const IceCfgNode *Node); | 
|  | 169 | 
|  | 170   bool getIsArg() const { return IsArgument; } | 
|  | 171   void setIsArg(IceCfg *Cfg); | 
|  | 172 | 
|  | 173   virtual void dump(IceOstream &Str) const; | 
|  | 174 | 
|  | 175   static bool classof(const IceOperand *Operand) { | 
|  | 176     return Operand->getKind() == Variable; | 
|  | 177   } | 
|  | 178 | 
|  | 179 private: | 
|  | 180   IceVariable(IceCfg *Cfg, IceType Type, const IceCfgNode *Node, uint32_t Index, | 
|  | 181               const IceString &Name) | 
|  | 182       : IceOperand(Cfg, Variable, Type), Number(Index), Name(Name), | 
|  | 183         DefInst(NULL), DefNode(Node), IsArgument(false) { | 
|  | 184     Vars = Cfg->allocateArrayOf<IceVariable *>(1); | 
|  | 185     Vars[0] = this; | 
|  | 186     NumVars = 1; | 
|  | 187   } | 
|  | 188   // Number is unique across all variables, and is used as a | 
|  | 189   // (bit)vector index for liveness analysis. | 
|  | 190   const uint32_t Number; | 
|  | 191   // Name is optional. | 
|  | 192   const IceString Name; | 
|  | 193   // DefInst is the instruction that produces this variable as its | 
|  | 194   // dest. | 
|  | 195   IceInst *DefInst; | 
|  | 196   // DefNode is the node where this variable was produced, and is | 
|  | 197   // reset to NULL if it is used outside that node.  This is used for | 
|  | 198   // detecting isMultiblockLife(). | 
|  | 199   const IceCfgNode *DefNode; | 
|  | 200   bool IsArgument; | 
|  | 201 }; | 
|  | 202 | 
|  | 203 #endif // SUBZERO_SRC_ICEOPERAND_H | 
| OLD | NEW | 
|---|