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/zone-containers.h" | 9 #include "src/zone-containers.h" |
| 10 | 10 |
| 11 #ifdef DEBUG | |
| 12 #include <iostream> | |
|
dcarney
2015/04/29 17:24:13
this is not allowed - adds static initializers
Mircea Trofin
2015/04/29 17:35:33
OK.
As a note, weird that it shows up in the bot
| |
| 13 #endif | |
| 14 | |
| 11 namespace v8 { | 15 namespace v8 { |
| 12 namespace internal { | 16 namespace internal { |
| 13 namespace compiler { | 17 namespace compiler { |
| 14 | 18 |
| 15 enum RegisterKind { | 19 enum RegisterKind { |
| 16 UNALLOCATED_REGISTERS, | 20 UNALLOCATED_REGISTERS, |
| 17 GENERAL_REGISTERS, | 21 GENERAL_REGISTERS, |
| 18 DOUBLE_REGISTERS | 22 DOUBLE_REGISTERS |
| 19 }; | 23 }; |
| 20 | 24 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 93 return LifetimePosition(FullStart().value_ + kStep); | 97 return LifetimePosition(FullStart().value_ + kStep); |
| 94 } | 98 } |
| 95 | 99 |
| 96 // Returns the lifetime position for the beginning of the previous START. | 100 // Returns the lifetime position for the beginning of the previous START. |
| 97 LifetimePosition PrevStart() const { | 101 LifetimePosition PrevStart() const { |
| 98 DCHECK(IsValid()); | 102 DCHECK(IsValid()); |
| 99 DCHECK(value_ >= kHalfStep); | 103 DCHECK(value_ >= kHalfStep); |
| 100 return LifetimePosition(Start().value_ - kHalfStep); | 104 return LifetimePosition(Start().value_ - kHalfStep); |
| 101 } | 105 } |
| 102 | 106 |
| 107 LifetimePosition Next() const { | |
|
dcarney
2015/04/29 17:24:13
are these really useful? they seem unusual...
Mircea Trofin
2015/04/29 17:35:33
Yes, see the way we pick split points.
| |
| 108 DCHECK(IsValid()); | |
| 109 return LifetimePosition(value_ + 1); | |
| 110 } | |
| 111 | |
| 112 LifetimePosition Prev() const { | |
| 113 DCHECK(IsValid()); | |
| 114 return LifetimePosition(value_ - 1); | |
| 115 } | |
| 116 | |
| 103 // Constructs the lifetime position which does not correspond to any | 117 // Constructs the lifetime position which does not correspond to any |
| 104 // instruction. | 118 // instruction. |
| 105 LifetimePosition() : value_(-1) {} | 119 LifetimePosition() : value_(-1) {} |
| 106 | 120 |
| 107 // Returns true if this lifetime positions corrensponds to some | 121 // Returns true if this lifetime positions corrensponds to some |
| 108 // instruction. | 122 // instruction. |
| 109 bool IsValid() const { return value_ != -1; } | 123 bool IsValid() const { return value_ != -1; } |
| 110 | 124 |
| 111 bool operator<(const LifetimePosition& that) const { | 125 bool operator<(const LifetimePosition& that) const { |
| 112 return this->value_ < that.value_; | 126 return this->value_ < that.value_; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 146 | 160 |
| 147 // Code relies on kStep and kHalfStep being a power of two. | 161 // Code relies on kStep and kHalfStep being a power of two. |
| 148 STATIC_ASSERT(IS_POWER_OF_TWO(kHalfStep)); | 162 STATIC_ASSERT(IS_POWER_OF_TWO(kHalfStep)); |
| 149 | 163 |
| 150 explicit LifetimePosition(int value) : value_(value) {} | 164 explicit LifetimePosition(int value) : value_(value) {} |
| 151 | 165 |
| 152 int value_; | 166 int value_; |
| 153 }; | 167 }; |
| 154 | 168 |
| 155 | 169 |
| 170 #ifdef DEBUG | |
| 171 static inline std::ostream& operator<<(std::ostream& os, | |
|
dcarney
2015/04/29 17:24:13
this should not be DEBUG and should not be inline
| |
| 172 const LifetimePosition& pos) { | |
| 173 os << '@' << pos.ToInstructionIndex(); | |
| 174 if (pos.IsGapPosition()) { | |
| 175 os << 'g'; | |
| 176 } else { | |
| 177 os << 'i'; | |
| 178 } | |
| 179 if (pos.IsStart()) { | |
| 180 os << 's'; | |
| 181 } else { | |
| 182 os << 'e'; | |
| 183 } | |
| 184 return os; | |
| 185 } | |
| 186 #endif | |
| 187 | |
| 188 | |
| 156 // Representation of the non-empty interval [start,end[. | 189 // Representation of the non-empty interval [start,end[. |
| 157 class UseInterval final : public ZoneObject { | 190 class UseInterval final : public ZoneObject { |
| 158 public: | 191 public: |
| 159 UseInterval(LifetimePosition start, LifetimePosition end) | 192 UseInterval(LifetimePosition start, LifetimePosition end) |
| 160 : start_(start), end_(end), next_(nullptr) { | 193 : start_(start), end_(end), next_(nullptr) { |
| 161 DCHECK(start < end); | 194 DCHECK(start < end); |
| 162 } | 195 } |
| 163 | 196 |
| 164 LifetimePosition start() const { return start_; } | 197 LifetimePosition start() const { return start_; } |
| 165 void set_start(LifetimePosition start) { start_ = start; } | 198 void set_start(LifetimePosition start) { start_ = start; } |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 565 | 598 |
| 566 // Creates a new live range. | 599 // Creates a new live range. |
| 567 LiveRange* NewLiveRange(int index); | 600 LiveRange* NewLiveRange(int index); |
| 568 | 601 |
| 569 void MarkAllocated(RegisterKind kind, int index); | 602 void MarkAllocated(RegisterKind kind, int index); |
| 570 | 603 |
| 571 PhiMapValue* InitializePhiMap(const InstructionBlock* block, | 604 PhiMapValue* InitializePhiMap(const InstructionBlock* block, |
| 572 PhiInstruction* phi); | 605 PhiInstruction* phi); |
| 573 PhiMapValue* GetPhiMapValueFor(int virtual_register); | 606 PhiMapValue* GetPhiMapValueFor(int virtual_register); |
| 574 | 607 |
| 608 #ifdef DEBUG | |
| 609 void Print(LiveRange* range); | |
|
dcarney
2015/04/29 17:24:13
these we don't do in v8. you'll need a local pat
Mircea Trofin
2015/04/29 17:35:33
I see. So do we have an ostream available in gdb,
| |
| 610 void Print(ZoneSet<LiveRange*>& conflicts); | |
| 611 void Print(InstructionSequence* code); | |
| 612 void Print(Instruction* instr); | |
| 613 void Print(InstructionSequence* code, InstructionBlock* block); | |
| 614 void PrintOperators(LiveRange* range); | |
| 615 void Print(LifetimePosition pos); | |
| 616 #endif | |
| 617 | |
| 575 private: | 618 private: |
| 576 Zone* const allocation_zone_; | 619 Zone* const allocation_zone_; |
| 577 Frame* const frame_; | 620 Frame* const frame_; |
| 578 InstructionSequence* const code_; | 621 InstructionSequence* const code_; |
| 579 const char* const debug_name_; | 622 const char* const debug_name_; |
| 580 const RegisterConfiguration* const config_; | 623 const RegisterConfiguration* const config_; |
| 581 PhiMap phi_map_; | 624 PhiMap phi_map_; |
| 582 ZoneVector<BitVector*> live_in_sets_; | 625 ZoneVector<BitVector*> live_in_sets_; |
| 583 ZoneVector<LiveRange*> live_ranges_; | 626 ZoneVector<LiveRange*> live_ranges_; |
| 584 ZoneVector<LiveRange*> fixed_live_ranges_; | 627 ZoneVector<LiveRange*> fixed_live_ranges_; |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 812 // http://blog.llvm.org/2011/09/greedy-register-allocation-in-llvm-30.html | 855 // http://blog.llvm.org/2011/09/greedy-register-allocation-in-llvm-30.html |
| 813 class GreedyAllocator final : public RegisterAllocator { | 856 class GreedyAllocator final : public RegisterAllocator { |
| 814 public: | 857 public: |
| 815 explicit GreedyAllocator(RegisterAllocationData* data, RegisterKind kind, | 858 explicit GreedyAllocator(RegisterAllocationData* data, RegisterKind kind, |
| 816 Zone* local_zone); | 859 Zone* local_zone); |
| 817 | 860 |
| 818 void AllocateRegisters(); | 861 void AllocateRegisters(); |
| 819 | 862 |
| 820 private: | 863 private: |
| 821 const RegisterConfiguration* config() const { return data()->config(); } | 864 const RegisterConfiguration* config() const { return data()->config(); } |
| 865 bool TryReuseSpillForPhi(LiveRange* range); | |
| 866 int GetHintedRegister(LiveRange* range); | |
| 822 | 867 |
| 823 typedef ZonePriorityQueue<std::pair<unsigned, LiveRange*>> PQueue; | 868 typedef ZonePriorityQueue<std::pair<unsigned, LiveRange*>> PQueue; |
| 824 | 869 |
| 825 unsigned GetLiveRangeSize(LiveRange* range); | 870 unsigned GetLiveRangeSize(LiveRange* range); |
| 826 void Enqueue(LiveRange* range); | 871 void Enqueue(LiveRange* range); |
| 827 | 872 |
| 828 void Evict(LiveRange* range); | 873 void Evict(LiveRange* range); |
| 829 float CalculateSpillWeight(LiveRange* range); | 874 float CalculateSpillWeight(LiveRange* range); |
| 830 float CalculateMaxSpillWeight(const ZoneSet<LiveRange*>& ranges); | 875 float CalculateMaxSpillWeight(const ZoneSet<LiveRange*>& ranges); |
| 831 | 876 |
| 832 | 877 |
| 833 bool TryAllocate(LiveRange* current, ZoneSet<LiveRange*>* conflicting); | 878 bool TryAllocate(LiveRange* current, ZoneSet<LiveRange*>* conflicting); |
| 834 bool TryAllocatePhysicalRegister(unsigned reg_id, LiveRange* range, | 879 bool TryAllocatePhysicalRegister(unsigned reg_id, LiveRange* range, |
| 835 ZoneSet<LiveRange*>* conflicting); | 880 ZoneSet<LiveRange*>* conflicting); |
| 836 bool HandleSpillOperands(LiveRange* range); | 881 bool HandleSpillOperands(LiveRange* range); |
| 837 bool AllocateBlockedRange(LiveRange*, const ZoneSet<LiveRange*>&); | 882 void AllocateBlockedRange(LiveRange* current, LifetimePosition pos, |
| 883 bool spill); | |
| 838 | 884 |
| 839 LiveRange* SpillBetweenUntil(LiveRange* range, LifetimePosition start, | 885 LiveRange* SpillBetweenUntil(LiveRange* range, LifetimePosition start, |
| 840 LifetimePosition until, LifetimePosition end); | 886 LifetimePosition until, LifetimePosition end); |
| 841 void AssignRangeToRegister(int reg_id, LiveRange* range); | 887 void AssignRangeToRegister(int reg_id, LiveRange* range); |
| 842 | 888 |
| 889 LifetimePosition FindProgressingSplitPosition(LiveRange* range, | |
| 890 bool* is_spill_pos); | |
| 891 | |
| 843 ZoneVector<CoallescedLiveRanges*> allocations_; | 892 ZoneVector<CoallescedLiveRanges*> allocations_; |
| 844 PQueue queue_; | 893 PQueue queue_; |
| 845 DISALLOW_COPY_AND_ASSIGN(GreedyAllocator); | 894 DISALLOW_COPY_AND_ASSIGN(GreedyAllocator); |
| 846 }; | 895 }; |
| 847 | 896 |
| 848 | 897 |
| 849 class OperandAssigner final : public ZoneObject { | 898 class OperandAssigner final : public ZoneObject { |
| 850 public: | 899 public: |
| 851 explicit OperandAssigner(RegisterAllocationData* data); | 900 explicit OperandAssigner(RegisterAllocationData* data); |
| 852 | 901 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 902 void ResolveControlFlow(const InstructionBlock* block, | 951 void ResolveControlFlow(const InstructionBlock* block, |
| 903 const InstructionOperand& cur_op, | 952 const InstructionOperand& cur_op, |
| 904 const InstructionBlock* pred, | 953 const InstructionBlock* pred, |
| 905 const InstructionOperand& pred_op); | 954 const InstructionOperand& pred_op); |
| 906 | 955 |
| 907 RegisterAllocationData* const data_; | 956 RegisterAllocationData* const data_; |
| 908 | 957 |
| 909 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); | 958 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); |
| 910 }; | 959 }; |
| 911 | 960 |
| 961 | |
| 912 } // namespace compiler | 962 } // namespace compiler |
| 913 } // namespace internal | 963 } // namespace internal |
| 914 } // namespace v8 | 964 } // namespace v8 |
| 915 | 965 |
| 916 #endif // V8_REGISTER_ALLOCATOR_H_ | 966 #endif // V8_REGISTER_ALLOCATOR_H_ |
| OLD | NEW |