| 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 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 } | 113 } |
| 114 | 114 |
| 115 /// Constant is the abstract base class for constants. All constants are | 115 /// Constant is the abstract base class for constants. All constants are |
| 116 /// allocated from a global arena and are pooled. | 116 /// allocated from a global arena and are pooled. |
| 117 class Constant : public Operand { | 117 class Constant : public Operand { |
| 118 Constant() = delete; | 118 Constant() = delete; |
| 119 Constant(const Constant &) = delete; | 119 Constant(const Constant &) = delete; |
| 120 Constant &operator=(const Constant &) = delete; | 120 Constant &operator=(const Constant &) = delete; |
| 121 | 121 |
| 122 public: | 122 public: |
| 123 virtual void emitPoolLabel(Ostream &Str, const GlobalContext *Ctx) const { | 123 virtual void emitPoolLabel(Ostream &Str) const { |
| 124 (void)Str; | 124 (void)Str; |
| 125 (void)Ctx; | |
| 126 llvm::report_fatal_error("emitPoolLabel not defined for type"); | 125 llvm::report_fatal_error("emitPoolLabel not defined for type"); |
| 127 }; | 126 }; |
| 128 void emit(const Cfg *Func) const override { emit(Func->getTarget()); } | 127 void emit(const Cfg *Func) const override { emit(Func->getTarget()); } |
| 129 virtual void emit(TargetLowering *Target) const = 0; | 128 virtual void emit(TargetLowering *Target) const = 0; |
| 130 | 129 |
| 131 static bool classof(const Operand *Operand) { | 130 static bool classof(const Operand *Operand) { |
| 132 OperandKind Kind = Operand->getKind(); | 131 OperandKind Kind = Operand->getKind(); |
| 133 return Kind >= kConst_Base && Kind <= kConst_Max; | 132 return Kind >= kConst_Base && Kind <= kConst_Max; |
| 134 } | 133 } |
| 135 | 134 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 165 | 164 |
| 166 public: | 165 public: |
| 167 using PrimType = T; | 166 using PrimType = T; |
| 168 | 167 |
| 169 static ConstantPrimitive *create(GlobalContext *Ctx, Type Ty, | 168 static ConstantPrimitive *create(GlobalContext *Ctx, Type Ty, |
| 170 PrimType Value) { | 169 PrimType Value) { |
| 171 return new (Ctx->allocate<ConstantPrimitive>()) | 170 return new (Ctx->allocate<ConstantPrimitive>()) |
| 172 ConstantPrimitive(Ty, Value); | 171 ConstantPrimitive(Ty, Value); |
| 173 } | 172 } |
| 174 PrimType getValue() const { return Value; } | 173 PrimType getValue() const { return Value; } |
| 175 void emitPoolLabel(Ostream &Str, const GlobalContext *Ctx) const final { | 174 void emitPoolLabel(Ostream &Str) const final { |
| 176 Str << ".L$" << getType() << "$"; | 175 Str << ".L$" << getType() << "$"; |
| 177 // Print hex characters byte by byte, starting from the most significant | 176 // Print hex characters byte by byte, starting from the most significant |
| 178 // byte. NOTE: This ordering assumes Subzero runs on a little-endian | 177 // byte. NOTE: This ordering assumes Subzero runs on a little-endian |
| 179 // platform. That means the possibility of different label names depending | 178 // platform. That means the possibility of different label names depending |
| 180 // on the endian-ness of the platform where Subzero runs. | 179 // on the endian-ness of the platform where Subzero runs. |
| 181 for (unsigned i = 0; i < sizeof(Value); ++i) { | 180 for (unsigned i = 0; i < sizeof(Value); ++i) { |
| 182 constexpr unsigned HexWidthChars = 2; | 181 constexpr unsigned HexWidthChars = 2; |
| 183 unsigned Offset = sizeof(Value) - 1 - i; | 182 unsigned Offset = sizeof(Value) - 1 - i; |
| 184 Str << llvm::format_hex_no_prefix( | 183 Str << llvm::format_hex_no_prefix( |
| 185 *(Offset + (const unsigned char *)&Value), HexWidthChars); | 184 *(Offset + (const unsigned char *)&Value), HexWidthChars); |
| 186 } | 185 } |
| 187 // For a floating-point value in DecorateAsm mode, also append the value in | 186 // For a floating-point value in DecorateAsm mode, also append the value in |
| 188 // human-readable sprintf form, changing '+' to 'p' and '-' to 'm' to | 187 // human-readable sprintf form, changing '+' to 'p' and '-' to 'm' to |
| 189 // maintain valid asm labels. | 188 // maintain valid asm labels. |
| 190 if (std::is_floating_point<PrimType>::value && !BuildDefs::minimal() && | 189 if (std::is_floating_point<PrimType>::value && !BuildDefs::minimal() && |
| 191 Ctx->getFlags().getDecorateAsm()) { | 190 GlobalContext::getFlags().getDecorateAsm()) { |
| 192 char Buf[30]; | 191 char Buf[30]; |
| 193 snprintf(Buf, llvm::array_lengthof(Buf), "$%g", (double)Value); | 192 snprintf(Buf, llvm::array_lengthof(Buf), "$%g", (double)Value); |
| 194 for (unsigned i = 0; i < llvm::array_lengthof(Buf) && Buf[i]; ++i) { | 193 for (unsigned i = 0; i < llvm::array_lengthof(Buf) && Buf[i]; ++i) { |
| 195 if (Buf[i] == '-') | 194 if (Buf[i] == '-') |
| 196 Buf[i] = 'm'; | 195 Buf[i] = 'm'; |
| 197 else if (Buf[i] == '+') | 196 else if (Buf[i] == '+') |
| 198 Buf[i] = 'p'; | 197 Buf[i] = 'p'; |
| 199 } | 198 } |
| 200 Str << Buf; | 199 Str << Buf; |
| 201 } | 200 } |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 | 294 |
| 296 /// RelocatableTuple bundles the parameters that are used to construct an | 295 /// RelocatableTuple bundles the parameters that are used to construct an |
| 297 /// ConstantRelocatable. It is done this way so that ConstantRelocatable can fit | 296 /// ConstantRelocatable. It is done this way so that ConstantRelocatable can fit |
| 298 /// into the global constant pool template mechanism. | 297 /// into the global constant pool template mechanism. |
| 299 class RelocatableTuple { | 298 class RelocatableTuple { |
| 300 RelocatableTuple() = delete; | 299 RelocatableTuple() = delete; |
| 301 RelocatableTuple &operator=(const RelocatableTuple &) = delete; | 300 RelocatableTuple &operator=(const RelocatableTuple &) = delete; |
| 302 | 301 |
| 303 public: | 302 public: |
| 304 RelocatableTuple(const RelocOffsetT Offset, | 303 RelocatableTuple(const RelocOffsetT Offset, |
| 305 const RelocOffsetArray &OffsetExpr, const IceString &Name, | 304 const RelocOffsetArray &OffsetExpr, const IceString &Name) |
| 306 bool SuppressMangling) | 305 : Offset(Offset), OffsetExpr(OffsetExpr), Name(Name) {} |
| 307 : Offset(Offset), OffsetExpr(OffsetExpr), Name(Name), | |
| 308 SuppressMangling(SuppressMangling) {} | |
| 309 | 306 |
| 310 RelocatableTuple(const RelocOffsetT Offset, | 307 RelocatableTuple(const RelocOffsetT Offset, |
| 311 const RelocOffsetArray &OffsetExpr, const IceString &Name, | 308 const RelocOffsetArray &OffsetExpr, const IceString &Name, |
| 312 const IceString &EmitString, bool SuppressMangling) | 309 const IceString &EmitString) |
| 313 : Offset(Offset), OffsetExpr(OffsetExpr), Name(Name), | 310 : Offset(Offset), OffsetExpr(OffsetExpr), Name(Name), |
| 314 EmitString(EmitString), SuppressMangling(SuppressMangling) {} | 311 EmitString(EmitString) {} |
| 315 | 312 |
| 316 RelocatableTuple(const RelocatableTuple &) = default; | 313 RelocatableTuple(const RelocatableTuple &) = default; |
| 317 | 314 |
| 318 const RelocOffsetT Offset; | 315 const RelocOffsetT Offset; |
| 319 const RelocOffsetArray OffsetExpr; | 316 const RelocOffsetArray OffsetExpr; |
| 320 const IceString Name; | 317 const IceString Name; |
| 321 const IceString EmitString; | 318 const IceString EmitString; |
| 322 const bool SuppressMangling; | |
| 323 }; | 319 }; |
| 324 | 320 |
| 325 bool operator==(const RelocatableTuple &A, const RelocatableTuple &B); | 321 bool operator==(const RelocatableTuple &A, const RelocatableTuple &B); |
| 326 | 322 |
| 327 /// ConstantRelocatable represents a symbolic constant combined with a fixed | 323 /// ConstantRelocatable represents a symbolic constant combined with a fixed |
| 328 /// offset. | 324 /// offset. |
| 329 class ConstantRelocatable : public Constant { | 325 class ConstantRelocatable : public Constant { |
| 330 ConstantRelocatable() = delete; | 326 ConstantRelocatable() = delete; |
| 331 ConstantRelocatable(const ConstantRelocatable &) = delete; | 327 ConstantRelocatable(const ConstantRelocatable &) = delete; |
| 332 ConstantRelocatable &operator=(const ConstantRelocatable &) = delete; | 328 ConstantRelocatable &operator=(const ConstantRelocatable &) = delete; |
| 333 | 329 |
| 334 public: | 330 public: |
| 335 static ConstantRelocatable *create(GlobalContext *Ctx, Type Ty, | 331 static ConstantRelocatable *create(GlobalContext *Ctx, Type Ty, |
| 336 const RelocatableTuple &Tuple) { | 332 const RelocatableTuple &Tuple) { |
| 337 return new (Ctx->allocate<ConstantRelocatable>()) | 333 return new (Ctx->allocate<ConstantRelocatable>()) ConstantRelocatable( |
| 338 ConstantRelocatable(Ty, Tuple.Offset, Tuple.OffsetExpr, Tuple.Name, | 334 Ty, Tuple.Offset, Tuple.OffsetExpr, Tuple.Name, Tuple.EmitString); |
| 339 Tuple.EmitString, Tuple.SuppressMangling); | |
| 340 } | 335 } |
| 341 | 336 |
| 342 RelocOffsetT getOffset() const { | 337 RelocOffsetT getOffset() const { |
| 343 RelocOffsetT Ret = Offset; | 338 RelocOffsetT Ret = Offset; |
| 344 for (const auto *const OffsetReloc : OffsetExpr) { | 339 for (const auto *const OffsetReloc : OffsetExpr) { |
| 345 Ret += OffsetReloc->getOffset(); | 340 Ret += OffsetReloc->getOffset(); |
| 346 } | 341 } |
| 347 return Ret; | 342 return Ret; |
| 348 } | 343 } |
| 349 | 344 |
| 350 const IceString &getEmitString() const { return EmitString; } | 345 const IceString &getEmitString() const { return EmitString; } |
| 351 | 346 |
| 352 const IceString &getName() const { return Name; } | 347 const IceString &getName() const { return Name; } |
| 353 bool getSuppressMangling() const { return SuppressMangling; } | |
| 354 using Constant::emit; | 348 using Constant::emit; |
| 355 void emit(TargetLowering *Target) const final; | 349 void emit(TargetLowering *Target) const final; |
| 356 void emitWithoutPrefix(const TargetLowering *Target, | 350 void emitWithoutPrefix(const TargetLowering *Target, |
| 357 const char *Suffix = "") const; | 351 const char *Suffix = "") const; |
| 358 using Constant::dump; | 352 using Constant::dump; |
| 359 void dump(const Cfg *Func, Ostream &Str) const override; | 353 void dump(const Cfg *Func, Ostream &Str) const override; |
| 360 | 354 |
| 361 static bool classof(const Operand *Operand) { | 355 static bool classof(const Operand *Operand) { |
| 362 OperandKind Kind = Operand->getKind(); | 356 OperandKind Kind = Operand->getKind(); |
| 363 return Kind == kConstRelocatable; | 357 return Kind == kConstRelocatable; |
| 364 } | 358 } |
| 365 | 359 |
| 366 private: | 360 private: |
| 367 ConstantRelocatable(Type Ty, const RelocOffsetT Offset, | 361 ConstantRelocatable(Type Ty, const RelocOffsetT Offset, |
| 368 const RelocOffsetArray &OffsetExpr, const IceString &Name, | 362 const RelocOffsetArray &OffsetExpr, const IceString &Name, |
| 369 const IceString &EmitString, bool SuppressMangling) | 363 const IceString &EmitString) |
| 370 : Constant(kConstRelocatable, Ty), Offset(Offset), OffsetExpr(OffsetExpr), | 364 : Constant(kConstRelocatable, Ty), Offset(Offset), OffsetExpr(OffsetExpr), |
| 371 Name(Name), EmitString(EmitString), SuppressMangling(SuppressMangling) { | 365 Name(Name), EmitString(EmitString) {} |
| 372 } | |
| 373 | 366 |
| 374 const RelocOffsetT Offset; /// fixed, known offset to add | 367 const RelocOffsetT Offset; /// fixed, known offset to add |
| 375 const RelocOffsetArray OffsetExpr; /// fixed, unknown offset to add | 368 const RelocOffsetArray OffsetExpr; /// fixed, unknown offset to add |
| 376 const IceString Name; /// optional for debug/dump | 369 const IceString Name; /// optional for debug/dump |
| 377 const IceString EmitString; /// optional for textual emission | 370 const IceString EmitString; /// optional for textual emission |
| 378 const bool SuppressMangling; | |
| 379 }; | 371 }; |
| 380 | 372 |
| 381 /// ConstantUndef represents an unspecified bit pattern. Although it is legal to | 373 /// ConstantUndef represents an unspecified bit pattern. Although it is legal to |
| 382 /// lower ConstantUndef to any value, backends should try to make code | 374 /// lower ConstantUndef to any value, backends should try to make code |
| 383 /// generation deterministic by lowering ConstantUndefs to 0. | 375 /// generation deterministic by lowering ConstantUndefs to 0. |
| 384 class ConstantUndef : public Constant { | 376 class ConstantUndef : public Constant { |
| 385 ConstantUndef() = delete; | 377 ConstantUndef() = delete; |
| 386 ConstantUndef(const ConstantUndef &) = delete; | 378 ConstantUndef(const ConstantUndef &) = delete; |
| 387 ConstantUndef &operator=(const ConstantUndef &) = delete; | 379 ConstantUndef &operator=(const ConstantUndef &) = delete; |
| 388 | 380 |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 void setIsImplicitArg(bool Val = true) { IsImplicitArgument = Val; } | 639 void setIsImplicitArg(bool Val = true) { IsImplicitArgument = Val; } |
| 648 | 640 |
| 649 void setIgnoreLiveness() { IgnoreLiveness = true; } | 641 void setIgnoreLiveness() { IgnoreLiveness = true; } |
| 650 bool getIgnoreLiveness() const { return IgnoreLiveness; } | 642 bool getIgnoreLiveness() const { return IgnoreLiveness; } |
| 651 | 643 |
| 652 int32_t getStackOffset() const { return StackOffset; } | 644 int32_t getStackOffset() const { return StackOffset; } |
| 653 void setStackOffset(int32_t Offset) { StackOffset = Offset; } | 645 void setStackOffset(int32_t Offset) { StackOffset = Offset; } |
| 654 /// Returns the variable's stack offset in symbolic form, to improve | 646 /// Returns the variable's stack offset in symbolic form, to improve |
| 655 /// readability in DecorateAsm mode. | 647 /// readability in DecorateAsm mode. |
| 656 IceString getSymbolicStackOffset(const Cfg *Func) const { | 648 IceString getSymbolicStackOffset(const Cfg *Func) const { |
| 649 if (!BuildDefs::dump()) |
| 650 return ""; |
| 657 return "lv$" + getName(Func); | 651 return "lv$" + getName(Func); |
| 658 } | 652 } |
| 659 | 653 |
| 660 bool hasReg() const { return getRegNum().hasValue(); } | 654 bool hasReg() const { return getRegNum().hasValue(); } |
| 661 RegNumT getRegNum() const { return RegNum; } | 655 RegNumT getRegNum() const { return RegNum; } |
| 662 void setRegNum(RegNumT NewRegNum) { | 656 void setRegNum(RegNumT NewRegNum) { |
| 663 // Regnum shouldn't be set more than once. | 657 // Regnum shouldn't be set more than once. |
| 664 assert(!hasReg() || RegNum == NewRegNum); | 658 assert(!hasReg() || RegNum == NewRegNum); |
| 665 RegNum = NewRegNum; | 659 RegNum = NewRegNum; |
| 666 } | 660 } |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 933 private: | 927 private: |
| 934 const Cfg *Func; | 928 const Cfg *Func; |
| 935 MetadataKind Kind; | 929 MetadataKind Kind; |
| 936 CfgVector<VariableTracking> Metadata; | 930 CfgVector<VariableTracking> Metadata; |
| 937 const static InstDefList NoDefinitions; | 931 const static InstDefList NoDefinitions; |
| 938 }; | 932 }; |
| 939 | 933 |
| 940 } // end of namespace Ice | 934 } // end of namespace Ice |
| 941 | 935 |
| 942 #endif // SUBZERO_SRC_ICEOPERAND_H | 936 #endif // SUBZERO_SRC_ICEOPERAND_H |
| OLD | NEW |