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 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 bool operator<(const RegWeight &A, const RegWeight &B); | 596 bool operator<(const RegWeight &A, const RegWeight &B); |
597 bool operator<=(const RegWeight &A, const RegWeight &B); | 597 bool operator<=(const RegWeight &A, const RegWeight &B); |
598 bool operator==(const RegWeight &A, const RegWeight &B); | 598 bool operator==(const RegWeight &A, const RegWeight &B); |
599 | 599 |
600 /// LiveRange is a set of instruction number intervals representing a variable's | 600 /// LiveRange is a set of instruction number intervals representing a variable's |
601 /// live range. Generally there is one interval per basic block where the | 601 /// live range. Generally there is one interval per basic block where the |
602 /// variable is live, but adjacent intervals get coalesced into a single | 602 /// variable is live, but adjacent intervals get coalesced into a single |
603 /// interval. | 603 /// interval. |
604 class LiveRange { | 604 class LiveRange { |
605 public: | 605 public: |
| 606 using RangeElementType = std::pair<InstNumberT, InstNumberT>; |
| 607 /// RangeType is arena-allocated from the Cfg's allocator. |
| 608 using RangeType = CfgVector<RangeElementType>; |
606 LiveRange() = default; | 609 LiveRange() = default; |
607 /// Special constructor for building a kill set. The advantage is that we can | 610 /// Special constructor for building a kill set. The advantage is that we can |
608 /// reserve the right amount of space in advance. | 611 /// reserve the right amount of space in advance. |
609 explicit LiveRange(const CfgVector<InstNumberT> &Kills) { | 612 explicit LiveRange(const CfgVector<InstNumberT> &Kills) { |
610 Range.reserve(Kills.size()); | 613 Range.reserve(Kills.size()); |
611 for (InstNumberT I : Kills) | 614 for (InstNumberT I : Kills) |
612 addSegment(I, I); | 615 addSegment(I, I); |
613 } | 616 } |
614 LiveRange(const LiveRange &) = default; | 617 LiveRange(const LiveRange &) = default; |
615 LiveRange &operator=(const LiveRange &) = default; | 618 LiveRange &operator=(const LiveRange &) = default; |
616 | 619 |
617 void reset() { | 620 void reset() { |
618 Range.clear(); | 621 Range.clear(); |
619 untrim(); | 622 untrim(); |
620 } | 623 } |
621 void addSegment(InstNumberT Start, InstNumberT End); | 624 void addSegment(InstNumberT Start, InstNumberT End, CfgNode *Node = nullptr); |
| 625 void addSegment(RangeElementType Segment, CfgNode *Node = nullptr) { |
| 626 addSegment(Segment.first, Segment.second, Node); |
| 627 } |
622 | 628 |
623 bool endsBefore(const LiveRange &Other) const; | 629 bool endsBefore(const LiveRange &Other) const; |
624 bool overlaps(const LiveRange &Other, bool UseTrimmed = false) const; | 630 bool overlaps(const LiveRange &Other, bool UseTrimmed = false) const; |
625 bool overlapsInst(InstNumberT OtherBegin, bool UseTrimmed = false) const; | 631 bool overlapsInst(InstNumberT OtherBegin, bool UseTrimmed = false) const; |
626 bool containsValue(InstNumberT Value, bool IsDest) const; | 632 bool containsValue(InstNumberT Value, bool IsDest) const; |
627 bool isEmpty() const { return Range.empty(); } | 633 bool isEmpty() const { return Range.empty(); } |
628 InstNumberT getStart() const { | 634 InstNumberT getStart() const { |
629 return Range.empty() ? -1 : Range.begin()->first; | 635 return Range.empty() ? -1 : Range.begin()->first; |
630 } | 636 } |
631 InstNumberT getEnd() const { | 637 InstNumberT getEnd() const { |
632 return Range.empty() ? -1 : Range.rbegin()->second; | 638 return Range.empty() ? -1 : Range.rbegin()->second; |
633 } | 639 } |
634 | 640 |
635 void untrim() { TrimmedBegin = Range.begin(); } | 641 void untrim() { TrimmedBegin = Range.begin(); } |
636 void trim(InstNumberT Lower); | 642 void trim(InstNumberT Lower); |
637 | 643 |
638 void dump(Ostream &Str) const; | 644 void dump(Ostream &Str) const; |
639 | 645 |
| 646 SizeT getNumSegments() const { return Range.size(); } |
| 647 |
| 648 const RangeType &getSegments() const { return Range; } |
| 649 CfgNode *getNodeForSegment(InstNumberT Begin) { |
| 650 auto Iter = NodeMap.find(Begin); |
| 651 assert(Iter != NodeMap.end()); |
| 652 return Iter->second; |
| 653 } |
| 654 |
640 private: | 655 private: |
641 using RangeElementType = std::pair<InstNumberT, InstNumberT>; | |
642 /// RangeType is arena-allocated from the Cfg's allocator. | |
643 using RangeType = CfgVector<RangeElementType>; | |
644 RangeType Range; | 656 RangeType Range; |
| 657 CfgUnorderedMap<InstNumberT, CfgNode *> NodeMap; |
645 /// TrimmedBegin is an optimization for the overlaps() computation. Since the | 658 /// TrimmedBegin is an optimization for the overlaps() computation. Since the |
646 /// linear-scan algorithm always calls it as overlaps(Cur) and Cur advances | 659 /// linear-scan algorithm always calls it as overlaps(Cur) and Cur advances |
647 /// monotonically according to live range start, we can optimize overlaps() by | 660 /// monotonically according to live range start, we can optimize overlaps() by |
648 /// ignoring all segments that end before the start of Cur's range. The | 661 /// ignoring all segments that end before the start of Cur's range. The |
649 /// linear-scan code enables this by calling trim() on the ranges of interest | 662 /// linear-scan code enables this by calling trim() on the ranges of interest |
650 /// as Cur advances. Note that linear-scan also has to initialize TrimmedBegin | 663 /// as Cur advances. Note that linear-scan also has to initialize TrimmedBegin |
651 /// at the beginning by calling untrim(). | 664 /// at the beginning by calling untrim(). |
652 RangeType::const_iterator TrimmedBegin; | 665 RangeType::const_iterator TrimmedBegin; |
653 }; | 666 }; |
654 | 667 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
737 } | 750 } |
738 bool isRematerializable() const { return IsRematerializable; } | 751 bool isRematerializable() const { return IsRematerializable; } |
739 | 752 |
740 void setRegClass(uint8_t RC) { RegisterClass = static_cast<RegClass>(RC); } | 753 void setRegClass(uint8_t RC) { RegisterClass = static_cast<RegClass>(RC); } |
741 RegClass getRegClass() const { return RegisterClass; } | 754 RegClass getRegClass() const { return RegisterClass; } |
742 | 755 |
743 LiveRange &getLiveRange() { return Live; } | 756 LiveRange &getLiveRange() { return Live; } |
744 const LiveRange &getLiveRange() const { return Live; } | 757 const LiveRange &getLiveRange() const { return Live; } |
745 void setLiveRange(const LiveRange &Range) { Live = Range; } | 758 void setLiveRange(const LiveRange &Range) { Live = Range; } |
746 void resetLiveRange() { Live.reset(); } | 759 void resetLiveRange() { Live.reset(); } |
747 void addLiveRange(InstNumberT Start, InstNumberT End) { | 760 void addLiveRange(InstNumberT Start, InstNumberT End, |
| 761 CfgNode *Node = nullptr) { |
748 assert(!getIgnoreLiveness()); | 762 assert(!getIgnoreLiveness()); |
749 Live.addSegment(Start, End); | 763 Live.addSegment(Start, End, Node); |
750 } | 764 } |
751 void trimLiveRange(InstNumberT Start) { Live.trim(Start); } | 765 void trimLiveRange(InstNumberT Start) { Live.trim(Start); } |
752 void untrimLiveRange() { Live.untrim(); } | 766 void untrimLiveRange() { Live.untrim(); } |
753 bool rangeEndsBefore(const Variable *Other) const { | 767 bool rangeEndsBefore(const Variable *Other) const { |
754 return Live.endsBefore(Other->Live); | 768 return Live.endsBefore(Other->Live); |
755 } | 769 } |
756 bool rangeOverlaps(const Variable *Other) const { | 770 bool rangeOverlaps(const Variable *Other) const { |
757 constexpr bool UseTrimmed = true; | 771 constexpr bool UseTrimmed = true; |
758 return Live.overlaps(Other->Live, UseTrimmed); | 772 return Live.overlaps(Other->Live, UseTrimmed); |
759 } | 773 } |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1044 return Operand->getKind() == kVariableBoolean; | 1058 return Operand->getKind() == kVariableBoolean; |
1045 } | 1059 } |
1046 | 1060 |
1047 private: | 1061 private: |
1048 Variable *BoolSource = nullptr; | 1062 Variable *BoolSource = nullptr; |
1049 }; | 1063 }; |
1050 | 1064 |
1051 } // end of namespace Ice | 1065 } // end of namespace Ice |
1052 | 1066 |
1053 #endif // SUBZERO_SRC_ICEOPERAND_H | 1067 #endif // SUBZERO_SRC_ICEOPERAND_H |
OLD | NEW |