Chromium Code Reviews| 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 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 460 // This is used as a cache, it doesn't affect correctness. | 464 // This is used as a cache, it doesn't affect correctness. |
| 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 |
| 474 struct PrintableLiveRange { | |
| 475 const RegisterConfiguration* register_configuration_; | |
| 476 const LiveRange* range_; | |
| 477 }; | |
| 478 | |
| 479 std::ostream& operator<<(std::ostream& os, | |
| 480 const PrintableLiveRange printable_range); | |
|
dcarney
2015/05/01 07:56:03
we usually use const & for these
Mircea Trofin
2015/05/01 15:06:33
Done.
| |
| 470 | 481 |
| 471 class SpillRange final : public ZoneObject { | 482 class SpillRange final : public ZoneObject { |
| 472 public: | 483 public: |
| 473 static const int kUnassignedSlot = -1; | 484 static const int kUnassignedSlot = -1; |
| 474 SpillRange(LiveRange* range, Zone* zone); | 485 SpillRange(LiveRange* range, Zone* zone); |
| 475 | 486 |
| 476 UseInterval* interval() const { return use_interval_; } | 487 UseInterval* interval() const { return use_interval_; } |
| 477 // Currently, only 4 or 8 byte slots are supported. | 488 // Currently, only 4 or 8 byte slots are supported. |
| 478 int ByteWidth() const; | 489 int ByteWidth() const; |
| 479 bool IsEmpty() const { return live_ranges_.empty(); } | 490 bool IsEmpty() const { return live_ranges_.empty(); } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 587 } | 598 } |
| 588 | 599 |
| 589 bool ExistsUseWithoutDefinition(); | 600 bool ExistsUseWithoutDefinition(); |
| 590 | 601 |
| 591 void MarkAllocated(RegisterKind kind, int index); | 602 void MarkAllocated(RegisterKind kind, int index); |
| 592 | 603 |
| 593 PhiMapValue* InitializePhiMap(const InstructionBlock* block, | 604 PhiMapValue* InitializePhiMap(const InstructionBlock* block, |
| 594 PhiInstruction* phi); | 605 PhiInstruction* phi); |
| 595 PhiMapValue* GetPhiMapValueFor(int virtual_register); | 606 PhiMapValue* GetPhiMapValueFor(int virtual_register); |
| 596 | 607 |
| 608 PrintableInstruction ToPrintable(Instruction* ins) const { | |
| 609 return {config_, ins}; | |
| 610 } | |
| 611 | |
| 612 PrintableInstructionOperand ToPrintable(InstructionOperand op) const { | |
| 613 return {config_, op}; | |
| 614 } | |
| 615 | |
| 616 PrintableInstructionSequence ToPrintable(InstructionSequence* seq) const { | |
| 617 return {config_, seq}; | |
| 618 } | |
| 619 | |
| 620 PrintableLiveRange ToPrintable(LiveRange* range) const { | |
| 621 return {config_, range}; | |
| 622 } | |
|
dcarney
2015/05/01 07:56:03
these are dead code (gdb only). drop.
in gdb you
Mircea Trofin
2015/05/01 15:06:33
But you still need to construct the Printable{xyz}
| |
| 623 | |
| 597 private: | 624 private: |
| 598 Zone* const allocation_zone_; | 625 Zone* const allocation_zone_; |
| 599 Frame* const frame_; | 626 Frame* const frame_; |
| 600 InstructionSequence* const code_; | 627 InstructionSequence* const code_; |
| 601 const char* const debug_name_; | 628 const char* const debug_name_; |
| 602 const RegisterConfiguration* const config_; | 629 const RegisterConfiguration* const config_; |
| 603 PhiMap phi_map_; | 630 PhiMap phi_map_; |
| 604 ZoneVector<BitVector*> live_in_sets_; | 631 ZoneVector<BitVector*> live_in_sets_; |
| 605 ZoneVector<LiveRange*> live_ranges_; | 632 ZoneVector<LiveRange*> live_ranges_; |
| 606 ZoneVector<LiveRange*> fixed_live_ranges_; | 633 ZoneVector<LiveRange*> fixed_live_ranges_; |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 819 ZoneVector<LiveRange*> active_live_ranges_; | 846 ZoneVector<LiveRange*> active_live_ranges_; |
| 820 ZoneVector<LiveRange*> inactive_live_ranges_; | 847 ZoneVector<LiveRange*> inactive_live_ranges_; |
| 821 | 848 |
| 822 #ifdef DEBUG | 849 #ifdef DEBUG |
| 823 LifetimePosition allocation_finger_; | 850 LifetimePosition allocation_finger_; |
| 824 #endif | 851 #endif |
| 825 | 852 |
| 826 DISALLOW_COPY_AND_ASSIGN(LinearScanAllocator); | 853 DISALLOW_COPY_AND_ASSIGN(LinearScanAllocator); |
| 827 }; | 854 }; |
| 828 | 855 |
| 829 class CoallescedLiveRanges; | 856 class CoallescedLiveRanges; |
|
dcarney
2015/05/01 07:56:03
i missed this earlier, but coalesced has one 'l',
Mircea Trofin
2015/05/01 15:06:33
Done.
| |
| 830 | 857 |
| 831 | 858 |
| 832 // A variant of the LLVM Greedy Register Allocator. See | 859 // A variant of the LLVM Greedy Register Allocator. See |
| 833 // http://blog.llvm.org/2011/09/greedy-register-allocation-in-llvm-30.html | 860 // http://blog.llvm.org/2011/09/greedy-register-allocation-in-llvm-30.html |
| 834 class GreedyAllocator final : public RegisterAllocator { | 861 class GreedyAllocator final : public RegisterAllocator { |
| 835 public: | 862 public: |
| 836 explicit GreedyAllocator(RegisterAllocationData* data, RegisterKind kind, | 863 explicit GreedyAllocator(RegisterAllocationData* data, RegisterKind kind, |
| 837 Zone* local_zone); | 864 Zone* local_zone); |
| 838 | 865 |
| 839 void AllocateRegisters(); | 866 void AllocateRegisters(); |
| 840 | 867 |
| 841 private: | 868 private: |
| 869 LifetimePosition GetSplittablePos(LifetimePosition pos); | |
| 842 const RegisterConfiguration* config() const { return data()->config(); } | 870 const RegisterConfiguration* config() const { return data()->config(); } |
| 871 Zone* local_zone() { return local_zone_; } | |
|
dcarney
2015/05/01 07:56:03
const
Mircea Trofin
2015/05/01 15:06:33
Done.
| |
| 872 bool TryReuseSpillForPhi(LiveRange* range); | |
| 873 int GetHintedRegister(LiveRange* range); | |
| 843 | 874 |
| 844 typedef ZonePriorityQueue<std::pair<unsigned, LiveRange*>> PQueue; | 875 typedef ZonePriorityQueue<std::pair<unsigned, LiveRange*>> PQueue; |
| 845 | 876 |
| 846 unsigned GetLiveRangeSize(LiveRange* range); | 877 unsigned GetLiveRangeSize(LiveRange* range); |
| 847 void Enqueue(LiveRange* range); | 878 void Enqueue(LiveRange* range); |
| 848 | 879 |
| 849 void Evict(LiveRange* range); | 880 void Evict(LiveRange* range); |
| 850 float CalculateSpillWeight(LiveRange* range); | 881 float CalculateSpillWeight(LiveRange* range); |
| 851 float CalculateMaxSpillWeight(const ZoneSet<LiveRange*>& ranges); | 882 float CalculateMaxSpillWeight(const ZoneSet<LiveRange*>& ranges); |
| 852 | 883 |
| 853 | 884 |
| 854 bool TryAllocate(LiveRange* current, ZoneSet<LiveRange*>* conflicting); | 885 bool TryAllocate(LiveRange* current, ZoneSet<LiveRange*>* conflicting); |
| 855 bool TryAllocatePhysicalRegister(unsigned reg_id, LiveRange* range, | 886 bool TryAllocatePhysicalRegister(unsigned reg_id, LiveRange* range, |
| 856 ZoneSet<LiveRange*>* conflicting); | 887 ZoneSet<LiveRange*>* conflicting); |
| 857 bool HandleSpillOperands(LiveRange* range); | 888 bool HandleSpillOperands(LiveRange* range); |
| 858 bool AllocateBlockedRange(LiveRange*, const ZoneSet<LiveRange*>&); | 889 void AllocateBlockedRange(LiveRange* current, LifetimePosition pos, |
| 890 bool spill); | |
| 859 | 891 |
| 860 LiveRange* SpillBetweenUntil(LiveRange* range, LifetimePosition start, | 892 LiveRange* SpillBetweenUntil(LiveRange* range, LifetimePosition start, |
| 861 LifetimePosition until, LifetimePosition end); | 893 LifetimePosition until, LifetimePosition end); |
| 862 void AssignRangeToRegister(int reg_id, LiveRange* range); | 894 void AssignRangeToRegister(int reg_id, LiveRange* range); |
| 863 | 895 |
| 896 LifetimePosition FindProgressingSplitPosition(LiveRange* range, | |
| 897 bool* is_spill_pos); | |
| 898 | |
| 899 Zone* local_zone_; | |
| 864 ZoneVector<CoallescedLiveRanges*> allocations_; | 900 ZoneVector<CoallescedLiveRanges*> allocations_; |
| 865 PQueue queue_; | 901 PQueue queue_; |
| 866 DISALLOW_COPY_AND_ASSIGN(GreedyAllocator); | 902 DISALLOW_COPY_AND_ASSIGN(GreedyAllocator); |
| 867 }; | 903 }; |
| 868 | 904 |
| 869 | 905 |
| 870 class SpillSlotLocator final : public ZoneObject { | 906 class SpillSlotLocator final : public ZoneObject { |
| 871 public: | 907 public: |
| 872 explicit SpillSlotLocator(RegisterAllocationData* data); | 908 explicit SpillSlotLocator(RegisterAllocationData* data); |
| 873 | 909 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 943 RegisterAllocationData* const data_; | 979 RegisterAllocationData* const data_; |
| 944 | 980 |
| 945 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); | 981 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); |
| 946 }; | 982 }; |
| 947 | 983 |
| 948 } // namespace compiler | 984 } // namespace compiler |
| 949 } // namespace internal | 985 } // namespace internal |
| 950 } // namespace v8 | 986 } // namespace v8 |
| 951 | 987 |
| 952 #endif // V8_REGISTER_ALLOCATOR_H_ | 988 #endif // V8_REGISTER_ALLOCATOR_H_ |
| OLD | NEW |