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 |