| 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 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 explicit LifetimePosition(int value) : value_(value) {} | 98 explicit LifetimePosition(int value) : value_(value) {} |
| 99 | 99 |
| 100 int value_; | 100 int value_; |
| 101 }; | 101 }; |
| 102 | 102 |
| 103 | 103 |
| 104 // Representation of the non-empty interval [start,end[. | 104 // Representation of the non-empty interval [start,end[. |
| 105 class UseInterval FINAL : public ZoneObject { | 105 class UseInterval FINAL : public ZoneObject { |
| 106 public: | 106 public: |
| 107 UseInterval(LifetimePosition start, LifetimePosition end) | 107 UseInterval(LifetimePosition start, LifetimePosition end) |
| 108 : start_(start), end_(end), next_(NULL) { | 108 : start_(start), end_(end), next_(nullptr) { |
| 109 DCHECK(start.Value() < end.Value()); | 109 DCHECK(start.Value() < end.Value()); |
| 110 } | 110 } |
| 111 | 111 |
| 112 LifetimePosition start() const { return start_; } | 112 LifetimePosition start() const { return start_; } |
| 113 LifetimePosition end() const { return end_; } | 113 LifetimePosition end() const { return end_; } |
| 114 UseInterval* next() const { return next_; } | 114 UseInterval* next() const { return next_; } |
| 115 | 115 |
| 116 // Split this interval at the given position without effecting the | 116 // Split this interval at the given position without effecting the |
| 117 // live range that owns it. The interval must contain the position. | 117 // live range that owns it. The interval must contain the position. |
| 118 void SplitAt(LifetimePosition pos, Zone* zone); | 118 void SplitAt(LifetimePosition pos, Zone* zone); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 141 }; | 141 }; |
| 142 | 142 |
| 143 | 143 |
| 144 // Representation of a use position. | 144 // Representation of a use position. |
| 145 class UsePosition FINAL : public ZoneObject { | 145 class UsePosition FINAL : public ZoneObject { |
| 146 public: | 146 public: |
| 147 UsePosition(LifetimePosition pos, InstructionOperand* operand, | 147 UsePosition(LifetimePosition pos, InstructionOperand* operand, |
| 148 InstructionOperand* hint); | 148 InstructionOperand* hint); |
| 149 | 149 |
| 150 InstructionOperand* operand() const { return operand_; } | 150 InstructionOperand* operand() const { return operand_; } |
| 151 bool HasOperand() const { return operand_ != NULL; } | 151 bool HasOperand() const { return operand_ != nullptr; } |
| 152 | 152 |
| 153 InstructionOperand* hint() const { return hint_; } | 153 InstructionOperand* hint() const { return hint_; } |
| 154 bool HasHint() const; | 154 bool HasHint() const; |
| 155 bool RequiresRegister() const; | 155 bool RequiresRegister() const; |
| 156 bool RegisterIsBeneficial() const; | 156 bool RegisterIsBeneficial() const; |
| 157 | 157 |
| 158 LifetimePosition pos() const { return pos_; } | 158 LifetimePosition pos() const { return pos_; } |
| 159 UsePosition* next() const { return next_; } | 159 UsePosition* next() const { return next_; } |
| 160 | 160 |
| 161 void set_next(UsePosition* next) { next_ = next; } | 161 void set_next(UsePosition* next) { next_ = next; } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 177 // intervals over the instruction ordering. | 177 // intervals over the instruction ordering. |
| 178 class LiveRange FINAL : public ZoneObject { | 178 class LiveRange FINAL : public ZoneObject { |
| 179 public: | 179 public: |
| 180 static const int kInvalidAssignment = 0x7fffffff; | 180 static const int kInvalidAssignment = 0x7fffffff; |
| 181 | 181 |
| 182 LiveRange(int id, Zone* zone); | 182 LiveRange(int id, Zone* zone); |
| 183 | 183 |
| 184 UseInterval* first_interval() const { return first_interval_; } | 184 UseInterval* first_interval() const { return first_interval_; } |
| 185 UsePosition* first_pos() const { return first_pos_; } | 185 UsePosition* first_pos() const { return first_pos_; } |
| 186 LiveRange* parent() const { return parent_; } | 186 LiveRange* parent() const { return parent_; } |
| 187 LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; } | 187 LiveRange* TopLevel() { return (parent_ == nullptr) ? this : parent_; } |
| 188 const LiveRange* TopLevel() const { | 188 const LiveRange* TopLevel() const { |
| 189 return (parent_ == NULL) ? this : parent_; | 189 return (parent_ == nullptr) ? this : parent_; |
| 190 } | 190 } |
| 191 LiveRange* next() const { return next_; } | 191 LiveRange* next() const { return next_; } |
| 192 bool IsChild() const { return parent() != NULL; } | 192 bool IsChild() const { return parent() != nullptr; } |
| 193 int id() const { return id_; } | 193 int id() const { return id_; } |
| 194 bool IsFixed() const { return id_ < 0; } | 194 bool IsFixed() const { return id_ < 0; } |
| 195 bool IsEmpty() const { return first_interval() == NULL; } | 195 bool IsEmpty() const { return first_interval() == nullptr; } |
| 196 InstructionOperand* CreateAssignedOperand(Zone* zone) const; | 196 InstructionOperand* CreateAssignedOperand(Zone* zone) const; |
| 197 int assigned_register() const { return assigned_register_; } | 197 int assigned_register() const { return assigned_register_; } |
| 198 int spill_start_index() const { return spill_start_index_; } | 198 int spill_start_index() const { return spill_start_index_; } |
| 199 void set_assigned_register(int reg); | 199 void set_assigned_register(int reg); |
| 200 void MakeSpilled(); | 200 void MakeSpilled(); |
| 201 bool is_phi() const { return is_phi_; } | 201 bool is_phi() const { return is_phi_; } |
| 202 void set_is_phi(bool is_phi) { is_phi_ = is_phi; } | 202 void set_is_phi(bool is_phi) { is_phi_ = is_phi; } |
| 203 bool is_non_loop_phi() const { return is_non_loop_phi_; } | 203 bool is_non_loop_phi() const { return is_non_loop_phi_; } |
| 204 void set_is_non_loop_phi(bool is_non_loop_phi) { | 204 void set_is_non_loop_phi(bool is_non_loop_phi) { |
| 205 is_non_loop_phi_ = is_non_loop_phi; | 205 is_non_loop_phi_ = is_non_loop_phi; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 return assigned_register_ != kInvalidAssignment; | 238 return assigned_register_ != kInvalidAssignment; |
| 239 } | 239 } |
| 240 bool IsSpilled() const { return spilled_; } | 240 bool IsSpilled() const { return spilled_; } |
| 241 | 241 |
| 242 InstructionOperand* current_hint_operand() const { | 242 InstructionOperand* current_hint_operand() const { |
| 243 DCHECK(current_hint_operand_ == FirstHint()); | 243 DCHECK(current_hint_operand_ == FirstHint()); |
| 244 return current_hint_operand_; | 244 return current_hint_operand_; |
| 245 } | 245 } |
| 246 InstructionOperand* FirstHint() const { | 246 InstructionOperand* FirstHint() const { |
| 247 UsePosition* pos = first_pos_; | 247 UsePosition* pos = first_pos_; |
| 248 while (pos != NULL && !pos->HasHint()) pos = pos->next(); | 248 while (pos != nullptr && !pos->HasHint()) pos = pos->next(); |
| 249 if (pos != NULL) return pos->hint(); | 249 if (pos != nullptr) return pos->hint(); |
| 250 return NULL; | 250 return nullptr; |
| 251 } | 251 } |
| 252 | 252 |
| 253 LifetimePosition Start() const { | 253 LifetimePosition Start() const { |
| 254 DCHECK(!IsEmpty()); | 254 DCHECK(!IsEmpty()); |
| 255 return first_interval()->start(); | 255 return first_interval()->start(); |
| 256 } | 256 } |
| 257 | 257 |
| 258 LifetimePosition End() const { | 258 LifetimePosition End() const { |
| 259 DCHECK(!IsEmpty()); | 259 DCHECK(!IsEmpty()); |
| 260 return last_interval_->end(); | 260 return last_interval_->end(); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 SpillRange* spill_range_; | 338 SpillRange* spill_range_; |
| 339 }; | 339 }; |
| 340 SpillAtDefinitionList* spills_at_definition_; | 340 SpillAtDefinitionList* spills_at_definition_; |
| 341 | 341 |
| 342 friend class RegisterAllocator; // Assigns to kind_. | 342 friend class RegisterAllocator; // Assigns to kind_. |
| 343 | 343 |
| 344 DISALLOW_COPY_AND_ASSIGN(LiveRange); | 344 DISALLOW_COPY_AND_ASSIGN(LiveRange); |
| 345 }; | 345 }; |
| 346 | 346 |
| 347 | 347 |
| 348 class SpillRange : public ZoneObject { | 348 class SpillRange FINAL : public ZoneObject { |
| 349 public: | 349 public: |
| 350 SpillRange(LiveRange* range, int id, Zone* zone); | 350 SpillRange(LiveRange* range, Zone* zone); |
| 351 bool TryMerge(SpillRange* other, Zone* zone); | 351 |
| 352 UseInterval* interval() const { return use_interval_; } |
| 353 RegisterKind Kind() const { return live_ranges_[0]->Kind(); } |
| 354 bool IsEmpty() const { return live_ranges_.empty(); } |
| 355 bool TryMerge(SpillRange* other); |
| 352 void SetOperand(InstructionOperand* op); | 356 void SetOperand(InstructionOperand* op); |
| 353 bool IsEmpty() { return live_ranges_.length() == 0; } | |
| 354 int id() const { return id_; } | |
| 355 UseInterval* interval() { return use_interval_; } | |
| 356 RegisterKind Kind() const { return live_ranges_.at(0)->Kind(); } | |
| 357 LifetimePosition End() const { return end_position_; } | |
| 358 bool IsIntersectingWith(SpillRange* other); | |
| 359 | 357 |
| 360 private: | 358 private: |
| 361 int id_; | 359 LifetimePosition End() const { return end_position_; } |
| 362 ZoneList<LiveRange*> live_ranges_; | 360 ZoneVector<LiveRange*>& live_ranges() { return live_ranges_; } |
| 361 bool IsIntersectingWith(SpillRange* other) const; |
| 362 // Merge intervals, making sure the use intervals are sorted |
| 363 void MergeDisjointIntervals(UseInterval* other); |
| 364 |
| 365 ZoneVector<LiveRange*> live_ranges_; |
| 363 UseInterval* use_interval_; | 366 UseInterval* use_interval_; |
| 364 LifetimePosition end_position_; | 367 LifetimePosition end_position_; |
| 365 | 368 |
| 366 // Merge intervals, making sure the use intervals are sorted | 369 DISALLOW_COPY_AND_ASSIGN(SpillRange); |
| 367 void MergeDisjointIntervals(UseInterval* other, Zone* zone); | |
| 368 }; | 370 }; |
| 369 | 371 |
| 370 | 372 |
| 371 class RegisterAllocator FINAL : public ZoneObject { | 373 class RegisterAllocator FINAL : public ZoneObject { |
| 372 public: | 374 public: |
| 373 explicit RegisterAllocator(const RegisterConfiguration* config, | 375 explicit RegisterAllocator(const RegisterConfiguration* config, |
| 374 Zone* local_zone, Frame* frame, | 376 Zone* local_zone, Frame* frame, |
| 375 InstructionSequence* code, | 377 InstructionSequence* code, |
| 376 const char* debug_name = nullptr); | 378 const char* debug_name = nullptr); |
| 377 | 379 |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 631 #endif | 633 #endif |
| 632 | 634 |
| 633 DISALLOW_COPY_AND_ASSIGN(RegisterAllocator); | 635 DISALLOW_COPY_AND_ASSIGN(RegisterAllocator); |
| 634 }; | 636 }; |
| 635 | 637 |
| 636 } // namespace compiler | 638 } // namespace compiler |
| 637 } // namespace internal | 639 } // namespace internal |
| 638 } // namespace v8 | 640 } // namespace v8 |
| 639 | 641 |
| 640 #endif // V8_REGISTER_ALLOCATOR_H_ | 642 #endif // V8_REGISTER_ALLOCATOR_H_ |
| OLD | NEW |