| 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 // This file declares the Operand class and its target-independent | 10 // This file declares the Operand class and its target-independent | 
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 80   // object's destructor should delete this object.  Generally, | 80   // object's destructor should delete this object.  Generally, | 
| 81   // constants are pooled globally, variables are pooled per-CFG, and | 81   // constants are pooled globally, variables are pooled per-CFG, and | 
| 82   // target-specific operands are not pooled. | 82   // target-specific operands are not pooled. | 
| 83   virtual bool isPooled() const { return false; } | 83   virtual bool isPooled() const { return false; } | 
| 84 | 84 | 
| 85   virtual ~Operand() {} | 85   virtual ~Operand() {} | 
| 86 | 86 | 
| 87 protected: | 87 protected: | 
| 88   Operand(OperandKind Kind, Type Ty) | 88   Operand(OperandKind Kind, Type Ty) | 
| 89       : Ty(Ty), Kind(Kind), NumVars(0), Vars(NULL) {} | 89       : Ty(Ty), Kind(Kind), NumVars(0), Vars(NULL) {} | 
| 90   Operand(Operand &&O) = default; |  | 
| 91 | 90 | 
| 92   const Type Ty; | 91   const Type Ty; | 
| 93   const OperandKind Kind; | 92   const OperandKind Kind; | 
| 94   // Vars and NumVars are initialized by the derived class. | 93   // Vars and NumVars are initialized by the derived class. | 
| 95   SizeT NumVars; | 94   SizeT NumVars; | 
| 96   Variable **Vars; | 95   Variable **Vars; | 
| 97 }; | 96 }; | 
| 98 | 97 | 
| 99 template<class StreamType> | 98 template<class StreamType> | 
| 100 inline StreamType &operator<<(StreamType &Str, const Operand &Op) { | 99 inline StreamType &operator<<(StreamType &Str, const Operand &Op) { | 
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 355   void untrim() { TrimmedBegin = Range.begin(); } | 354   void untrim() { TrimmedBegin = Range.begin(); } | 
| 356   void trim(InstNumberT Lower); | 355   void trim(InstNumberT Lower); | 
| 357 | 356 | 
| 358   RegWeight getWeight() const { return Weight; } | 357   RegWeight getWeight() const { return Weight; } | 
| 359   void setWeight(const RegWeight &NewWeight) { Weight = NewWeight; } | 358   void setWeight(const RegWeight &NewWeight) { Weight = NewWeight; } | 
| 360   void addWeight(uint32_t Delta) { Weight.addWeight(Delta); } | 359   void addWeight(uint32_t Delta) { Weight.addWeight(Delta); } | 
| 361   void dump(Ostream &Str) const; | 360   void dump(Ostream &Str) const; | 
| 362 | 361 | 
| 363 private: | 362 private: | 
| 364   typedef std::pair<InstNumberT, InstNumberT> RangeElementType; | 363   typedef std::pair<InstNumberT, InstNumberT> RangeElementType; | 
| 365   // Assume a common case of 2 or fewer segments per live range. | 364   // RangeType is arena-allocated from the Cfg's allocator. | 
| 366   typedef llvm::SmallVector<RangeElementType, 2> RangeType; | 365   typedef std::vector<RangeElementType, CfgLocalAllocator<RangeElementType>> | 
|  | 366   RangeType; | 
| 367   RangeType Range; | 367   RangeType Range; | 
| 368   RegWeight Weight; | 368   RegWeight Weight; | 
| 369   // TrimmedBegin is an optimization for the overlaps() computation. | 369   // TrimmedBegin is an optimization for the overlaps() computation. | 
| 370   // Since the linear-scan algorithm always calls it as overlaps(Cur) | 370   // Since the linear-scan algorithm always calls it as overlaps(Cur) | 
| 371   // and Cur advances monotonically according to live range start, we | 371   // and Cur advances monotonically according to live range start, we | 
| 372   // can optimize overlaps() by ignoring all segments that end before | 372   // can optimize overlaps() by ignoring all segments that end before | 
| 373   // the start of Cur's range.  The linear-scan code enables this by | 373   // the start of Cur's range.  The linear-scan code enables this by | 
| 374   // calling trim() on the ranges of interest as Cur advances.  Note | 374   // calling trim() on the ranges of interest as Cur advances.  Note | 
| 375   // that linear-scan also has to initialize TrimmedBegin at the | 375   // that linear-scan also has to initialize TrimmedBegin at the | 
| 376   // beginning by calling untrim(). | 376   // beginning by calling untrim(). | 
| 377   RangeType::const_iterator TrimmedBegin; | 377   RangeType::const_iterator TrimmedBegin; | 
| 378 }; | 378 }; | 
| 379 | 379 | 
| 380 Ostream &operator<<(Ostream &Str, const LiveRange &L); | 380 Ostream &operator<<(Ostream &Str, const LiveRange &L); | 
| 381 | 381 | 
| 382 // Variable represents an operand that is register-allocated or | 382 // Variable represents an operand that is register-allocated or | 
| 383 // stack-allocated.  If it is register-allocated, it will ultimately | 383 // stack-allocated.  If it is register-allocated, it will ultimately | 
| 384 // have a non-negative RegNum field. | 384 // have a non-negative RegNum field. | 
| 385 class Variable : public Operand { | 385 class Variable : public Operand { | 
| 386   Variable(const Variable &) = delete; | 386   Variable(const Variable &) = delete; | 
| 387   Variable &operator=(const Variable &) = delete; | 387   Variable &operator=(const Variable &) = delete; | 
| 388   Variable(Variable &&V) = default; |  | 
| 389 | 388 | 
| 390 public: | 389 public: | 
| 391   static Variable *create(Cfg *Func, Type Ty, SizeT Index) { | 390   static Variable *create(Cfg *Func, Type Ty, SizeT Index) { | 
| 392     return new (Func->allocate<Variable>()) Variable(kVariable, Ty, Index); | 391     return new (Func->allocate<Variable>()) Variable(kVariable, Ty, Index); | 
| 393   } | 392   } | 
| 394 | 393 | 
| 395   SizeT getIndex() const { return Number; } | 394   SizeT getIndex() const { return Number; } | 
| 396   IceString getName(const Cfg *Func) const; | 395   IceString getName(const Cfg *Func) const; | 
| 397   void setName(Cfg *Func, const IceString &NewName) { | 396   void setName(Cfg *Func, const IceString &NewName) { | 
| 398     // Make sure that the name can only be set once. | 397     // Make sure that the name can only be set once. | 
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 459   Variable *getHi() const { return HiVar; } | 458   Variable *getHi() const { return HiVar; } | 
| 460   void setLoHi(Variable *Lo, Variable *Hi) { | 459   void setLoHi(Variable *Lo, Variable *Hi) { | 
| 461     assert(LoVar == NULL); | 460     assert(LoVar == NULL); | 
| 462     assert(HiVar == NULL); | 461     assert(HiVar == NULL); | 
| 463     LoVar = Lo; | 462     LoVar = Lo; | 
| 464     HiVar = Hi; | 463     HiVar = Hi; | 
| 465   } | 464   } | 
| 466   // Creates a temporary copy of the variable with a different type. | 465   // Creates a temporary copy of the variable with a different type. | 
| 467   // Used primarily for syntactic correctness of textual assembly | 466   // Used primarily for syntactic correctness of textual assembly | 
| 468   // emission.  Note that only basic information is copied, in | 467   // emission.  Note that only basic information is copied, in | 
| 469   // particular not DefInst, IsArgument, Weight, LoVar, HiVar, | 468   // particular not IsArgument, IsImplicitArgument, IgnoreLiveness, | 
| 470   // VarsReal. | 469   // RegNumTmp, Weight, Live, LoVar, HiVar, VarsReal. | 
| 471   Variable asType(Type Ty); | 470   Variable *asType(Type Ty); | 
| 472 | 471 | 
| 473   void emit(const Cfg *Func) const override; | 472   void emit(const Cfg *Func) const override; | 
| 474   using Operand::dump; | 473   using Operand::dump; | 
| 475   void dump(const Cfg *Func, Ostream &Str) const override; | 474   void dump(const Cfg *Func, Ostream &Str) const override; | 
| 476 | 475 | 
| 477   static bool classof(const Operand *Operand) { | 476   static bool classof(const Operand *Operand) { | 
| 478     OperandKind Kind = Operand->getKind(); | 477     OperandKind Kind = Operand->getKind(); | 
| 479     return Kind >= kVariable && Kind <= kVariable_Num; | 478     return Kind >= kVariable && Kind <= kVariable_Num; | 
| 480   } | 479   } | 
| 481 | 480 | 
| 482   // The destructor is public because of the asType() method. |  | 
| 483   ~Variable() override {} |  | 
| 484 |  | 
| 485 protected: | 481 protected: | 
| 486   Variable(OperandKind K, Type Ty, SizeT Index) | 482   Variable(OperandKind K, Type Ty, SizeT Index) | 
| 487       : Operand(K, Ty), Number(Index), NameIndex(Cfg::IdentifierIndexInvalid), | 483       : Operand(K, Ty), Number(Index), NameIndex(Cfg::IdentifierIndexInvalid), | 
| 488         IsArgument(false), IsImplicitArgument(false), IgnoreLiveness(false), | 484         IsArgument(false), IsImplicitArgument(false), IgnoreLiveness(false), | 
| 489         StackOffset(0), RegNum(NoRegister), RegNumTmp(NoRegister), Weight(1), | 485         StackOffset(0), RegNum(NoRegister), RegNumTmp(NoRegister), Weight(1), | 
| 490         LoVar(NULL), HiVar(NULL) { | 486         LoVar(NULL), HiVar(NULL) { | 
| 491     Vars = VarsReal; | 487     Vars = VarsReal; | 
| 492     Vars[0] = this; | 488     Vars[0] = this; | 
| 493     NumVars = 1; | 489     NumVars = 1; | 
| 494   } | 490   } | 
|  | 491   ~Variable() override {} | 
| 495   // Number is unique across all variables, and is used as a | 492   // Number is unique across all variables, and is used as a | 
| 496   // (bit)vector index for liveness analysis. | 493   // (bit)vector index for liveness analysis. | 
| 497   const SizeT Number; | 494   const SizeT Number; | 
| 498   Cfg::IdentifierIndexType NameIndex; | 495   Cfg::IdentifierIndexType NameIndex; | 
| 499   bool IsArgument; | 496   bool IsArgument; | 
| 500   bool IsImplicitArgument; | 497   bool IsImplicitArgument; | 
| 501   // IgnoreLiveness means that the variable should be ignored when | 498   // IgnoreLiveness means that the variable should be ignored when | 
| 502   // constructing and validating live ranges.  This is usually | 499   // constructing and validating live ranges.  This is usually | 
| 503   // reserved for the stack pointer. | 500   // reserved for the stack pointer. | 
| 504   bool IgnoreLiveness; | 501   bool IgnoreLiveness; | 
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 631 private: | 628 private: | 
| 632   const Cfg *Func; | 629   const Cfg *Func; | 
| 633   MetadataKind Kind; | 630   MetadataKind Kind; | 
| 634   std::vector<VariableTracking> Metadata; | 631   std::vector<VariableTracking> Metadata; | 
| 635   const static InstDefList NoDefinitions; | 632   const static InstDefList NoDefinitions; | 
| 636 }; | 633 }; | 
| 637 | 634 | 
| 638 } // end of namespace Ice | 635 } // end of namespace Ice | 
| 639 | 636 | 
| 640 #endif // SUBZERO_SRC_ICEOPERAND_H | 637 #endif // SUBZERO_SRC_ICEOPERAND_H | 
| OLD | NEW | 
|---|