| 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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 | 131 |
| 132 // Representation of the non-empty interval [start,end[. | 132 // Representation of the non-empty interval [start,end[. |
| 133 class UseInterval final : public ZoneObject { | 133 class UseInterval final : public ZoneObject { |
| 134 public: | 134 public: |
| 135 UseInterval(LifetimePosition start, LifetimePosition end) | 135 UseInterval(LifetimePosition start, LifetimePosition end) |
| 136 : start_(start), end_(end), next_(nullptr) { | 136 : start_(start), end_(end), next_(nullptr) { |
| 137 DCHECK(start.Value() < end.Value()); | 137 DCHECK(start.Value() < end.Value()); |
| 138 } | 138 } |
| 139 | 139 |
| 140 LifetimePosition start() const { return start_; } | 140 LifetimePosition start() const { return start_; } |
| 141 void set_start(LifetimePosition start) { start_ = start; } |
| 141 LifetimePosition end() const { return end_; } | 142 LifetimePosition end() const { return end_; } |
| 143 void set_end(LifetimePosition end) { end_ = end; } |
| 142 UseInterval* next() const { return next_; } | 144 UseInterval* next() const { return next_; } |
| 145 void set_next(UseInterval* next) { next_ = next; } |
| 143 | 146 |
| 144 // Split this interval at the given position without effecting the | 147 // Split this interval at the given position without effecting the |
| 145 // live range that owns it. The interval must contain the position. | 148 // live range that owns it. The interval must contain the position. |
| 146 void SplitAt(LifetimePosition pos, Zone* zone); | 149 void SplitAt(LifetimePosition pos, Zone* zone); |
| 147 | 150 |
| 148 // If this interval intersects with other return smallest position | 151 // If this interval intersects with other return smallest position |
| 149 // that belongs to both of them. | 152 // that belongs to both of them. |
| 150 LifetimePosition Intersect(const UseInterval* other) const { | 153 LifetimePosition Intersect(const UseInterval* other) const { |
| 151 if (other->start().Value() < start_.Value()) return other->Intersect(this); | 154 if (other->start().Value() < start_.Value()) return other->Intersect(this); |
| 152 if (other->start().Value() < end_.Value()) return other->start(); | 155 if (other->start().Value() < end_.Value()) return other->start(); |
| 153 return LifetimePosition::Invalid(); | 156 return LifetimePosition::Invalid(); |
| 154 } | 157 } |
| 155 | 158 |
| 156 bool Contains(LifetimePosition point) const { | 159 bool Contains(LifetimePosition point) const { |
| 157 return start_.Value() <= point.Value() && point.Value() < end_.Value(); | 160 return start_.Value() <= point.Value() && point.Value() < end_.Value(); |
| 158 } | 161 } |
| 159 | 162 |
| 160 void set_start(LifetimePosition start) { start_ = start; } | 163 private: |
| 161 void set_next(UseInterval* next) { next_ = next; } | |
| 162 | |
| 163 LifetimePosition start_; | 164 LifetimePosition start_; |
| 164 LifetimePosition end_; | 165 LifetimePosition end_; |
| 165 UseInterval* next_; | 166 UseInterval* next_; |
| 166 | 167 |
| 167 private: | |
| 168 DISALLOW_COPY_AND_ASSIGN(UseInterval); | 168 DISALLOW_COPY_AND_ASSIGN(UseInterval); |
| 169 }; | 169 }; |
| 170 | 170 |
| 171 | 171 |
| 172 enum class UsePositionType : uint8_t { kAny, kRequiresRegister, kRequiresSlot }; | 172 enum class UsePositionType : uint8_t { kAny, kRequiresRegister, kRequiresSlot }; |
| 173 | 173 |
| 174 | 174 |
| 175 // Representation of a use position. | 175 // Representation of a use position. |
| 176 class UsePosition final : public ZoneObject { | 176 class UsePosition final : public ZoneObject { |
| 177 public: | 177 public: |
| 178 UsePosition(LifetimePosition pos, InstructionOperand* operand, | 178 UsePosition(LifetimePosition pos, InstructionOperand* operand, |
| 179 InstructionOperand* hint); | 179 InstructionOperand* hint); |
| 180 | 180 |
| 181 InstructionOperand* operand() const { return operand_; } | 181 InstructionOperand* operand() const { return operand_; } |
| 182 bool HasOperand() const { return operand_ != nullptr; } | 182 bool HasOperand() const { return operand_ != nullptr; } |
| 183 | 183 |
| 184 InstructionOperand* hint() const { return hint_; } | 184 InstructionOperand* hint() const { return hint_; } |
| 185 bool HasHint() const; | 185 bool HasHint() const; |
| 186 bool RegisterIsBeneficial() const { | 186 bool RegisterIsBeneficial() const { |
| 187 return RegisterBeneficialField::decode(flags_); | 187 return RegisterBeneficialField::decode(flags_); |
| 188 } | 188 } |
| 189 UsePositionType type() const { return TypeField::decode(flags_); } | 189 UsePositionType type() const { return TypeField::decode(flags_); } |
| 190 | 190 |
| 191 LifetimePosition pos() const { return pos_; } | 191 LifetimePosition pos() const { return pos_; } |
| 192 UsePosition* next() const { return next_; } | 192 UsePosition* next() const { return next_; } |
| 193 | 193 |
| 194 void set_next(UsePosition* next) { next_ = next; } | 194 void set_next(UsePosition* next) { next_ = next; } |
| 195 void set_type(UsePositionType type, bool register_beneficial); | 195 void set_type(UsePositionType type, bool register_beneficial); |
| 196 | 196 |
| 197 private: |
| 198 typedef BitField8<UsePositionType, 0, 2> TypeField; |
| 199 typedef BitField8<bool, 2, 1> RegisterBeneficialField; |
| 200 |
| 197 InstructionOperand* const operand_; | 201 InstructionOperand* const operand_; |
| 198 InstructionOperand* const hint_; | 202 InstructionOperand* const hint_; |
| 199 LifetimePosition const pos_; | 203 LifetimePosition const pos_; |
| 200 UsePosition* next_; | 204 UsePosition* next_; |
| 201 | |
| 202 private: | |
| 203 typedef BitField8<UsePositionType, 0, 2> TypeField; | |
| 204 typedef BitField8<bool, 2, 1> RegisterBeneficialField; | |
| 205 uint8_t flags_; | 205 uint8_t flags_; |
| 206 | 206 |
| 207 DISALLOW_COPY_AND_ASSIGN(UsePosition); | 207 DISALLOW_COPY_AND_ASSIGN(UsePosition); |
| 208 }; | 208 }; |
| 209 | 209 |
| 210 class SpillRange; | 210 class SpillRange; |
| 211 | 211 |
| 212 | 212 |
| 213 // Representation of SSA values' live ranges as a collection of (continuous) | 213 // Representation of SSA values' live ranges as a collection of (continuous) |
| 214 // intervals over the instruction ordering. | 214 // intervals over the instruction ordering. |
| 215 class LiveRange final : public ZoneObject { | 215 class LiveRange final : public ZoneObject { |
| 216 public: | 216 public: |
| 217 static const int kInvalidAssignment = 0x7fffffff; | 217 static const int kInvalidAssignment = 0x7fffffff; |
| 218 | 218 |
| 219 LiveRange(int id, Zone* zone); | 219 explicit LiveRange(int id); |
| 220 | 220 |
| 221 UseInterval* first_interval() const { return first_interval_; } | 221 UseInterval* first_interval() const { return first_interval_; } |
| 222 UsePosition* first_pos() const { return first_pos_; } | 222 UsePosition* first_pos() const { return first_pos_; } |
| 223 LiveRange* parent() const { return parent_; } | 223 LiveRange* parent() const { return parent_; } |
| 224 LiveRange* TopLevel() { return (parent_ == nullptr) ? this : parent_; } | 224 LiveRange* TopLevel() { return (parent_ == nullptr) ? this : parent_; } |
| 225 const LiveRange* TopLevel() const { | 225 const LiveRange* TopLevel() const { |
| 226 return (parent_ == nullptr) ? this : parent_; | 226 return (parent_ == nullptr) ? this : parent_; |
| 227 } | 227 } |
| 228 LiveRange* next() const { return next_; } | 228 LiveRange* next() const { return next_; } |
| 229 bool IsChild() const { return parent() != nullptr; } | 229 bool IsChild() const { return parent() != nullptr; } |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 } | 295 } |
| 296 | 296 |
| 297 LifetimePosition End() const { | 297 LifetimePosition End() const { |
| 298 DCHECK(!IsEmpty()); | 298 DCHECK(!IsEmpty()); |
| 299 return last_interval_->end(); | 299 return last_interval_->end(); |
| 300 } | 300 } |
| 301 | 301 |
| 302 enum class SpillType { kNoSpillType, kSpillOperand, kSpillRange }; | 302 enum class SpillType { kNoSpillType, kSpillOperand, kSpillRange }; |
| 303 SpillType spill_type() const { return spill_type_; } | 303 SpillType spill_type() const { return spill_type_; } |
| 304 InstructionOperand* GetSpillOperand() const { | 304 InstructionOperand* GetSpillOperand() const { |
| 305 return spill_type_ == SpillType::kSpillOperand ? spill_operand_ : nullptr; | 305 DCHECK(spill_type_ == SpillType::kSpillOperand); |
| 306 return spill_operand_; |
| 306 } | 307 } |
| 307 SpillRange* GetSpillRange() const { | 308 SpillRange* GetSpillRange() const { |
| 308 return spill_type_ == SpillType::kSpillRange ? spill_range_ : nullptr; | 309 DCHECK(spill_type_ == SpillType::kSpillRange); |
| 310 return spill_range_; |
| 309 } | 311 } |
| 310 bool HasNoSpillType() const { return spill_type_ == SpillType::kNoSpillType; } | 312 bool HasNoSpillType() const { return spill_type_ == SpillType::kNoSpillType; } |
| 311 bool HasSpillOperand() const { | 313 bool HasSpillOperand() const { |
| 312 return spill_type_ == SpillType::kSpillOperand; | 314 return spill_type_ == SpillType::kSpillOperand; |
| 313 } | 315 } |
| 314 bool HasSpillRange() const { return spill_type_ == SpillType::kSpillRange; } | 316 bool HasSpillRange() const { return spill_type_ == SpillType::kSpillRange; } |
| 315 | 317 |
| 316 void SpillAtDefinition(Zone* zone, int gap_index, | 318 void SpillAtDefinition(Zone* zone, int gap_index, |
| 317 InstructionOperand* operand); | 319 InstructionOperand* operand); |
| 318 void SetSpillOperand(InstructionOperand* operand); | 320 void SetSpillOperand(InstructionOperand* operand); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 // allocation. | 456 // allocation. |
| 455 Zone* code_zone() const { return code()->zone(); } | 457 Zone* code_zone() const { return code()->zone(); } |
| 456 const PhiMap& phi_map() const { return phi_map_; } | 458 const PhiMap& phi_map() const { return phi_map_; } |
| 457 PhiMap& phi_map() { return phi_map_; } | 459 PhiMap& phi_map() { return phi_map_; } |
| 458 Frame* frame() const { return frame_; } | 460 Frame* frame() const { return frame_; } |
| 459 const char* debug_name() const { return debug_name_; } | 461 const char* debug_name() const { return debug_name_; } |
| 460 const RegisterConfiguration* config() const { return config_; } | 462 const RegisterConfiguration* config() const { return config_; } |
| 461 | 463 |
| 462 void SetLiveRangeAssignedRegister(LiveRange* range, int reg); | 464 void SetLiveRangeAssignedRegister(LiveRange* range, int reg); |
| 463 LiveRange* LiveRangeFor(int index); | 465 LiveRange* LiveRangeFor(int index); |
| 464 Instruction* InstructionAt(int index) { return code()->InstructionAt(index); } | 466 Instruction* InstructionAt(int index) const { |
| 467 return code()->InstructionAt(index); |
| 468 } |
| 465 | 469 |
| 466 void AssignPhiInput(LiveRange* range, const InstructionOperand& assignment); | 470 void AssignPhiInput(LiveRange* range, const InstructionOperand& assignment); |
| 467 SpillRange* AssignSpillRangeToLiveRange(LiveRange* range); | 471 SpillRange* AssignSpillRangeToLiveRange(LiveRange* range); |
| 468 | 472 |
| 469 MoveOperands* AddGapMove(int index, Instruction::GapPosition position, | 473 MoveOperands* AddGapMove(int index, Instruction::GapPosition position, |
| 470 const InstructionOperand& from, | 474 const InstructionOperand& from, |
| 471 const InstructionOperand& to); | 475 const InstructionOperand& to); |
| 472 | 476 |
| 473 bool IsBlockBoundary(LifetimePosition pos) { | |
| 474 return pos.IsFullStart() && | |
| 475 code() | |
| 476 ->GetInstructionBlock(pos.ToInstructionIndex()) | |
| 477 ->code_start() == pos.ToInstructionIndex(); | |
| 478 } | |
| 479 | |
| 480 const InstructionBlock* GetInstructionBlock(LifetimePosition pos) const { | |
| 481 return code()->GetInstructionBlock(pos.ToInstructionIndex()); | |
| 482 } | |
| 483 | |
| 484 bool IsReference(int virtual_register) const { | 477 bool IsReference(int virtual_register) const { |
| 485 return code()->IsReference(virtual_register); | 478 return code()->IsReference(virtual_register); |
| 486 } | 479 } |
| 487 | 480 |
| 488 bool ExistsUseWithoutDefinition(); | 481 bool ExistsUseWithoutDefinition(); |
| 489 | 482 |
| 490 // Creates a new live range. | 483 // Creates a new live range. |
| 491 LiveRange* NewLiveRange(int index); | 484 LiveRange* NewLiveRange(int index); |
| 492 | 485 |
| 493 private: | 486 private: |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 InstructionOperand* operand, InstructionOperand* hint); | 575 InstructionOperand* operand, InstructionOperand* hint); |
| 583 | 576 |
| 584 RegisterAllocationData* const data_; | 577 RegisterAllocationData* const data_; |
| 585 | 578 |
| 586 DISALLOW_COPY_AND_ASSIGN(LiveRangeBuilder); | 579 DISALLOW_COPY_AND_ASSIGN(LiveRangeBuilder); |
| 587 }; | 580 }; |
| 588 | 581 |
| 589 | 582 |
| 590 class LinearScanAllocator final : public ZoneObject { | 583 class LinearScanAllocator final : public ZoneObject { |
| 591 public: | 584 public: |
| 592 explicit LinearScanAllocator(RegisterAllocationData* data, RegisterKind kind); | 585 LinearScanAllocator(RegisterAllocationData* data, RegisterKind kind, |
| 586 Zone* local_zone); |
| 593 | 587 |
| 594 // Phase 4: compute register assignments. | 588 // Phase 4: compute register assignments. |
| 595 void AllocateRegisters(); | 589 void AllocateRegisters(); |
| 596 | 590 |
| 597 private: | 591 private: |
| 598 RegisterAllocationData* data() const { return data_; } | 592 RegisterAllocationData* data() const { return data_; } |
| 599 InstructionSequence* code() const { return data()->code(); } | 593 InstructionSequence* code() const { return data()->code(); } |
| 600 Zone* allocation_zone() const { return data()->allocation_zone(); } | 594 Zone* allocation_zone() const { return data()->allocation_zone(); } |
| 601 Zone* code_zone() const { return code()->zone(); } | 595 Zone* code_zone() const { return code()->zone(); } |
| 602 const RegisterConfiguration* config() const { return data()->config(); } | 596 const RegisterConfiguration* config() const { return data()->config(); } |
| 597 int num_registers() const { return num_registers_; } |
| 598 const char* RegisterName(int allocation_index) const; |
| 599 |
| 600 ZoneVector<LiveRange*>& live_ranges() { return data()->live_ranges(); } |
| 601 ZoneVector<LiveRange*>& unhandled_live_ranges() { |
| 602 return unhandled_live_ranges_; |
| 603 } |
| 604 ZoneVector<LiveRange*>& active_live_ranges() { return active_live_ranges_; } |
| 605 ZoneVector<LiveRange*>& inactive_live_ranges() { |
| 606 return inactive_live_ranges_; |
| 607 } |
| 608 ZoneVector<SpillRange*>& spill_ranges() { return data()->spill_ranges(); } |
| 609 RegisterAllocationData::PhiMap& phi_map() { return data()->phi_map(); } |
| 603 | 610 |
| 604 Instruction* InstructionAt(int index) { return code()->InstructionAt(index); } | 611 Instruction* InstructionAt(int index) { return code()->InstructionAt(index); } |
| 605 | |
| 606 int GetVirtualRegister() { return code()->NextVirtualRegister(); } | |
| 607 | |
| 608 bool IsReference(int virtual_register) const { | 612 bool IsReference(int virtual_register) const { |
| 609 return data()->IsReference(virtual_register); | 613 return data()->IsReference(virtual_register); |
| 610 } | 614 } |
| 611 | |
| 612 LiveRange* LiveRangeFor(int index) { return data()->LiveRangeFor(index); } | 615 LiveRange* LiveRangeFor(int index) { return data()->LiveRangeFor(index); } |
| 613 | 616 |
| 614 // Helper methods for updating the life range lists. | 617 // Helper methods for updating the life range lists. |
| 615 void AddToActive(LiveRange* range); | 618 void AddToActive(LiveRange* range); |
| 616 void AddToInactive(LiveRange* range); | 619 void AddToInactive(LiveRange* range); |
| 617 void AddToUnhandledSorted(LiveRange* range); | 620 void AddToUnhandledSorted(LiveRange* range); |
| 618 void AddToUnhandledUnsorted(LiveRange* range); | 621 void AddToUnhandledUnsorted(LiveRange* range); |
| 619 void SortUnhandled(); | 622 void SortUnhandled(); |
| 620 bool UnhandledIsSorted(); | 623 bool UnhandledIsSorted(); |
| 621 void ActiveToHandled(LiveRange* range); | 624 void ActiveToHandled(LiveRange* range); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 641 // Split the given range in a position from the interval [start, end]. | 644 // Split the given range in a position from the interval [start, end]. |
| 642 LiveRange* SplitBetween(LiveRange* range, LifetimePosition start, | 645 LiveRange* SplitBetween(LiveRange* range, LifetimePosition start, |
| 643 LifetimePosition end); | 646 LifetimePosition end); |
| 644 | 647 |
| 645 // Find a lifetime position in the interval [start, end] which | 648 // Find a lifetime position in the interval [start, end] which |
| 646 // is optimal for splitting: it is either header of the outermost | 649 // is optimal for splitting: it is either header of the outermost |
| 647 // loop covered by this interval or the latest possible position. | 650 // loop covered by this interval or the latest possible position. |
| 648 LifetimePosition FindOptimalSplitPos(LifetimePosition start, | 651 LifetimePosition FindOptimalSplitPos(LifetimePosition start, |
| 649 LifetimePosition end); | 652 LifetimePosition end); |
| 650 | 653 |
| 654 void Spill(LiveRange* range); |
| 655 |
| 651 // Spill the given life range after position pos. | 656 // Spill the given life range after position pos. |
| 652 void SpillAfter(LiveRange* range, LifetimePosition pos); | 657 void SpillAfter(LiveRange* range, LifetimePosition pos); |
| 653 | 658 |
| 654 // Spill the given life range after position [start] and up to position [end]. | 659 // Spill the given life range after position [start] and up to position [end]. |
| 655 void SpillBetween(LiveRange* range, LifetimePosition start, | 660 void SpillBetween(LiveRange* range, LifetimePosition start, |
| 656 LifetimePosition end); | 661 LifetimePosition end); |
| 657 | 662 |
| 658 // Spill the given life range after position [start] and up to position [end]. | 663 // Spill the given life range after position [start] and up to position [end]. |
| 659 // Range is guaranteed to be spilled at least until position [until]. | 664 // Range is guaranteed to be spilled at least until position [until]. |
| 660 void SpillBetweenUntil(LiveRange* range, LifetimePosition start, | 665 void SpillBetweenUntil(LiveRange* range, LifetimePosition start, |
| 661 LifetimePosition until, LifetimePosition end); | 666 LifetimePosition until, LifetimePosition end); |
| 662 | 667 |
| 663 void SplitAndSpillIntersecting(LiveRange* range); | 668 void SplitAndSpillIntersecting(LiveRange* range); |
| 664 | 669 |
| 665 // If we are trying to spill a range inside the loop try to | 670 // If we are trying to spill a range inside the loop try to |
| 666 // hoist spill position out to the point just before the loop. | 671 // hoist spill position out to the point just before the loop. |
| 667 LifetimePosition FindOptimalSpillingPos(LiveRange* range, | 672 LifetimePosition FindOptimalSpillingPos(LiveRange* range, |
| 668 LifetimePosition pos); | 673 LifetimePosition pos); |
| 669 | 674 |
| 670 void Spill(LiveRange* range); | |
| 671 | |
| 672 // Return the block which contains give lifetime position. | |
| 673 const InstructionBlock* GetInstructionBlock(LifetimePosition pos) const { | |
| 674 return data()->GetInstructionBlock(pos); | |
| 675 } | |
| 676 | |
| 677 void SetLiveRangeAssignedRegister(LiveRange* range, int reg) { | |
| 678 data()->SetLiveRangeAssignedRegister(range, reg); | |
| 679 } | |
| 680 | |
| 681 // Helper methods for the fixed registers. | |
| 682 int RegisterCount() const { return num_registers_; } | |
| 683 const char* RegisterName(int allocation_index); | |
| 684 | |
| 685 ZoneVector<LiveRange*>& live_ranges() { return data()->live_ranges(); } | |
| 686 ZoneVector<LiveRange*>& fixed_live_ranges() { | |
| 687 return data()->fixed_live_ranges(); | |
| 688 } | |
| 689 ZoneVector<LiveRange*>& fixed_double_live_ranges() { | |
| 690 return data()->fixed_double_live_ranges(); | |
| 691 } | |
| 692 ZoneVector<LiveRange*>& unhandled_live_ranges() { | |
| 693 return unhandled_live_ranges_; | |
| 694 } | |
| 695 ZoneVector<LiveRange*>& active_live_ranges() { return active_live_ranges_; } | |
| 696 ZoneVector<LiveRange*>& inactive_live_ranges() { | |
| 697 return inactive_live_ranges_; | |
| 698 } | |
| 699 ZoneVector<SpillRange*>& spill_ranges() { return data()->spill_ranges(); } | |
| 700 RegisterAllocationData::PhiMap& phi_map() { return data()->phi_map(); } | |
| 701 | |
| 702 RegisterAllocationData* const data_; | 675 RegisterAllocationData* const data_; |
| 703 const RegisterKind mode_; | 676 const RegisterKind mode_; |
| 704 const int num_registers_; | 677 const int num_registers_; |
| 705 | 678 |
| 706 ZoneVector<LiveRange*> unhandled_live_ranges_; | 679 ZoneVector<LiveRange*> unhandled_live_ranges_; |
| 707 ZoneVector<LiveRange*> active_live_ranges_; | 680 ZoneVector<LiveRange*> active_live_ranges_; |
| 708 ZoneVector<LiveRange*> inactive_live_ranges_; | 681 ZoneVector<LiveRange*> inactive_live_ranges_; |
| 709 | 682 |
| 710 #ifdef DEBUG | 683 #ifdef DEBUG |
| 711 LifetimePosition allocation_finger_; | 684 LifetimePosition allocation_finger_; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 | 727 |
| 755 DISALLOW_COPY_AND_ASSIGN(ReferenceMapPopulator); | 728 DISALLOW_COPY_AND_ASSIGN(ReferenceMapPopulator); |
| 756 }; | 729 }; |
| 757 | 730 |
| 758 | 731 |
| 759 class LiveRangeConnector final : public ZoneObject { | 732 class LiveRangeConnector final : public ZoneObject { |
| 760 public: | 733 public: |
| 761 explicit LiveRangeConnector(RegisterAllocationData* data); | 734 explicit LiveRangeConnector(RegisterAllocationData* data); |
| 762 | 735 |
| 763 // Phase 8: reconnect split ranges with moves. | 736 // Phase 8: reconnect split ranges with moves. |
| 764 void ConnectRanges(Zone* temp_zone); | 737 void ConnectRanges(Zone* local_zone); |
| 765 | 738 |
| 766 // Phase 9: insert moves to connect ranges across basic blocks. | 739 // Phase 9: insert moves to connect ranges across basic blocks. |
| 767 void ResolveControlFlow(); | 740 void ResolveControlFlow(Zone* local_zone); |
| 768 | 741 |
| 769 private: | 742 private: |
| 770 const InstructionBlock* GetInstructionBlock(LifetimePosition pos) const { | |
| 771 return data()->GetInstructionBlock(pos); | |
| 772 } | |
| 773 bool CanEagerlyResolveControlFlow(const InstructionBlock* block) const; | 743 bool CanEagerlyResolveControlFlow(const InstructionBlock* block) const; |
| 774 void ResolveControlFlow(const InstructionBlock* block, | 744 void ResolveControlFlow(const InstructionBlock* block, |
| 775 const InstructionOperand& cur_op, | 745 const InstructionOperand& cur_op, |
| 776 const InstructionBlock* pred, | 746 const InstructionBlock* pred, |
| 777 const InstructionOperand& pred_op); | 747 const InstructionOperand& pred_op); |
| 778 InstructionSequence* code() const { return data()->code(); } | 748 InstructionSequence* code() const { return data()->code(); } |
| 779 Zone* code_zone() const { return code()->zone(); } | 749 Zone* code_zone() const { return code()->zone(); } |
| 780 RegisterAllocationData* data() const { return data_; } | 750 RegisterAllocationData* data() const { return data_; } |
| 781 | 751 |
| 782 RegisterAllocationData* const data_; | 752 RegisterAllocationData* const data_; |
| 783 | 753 |
| 784 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); | 754 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); |
| 785 }; | 755 }; |
| 786 | 756 |
| 787 } // namespace compiler | 757 } // namespace compiler |
| 788 } // namespace internal | 758 } // namespace internal |
| 789 } // namespace v8 | 759 } // namespace v8 |
| 790 | 760 |
| 791 #endif // V8_REGISTER_ALLOCATOR_H_ | 761 #endif // V8_REGISTER_ALLOCATOR_H_ |
| OLD | NEW |