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

Side by Side Diff: src/lithium-allocator.h

Issue 5862002: Version 3.0.2. (Closed)
Patch Set: Created 10 years 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 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 class LArgument; 48 class LArgument;
49 class LChunk; 49 class LChunk;
50 class LConstantOperand; 50 class LConstantOperand;
51 class LGap; 51 class LGap;
52 class LInstruction; 52 class LInstruction;
53 class LParallelMove; 53 class LParallelMove;
54 class LPointerMap; 54 class LPointerMap;
55 class LStackSlot; 55 class LStackSlot;
56 class LRegister; 56 class LRegister;
57 57
58
59 // This class represents a single point of a LOperand's lifetime. 58 // This class represents a single point of a LOperand's lifetime.
60 // For each lithium instruction there are exactly two lifetime positions: 59 // For each lithium instruction there are exactly two lifetime positions:
61 // the beginning and the end of the instruction. Lifetime positions for 60 // the beginning and the end of the instruction. Lifetime positions for
62 // different lithium instructions are disjoint. 61 // different lithium instructions are disjoint.
63 class LifetimePosition { 62 class LifetimePosition {
64 public: 63 public:
65 // Return the lifetime position that corresponds to the beginning of 64 // Return the lifetime position that corresponds to the beginning of
66 // the instruction with the given index. 65 // the instruction with the given index.
67 static LifetimePosition FromInstructionIndex(int index) { 66 static LifetimePosition FromInstructionIndex(int index) {
68 return LifetimePosition(index * kStep); 67 return LifetimePosition(index * kStep);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 } 114 }
116 115
117 // Constructs the lifetime position which does not correspond to any 116 // Constructs the lifetime position which does not correspond to any
118 // instruction. 117 // instruction.
119 LifetimePosition() : value_(-1) {} 118 LifetimePosition() : value_(-1) {}
120 119
121 // Returns true if this lifetime positions corrensponds to some 120 // Returns true if this lifetime positions corrensponds to some
122 // instruction. 121 // instruction.
123 bool IsValid() const { return value_ != -1; } 122 bool IsValid() const { return value_ != -1; }
124 123
125 static inline LifetimePosition Invalid() { return LifetimePosition(); } 124 static LifetimePosition Invalid() { return LifetimePosition(); }
126
127 static inline LifetimePosition MaxPosition() {
128 // We have to use this kind of getter instead of static member due to
129 // crash bug in GDB.
130 return LifetimePosition(kMaxInt);
131 }
132 125
133 private: 126 private:
134 static const int kStep = 2; 127 static const int kStep = 2;
135 128
136 // Code relies on kStep being a power of two. 129 // Code relies on kStep being a power of two.
137 STATIC_ASSERT(IS_POWER_OF_TWO(kStep)); 130 STATIC_ASSERT(IS_POWER_OF_TWO(kStep));
138 131
139 explicit LifetimePosition(int value) : value_(value) { } 132 explicit LifetimePosition(int value) : value_(value) { }
140 133
141 int value_; 134 int value_;
142 }; 135 };
143 136
144 137
145 enum RegisterKind {
146 NONE,
147 GENERAL_REGISTERS,
148 DOUBLE_REGISTERS
149 };
150
151
152 class LOperand: public ZoneObject { 138 class LOperand: public ZoneObject {
153 public: 139 public:
154 enum Kind { 140 enum Kind {
155 INVALID, 141 INVALID,
156 UNALLOCATED, 142 UNALLOCATED,
157 CONSTANT_OPERAND, 143 CONSTANT_OPERAND,
158 STACK_SLOT, 144 STACK_SLOT,
159 DOUBLE_STACK_SLOT, 145 DOUBLE_STACK_SLOT,
160 REGISTER, 146 REGISTER,
161 DOUBLE_REGISTER, 147 DOUBLE_REGISTER,
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 587
602 // Representation of SSA values' live ranges as a collection of (continuous) 588 // Representation of SSA values' live ranges as a collection of (continuous)
603 // intervals over the instruction ordering. 589 // intervals over the instruction ordering.
604 class LiveRange: public ZoneObject { 590 class LiveRange: public ZoneObject {
605 public: 591 public:
606 static const int kInvalidAssignment = 0x7fffffff; 592 static const int kInvalidAssignment = 0x7fffffff;
607 593
608 explicit LiveRange(int id) 594 explicit LiveRange(int id)
609 : id_(id), 595 : id_(id),
610 spilled_(false), 596 spilled_(false),
597 assigned_double_(false),
611 assigned_register_(kInvalidAssignment), 598 assigned_register_(kInvalidAssignment),
612 assigned_register_kind_(NONE),
613 last_interval_(NULL), 599 last_interval_(NULL),
614 first_interval_(NULL), 600 first_interval_(NULL),
615 first_pos_(NULL), 601 first_pos_(NULL),
616 parent_(NULL), 602 parent_(NULL),
617 next_(NULL), 603 next_(NULL),
618 current_interval_(NULL), 604 current_interval_(NULL),
619 last_processed_use_(NULL), 605 last_processed_use_(NULL),
620 spill_start_index_(kMaxInt) { 606 spill_start_index_(kMaxInt) {
621 spill_operand_ = new LUnallocated(LUnallocated::IGNORE); 607 spill_operand_ = new LUnallocated(LUnallocated::IGNORE);
622 } 608 }
623 609
624 UseInterval* first_interval() const { return first_interval_; } 610 UseInterval* first_interval() const { return first_interval_; }
625 UsePosition* first_pos() const { return first_pos_; } 611 UsePosition* first_pos() const { return first_pos_; }
626 LiveRange* parent() const { return parent_; } 612 LiveRange* parent() const { return parent_; }
627 LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; } 613 LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; }
628 LiveRange* next() const { return next_; } 614 LiveRange* next() const { return next_; }
629 bool IsChild() const { return parent() != NULL; } 615 bool IsChild() const { return parent() != NULL; }
630 bool IsParent() const { return parent() == NULL; } 616 bool IsParent() const { return parent() == NULL; }
631 int id() const { return id_; } 617 int id() const { return id_; }
632 bool IsFixed() const { return id_ < 0; } 618 bool IsFixed() const { return id_ < 0; }
633 bool IsEmpty() const { return first_interval() == NULL; } 619 bool IsEmpty() const { return first_interval() == NULL; }
634 LOperand* CreateAssignedOperand(); 620 LOperand* CreateAssignedOperand();
635 int assigned_register() const { return assigned_register_; } 621 int assigned_register() const { return assigned_register_; }
636 int spill_start_index() const { return spill_start_index_; } 622 int spill_start_index() const { return spill_start_index_; }
637 void set_assigned_register(int reg, RegisterKind register_kind) { 623 void set_assigned_register(int reg, bool double_reg) {
638 ASSERT(!HasRegisterAssigned() && !IsSpilled()); 624 ASSERT(!HasRegisterAssigned() && !IsSpilled());
639 assigned_register_ = reg; 625 assigned_register_ = reg;
640 assigned_register_kind_ = register_kind; 626 assigned_double_ = double_reg;
641 ConvertOperands(); 627 ConvertOperands();
642 } 628 }
643 void MakeSpilled() { 629 void MakeSpilled() {
644 ASSERT(!IsSpilled()); 630 ASSERT(!IsSpilled());
645 ASSERT(TopLevel()->HasAllocatedSpillOperand()); 631 ASSERT(TopLevel()->HasAllocatedSpillOperand());
646 spilled_ = true; 632 spilled_ = true;
647 assigned_register_ = kInvalidAssignment; 633 assigned_register_ = kInvalidAssignment;
648 ConvertOperands(); 634 ConvertOperands();
649 } 635 }
650 636
651 // Returns use position in this live range that follows both start 637 // Returns use position in this live range that follows both start
652 // and last processed use position. 638 // and last processed use position.
653 // Modifies internal state of live range! 639 // Modifies internal state of live range!
654 UsePosition* NextUsePosition(LifetimePosition start); 640 UsePosition* NextUsePosition(LifetimePosition start);
655 641
656 // Returns use position for which register is required in this live 642 // Returns use position for which register is required in this live
657 // range and which follows both start and last processed use position 643 // range and which follows both start and last processed use position
658 // Modifies internal state of live range! 644 // Modifies internal state of live range!
659 UsePosition* NextRegisterPosition(LifetimePosition start); 645 UsePosition* NextRegisterPosition(LifetimePosition start);
660 646
661 // Returns use position for which register is beneficial in this live 647 // Returns use position for which register is beneficial in this live
662 // range and which follows both start and last processed use position 648 // range and which follows both start and last processed use position
663 // Modifies internal state of live range! 649 // Modifies internal state of live range!
664 UsePosition* NextUsePositionRegisterIsBeneficial(LifetimePosition start); 650 UsePosition* NextUsePositionRegisterIsBeneficial(LifetimePosition start);
665 651
666 // Can this live range be spilled at this position. 652 // Can this live range be spilled at this position.
667 bool CanBeSpilled(LifetimePosition pos); 653 bool CanBeSpilled(LifetimePosition pos);
668 654
669 // Split this live range at the given position which must follow the start of
670 // the range.
671 // All uses following the given position will be moved from this
672 // live range to the result live range.
673 void SplitAt(LifetimePosition position, LiveRange* result); 655 void SplitAt(LifetimePosition position, LiveRange* result);
674 656
675 bool IsDouble() const { return assigned_register_kind_ == DOUBLE_REGISTERS; } 657 bool IsDouble() const { return assigned_double_; }
676 bool HasRegisterAssigned() const { 658 bool HasRegisterAssigned() const {
677 return assigned_register_ != kInvalidAssignment; 659 return assigned_register_ != kInvalidAssignment;
678 } 660 }
679 bool IsSpilled() const { return spilled_; } 661 bool IsSpilled() const { return spilled_; }
680 UsePosition* FirstPosWithHint() const; 662 UsePosition* FirstPosWithHint() const;
681 663
682 LOperand* FirstHint() const { 664 LOperand* FirstHint() const {
683 UsePosition* pos = FirstPosWithHint(); 665 UsePosition* pos = FirstPosWithHint();
684 if (pos != NULL) return pos->hint(); 666 if (pos != NULL) return pos->hint();
685 return NULL; 667 return NULL;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 #endif 714 #endif
733 715
734 private: 716 private:
735 void ConvertOperands(); 717 void ConvertOperands();
736 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; 718 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const;
737 void AdvanceLastProcessedMarker(UseInterval* to_start_of, 719 void AdvanceLastProcessedMarker(UseInterval* to_start_of,
738 LifetimePosition but_not_past) const; 720 LifetimePosition but_not_past) const;
739 721
740 int id_; 722 int id_;
741 bool spilled_; 723 bool spilled_;
724 bool assigned_double_;
742 int assigned_register_; 725 int assigned_register_;
743 RegisterKind assigned_register_kind_;
744 UseInterval* last_interval_; 726 UseInterval* last_interval_;
745 UseInterval* first_interval_; 727 UseInterval* first_interval_;
746 UsePosition* first_pos_; 728 UsePosition* first_pos_;
747 LiveRange* parent_; 729 LiveRange* parent_;
748 LiveRange* next_; 730 LiveRange* next_;
749 // This is used as a cache, it doesn't affect correctness. 731 // This is used as a cache, it doesn't affect correctness.
750 mutable UseInterval* current_interval_; 732 mutable UseInterval* current_interval_;
751 UsePosition* last_processed_use_; 733 UsePosition* last_processed_use_;
752 LOperand* spill_operand_; 734 LOperand* spill_operand_;
753 int spill_start_index_; 735 int spill_start_index_;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 void RecordDefinition(HInstruction* instr, LUnallocated* operand); 767 void RecordDefinition(HInstruction* instr, LUnallocated* operand);
786 // Record a temporary operand. 768 // Record a temporary operand.
787 void RecordTemporary(LUnallocated* operand); 769 void RecordTemporary(LUnallocated* operand);
788 770
789 // Marks the current instruction as a call. 771 // Marks the current instruction as a call.
790 void MarkAsCall(); 772 void MarkAsCall();
791 773
792 // Checks whether the value of a given virtual register is tagged. 774 // Checks whether the value of a given virtual register is tagged.
793 bool HasTaggedValue(int virtual_register) const; 775 bool HasTaggedValue(int virtual_register) const;
794 776
795 // Returns the register kind required by the given virtual register. 777 // Checks whether the value of a given virtual register is a double.
796 RegisterKind RequiredRegisterKind(int virtual_register) const; 778 bool HasDoubleValue(int virtual_register) const;
797 779
798 // Begin a new instruction. 780 // Begin a new instruction.
799 void BeginInstruction(); 781 void BeginInstruction();
800 782
801 // Summarize the current instruction. 783 // Summarize the current instruction.
802 void SummarizeInstruction(int index); 784 void SummarizeInstruction(int index);
803 785
804 // Summarize the current instruction. 786 // Summarize the current instruction.
805 void OmitInstruction(); 787 void OmitInstruction();
806 788
(...skipping 18 matching lines...) Expand all
825 ASSERT(!has_osr_entry_); 807 ASSERT(!has_osr_entry_);
826 // Simply set a flag to find and process instruction later. 808 // Simply set a flag to find and process instruction later.
827 has_osr_entry_ = true; 809 has_osr_entry_ = true;
828 } 810 }
829 811
830 #ifdef DEBUG 812 #ifdef DEBUG
831 void Verify() const; 813 void Verify() const;
832 #endif 814 #endif
833 815
834 private: 816 private:
817 enum OperationMode {
818 NONE,
819 CPU_REGISTERS,
820 XMM_REGISTERS
821 };
822
835 void MeetRegisterConstraints(); 823 void MeetRegisterConstraints();
836 void ResolvePhis(); 824 void ResolvePhis();
837 void BuildLiveRanges(); 825 void BuildLiveRanges();
838 void AllocateGeneralRegisters(); 826 void AllocateGeneralRegisters();
839 void AllocateDoubleRegisters(); 827 void AllocateDoubleRegisters();
840 void ConnectRanges(); 828 void ConnectRanges();
841 void ResolveControlFlow(); 829 void ResolveControlFlow();
842 void PopulatePointerMaps(); 830 void PopulatePointerMaps();
843 void ProcessOsrEntry(); 831 void ProcessOsrEntry();
844 void AllocateRegisters(); 832 void AllocateRegisters();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 void ActiveToHandled(LiveRange* range); 864 void ActiveToHandled(LiveRange* range);
877 void ActiveToInactive(LiveRange* range); 865 void ActiveToInactive(LiveRange* range);
878 void InactiveToHandled(LiveRange* range); 866 void InactiveToHandled(LiveRange* range);
879 void InactiveToActive(LiveRange* range); 867 void InactiveToActive(LiveRange* range);
880 void FreeSpillSlot(LiveRange* range); 868 void FreeSpillSlot(LiveRange* range);
881 LOperand* TryReuseSpillSlot(LiveRange* range); 869 LOperand* TryReuseSpillSlot(LiveRange* range);
882 870
883 // Helper methods for allocating registers. 871 // Helper methods for allocating registers.
884 bool TryAllocateFreeReg(LiveRange* range); 872 bool TryAllocateFreeReg(LiveRange* range);
885 void AllocateBlockedReg(LiveRange* range); 873 void AllocateBlockedReg(LiveRange* range);
886 874 void SplitAndSpillIntersecting(LiveRange* range);
887 // Live range splitting helpers.
888
889 // Split the given range at the given position.
890 // If range starts at or after the given position then the
891 // original range is returned.
892 // Otherwise returns the live range that starts at pos and contains
893 // all uses from the original range that follow pos. Uses at pos will
894 // still be owned by the original range after splitting.
895 LiveRange* SplitAt(LiveRange* range, LifetimePosition pos);
896
897 // Split the given range in a position from the interval [start, end].
898 LiveRange* SplitBetween(LiveRange* range,
899 LifetimePosition start,
900 LifetimePosition end);
901
902 // Find a lifetime position in the interval [start, end] which
903 // is optimal for splitting: it is either header of the outermost
904 // loop covered by this interval or the latest possible position.
905 LifetimePosition FindOptimalSplitPos(LifetimePosition start, 875 LifetimePosition FindOptimalSplitPos(LifetimePosition start,
906 LifetimePosition end); 876 LifetimePosition end);
907 877 LiveRange* Split(LiveRange* range,
908 // Spill the given life range after position pos. 878 LifetimePosition start,
909 void SpillAfter(LiveRange* range, LifetimePosition pos); 879 LifetimePosition end);
910 880 LiveRange* Split(LiveRange* range, LifetimePosition split_pos);
911 // Spill the given life range after position start and up to position end. 881 void SplitAndSpill(LiveRange* range,
912 void SpillBetween(LiveRange* range, 882 LifetimePosition start,
913 LifetimePosition start, 883 LifetimePosition end);
914 LifetimePosition end); 884 void SplitAndSpill(LiveRange* range, LifetimePosition at);
915
916 void SplitAndSpillIntersecting(LiveRange* range);
917
918 void Spill(LiveRange* range); 885 void Spill(LiveRange* range);
919 bool IsBlockBoundary(LifetimePosition pos); 886 bool IsBlockBoundary(LifetimePosition pos);
920 void AddGapMove(int pos, LiveRange* prev, LiveRange* next); 887 void AddGapMove(int pos, LiveRange* prev, LiveRange* next);
921 888
922 // Helper methods for resolving control flow. 889 // Helper methods for resolving control flow.
923 void ResolveControlFlow(LiveRange* range, 890 void ResolveControlFlow(LiveRange* range,
924 HBasicBlock* block, 891 HBasicBlock* block,
925 HBasicBlock* pred); 892 HBasicBlock* pred);
926 893
927 // Return parallel move that should be used to connect ranges split at the 894 // Return parallel move that should be used to connect ranges split at the
(...skipping 12 matching lines...) Expand all
940 // Helper methods for the fixed registers. 907 // Helper methods for the fixed registers.
941 int RegisterCount() const; 908 int RegisterCount() const;
942 static int FixedLiveRangeID(int index) { return -index - 1; } 909 static int FixedLiveRangeID(int index) { return -index - 1; }
943 static int FixedDoubleLiveRangeID(int index); 910 static int FixedDoubleLiveRangeID(int index);
944 LiveRange* FixedLiveRangeFor(int index); 911 LiveRange* FixedLiveRangeFor(int index);
945 LiveRange* FixedDoubleLiveRangeFor(int index); 912 LiveRange* FixedDoubleLiveRangeFor(int index);
946 LiveRange* LiveRangeFor(int index); 913 LiveRange* LiveRangeFor(int index);
947 HPhi* LookupPhi(LOperand* operand) const; 914 HPhi* LookupPhi(LOperand* operand) const;
948 LGap* GetLastGap(HBasicBlock* block) const; 915 LGap* GetLastGap(HBasicBlock* block) const;
949 916
950 const char* RegisterName(int allocation_index);
951
952 LChunk* chunk_; 917 LChunk* chunk_;
953 ZoneList<InstructionSummary*> summaries_; 918 ZoneList<InstructionSummary*> summaries_;
954 InstructionSummary* next_summary_; 919 InstructionSummary* next_summary_;
955 920
956 ZoneList<InstructionSummary*> summary_stack_; 921 ZoneList<InstructionSummary*> summary_stack_;
957 922
958 // During liveness analysis keep a mapping from block id to live_in sets 923 // During liveness analysis keep a mapping from block id to live_in sets
959 // for blocks already analyzed. 924 // for blocks already analyzed.
960 ZoneList<BitVector*> live_in_sets_; 925 ZoneList<BitVector*> live_in_sets_;
961 926
962 // Liveness analysis results. 927 // Liveness analysis results.
963 ZoneList<LiveRange*> live_ranges_; 928 ZoneList<LiveRange*> live_ranges_;
964 929
965 // Lists of live ranges 930 // Lists of live ranges
966 ZoneList<LiveRange*> fixed_live_ranges_; 931 ZoneList<LiveRange*> fixed_live_ranges_;
967 ZoneList<LiveRange*> fixed_double_live_ranges_; 932 ZoneList<LiveRange*> fixed_double_live_ranges_;
968 ZoneList<LiveRange*> unhandled_live_ranges_; 933 ZoneList<LiveRange*> unhandled_live_ranges_;
969 ZoneList<LiveRange*> active_live_ranges_; 934 ZoneList<LiveRange*> active_live_ranges_;
970 ZoneList<LiveRange*> inactive_live_ranges_; 935 ZoneList<LiveRange*> inactive_live_ranges_;
971 ZoneList<LiveRange*> reusable_slots_; 936 ZoneList<LiveRange*> reusable_slots_;
972 937
973 // Next virtual register number to be assigned to temporaries. 938 // Next virtual register number to be assigned to temporaries.
974 int next_virtual_register_; 939 int next_virtual_register_;
975 940
976 RegisterKind mode_; 941 OperationMode mode_;
977 int num_registers_; 942 int num_registers_;
978 943
979 HGraph* graph_; 944 HGraph* graph_;
980 945
981 bool has_osr_entry_; 946 bool has_osr_entry_;
982 947
983 DISALLOW_COPY_AND_ASSIGN(LAllocator); 948 DISALLOW_COPY_AND_ASSIGN(LAllocator);
984 }; 949 };
985 950
986 951
987 } } // namespace v8::internal 952 } } // namespace v8::internal
988 953
989 #endif // V8_LITHIUM_ALLOCATOR_H_ 954 #endif // V8_LITHIUM_ALLOCATOR_H_
OLDNEW
« ChangeLog ('K') | « src/json.js ('k') | src/lithium-allocator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698