| 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 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 RegisterAllocator : public ZoneObject { | 586 class RegisterAllocator : public ZoneObject { |
| 587 public: | 587 public: |
| 588 explicit RegisterAllocator(RegisterAllocationData* data, RegisterKind kind); | 588 explicit RegisterAllocator(RegisterAllocationData* data); |
| 589 | 589 |
| 590 protected: | 590 protected: |
| 591 RegisterAllocationData* data() const { return data_; } | 591 RegisterAllocationData* data() const { return data_; } |
| 592 InstructionSequence* code() const { return data()->code(); } | 592 InstructionSequence* code() const { return data()->code(); } |
| 593 RegisterKind mode() const { return mode_; } | |
| 594 int num_registers() const { return num_registers_; } | |
| 595 | |
| 596 Zone* allocation_zone() const { return data()->allocation_zone(); } | 593 Zone* allocation_zone() const { return data()->allocation_zone(); } |
| 597 | 594 |
| 598 LiveRange* LiveRangeFor(int index) { return data()->LiveRangeFor(index); } | 595 LiveRange* LiveRangeFor(int index) { return data()->LiveRangeFor(index); } |
| 599 | 596 |
| 600 // Split the given range at the given position. | 597 // Split the given range at the given position. |
| 601 // If range starts at or after the given position then the | 598 // If range starts at or after the given position then the |
| 602 // original range is returned. | 599 // original range is returned. |
| 603 // Otherwise returns the live range that starts at pos and contains | 600 // Otherwise returns the live range that starts at pos and contains |
| 604 // all uses from the original range that follow pos. Uses at pos will | 601 // all uses from the original range that follow pos. Uses at pos will |
| 605 // still be owned by the original range after splitting. | 602 // still be owned by the original range after splitting. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 617 | 614 |
| 618 void Spill(LiveRange* range); | 615 void Spill(LiveRange* range); |
| 619 | 616 |
| 620 // If we are trying to spill a range inside the loop try to | 617 // If we are trying to spill a range inside the loop try to |
| 621 // hoist spill position out to the point just before the loop. | 618 // hoist spill position out to the point just before the loop. |
| 622 LifetimePosition FindOptimalSpillingPos(LiveRange* range, | 619 LifetimePosition FindOptimalSpillingPos(LiveRange* range, |
| 623 LifetimePosition pos); | 620 LifetimePosition pos); |
| 624 | 621 |
| 625 private: | 622 private: |
| 626 RegisterAllocationData* const data_; | 623 RegisterAllocationData* const data_; |
| 627 const RegisterKind mode_; | |
| 628 const int num_registers_; | |
| 629 | 624 |
| 630 DISALLOW_COPY_AND_ASSIGN(RegisterAllocator); | 625 DISALLOW_COPY_AND_ASSIGN(RegisterAllocator); |
| 631 }; | 626 }; |
| 632 | 627 |
| 633 | 628 |
| 634 class LinearScanAllocator final : public RegisterAllocator { | 629 class LinearScanAllocator final : public RegisterAllocator { |
| 635 public: | 630 public: |
| 636 LinearScanAllocator(RegisterAllocationData* data, RegisterKind kind, | 631 LinearScanAllocator(RegisterAllocationData* data, RegisterKind kind, |
| 637 Zone* local_zone); | 632 Zone* local_zone); |
| 638 | 633 |
| 639 // Phase 4: compute register assignments. | 634 // Phase 4: compute register assignments. |
| 640 void AllocateRegisters(); | 635 void AllocateRegisters(); |
| 641 | 636 |
| 642 private: | 637 private: |
| 638 int num_registers() const { return num_registers_; } |
| 643 const char* RegisterName(int allocation_index) const; | 639 const char* RegisterName(int allocation_index) const; |
| 644 | 640 |
| 645 ZoneVector<LiveRange*>& unhandled_live_ranges() { | 641 ZoneVector<LiveRange*>& unhandled_live_ranges() { |
| 646 return unhandled_live_ranges_; | 642 return unhandled_live_ranges_; |
| 647 } | 643 } |
| 648 ZoneVector<LiveRange*>& active_live_ranges() { return active_live_ranges_; } | 644 ZoneVector<LiveRange*>& active_live_ranges() { return active_live_ranges_; } |
| 649 ZoneVector<LiveRange*>& inactive_live_ranges() { | 645 ZoneVector<LiveRange*>& inactive_live_ranges() { |
| 650 return inactive_live_ranges_; | 646 return inactive_live_ranges_; |
| 651 } | 647 } |
| 652 | 648 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 674 void SpillBetween(LiveRange* range, LifetimePosition start, | 670 void SpillBetween(LiveRange* range, LifetimePosition start, |
| 675 LifetimePosition end); | 671 LifetimePosition end); |
| 676 | 672 |
| 677 // 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]. |
| 678 // Range is guaranteed to be spilled at least until position [until]. | 674 // Range is guaranteed to be spilled at least until position [until]. |
| 679 void SpillBetweenUntil(LiveRange* range, LifetimePosition start, | 675 void SpillBetweenUntil(LiveRange* range, LifetimePosition start, |
| 680 LifetimePosition until, LifetimePosition end); | 676 LifetimePosition until, LifetimePosition end); |
| 681 | 677 |
| 682 void SplitAndSpillIntersecting(LiveRange* range); | 678 void SplitAndSpillIntersecting(LiveRange* range); |
| 683 | 679 |
| 680 const RegisterKind mode_; |
| 681 const int num_registers_; |
| 682 |
| 684 ZoneVector<LiveRange*> unhandled_live_ranges_; | 683 ZoneVector<LiveRange*> unhandled_live_ranges_; |
| 685 ZoneVector<LiveRange*> active_live_ranges_; | 684 ZoneVector<LiveRange*> active_live_ranges_; |
| 686 ZoneVector<LiveRange*> inactive_live_ranges_; | 685 ZoneVector<LiveRange*> inactive_live_ranges_; |
| 687 | 686 |
| 688 #ifdef DEBUG | 687 #ifdef DEBUG |
| 689 LifetimePosition allocation_finger_; | 688 LifetimePosition allocation_finger_; |
| 690 #endif | 689 #endif |
| 691 | 690 |
| 692 DISALLOW_COPY_AND_ASSIGN(LinearScanAllocator); | 691 DISALLOW_COPY_AND_ASSIGN(LinearScanAllocator); |
| 693 }; | 692 }; |
| 694 | 693 |
| 695 class CoallescedLiveRanges; | |
| 696 | 694 |
| 697 | |
| 698 // A variant of the LLVM Greedy Register Allocator. See | |
| 699 // http://blog.llvm.org/2011/09/greedy-register-allocation-in-llvm-30.html | |
| 700 class GreedyAllocator final : public RegisterAllocator { | |
| 701 public: | |
| 702 explicit GreedyAllocator(RegisterAllocationData* data, RegisterKind kind, | |
| 703 Zone* local_zone); | |
| 704 | |
| 705 void AllocateRegisters(); | |
| 706 | |
| 707 private: | |
| 708 const RegisterConfiguration* config() const { return data()->config(); } | |
| 709 | |
| 710 typedef ZonePriorityQueue<std::pair<unsigned, LiveRange*>> PQueue; | |
| 711 | |
| 712 unsigned GetLiveRangeSize(LiveRange* range); | |
| 713 void Enqueue(LiveRange* range); | |
| 714 | |
| 715 void Evict(LiveRange* range); | |
| 716 float CalculateSpillWeight(LiveRange* range); | |
| 717 float CalculateMaxSpillWeight(const ZoneSet<LiveRange*>& ranges); | |
| 718 | |
| 719 | |
| 720 bool TryAllocate(LiveRange* current, ZoneSet<LiveRange*>* conflicting); | |
| 721 bool TryAllocatePhysicalRegister(unsigned reg_id, LiveRange* range, | |
| 722 ZoneSet<LiveRange*>* conflicting); | |
| 723 bool HandleSpillOperands(LiveRange* range); | |
| 724 bool AllocateBlockedRange(LiveRange*, const ZoneSet<LiveRange*>&); | |
| 725 | |
| 726 LiveRange* SpillBetweenUntil(LiveRange* range, LifetimePosition start, | |
| 727 LifetimePosition until, LifetimePosition end); | |
| 728 void AssignRangeToRegister(int reg_id, LiveRange* range); | |
| 729 | |
| 730 ZoneVector<CoallescedLiveRanges*> allocations_; | |
| 731 PQueue queue_; | |
| 732 DISALLOW_COPY_AND_ASSIGN(GreedyAllocator); | |
| 733 }; | |
| 734 | |
| 735 | |
| 736 class OperandAssigner final : public ZoneObject { | 695 class OperandAssigner final : public ZoneObject { |
| 737 public: | 696 public: |
| 738 explicit OperandAssigner(RegisterAllocationData* data); | 697 explicit OperandAssigner(RegisterAllocationData* data); |
| 739 | 698 |
| 740 // Phase 5: assign spill splots. | 699 // Phase 5: assign spill splots. |
| 741 void AssignSpillSlots(); | 700 void AssignSpillSlots(); |
| 742 | 701 |
| 743 // Phase 6: commit assignment. | 702 // Phase 6: commit assignment. |
| 744 void CommitAssignment(); | 703 void CommitAssignment(); |
| 745 | 704 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 RegisterAllocationData* const data_; | 753 RegisterAllocationData* const data_; |
| 795 | 754 |
| 796 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); | 755 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); |
| 797 }; | 756 }; |
| 798 | 757 |
| 799 } // namespace compiler | 758 } // namespace compiler |
| 800 } // namespace internal | 759 } // namespace internal |
| 801 } // namespace v8 | 760 } // namespace v8 |
| 802 | 761 |
| 803 #endif // V8_REGISTER_ALLOCATOR_H_ | 762 #endif // V8_REGISTER_ALLOCATOR_H_ |
| OLD | NEW |