| 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 |