Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: src/IceOperand.h

Issue 2172313002: Subzero : Live Range Splitting after initial Register Allocation (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Cleanup Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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) {
Jim Stichnoth 2016/07/29 17:04:07 How about: void addSegment(RangeElementType Segme
manasijm 2016/08/01 22:20:04 Done.
626 addSegment(Segment.first, Segment.second);
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() { return Range.size(); }
Jim Stichnoth 2016/07/29 17:04:07 SizeT getNumSegments() const ...
manasijm 2016/08/01 22:20:03 Done.
647
648 const RangeType &getSegments() { return Range; }
Jim Stichnoth 2016/07/29 17:04:07 can this be const?
manasijm 2016/08/01 22:20:03 Done.
649 CfgNode *getNodeForSegment(InstNumberT Begin) { return NodeMap[Begin]; }
Jim Stichnoth 2016/07/29 17:04:07 const?
manasijm 2016/08/01 22:20:04 Probably not.
650
640 private: 651 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; 652 RangeType Range;
653 CfgUnorderedMap<InstNumberT, CfgNode *> NodeMap;
645 /// TrimmedBegin is an optimization for the overlaps() computation. Since the 654 /// TrimmedBegin is an optimization for the overlaps() computation. Since the
646 /// linear-scan algorithm always calls it as overlaps(Cur) and Cur advances 655 /// linear-scan algorithm always calls it as overlaps(Cur) and Cur advances
647 /// monotonically according to live range start, we can optimize overlaps() by 656 /// 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 657 /// 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 658 /// 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 659 /// as Cur advances. Note that linear-scan also has to initialize TrimmedBegin
651 /// at the beginning by calling untrim(). 660 /// at the beginning by calling untrim().
652 RangeType::const_iterator TrimmedBegin; 661 RangeType::const_iterator TrimmedBegin;
653 }; 662 };
654 663
(...skipping 13 matching lines...) Expand all
668 RR_MustNotHaveRegister, 677 RR_MustNotHaveRegister,
669 }; 678 };
670 679
671 public: 680 public:
672 static Variable *create(Cfg *Func, Type Ty, SizeT Index) { 681 static Variable *create(Cfg *Func, Type Ty, SizeT Index) {
673 return new (Func->allocate<Variable>()) 682 return new (Func->allocate<Variable>())
674 Variable(Func, kVariable, Ty, Index); 683 Variable(Func, kVariable, Ty, Index);
675 } 684 }
676 685
677 SizeT getIndex() const { return Number; } 686 SizeT getIndex() const { return Number; }
687 void setIndex(SizeT NewIndex) { Number = NewIndex; }
678 std::string getName() const { 688 std::string getName() const {
679 if (Name.hasStdString()) 689 if (Name.hasStdString())
680 return Name.toString(); 690 return Name.toString();
681 return "__" + std::to_string(getIndex()); 691 return "__" + std::to_string(getIndex());
682 } 692 }
683 virtual void setName(const Cfg *Func, const std::string &NewName) { 693 virtual void setName(const Cfg *Func, const std::string &NewName) {
684 if (NewName.empty()) 694 if (NewName.empty())
685 return; 695 return;
686 Name = VariableString::createWithString(Func, NewName); 696 Name = VariableString::createWithString(Func, NewName);
687 } 697 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 } 747 }
738 bool isRematerializable() const { return IsRematerializable; } 748 bool isRematerializable() const { return IsRematerializable; }
739 749
740 void setRegClass(uint8_t RC) { RegisterClass = static_cast<RegClass>(RC); } 750 void setRegClass(uint8_t RC) { RegisterClass = static_cast<RegClass>(RC); }
741 RegClass getRegClass() const { return RegisterClass; } 751 RegClass getRegClass() const { return RegisterClass; }
742 752
743 LiveRange &getLiveRange() { return Live; } 753 LiveRange &getLiveRange() { return Live; }
744 const LiveRange &getLiveRange() const { return Live; } 754 const LiveRange &getLiveRange() const { return Live; }
745 void setLiveRange(const LiveRange &Range) { Live = Range; } 755 void setLiveRange(const LiveRange &Range) { Live = Range; }
746 void resetLiveRange() { Live.reset(); } 756 void resetLiveRange() { Live.reset(); }
747 void addLiveRange(InstNumberT Start, InstNumberT End) { 757 void addLiveRange(InstNumberT Start, InstNumberT End,
758 CfgNode *Node = nullptr) {
748 assert(!getIgnoreLiveness()); 759 assert(!getIgnoreLiveness());
749 Live.addSegment(Start, End); 760 Live.addSegment(Start, End, Node);
750 } 761 }
751 void trimLiveRange(InstNumberT Start) { Live.trim(Start); } 762 void trimLiveRange(InstNumberT Start) { Live.trim(Start); }
752 void untrimLiveRange() { Live.untrim(); } 763 void untrimLiveRange() { Live.untrim(); }
753 bool rangeEndsBefore(const Variable *Other) const { 764 bool rangeEndsBefore(const Variable *Other) const {
754 return Live.endsBefore(Other->Live); 765 return Live.endsBefore(Other->Live);
755 } 766 }
756 bool rangeOverlaps(const Variable *Other) const { 767 bool rangeOverlaps(const Variable *Other) const {
757 constexpr bool UseTrimmed = true; 768 constexpr bool UseTrimmed = true;
758 return Live.overlaps(Other->Live, UseTrimmed); 769 return Live.overlaps(Other->Live, UseTrimmed);
759 } 770 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 Variable(const Cfg *Func, OperandKind K, Type Ty, SizeT Index) 812 Variable(const Cfg *Func, OperandKind K, Type Ty, SizeT Index)
802 : Operand(K, Ty), Number(Index), 813 : Operand(K, Ty), Number(Index),
803 Name(VariableString::createWithoutString(Func)), 814 Name(VariableString::createWithoutString(Func)),
804 RegisterClass(static_cast<RegClass>(Ty)) { 815 RegisterClass(static_cast<RegClass>(Ty)) {
805 Vars = VarsReal; 816 Vars = VarsReal;
806 Vars[0] = this; 817 Vars[0] = this;
807 NumVars = 1; 818 NumVars = 1;
808 } 819 }
809 /// Number is unique across all variables, and is used as a (bit)vector index 820 /// Number is unique across all variables, and is used as a (bit)vector index
810 /// for liveness analysis. 821 /// for liveness analysis.
811 const SizeT Number; 822 SizeT Number;
812 VariableString Name; 823 VariableString Name;
813 bool IsArgument = false; 824 bool IsArgument = false;
814 bool IsImplicitArgument = false; 825 bool IsImplicitArgument = false;
815 /// IgnoreLiveness means that the variable should be ignored when constructing 826 /// IgnoreLiveness means that the variable should be ignored when constructing
816 /// and validating live ranges. This is usually reserved for the stack 827 /// and validating live ranges. This is usually reserved for the stack
817 /// pointer and other physical registers specifically referenced by name. 828 /// pointer and other physical registers specifically referenced by name.
818 bool IgnoreLiveness = false; 829 bool IgnoreLiveness = false;
819 // If IsRematerializable, RegNum keeps track of which register (stack or frame 830 // If IsRematerializable, RegNum keeps track of which register (stack or frame
820 // pointer), and StackOffset is the known offset from that register. 831 // pointer), and StackOffset is the known offset from that register.
821 bool IsRematerializable = false; 832 bool IsRematerializable = false;
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1044 return Operand->getKind() == kVariableBoolean; 1055 return Operand->getKind() == kVariableBoolean;
1045 } 1056 }
1046 1057
1047 private: 1058 private:
1048 Variable *BoolSource = nullptr; 1059 Variable *BoolSource = nullptr;
1049 }; 1060 };
1050 1061
1051 } // end of namespace Ice 1062 } // end of namespace Ice
1052 1063
1053 #endif // SUBZERO_SRC_ICEOPERAND_H 1064 #endif // SUBZERO_SRC_ICEOPERAND_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698