OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_REGISTER_ALLOCATOR_H_ | 5 #ifndef V8_REGISTER_ALLOCATOR_H_ |
6 #define V8_REGISTER_ALLOCATOR_H_ | 6 #define V8_REGISTER_ALLOCATOR_H_ |
7 | 7 |
8 #include "src/compiler/instruction.h" | 8 #include "src/compiler/instruction.h" |
| 9 #include "src/ostreams.h" |
9 #include "src/zone-containers.h" | 10 #include "src/zone-containers.h" |
10 | 11 |
11 namespace v8 { | 12 namespace v8 { |
12 namespace internal { | 13 namespace internal { |
13 namespace compiler { | 14 namespace compiler { |
14 | 15 |
15 enum RegisterKind { | 16 enum RegisterKind { |
16 GENERAL_REGISTERS, | 17 GENERAL_REGISTERS, |
17 DOUBLE_REGISTERS | 18 DOUBLE_REGISTERS |
18 }; | 19 }; |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 | 146 |
146 // Code relies on kStep and kHalfStep being a power of two. | 147 // Code relies on kStep and kHalfStep being a power of two. |
147 STATIC_ASSERT(IS_POWER_OF_TWO(kHalfStep)); | 148 STATIC_ASSERT(IS_POWER_OF_TWO(kHalfStep)); |
148 | 149 |
149 explicit LifetimePosition(int value) : value_(value) {} | 150 explicit LifetimePosition(int value) : value_(value) {} |
150 | 151 |
151 int value_; | 152 int value_; |
152 }; | 153 }; |
153 | 154 |
154 | 155 |
| 156 std::ostream& operator<<(std::ostream& os, const LifetimePosition pos); |
| 157 |
| 158 |
155 // Representation of the non-empty interval [start,end[. | 159 // Representation of the non-empty interval [start,end[. |
156 class UseInterval final : public ZoneObject { | 160 class UseInterval final : public ZoneObject { |
157 public: | 161 public: |
158 UseInterval(LifetimePosition start, LifetimePosition end) | 162 UseInterval(LifetimePosition start, LifetimePosition end) |
159 : start_(start), end_(end), next_(nullptr) { | 163 : start_(start), end_(end), next_(nullptr) { |
160 DCHECK(start < end); | 164 DCHECK(start < end); |
161 } | 165 } |
162 | 166 |
163 LifetimePosition start() const { return start_; } | 167 LifetimePosition start() const { return start_; } |
164 void set_start(LifetimePosition start) { start_ = start; } | 168 void set_start(LifetimePosition start) { start_ = start; } |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 mutable UseInterval* current_interval_; | 465 mutable UseInterval* current_interval_; |
462 // This is used as a cache, it doesn't affect correctness. | 466 // This is used as a cache, it doesn't affect correctness. |
463 mutable UsePosition* last_processed_use_; | 467 mutable UsePosition* last_processed_use_; |
464 // This is used as a cache, it's invalid outside of BuildLiveRanges. | 468 // This is used as a cache, it's invalid outside of BuildLiveRanges. |
465 mutable UsePosition* current_hint_position_; | 469 mutable UsePosition* current_hint_position_; |
466 | 470 |
467 DISALLOW_COPY_AND_ASSIGN(LiveRange); | 471 DISALLOW_COPY_AND_ASSIGN(LiveRange); |
468 }; | 472 }; |
469 | 473 |
470 | 474 |
| 475 struct PrintableLiveRange { |
| 476 const RegisterConfiguration* register_configuration_; |
| 477 const LiveRange* range_; |
| 478 }; |
| 479 |
| 480 |
| 481 std::ostream& operator<<(std::ostream& os, |
| 482 const PrintableLiveRange& printable_range); |
| 483 |
| 484 |
471 class SpillRange final : public ZoneObject { | 485 class SpillRange final : public ZoneObject { |
472 public: | 486 public: |
473 static const int kUnassignedSlot = -1; | 487 static const int kUnassignedSlot = -1; |
474 SpillRange(LiveRange* range, Zone* zone); | 488 SpillRange(LiveRange* range, Zone* zone); |
475 | 489 |
476 UseInterval* interval() const { return use_interval_; } | 490 UseInterval* interval() const { return use_interval_; } |
477 // Currently, only 4 or 8 byte slots are supported. | 491 // Currently, only 4 or 8 byte slots are supported. |
478 int ByteWidth() const; | 492 int ByteWidth() const; |
479 bool IsEmpty() const { return live_ranges_.empty(); } | 493 bool IsEmpty() const { return live_ranges_.empty(); } |
480 bool TryMerge(SpillRange* other); | 494 bool TryMerge(SpillRange* other); |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
819 ZoneVector<LiveRange*> active_live_ranges_; | 833 ZoneVector<LiveRange*> active_live_ranges_; |
820 ZoneVector<LiveRange*> inactive_live_ranges_; | 834 ZoneVector<LiveRange*> inactive_live_ranges_; |
821 | 835 |
822 #ifdef DEBUG | 836 #ifdef DEBUG |
823 LifetimePosition allocation_finger_; | 837 LifetimePosition allocation_finger_; |
824 #endif | 838 #endif |
825 | 839 |
826 DISALLOW_COPY_AND_ASSIGN(LinearScanAllocator); | 840 DISALLOW_COPY_AND_ASSIGN(LinearScanAllocator); |
827 }; | 841 }; |
828 | 842 |
829 class CoallescedLiveRanges; | 843 class CoalescedLiveRanges; |
830 | 844 |
831 | 845 |
832 // A variant of the LLVM Greedy Register Allocator. See | 846 // A variant of the LLVM Greedy Register Allocator. See |
833 // http://blog.llvm.org/2011/09/greedy-register-allocation-in-llvm-30.html | 847 // http://blog.llvm.org/2011/09/greedy-register-allocation-in-llvm-30.html |
834 class GreedyAllocator final : public RegisterAllocator { | 848 class GreedyAllocator final : public RegisterAllocator { |
835 public: | 849 public: |
836 explicit GreedyAllocator(RegisterAllocationData* data, RegisterKind kind, | 850 explicit GreedyAllocator(RegisterAllocationData* data, RegisterKind kind, |
837 Zone* local_zone); | 851 Zone* local_zone); |
838 | 852 |
839 void AllocateRegisters(); | 853 void AllocateRegisters(); |
840 | 854 |
841 private: | 855 private: |
| 856 LifetimePosition GetSplittablePos(LifetimePosition pos); |
842 const RegisterConfiguration* config() const { return data()->config(); } | 857 const RegisterConfiguration* config() const { return data()->config(); } |
| 858 Zone* local_zone() const { return local_zone_; } |
| 859 bool TryReuseSpillForPhi(LiveRange* range); |
| 860 int GetHintedRegister(LiveRange* range); |
843 | 861 |
844 typedef ZonePriorityQueue<std::pair<unsigned, LiveRange*>> PQueue; | 862 typedef ZonePriorityQueue<std::pair<unsigned, LiveRange*>> PQueue; |
845 | 863 |
846 unsigned GetLiveRangeSize(LiveRange* range); | 864 unsigned GetLiveRangeSize(LiveRange* range); |
847 void Enqueue(LiveRange* range); | 865 void Enqueue(LiveRange* range); |
848 | 866 |
849 void Evict(LiveRange* range); | 867 void Evict(LiveRange* range); |
850 float CalculateSpillWeight(LiveRange* range); | 868 float CalculateSpillWeight(LiveRange* range); |
851 float CalculateMaxSpillWeight(const ZoneSet<LiveRange*>& ranges); | 869 float CalculateMaxSpillWeight(const ZoneSet<LiveRange*>& ranges); |
852 | 870 |
853 | 871 |
854 bool TryAllocate(LiveRange* current, ZoneSet<LiveRange*>* conflicting); | 872 bool TryAllocate(LiveRange* current, ZoneSet<LiveRange*>* conflicting); |
855 bool TryAllocatePhysicalRegister(unsigned reg_id, LiveRange* range, | 873 bool TryAllocatePhysicalRegister(unsigned reg_id, LiveRange* range, |
856 ZoneSet<LiveRange*>* conflicting); | 874 ZoneSet<LiveRange*>* conflicting); |
857 bool HandleSpillOperands(LiveRange* range); | 875 bool HandleSpillOperands(LiveRange* range); |
858 bool AllocateBlockedRange(LiveRange*, const ZoneSet<LiveRange*>&); | 876 void AllocateBlockedRange(LiveRange* current, LifetimePosition pos, |
| 877 bool spill); |
859 | 878 |
860 LiveRange* SpillBetweenUntil(LiveRange* range, LifetimePosition start, | 879 LiveRange* SpillBetweenUntil(LiveRange* range, LifetimePosition start, |
861 LifetimePosition until, LifetimePosition end); | 880 LifetimePosition until, LifetimePosition end); |
862 void AssignRangeToRegister(int reg_id, LiveRange* range); | 881 void AssignRangeToRegister(int reg_id, LiveRange* range); |
863 | 882 |
864 ZoneVector<CoallescedLiveRanges*> allocations_; | 883 LifetimePosition FindProgressingSplitPosition(LiveRange* range, |
| 884 bool* is_spill_pos); |
| 885 |
| 886 Zone* local_zone_; |
| 887 ZoneVector<CoalescedLiveRanges*> allocations_; |
865 PQueue queue_; | 888 PQueue queue_; |
866 DISALLOW_COPY_AND_ASSIGN(GreedyAllocator); | 889 DISALLOW_COPY_AND_ASSIGN(GreedyAllocator); |
867 }; | 890 }; |
868 | 891 |
869 | 892 |
870 class SpillSlotLocator final : public ZoneObject { | 893 class SpillSlotLocator final : public ZoneObject { |
871 public: | 894 public: |
872 explicit SpillSlotLocator(RegisterAllocationData* data); | 895 explicit SpillSlotLocator(RegisterAllocationData* data); |
873 | 896 |
874 void LocateSpillSlots(); | 897 void LocateSpillSlots(); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
943 RegisterAllocationData* const data_; | 966 RegisterAllocationData* const data_; |
944 | 967 |
945 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); | 968 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); |
946 }; | 969 }; |
947 | 970 |
948 } // namespace compiler | 971 } // namespace compiler |
949 } // namespace internal | 972 } // namespace internal |
950 } // namespace v8 | 973 } // namespace v8 |
951 | 974 |
952 #endif // V8_REGISTER_ALLOCATOR_H_ | 975 #endif // V8_REGISTER_ALLOCATOR_H_ |
OLD | NEW |