| 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 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 InstructionOperand* hint); | 576 InstructionOperand* hint); |
| 577 void Use(LifetimePosition block_start, LifetimePosition position, | 577 void Use(LifetimePosition block_start, LifetimePosition position, |
| 578 InstructionOperand* operand, InstructionOperand* hint); | 578 InstructionOperand* operand, InstructionOperand* hint); |
| 579 | 579 |
| 580 RegisterAllocationData* const data_; | 580 RegisterAllocationData* const data_; |
| 581 | 581 |
| 582 DISALLOW_COPY_AND_ASSIGN(LiveRangeBuilder); | 582 DISALLOW_COPY_AND_ASSIGN(LiveRangeBuilder); |
| 583 }; | 583 }; |
| 584 | 584 |
| 585 | 585 |
| 586 class LinearScanAllocator final : public ZoneObject { | 586 class RegisterAllocator : public ZoneObject { |
| 587 public: |
| 588 explicit RegisterAllocator(RegisterAllocationData* data); |
| 589 |
| 590 protected: |
| 591 RegisterAllocationData* data() const { return data_; } |
| 592 InstructionSequence* code() const { return data()->code(); } |
| 593 Zone* allocation_zone() const { return data()->allocation_zone(); } |
| 594 |
| 595 LiveRange* LiveRangeFor(int index) { return data()->LiveRangeFor(index); } |
| 596 |
| 597 // Split the given range at the given position. |
| 598 // If range starts at or after the given position then the |
| 599 // original range is returned. |
| 600 // Otherwise returns the live range that starts at pos and contains |
| 601 // all uses from the original range that follow pos. Uses at pos will |
| 602 // still be owned by the original range after splitting. |
| 603 LiveRange* SplitRangeAt(LiveRange* range, LifetimePosition pos); |
| 604 |
| 605 // Split the given range in a position from the interval [start, end]. |
| 606 LiveRange* SplitBetween(LiveRange* range, LifetimePosition start, |
| 607 LifetimePosition end); |
| 608 |
| 609 // Find a lifetime position in the interval [start, end] which |
| 610 // is optimal for splitting: it is either header of the outermost |
| 611 // loop covered by this interval or the latest possible position. |
| 612 LifetimePosition FindOptimalSplitPos(LifetimePosition start, |
| 613 LifetimePosition end); |
| 614 |
| 615 void Spill(LiveRange* range); |
| 616 |
| 617 // If we are trying to spill a range inside the loop try to |
| 618 // hoist spill position out to the point just before the loop. |
| 619 LifetimePosition FindOptimalSpillingPos(LiveRange* range, |
| 620 LifetimePosition pos); |
| 621 |
| 622 private: |
| 623 RegisterAllocationData* const data_; |
| 624 |
| 625 DISALLOW_COPY_AND_ASSIGN(RegisterAllocator); |
| 626 }; |
| 627 |
| 628 |
| 629 class LinearScanAllocator final : public RegisterAllocator { |
| 587 public: | 630 public: |
| 588 LinearScanAllocator(RegisterAllocationData* data, RegisterKind kind, | 631 LinearScanAllocator(RegisterAllocationData* data, RegisterKind kind, |
| 589 Zone* local_zone); | 632 Zone* local_zone); |
| 590 | 633 |
| 591 // Phase 4: compute register assignments. | 634 // Phase 4: compute register assignments. |
| 592 void AllocateRegisters(); | 635 void AllocateRegisters(); |
| 593 | 636 |
| 594 private: | 637 private: |
| 595 RegisterAllocationData* data() const { return data_; } | |
| 596 InstructionSequence* code() const { return data()->code(); } | |
| 597 Zone* allocation_zone() const { return data()->allocation_zone(); } | |
| 598 int num_registers() const { return num_registers_; } | 638 int num_registers() const { return num_registers_; } |
| 599 const char* RegisterName(int allocation_index) const; | 639 const char* RegisterName(int allocation_index) const; |
| 600 | 640 |
| 601 ZoneVector<LiveRange*>& unhandled_live_ranges() { | 641 ZoneVector<LiveRange*>& unhandled_live_ranges() { |
| 602 return unhandled_live_ranges_; | 642 return unhandled_live_ranges_; |
| 603 } | 643 } |
| 604 ZoneVector<LiveRange*>& active_live_ranges() { return active_live_ranges_; } | 644 ZoneVector<LiveRange*>& active_live_ranges() { return active_live_ranges_; } |
| 605 ZoneVector<LiveRange*>& inactive_live_ranges() { | 645 ZoneVector<LiveRange*>& inactive_live_ranges() { |
| 606 return inactive_live_ranges_; | 646 return inactive_live_ranges_; |
| 607 } | 647 } |
| 608 | 648 |
| 609 LiveRange* LiveRangeFor(int index) { return data()->LiveRangeFor(index); } | |
| 610 | |
| 611 // Helper methods for updating the life range lists. | 649 // Helper methods for updating the life range lists. |
| 612 void AddToActive(LiveRange* range); | 650 void AddToActive(LiveRange* range); |
| 613 void AddToInactive(LiveRange* range); | 651 void AddToInactive(LiveRange* range); |
| 614 void AddToUnhandledSorted(LiveRange* range); | 652 void AddToUnhandledSorted(LiveRange* range); |
| 615 void AddToUnhandledUnsorted(LiveRange* range); | 653 void AddToUnhandledUnsorted(LiveRange* range); |
| 616 void SortUnhandled(); | 654 void SortUnhandled(); |
| 617 bool UnhandledIsSorted(); | 655 bool UnhandledIsSorted(); |
| 618 void ActiveToHandled(LiveRange* range); | 656 void ActiveToHandled(LiveRange* range); |
| 619 void ActiveToInactive(LiveRange* range); | 657 void ActiveToInactive(LiveRange* range); |
| 620 void InactiveToHandled(LiveRange* range); | 658 void InactiveToHandled(LiveRange* range); |
| 621 void InactiveToActive(LiveRange* range); | 659 void InactiveToActive(LiveRange* range); |
| 622 | 660 |
| 623 // Helper methods for allocating registers. | 661 // Helper methods for allocating registers. |
| 624 bool TryReuseSpillForPhi(LiveRange* range); | 662 bool TryReuseSpillForPhi(LiveRange* range); |
| 625 bool TryAllocateFreeReg(LiveRange* range); | 663 bool TryAllocateFreeReg(LiveRange* range); |
| 626 void AllocateBlockedReg(LiveRange* range); | 664 void AllocateBlockedReg(LiveRange* range); |
| 627 | 665 |
| 628 // Live range splitting helpers. | |
| 629 | |
| 630 // Split the given range at the given position. | |
| 631 // If range starts at or after the given position then the | |
| 632 // original range is returned. | |
| 633 // Otherwise returns the live range that starts at pos and contains | |
| 634 // all uses from the original range that follow pos. Uses at pos will | |
| 635 // still be owned by the original range after splitting. | |
| 636 LiveRange* SplitRangeAt(LiveRange* range, LifetimePosition pos); | |
| 637 | |
| 638 // Split the given range in a position from the interval [start, end]. | |
| 639 LiveRange* SplitBetween(LiveRange* range, LifetimePosition start, | |
| 640 LifetimePosition end); | |
| 641 | |
| 642 // Find a lifetime position in the interval [start, end] which | |
| 643 // is optimal for splitting: it is either header of the outermost | |
| 644 // loop covered by this interval or the latest possible position. | |
| 645 LifetimePosition FindOptimalSplitPos(LifetimePosition start, | |
| 646 LifetimePosition end); | |
| 647 | |
| 648 void Spill(LiveRange* range); | |
| 649 | |
| 650 // Spill the given life range after position pos. | 666 // Spill the given life range after position pos. |
| 651 void SpillAfter(LiveRange* range, LifetimePosition pos); | 667 void SpillAfter(LiveRange* range, LifetimePosition pos); |
| 652 | 668 |
| 653 // Spill the given life range after position [start] and up to position [end]. | 669 // Spill the given life range after position [start] and up to position [end]. |
| 654 void SpillBetween(LiveRange* range, LifetimePosition start, | 670 void SpillBetween(LiveRange* range, LifetimePosition start, |
| 655 LifetimePosition end); | 671 LifetimePosition end); |
| 656 | 672 |
| 657 // Spill the given life range after position [start] and up to position [end]. | 673 // Spill the given life range after position [start] and up to position [end]. |
| 658 // Range is guaranteed to be spilled at least until position [until]. | 674 // Range is guaranteed to be spilled at least until position [until]. |
| 659 void SpillBetweenUntil(LiveRange* range, LifetimePosition start, | 675 void SpillBetweenUntil(LiveRange* range, LifetimePosition start, |
| 660 LifetimePosition until, LifetimePosition end); | 676 LifetimePosition until, LifetimePosition end); |
| 661 | 677 |
| 662 void SplitAndSpillIntersecting(LiveRange* range); | 678 void SplitAndSpillIntersecting(LiveRange* range); |
| 663 | 679 |
| 664 // If we are trying to spill a range inside the loop try to | |
| 665 // hoist spill position out to the point just before the loop. | |
| 666 LifetimePosition FindOptimalSpillingPos(LiveRange* range, | |
| 667 LifetimePosition pos); | |
| 668 | |
| 669 RegisterAllocationData* const data_; | |
| 670 const RegisterKind mode_; | 680 const RegisterKind mode_; |
| 671 const int num_registers_; | 681 const int num_registers_; |
| 672 | 682 |
| 673 ZoneVector<LiveRange*> unhandled_live_ranges_; | 683 ZoneVector<LiveRange*> unhandled_live_ranges_; |
| 674 ZoneVector<LiveRange*> active_live_ranges_; | 684 ZoneVector<LiveRange*> active_live_ranges_; |
| 675 ZoneVector<LiveRange*> inactive_live_ranges_; | 685 ZoneVector<LiveRange*> inactive_live_ranges_; |
| 676 | 686 |
| 677 #ifdef DEBUG | 687 #ifdef DEBUG |
| 678 LifetimePosition allocation_finger_; | 688 LifetimePosition allocation_finger_; |
| 679 #endif | 689 #endif |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 743 RegisterAllocationData* const data_; | 753 RegisterAllocationData* const data_; |
| 744 | 754 |
| 745 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); | 755 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); |
| 746 }; | 756 }; |
| 747 | 757 |
| 748 } // namespace compiler | 758 } // namespace compiler |
| 749 } // namespace internal | 759 } // namespace internal |
| 750 } // namespace v8 | 760 } // namespace v8 |
| 751 | 761 |
| 752 #endif // V8_REGISTER_ALLOCATOR_H_ | 762 #endif // V8_REGISTER_ALLOCATOR_H_ |
| OLD | NEW |