| 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 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 /// monotonically according to live range start, we can optimize overlaps() by | 421 /// monotonically according to live range start, we can optimize overlaps() by |
| 422 /// ignoring all segments that end before the start of Cur's range. The | 422 /// ignoring all segments that end before the start of Cur's range. The |
| 423 /// linear-scan code enables this by calling trim() on the ranges of interest | 423 /// linear-scan code enables this by calling trim() on the ranges of interest |
| 424 /// as Cur advances. Note that linear-scan also has to initialize TrimmedBegin | 424 /// as Cur advances. Note that linear-scan also has to initialize TrimmedBegin |
| 425 /// at the beginning by calling untrim(). | 425 /// at the beginning by calling untrim(). |
| 426 RangeType::const_iterator TrimmedBegin; | 426 RangeType::const_iterator TrimmedBegin; |
| 427 }; | 427 }; |
| 428 | 428 |
| 429 Ostream &operator<<(Ostream &Str, const LiveRange &L); | 429 Ostream &operator<<(Ostream &Str, const LiveRange &L); |
| 430 | 430 |
| 431 /// RegClass indicates the physical register class that a Variable may be |
| 432 /// register-allocated from. By default, a variable's register class is |
| 433 /// directly associated with its type. However, the target lowering may define |
| 434 /// additional target-specific register classes by extending the set of enum |
| 435 /// values. |
| 436 enum RegClass : uint8_t { |
| 437 // Define RC_void, RC_i1, RC_i8, etc. |
| 438 #define X(tag, sizeLog2, align, elts, elty, str) RC_##tag = IceType_##tag, |
| 439 ICETYPE_TABLE |
| 440 #undef X |
| 441 RC_Target, |
| 442 // Leave plenty of space for target-specific values. |
| 443 RC_Max = std::numeric_limits<uint8_t>::max() |
| 444 }; |
| 445 static_assert(RC_Target == static_cast<RegClass>(IceType_NUM), |
| 446 "Expected RC_Target and IceType_NUM to be the same"); |
| 447 |
| 431 /// Variable represents an operand that is register-allocated or | 448 /// Variable represents an operand that is register-allocated or |
| 432 /// stack-allocated. If it is register-allocated, it will ultimately have a | 449 /// stack-allocated. If it is register-allocated, it will ultimately have a |
| 433 /// non-negative RegNum field. | 450 /// non-negative RegNum field. |
| 434 class Variable : public Operand { | 451 class Variable : public Operand { |
| 435 Variable() = delete; | 452 Variable() = delete; |
| 436 Variable(const Variable &) = delete; | 453 Variable(const Variable &) = delete; |
| 437 Variable &operator=(const Variable &) = delete; | 454 Variable &operator=(const Variable &) = delete; |
| 438 | 455 |
| 439 enum RegRequirement : uint8_t { | 456 enum RegRequirement : uint8_t { |
| 440 RR_MayHaveRegister, | 457 RR_MayHaveRegister, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 | 503 |
| 487 RegWeight getWeight(const Cfg *Func) const; | 504 RegWeight getWeight(const Cfg *Func) const; |
| 488 | 505 |
| 489 void setMustHaveReg() { RegRequirement = RR_MustHaveRegister; } | 506 void setMustHaveReg() { RegRequirement = RR_MustHaveRegister; } |
| 490 bool mustHaveReg() const { return RegRequirement == RR_MustHaveRegister; } | 507 bool mustHaveReg() const { return RegRequirement == RR_MustHaveRegister; } |
| 491 void setMustNotHaveReg() { RegRequirement = RR_MustNotHaveRegister; } | 508 void setMustNotHaveReg() { RegRequirement = RR_MustNotHaveRegister; } |
| 492 bool mustNotHaveReg() const { | 509 bool mustNotHaveReg() const { |
| 493 return RegRequirement == RR_MustNotHaveRegister; | 510 return RegRequirement == RR_MustNotHaveRegister; |
| 494 } | 511 } |
| 495 | 512 |
| 513 void setRegClass(uint8_t RC) { RegisterClass = static_cast<RegClass>(RC); } |
| 514 RegClass getRegClass() const { return RegisterClass; } |
| 515 |
| 496 LiveRange &getLiveRange() { return Live; } | 516 LiveRange &getLiveRange() { return Live; } |
| 497 const LiveRange &getLiveRange() const { return Live; } | 517 const LiveRange &getLiveRange() const { return Live; } |
| 498 void setLiveRange(const LiveRange &Range) { Live = Range; } | 518 void setLiveRange(const LiveRange &Range) { Live = Range; } |
| 499 void resetLiveRange() { Live.reset(); } | 519 void resetLiveRange() { Live.reset(); } |
| 500 void addLiveRange(InstNumberT Start, InstNumberT End) { | 520 void addLiveRange(InstNumberT Start, InstNumberT End) { |
| 501 assert(!getIgnoreLiveness()); | 521 assert(!getIgnoreLiveness()); |
| 502 Live.addSegment(Start, End); | 522 Live.addSegment(Start, End); |
| 503 } | 523 } |
| 504 void trimLiveRange(InstNumberT Start) { Live.trim(Start); } | 524 void trimLiveRange(InstNumberT Start) { Live.trim(Start); } |
| 505 void untrimLiveRange() { Live.untrim(); } | 525 void untrimLiveRange() { Live.untrim(); } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 530 /// Return reg num of base register, if different from stack/frame register. | 550 /// Return reg num of base register, if different from stack/frame register. |
| 531 virtual int32_t getBaseRegNum() const { return NoRegister; } | 551 virtual int32_t getBaseRegNum() const { return NoRegister; } |
| 532 | 552 |
| 533 static bool classof(const Operand *Operand) { | 553 static bool classof(const Operand *Operand) { |
| 534 OperandKind Kind = Operand->getKind(); | 554 OperandKind Kind = Operand->getKind(); |
| 535 return Kind >= kVariable && Kind <= kVariable_Max; | 555 return Kind >= kVariable && Kind <= kVariable_Max; |
| 536 } | 556 } |
| 537 | 557 |
| 538 protected: | 558 protected: |
| 539 Variable(OperandKind K, Type Ty, SizeT Index) | 559 Variable(OperandKind K, Type Ty, SizeT Index) |
| 540 : Operand(K, Ty), Number(Index) { | 560 : Operand(K, Ty), Number(Index), |
| 561 RegisterClass(static_cast<RegClass>(Ty)) { |
| 541 Vars = VarsReal; | 562 Vars = VarsReal; |
| 542 Vars[0] = this; | 563 Vars[0] = this; |
| 543 NumVars = 1; | 564 NumVars = 1; |
| 544 } | 565 } |
| 545 /// Number is unique across all variables, and is used as a (bit)vector index | 566 /// Number is unique across all variables, and is used as a (bit)vector index |
| 546 /// for liveness analysis. | 567 /// for liveness analysis. |
| 547 const SizeT Number; | 568 const SizeT Number; |
| 548 Cfg::IdentifierIndexType NameIndex = Cfg::IdentifierIndexInvalid; | 569 Cfg::IdentifierIndexType NameIndex = Cfg::IdentifierIndexInvalid; |
| 549 bool IsArgument = false; | 570 bool IsArgument = false; |
| 550 bool IsImplicitArgument = false; | 571 bool IsImplicitArgument = false; |
| 551 /// IgnoreLiveness means that the variable should be ignored when constructing | 572 /// IgnoreLiveness means that the variable should be ignored when constructing |
| 552 /// and validating live ranges. This is usually reserved for the stack | 573 /// and validating live ranges. This is usually reserved for the stack |
| 553 /// pointer and other physical registers specifically referenced by name. | 574 /// pointer and other physical registers specifically referenced by name. |
| 554 bool IgnoreLiveness = false; | 575 bool IgnoreLiveness = false; |
| 555 RegRequirement RegRequirement = RR_MayHaveRegister; | 576 RegRequirement RegRequirement = RR_MayHaveRegister; |
| 577 RegClass RegisterClass; |
| 556 /// RegNum is the allocated register, or NoRegister if it isn't | 578 /// RegNum is the allocated register, or NoRegister if it isn't |
| 557 /// register-allocated. | 579 /// register-allocated. |
| 558 int32_t RegNum = NoRegister; | 580 int32_t RegNum = NoRegister; |
| 559 /// RegNumTmp is the tentative assignment during register allocation. | 581 /// RegNumTmp is the tentative assignment during register allocation. |
| 560 int32_t RegNumTmp = NoRegister; | 582 int32_t RegNumTmp = NoRegister; |
| 561 /// StackOffset is the canonical location on stack (only if | 583 /// StackOffset is the canonical location on stack (only if |
| 562 /// RegNum==NoRegister || IsArgument). | 584 /// RegNum==NoRegister || IsArgument). |
| 563 int32_t StackOffset = 0; | 585 int32_t StackOffset = 0; |
| 564 LiveRange Live; | 586 LiveRange Live; |
| 565 /// VarsReal (and Operand::Vars) are set up such that Vars[0] == this. | 587 /// VarsReal (and Operand::Vars) are set up such that Vars[0] == this. |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 private: | 757 private: |
| 736 const Cfg *Func; | 758 const Cfg *Func; |
| 737 MetadataKind Kind; | 759 MetadataKind Kind; |
| 738 CfgVector<VariableTracking> Metadata; | 760 CfgVector<VariableTracking> Metadata; |
| 739 const static InstDefList NoDefinitions; | 761 const static InstDefList NoDefinitions; |
| 740 }; | 762 }; |
| 741 | 763 |
| 742 } // end of namespace Ice | 764 } // end of namespace Ice |
| 743 | 765 |
| 744 #endif // SUBZERO_SRC_ICEOPERAND_H | 766 #endif // SUBZERO_SRC_ICEOPERAND_H |
| OLD | NEW |