| OLD | NEW |
| 1 //===- subzero/src/IceOperand.h - High-level operands -----------*- C++ -*-===// | 1 //===- subzero/src/IceOperand.h - High-level operands -----------*- C++ -*-===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 /// | 9 /// |
| 10 /// \file | 10 /// \file |
| 11 /// This file declares the Operand class and its target-independent subclasses. | 11 /// This file declares the Operand class and its target-independent subclasses. |
| 12 /// The main classes are Variable, which represents an LLVM variable that is | 12 /// The main classes are Variable, which represents an LLVM variable that is |
| 13 /// either register- or stack-allocated, and the Constant hierarchy, which | 13 /// either register- or stack-allocated, and the Constant hierarchy, which |
| 14 /// represents integer, floating-point, and/or symbolic constants. | 14 /// represents integer, floating-point, and/or symbolic constants. |
| 15 /// | 15 /// |
| 16 //===----------------------------------------------------------------------===// | 16 //===----------------------------------------------------------------------===// |
| 17 | 17 |
| 18 #ifndef SUBZERO_SRC_ICEOPERAND_H | 18 #ifndef SUBZERO_SRC_ICEOPERAND_H |
| 19 #define SUBZERO_SRC_ICEOPERAND_H | 19 #define SUBZERO_SRC_ICEOPERAND_H |
| 20 | 20 |
| 21 #include "IceCfg.h" | 21 #include "IceCfg.h" |
| 22 #include "IceDefs.h" | 22 #include "IceDefs.h" |
| 23 #include "IceGlobalContext.h" | 23 #include "IceGlobalContext.h" |
| 24 #include "IceTypes.h" | 24 #include "IceTypes.h" |
| 25 | 25 |
| 26 #include "llvm/Support/Format.h" |
| 27 |
| 26 namespace Ice { | 28 namespace Ice { |
| 27 | 29 |
| 28 class Operand { | 30 class Operand { |
| 29 Operand() = delete; | 31 Operand() = delete; |
| 30 Operand(const Operand &) = delete; | 32 Operand(const Operand &) = delete; |
| 31 Operand &operator=(const Operand &) = delete; | 33 Operand &operator=(const Operand &) = delete; |
| 32 | 34 |
| 33 public: | 35 public: |
| 34 static constexpr size_t MaxTargetKinds = 10; | 36 static constexpr size_t MaxTargetKinds = 10; |
| 35 enum OperandKind { | 37 enum OperandKind { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 } | 110 } |
| 109 | 111 |
| 110 /// Constant is the abstract base class for constants. All constants are | 112 /// Constant is the abstract base class for constants. All constants are |
| 111 /// allocated from a global arena and are pooled. | 113 /// allocated from a global arena and are pooled. |
| 112 class Constant : public Operand { | 114 class Constant : public Operand { |
| 113 Constant() = delete; | 115 Constant() = delete; |
| 114 Constant(const Constant &) = delete; | 116 Constant(const Constant &) = delete; |
| 115 Constant &operator=(const Constant &) = delete; | 117 Constant &operator=(const Constant &) = delete; |
| 116 | 118 |
| 117 public: | 119 public: |
| 118 void emitPoolLabel(Ostream &Str) const { | 120 virtual void emitPoolLabel(Ostream &Str, const GlobalContext *Ctx) const { |
| 119 Str << ".L$" << getType() << "$" << PoolEntryID; | 121 (void)Str; |
| 120 } | 122 (void)Ctx; |
| 123 llvm::report_fatal_error("emitPoolLabel not defined for type"); |
| 124 }; |
| 121 void emit(const Cfg *Func) const override { emit(Func->getTarget()); } | 125 void emit(const Cfg *Func) const override { emit(Func->getTarget()); } |
| 122 virtual void emit(TargetLowering *Target) const = 0; | 126 virtual void emit(TargetLowering *Target) const = 0; |
| 123 | 127 |
| 124 static bool classof(const Operand *Operand) { | 128 static bool classof(const Operand *Operand) { |
| 125 OperandKind Kind = Operand->getKind(); | 129 OperandKind Kind = Operand->getKind(); |
| 126 return Kind >= kConst_Base && Kind <= kConst_Max; | 130 return Kind >= kConst_Base && Kind <= kConst_Max; |
| 127 } | 131 } |
| 128 | 132 |
| 129 /// Judge if this given immediate should be randomized or pooled By default | 133 /// Judge if this given immediate should be randomized or pooled By default |
| 130 /// should return false, only constant integers should truly go through this | 134 /// should return false, only constant integers should truly go through this |
| 131 /// method. | 135 /// method. |
| 132 virtual bool shouldBeRandomizedOrPooled(const GlobalContext *Ctx) { | 136 virtual bool shouldBeRandomizedOrPooled(const GlobalContext *Ctx) { |
| 133 (void)Ctx; | 137 (void)Ctx; |
| 134 return false; | 138 return false; |
| 135 } | 139 } |
| 136 | 140 |
| 137 void setShouldBePooled(bool R) { shouldBePooled = R; } | 141 void setShouldBePooled(bool R) { shouldBePooled = R; } |
| 138 | 142 |
| 139 bool getShouldBePooled() const { return shouldBePooled; } | 143 bool getShouldBePooled() const { return shouldBePooled; } |
| 140 | 144 |
| 141 protected: | 145 protected: |
| 142 Constant(OperandKind Kind, Type Ty, uint32_t PoolEntryID) | 146 Constant(OperandKind Kind, Type Ty) |
| 143 : Operand(Kind, Ty), PoolEntryID(PoolEntryID), shouldBePooled(false) { | 147 : Operand(Kind, Ty), shouldBePooled(false) { |
| 144 Vars = nullptr; | 148 Vars = nullptr; |
| 145 NumVars = 0; | 149 NumVars = 0; |
| 146 } | 150 } |
| 147 /// PoolEntryID is an integer that uniquely identifies the constant within its | |
| 148 /// constant pool. It is used for building the constant pool in the object | |
| 149 /// code and for referencing its entries. | |
| 150 const uint32_t PoolEntryID; | |
| 151 /// Whether we should pool this constant. Usually Float/Double and pooled | 151 /// Whether we should pool this constant. Usually Float/Double and pooled |
| 152 /// Integers should be flagged true. | 152 /// Integers should be flagged true. |
| 153 bool shouldBePooled; | 153 bool shouldBePooled; |
| 154 }; | 154 }; |
| 155 | 155 |
| 156 /// ConstantPrimitive<> wraps a primitive type. | 156 /// ConstantPrimitive<> wraps a primitive type. |
| 157 template <typename T, Operand::OperandKind K> | 157 template <typename T, Operand::OperandKind K> |
| 158 class ConstantPrimitive : public Constant { | 158 class ConstantPrimitive : public Constant { |
| 159 ConstantPrimitive() = delete; | 159 ConstantPrimitive() = delete; |
| 160 ConstantPrimitive(const ConstantPrimitive &) = delete; | 160 ConstantPrimitive(const ConstantPrimitive &) = delete; |
| 161 ConstantPrimitive &operator=(const ConstantPrimitive &) = delete; | 161 ConstantPrimitive &operator=(const ConstantPrimitive &) = delete; |
| 162 | 162 |
| 163 public: | 163 public: |
| 164 using PrimType = T; | 164 using PrimType = T; |
| 165 | 165 |
| 166 static ConstantPrimitive *create(GlobalContext *Ctx, Type Ty, PrimType Value, | 166 static ConstantPrimitive *create(GlobalContext *Ctx, Type Ty, |
| 167 uint32_t PoolEntryID) { | 167 PrimType Value) { |
| 168 assert(!Ctx->isIRGenerationDisabled() && | 168 assert(!Ctx->isIRGenerationDisabled() && |
| 169 "Attempt to build primitive constant when IR generation disabled"); | 169 "Attempt to build primitive constant when IR generation disabled"); |
| 170 return new (Ctx->allocate<ConstantPrimitive>()) | 170 return new (Ctx->allocate<ConstantPrimitive>()) |
| 171 ConstantPrimitive(Ty, Value, PoolEntryID); | 171 ConstantPrimitive(Ty, Value); |
| 172 } | 172 } |
| 173 PrimType getValue() const { return Value; } | 173 PrimType getValue() const { return Value; } |
| 174 void emitPoolLabel(Ostream &Str, const GlobalContext *Ctx) const final { |
| 175 Str << ".L$" << getType() << "$"; |
| 176 // Print hex characters byte by byte, starting from the most significant |
| 177 // byte. NOTE: This ordering assumes Subzero runs on a little-endian |
| 178 // platform. That means the possibility of different label names depending |
| 179 // on the endian-ness of the platform where Subzero runs. |
| 180 for (unsigned i = 0; i < sizeof(Value); ++i) { |
| 181 constexpr unsigned HexWidthChars = 2; |
| 182 unsigned Offset = sizeof(Value) - 1 - i; |
| 183 Str << llvm::format_hex_no_prefix( |
| 184 *(Offset + (const unsigned char *)&Value), HexWidthChars); |
| 185 } |
| 186 // For a floating-point value in DecorateAsm mode, also append the value in |
| 187 // human-readable sprintf form, changing '+' to 'p' and '-' to 'm' to |
| 188 // maintain valid asm labels. |
| 189 if (std::is_floating_point<PrimType>::value && !BuildDefs::minimal() && |
| 190 Ctx->getFlags().getDecorateAsm()) { |
| 191 char Buf[30]; |
| 192 snprintf(Buf, llvm::array_lengthof(Buf), "$%g", (double)Value); |
| 193 for (unsigned i = 0; i < llvm::array_lengthof(Buf) && Buf[i]; ++i) { |
| 194 if (Buf[i] == '-') |
| 195 Buf[i] = 'm'; |
| 196 else if (Buf[i] == '+') |
| 197 Buf[i] = 'p'; |
| 198 } |
| 199 Str << Buf; |
| 200 } |
| 201 } |
| 174 using Constant::emit; | 202 using Constant::emit; |
| 175 void emit(TargetLowering *Target) const final; | 203 void emit(TargetLowering *Target) const final; |
| 176 using Constant::dump; | 204 using Constant::dump; |
| 177 void dump(const Cfg *, Ostream &Str) const override { | 205 void dump(const Cfg *, Ostream &Str) const override { |
| 178 if (BuildDefs::dump()) | 206 if (BuildDefs::dump()) |
| 179 Str << getValue(); | 207 Str << getValue(); |
| 180 } | 208 } |
| 181 | 209 |
| 182 static bool classof(const Operand *Operand) { | 210 static bool classof(const Operand *Operand) { |
| 183 return Operand->getKind() == K; | 211 return Operand->getKind() == K; |
| 184 } | 212 } |
| 185 | 213 |
| 186 virtual bool shouldBeRandomizedOrPooled(const GlobalContext *Ctx) override { | 214 virtual bool shouldBeRandomizedOrPooled(const GlobalContext *Ctx) override { |
| 187 (void)Ctx; | 215 (void)Ctx; |
| 188 return false; | 216 return false; |
| 189 } | 217 } |
| 190 | 218 |
| 191 private: | 219 private: |
| 192 ConstantPrimitive(Type Ty, PrimType Value, uint32_t PoolEntryID) | 220 ConstantPrimitive(Type Ty, PrimType Value) : Constant(K, Ty), Value(Value) {} |
| 193 : Constant(K, Ty, PoolEntryID), Value(Value) {} | |
| 194 const PrimType Value; | 221 const PrimType Value; |
| 195 }; | 222 }; |
| 196 | 223 |
| 197 using ConstantInteger32 = ConstantPrimitive<int32_t, Operand::kConstInteger32>; | 224 using ConstantInteger32 = ConstantPrimitive<int32_t, Operand::kConstInteger32>; |
| 198 using ConstantInteger64 = ConstantPrimitive<int64_t, Operand::kConstInteger64>; | 225 using ConstantInteger64 = ConstantPrimitive<int64_t, Operand::kConstInteger64>; |
| 199 using ConstantFloat = ConstantPrimitive<float, Operand::kConstFloat>; | 226 using ConstantFloat = ConstantPrimitive<float, Operand::kConstFloat>; |
| 200 using ConstantDouble = ConstantPrimitive<double, Operand::kConstDouble>; | 227 using ConstantDouble = ConstantPrimitive<double, Operand::kConstDouble>; |
| 201 | 228 |
| 202 template <> | 229 template <> |
| 203 inline void ConstantInteger32::dump(const Cfg *, Ostream &Str) const { | 230 inline void ConstantInteger32::dump(const Cfg *, Ostream &Str) const { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 | 270 |
| 244 /// ConstantRelocatable represents a symbolic constant combined with a fixed | 271 /// ConstantRelocatable represents a symbolic constant combined with a fixed |
| 245 /// offset. | 272 /// offset. |
| 246 class ConstantRelocatable : public Constant { | 273 class ConstantRelocatable : public Constant { |
| 247 ConstantRelocatable() = delete; | 274 ConstantRelocatable() = delete; |
| 248 ConstantRelocatable(const ConstantRelocatable &) = delete; | 275 ConstantRelocatable(const ConstantRelocatable &) = delete; |
| 249 ConstantRelocatable &operator=(const ConstantRelocatable &) = delete; | 276 ConstantRelocatable &operator=(const ConstantRelocatable &) = delete; |
| 250 | 277 |
| 251 public: | 278 public: |
| 252 static ConstantRelocatable *create(GlobalContext *Ctx, Type Ty, | 279 static ConstantRelocatable *create(GlobalContext *Ctx, Type Ty, |
| 253 const RelocatableTuple &Tuple, | 280 const RelocatableTuple &Tuple) { |
| 254 uint32_t PoolEntryID) { | |
| 255 assert(!Ctx->isIRGenerationDisabled() && | 281 assert(!Ctx->isIRGenerationDisabled() && |
| 256 "Attempt to build relocatable constant when IR generation disabled"); | 282 "Attempt to build relocatable constant when IR generation disabled"); |
| 257 return new (Ctx->allocate<ConstantRelocatable>()) ConstantRelocatable( | 283 return new (Ctx->allocate<ConstantRelocatable>()) ConstantRelocatable( |
| 258 Ty, Tuple.Offset, Tuple.Name, Tuple.SuppressMangling, PoolEntryID); | 284 Ty, Tuple.Offset, Tuple.Name, Tuple.SuppressMangling); |
| 259 } | 285 } |
| 260 | 286 |
| 261 RelocOffsetT getOffset() const { return Offset; } | 287 RelocOffsetT getOffset() const { return Offset; } |
| 262 const IceString &getName() const { return Name; } | 288 const IceString &getName() const { return Name; } |
| 263 void setSuppressMangling(bool Value) { SuppressMangling = Value; } | 289 void setSuppressMangling(bool Value) { SuppressMangling = Value; } |
| 264 bool getSuppressMangling() const { return SuppressMangling; } | 290 bool getSuppressMangling() const { return SuppressMangling; } |
| 265 using Constant::emit; | 291 using Constant::emit; |
| 266 void emit(TargetLowering *Target) const final; | 292 void emit(TargetLowering *Target) const final; |
| 267 void emitWithoutPrefix(TargetLowering *Target) const; | 293 void emitWithoutPrefix(TargetLowering *Target) const; |
| 268 using Constant::dump; | 294 using Constant::dump; |
| 269 void dump(const Cfg *Func, Ostream &Str) const override; | 295 void dump(const Cfg *Func, Ostream &Str) const override; |
| 270 | 296 |
| 271 static bool classof(const Operand *Operand) { | 297 static bool classof(const Operand *Operand) { |
| 272 OperandKind Kind = Operand->getKind(); | 298 OperandKind Kind = Operand->getKind(); |
| 273 return Kind == kConstRelocatable; | 299 return Kind == kConstRelocatable; |
| 274 } | 300 } |
| 275 | 301 |
| 276 private: | 302 private: |
| 277 ConstantRelocatable(Type Ty, RelocOffsetT Offset, const IceString &Name, | 303 ConstantRelocatable(Type Ty, RelocOffsetT Offset, const IceString &Name, |
| 278 bool SuppressMangling, uint32_t PoolEntryID) | 304 bool SuppressMangling) |
| 279 : Constant(kConstRelocatable, Ty, PoolEntryID), Offset(Offset), | 305 : Constant(kConstRelocatable, Ty), Offset(Offset), Name(Name), |
| 280 Name(Name), SuppressMangling(SuppressMangling) {} | 306 SuppressMangling(SuppressMangling) {} |
| 281 const RelocOffsetT Offset; /// fixed offset to add | 307 const RelocOffsetT Offset; /// fixed offset to add |
| 282 const IceString Name; /// optional for debug/dump | 308 const IceString Name; /// optional for debug/dump |
| 283 bool SuppressMangling; | 309 bool SuppressMangling; |
| 284 }; | 310 }; |
| 285 | 311 |
| 286 /// ConstantUndef represents an unspecified bit pattern. Although it is legal to | 312 /// ConstantUndef represents an unspecified bit pattern. Although it is legal to |
| 287 /// lower ConstantUndef to any value, backends should try to make code | 313 /// lower ConstantUndef to any value, backends should try to make code |
| 288 /// generation deterministic by lowering ConstantUndefs to 0. | 314 /// generation deterministic by lowering ConstantUndefs to 0. |
| 289 class ConstantUndef : public Constant { | 315 class ConstantUndef : public Constant { |
| 290 ConstantUndef() = delete; | 316 ConstantUndef() = delete; |
| 291 ConstantUndef(const ConstantUndef &) = delete; | 317 ConstantUndef(const ConstantUndef &) = delete; |
| 292 ConstantUndef &operator=(const ConstantUndef &) = delete; | 318 ConstantUndef &operator=(const ConstantUndef &) = delete; |
| 293 | 319 |
| 294 public: | 320 public: |
| 295 static ConstantUndef *create(GlobalContext *Ctx, Type Ty, | 321 static ConstantUndef *create(GlobalContext *Ctx, Type Ty) { |
| 296 uint32_t PoolEntryID) { | |
| 297 assert(!Ctx->isIRGenerationDisabled() && | 322 assert(!Ctx->isIRGenerationDisabled() && |
| 298 "Attempt to build undefined constant when IR generation disabled"); | 323 "Attempt to build undefined constant when IR generation disabled"); |
| 299 return new (Ctx->allocate<ConstantUndef>()) ConstantUndef(Ty, PoolEntryID); | 324 return new (Ctx->allocate<ConstantUndef>()) ConstantUndef(Ty); |
| 300 } | 325 } |
| 301 | 326 |
| 302 using Constant::emit; | 327 using Constant::emit; |
| 303 void emit(TargetLowering *Target) const final; | 328 void emit(TargetLowering *Target) const final; |
| 304 using Constant::dump; | 329 using Constant::dump; |
| 305 void dump(const Cfg *, Ostream &Str) const override { | 330 void dump(const Cfg *, Ostream &Str) const override { |
| 306 if (BuildDefs::dump()) | 331 if (BuildDefs::dump()) |
| 307 Str << "undef"; | 332 Str << "undef"; |
| 308 } | 333 } |
| 309 | 334 |
| 310 static bool classof(const Operand *Operand) { | 335 static bool classof(const Operand *Operand) { |
| 311 return Operand->getKind() == kConstUndef; | 336 return Operand->getKind() == kConstUndef; |
| 312 } | 337 } |
| 313 | 338 |
| 314 private: | 339 private: |
| 315 ConstantUndef(Type Ty, uint32_t PoolEntryID) | 340 ConstantUndef(Type Ty) : Constant(kConstUndef, Ty) {} |
| 316 : Constant(kConstUndef, Ty, PoolEntryID) {} | |
| 317 }; | 341 }; |
| 318 | 342 |
| 319 /// RegWeight is a wrapper for a uint32_t weight value, with a special value | 343 /// RegWeight is a wrapper for a uint32_t weight value, with a special value |
| 320 /// that represents infinite weight, and an addWeight() method that ensures that | 344 /// that represents infinite weight, and an addWeight() method that ensures that |
| 321 /// W+infinity=infinity. | 345 /// W+infinity=infinity. |
| 322 class RegWeight { | 346 class RegWeight { |
| 323 public: | 347 public: |
| 324 RegWeight() = default; | 348 RegWeight() = default; |
| 325 explicit RegWeight(uint32_t Weight) : Weight(Weight) {} | 349 explicit RegWeight(uint32_t Weight) : Weight(Weight) {} |
| 326 RegWeight(const RegWeight &) = default; | 350 RegWeight(const RegWeight &) = default; |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 private: | 734 private: |
| 711 const Cfg *Func; | 735 const Cfg *Func; |
| 712 MetadataKind Kind; | 736 MetadataKind Kind; |
| 713 CfgVector<VariableTracking> Metadata; | 737 CfgVector<VariableTracking> Metadata; |
| 714 const static InstDefList NoDefinitions; | 738 const static InstDefList NoDefinitions; |
| 715 }; | 739 }; |
| 716 | 740 |
| 717 } // end of namespace Ice | 741 } // end of namespace Ice |
| 718 | 742 |
| 719 #endif // SUBZERO_SRC_ICEOPERAND_H | 743 #endif // SUBZERO_SRC_ICEOPERAND_H |
| OLD | NEW |