| 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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 | 134 |
| 135 LifetimePosition start_; | 135 LifetimePosition start_; |
| 136 LifetimePosition end_; | 136 LifetimePosition end_; |
| 137 UseInterval* next_; | 137 UseInterval* next_; |
| 138 | 138 |
| 139 private: | 139 private: |
| 140 DISALLOW_COPY_AND_ASSIGN(UseInterval); | 140 DISALLOW_COPY_AND_ASSIGN(UseInterval); |
| 141 }; | 141 }; |
| 142 | 142 |
| 143 | 143 |
| 144 enum class UsePositionType : uint8_t { kAny, kRequiresRegister, kRequiresSlot }; |
| 145 |
| 146 |
| 144 // Representation of a use position. | 147 // Representation of a use position. |
| 145 class UsePosition FINAL : public ZoneObject { | 148 class UsePosition FINAL : public ZoneObject { |
| 146 public: | 149 public: |
| 147 UsePosition(LifetimePosition pos, InstructionOperand* operand, | 150 UsePosition(LifetimePosition pos, InstructionOperand* operand, |
| 148 InstructionOperand* hint); | 151 InstructionOperand* hint); |
| 149 | 152 |
| 150 InstructionOperand* operand() const { return operand_; } | 153 InstructionOperand* operand() const { return operand_; } |
| 151 bool HasOperand() const { return operand_ != nullptr; } | 154 bool HasOperand() const { return operand_ != nullptr; } |
| 152 | 155 |
| 153 InstructionOperand* hint() const { return hint_; } | 156 InstructionOperand* hint() const { return hint_; } |
| 154 bool HasHint() const; | 157 bool HasHint() const; |
| 155 bool RequiresRegister() const; | 158 bool RegisterIsBeneficial() const { |
| 156 bool RegisterIsBeneficial() const; | 159 return RegisterBeneficialField::decode(flags_); |
| 160 } |
| 161 UsePositionType type() const { return TypeField::decode(flags_); } |
| 157 | 162 |
| 158 LifetimePosition pos() const { return pos_; } | 163 LifetimePosition pos() const { return pos_; } |
| 159 UsePosition* next() const { return next_; } | 164 UsePosition* next() const { return next_; } |
| 160 | 165 |
| 161 void set_next(UsePosition* next) { next_ = next; } | 166 void set_next(UsePosition* next) { next_ = next; } |
| 167 void set_type(UsePositionType type, bool register_beneficial); |
| 162 | 168 |
| 163 InstructionOperand* const operand_; | 169 InstructionOperand* const operand_; |
| 164 InstructionOperand* const hint_; | 170 InstructionOperand* const hint_; |
| 165 LifetimePosition const pos_; | 171 LifetimePosition const pos_; |
| 166 UsePosition* next_; | 172 UsePosition* next_; |
| 167 bool requires_reg_ : 1; | |
| 168 bool register_beneficial_ : 1; | |
| 169 | 173 |
| 170 private: | 174 private: |
| 175 typedef BitField8<UsePositionType, 0, 2> TypeField; |
| 176 typedef BitField8<bool, 2, 1> RegisterBeneficialField; |
| 177 uint8_t flags_; |
| 178 |
| 171 DISALLOW_COPY_AND_ASSIGN(UsePosition); | 179 DISALLOW_COPY_AND_ASSIGN(UsePosition); |
| 172 }; | 180 }; |
| 173 | 181 |
| 174 class SpillRange; | 182 class SpillRange; |
| 175 | 183 |
| 176 | 184 |
| 177 // TODO(dcarney): remove this cache. | 185 // TODO(dcarney): remove this cache. |
| 178 class InstructionOperandCache FINAL : public ZoneObject { | 186 class InstructionOperandCache FINAL : public ZoneObject { |
| 179 public: | 187 public: |
| 180 InstructionOperandCache(); | 188 InstructionOperandCache(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 int assigned_register() const { return assigned_register_; } | 234 int assigned_register() const { return assigned_register_; } |
| 227 int spill_start_index() const { return spill_start_index_; } | 235 int spill_start_index() const { return spill_start_index_; } |
| 228 void set_assigned_register(int reg, InstructionOperandCache* cache); | 236 void set_assigned_register(int reg, InstructionOperandCache* cache); |
| 229 void MakeSpilled(); | 237 void MakeSpilled(); |
| 230 bool is_phi() const { return is_phi_; } | 238 bool is_phi() const { return is_phi_; } |
| 231 void set_is_phi(bool is_phi) { is_phi_ = is_phi; } | 239 void set_is_phi(bool is_phi) { is_phi_ = is_phi; } |
| 232 bool is_non_loop_phi() const { return is_non_loop_phi_; } | 240 bool is_non_loop_phi() const { return is_non_loop_phi_; } |
| 233 void set_is_non_loop_phi(bool is_non_loop_phi) { | 241 void set_is_non_loop_phi(bool is_non_loop_phi) { |
| 234 is_non_loop_phi_ = is_non_loop_phi; | 242 is_non_loop_phi_ = is_non_loop_phi; |
| 235 } | 243 } |
| 244 bool has_slot_use() const { return has_slot_use_; } |
| 245 void set_has_slot_use(bool has_slot_use) { has_slot_use_ = has_slot_use; } |
| 236 | 246 |
| 237 // Returns use position in this live range that follows both start | 247 // Returns use position in this live range that follows both start |
| 238 // and last processed use position. | 248 // and last processed use position. |
| 239 // Modifies internal state of live range! | 249 // Modifies internal state of live range! |
| 240 UsePosition* NextUsePosition(LifetimePosition start); | 250 UsePosition* NextUsePosition(LifetimePosition start); |
| 241 | 251 |
| 242 // Returns use position for which register is required in this live | 252 // Returns use position for which register is required in this live |
| 243 // range and which follows both start and last processed use position | 253 // range and which follows both start and last processed use position |
| 244 // Modifies internal state of live range! | 254 // Modifies internal state of live range! |
| 245 UsePosition* NextRegisterPosition(LifetimePosition start); | 255 UsePosition* NextRegisterPosition(LifetimePosition start); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 return spill_type_ == SpillType::kSpillOperand; | 312 return spill_type_ == SpillType::kSpillOperand; |
| 303 } | 313 } |
| 304 bool HasSpillRange() const { return spill_type_ == SpillType::kSpillRange; } | 314 bool HasSpillRange() const { return spill_type_ == SpillType::kSpillRange; } |
| 305 | 315 |
| 306 void SpillAtDefinition(Zone* zone, int gap_index, | 316 void SpillAtDefinition(Zone* zone, int gap_index, |
| 307 InstructionOperand* operand); | 317 InstructionOperand* operand); |
| 308 void SetSpillOperand(InstructionOperand* operand); | 318 void SetSpillOperand(InstructionOperand* operand); |
| 309 void SetSpillRange(SpillRange* spill_range); | 319 void SetSpillRange(SpillRange* spill_range); |
| 310 void CommitSpillOperand(InstructionOperand* operand); | 320 void CommitSpillOperand(InstructionOperand* operand); |
| 311 void CommitSpillsAtDefinition(InstructionSequence* sequence, | 321 void CommitSpillsAtDefinition(InstructionSequence* sequence, |
| 312 InstructionOperand* operand); | 322 InstructionOperand* operand, |
| 323 bool might_be_duplicated); |
| 313 | 324 |
| 314 void SetSpillStartIndex(int start) { | 325 void SetSpillStartIndex(int start) { |
| 315 spill_start_index_ = Min(start, spill_start_index_); | 326 spill_start_index_ = Min(start, spill_start_index_); |
| 316 } | 327 } |
| 317 | 328 |
| 318 bool ShouldBeAllocatedBefore(const LiveRange* other) const; | 329 bool ShouldBeAllocatedBefore(const LiveRange* other) const; |
| 319 bool CanCover(LifetimePosition position) const; | 330 bool CanCover(LifetimePosition position) const; |
| 320 bool Covers(LifetimePosition position); | 331 bool Covers(LifetimePosition position); |
| 321 LifetimePosition FirstIntersection(LiveRange* other); | 332 LifetimePosition FirstIntersection(LiveRange* other); |
| 322 | 333 |
| 323 // Add a new interval or a new use position to this live range. | 334 // Add a new interval or a new use position to this live range. |
| 324 void EnsureInterval(LifetimePosition start, LifetimePosition end, Zone* zone); | 335 void EnsureInterval(LifetimePosition start, LifetimePosition end, Zone* zone); |
| 325 void AddUseInterval(LifetimePosition start, LifetimePosition end, Zone* zone); | 336 void AddUseInterval(LifetimePosition start, LifetimePosition end, Zone* zone); |
| 326 void AddUsePosition(LifetimePosition pos, InstructionOperand* operand, | 337 void AddUsePosition(LifetimePosition pos, InstructionOperand* operand, |
| 327 InstructionOperand* hint, Zone* zone); | 338 InstructionOperand* hint, Zone* zone); |
| 328 | 339 |
| 329 // Shorten the most recently added interval by setting a new start. | 340 // Shorten the most recently added interval by setting a new start. |
| 330 void ShortenTo(LifetimePosition start); | 341 void ShortenTo(LifetimePosition start); |
| 331 | 342 |
| 332 #ifdef DEBUG | 343 #ifdef DEBUG |
| 333 // True if target overlaps an existing interval. | 344 // True if target overlaps an existing interval. |
| 334 bool HasOverlap(UseInterval* target) const; | 345 bool HasOverlap(UseInterval* target) const; |
| 335 void Verify() const; | 346 void Verify() const; |
| 336 #endif | 347 #endif |
| 337 | 348 |
| 338 private: | 349 private: |
| 339 struct SpillAtDefinitionList; | 350 struct SpillAtDefinitionList; |
| 340 | 351 |
| 341 void ConvertUsesToOperand(InstructionOperand* op); | 352 void ConvertUsesToOperand(InstructionOperand* op, |
| 353 InstructionOperand* spill_op); |
| 342 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; | 354 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; |
| 343 void AdvanceLastProcessedMarker(UseInterval* to_start_of, | 355 void AdvanceLastProcessedMarker(UseInterval* to_start_of, |
| 344 LifetimePosition but_not_past) const; | 356 LifetimePosition but_not_past) const; |
| 345 | 357 |
| 346 // TODO(dcarney): pack this structure better. | 358 // TODO(dcarney): pack this structure better. |
| 347 int id_; | 359 int id_; |
| 348 bool spilled_; | 360 bool spilled_ : 1; |
| 349 bool is_phi_; | 361 bool has_slot_use_ : 1; // Relevant only for parent. |
| 350 bool is_non_loop_phi_; | 362 bool is_phi_ : 1; |
| 363 bool is_non_loop_phi_ : 1; |
| 351 RegisterKind kind_; | 364 RegisterKind kind_; |
| 352 int assigned_register_; | 365 int assigned_register_; |
| 353 UseInterval* last_interval_; | 366 UseInterval* last_interval_; |
| 354 UseInterval* first_interval_; | 367 UseInterval* first_interval_; |
| 355 UsePosition* first_pos_; | 368 UsePosition* first_pos_; |
| 356 LiveRange* parent_; | 369 LiveRange* parent_; |
| 357 LiveRange* next_; | 370 LiveRange* next_; |
| 358 // This is used as a cache, it doesn't affect correctness. | 371 // This is used as a cache, it doesn't affect correctness. |
| 359 mutable UseInterval* current_interval_; | 372 mutable UseInterval* current_interval_; |
| 360 UsePosition* last_processed_use_; | 373 UsePosition* last_processed_use_; |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 #endif | 654 #endif |
| 642 | 655 |
| 643 DISALLOW_COPY_AND_ASSIGN(RegisterAllocator); | 656 DISALLOW_COPY_AND_ASSIGN(RegisterAllocator); |
| 644 }; | 657 }; |
| 645 | 658 |
| 646 } // namespace compiler | 659 } // namespace compiler |
| 647 } // namespace internal | 660 } // namespace internal |
| 648 } // namespace v8 | 661 } // namespace v8 |
| 649 | 662 |
| 650 #endif // V8_REGISTER_ALLOCATOR_H_ | 663 #endif // V8_REGISTER_ALLOCATOR_H_ |
| OLD | NEW |