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); | 588 explicit RegisterAllocator(RegisterAllocationData* data, RegisterKind kind); |
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 |
593 Zone* allocation_zone() const { return data()->allocation_zone(); } | 596 Zone* allocation_zone() const { return data()->allocation_zone(); } |
594 | 597 |
595 LiveRange* LiveRangeFor(int index) { return data()->LiveRangeFor(index); } | 598 LiveRange* LiveRangeFor(int index) { return data()->LiveRangeFor(index); } |
596 | 599 |
597 // Split the given range at the given position. | 600 // Split the given range at the given position. |
598 // If range starts at or after the given position then the | 601 // If range starts at or after the given position then the |
599 // original range is returned. | 602 // original range is returned. |
600 // Otherwise returns the live range that starts at pos and contains | 603 // 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 | 604 // all uses from the original range that follow pos. Uses at pos will |
602 // still be owned by the original range after splitting. | 605 // still be owned by the original range after splitting. |
(...skipping 11 matching lines...) Expand all Loading... |
614 | 617 |
615 void Spill(LiveRange* range); | 618 void Spill(LiveRange* range); |
616 | 619 |
617 // If we are trying to spill a range inside the loop try to | 620 // 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. | 621 // hoist spill position out to the point just before the loop. |
619 LifetimePosition FindOptimalSpillingPos(LiveRange* range, | 622 LifetimePosition FindOptimalSpillingPos(LiveRange* range, |
620 LifetimePosition pos); | 623 LifetimePosition pos); |
621 | 624 |
622 private: | 625 private: |
623 RegisterAllocationData* const data_; | 626 RegisterAllocationData* const data_; |
| 627 const RegisterKind mode_; |
| 628 const int num_registers_; |
624 | 629 |
625 DISALLOW_COPY_AND_ASSIGN(RegisterAllocator); | 630 DISALLOW_COPY_AND_ASSIGN(RegisterAllocator); |
626 }; | 631 }; |
627 | 632 |
628 | 633 |
629 class LinearScanAllocator final : public RegisterAllocator { | 634 class LinearScanAllocator final : public RegisterAllocator { |
630 public: | 635 public: |
631 LinearScanAllocator(RegisterAllocationData* data, RegisterKind kind, | 636 LinearScanAllocator(RegisterAllocationData* data, RegisterKind kind, |
632 Zone* local_zone); | 637 Zone* local_zone); |
633 | 638 |
634 // Phase 4: compute register assignments. | 639 // Phase 4: compute register assignments. |
635 void AllocateRegisters(); | 640 void AllocateRegisters(); |
636 | 641 |
637 private: | 642 private: |
638 int num_registers() const { return num_registers_; } | |
639 const char* RegisterName(int allocation_index) const; | 643 const char* RegisterName(int allocation_index) const; |
640 | 644 |
641 ZoneVector<LiveRange*>& unhandled_live_ranges() { | 645 ZoneVector<LiveRange*>& unhandled_live_ranges() { |
642 return unhandled_live_ranges_; | 646 return unhandled_live_ranges_; |
643 } | 647 } |
644 ZoneVector<LiveRange*>& active_live_ranges() { return active_live_ranges_; } | 648 ZoneVector<LiveRange*>& active_live_ranges() { return active_live_ranges_; } |
645 ZoneVector<LiveRange*>& inactive_live_ranges() { | 649 ZoneVector<LiveRange*>& inactive_live_ranges() { |
646 return inactive_live_ranges_; | 650 return inactive_live_ranges_; |
647 } | 651 } |
648 | 652 |
(...skipping 21 matching lines...) Expand all Loading... |
670 void SpillBetween(LiveRange* range, LifetimePosition start, | 674 void SpillBetween(LiveRange* range, LifetimePosition start, |
671 LifetimePosition end); | 675 LifetimePosition end); |
672 | 676 |
673 // Spill the given life range after position [start] and up to position [end]. | 677 // Spill the given life range after position [start] and up to position [end]. |
674 // Range is guaranteed to be spilled at least until position [until]. | 678 // Range is guaranteed to be spilled at least until position [until]. |
675 void SpillBetweenUntil(LiveRange* range, LifetimePosition start, | 679 void SpillBetweenUntil(LiveRange* range, LifetimePosition start, |
676 LifetimePosition until, LifetimePosition end); | 680 LifetimePosition until, LifetimePosition end); |
677 | 681 |
678 void SplitAndSpillIntersecting(LiveRange* range); | 682 void SplitAndSpillIntersecting(LiveRange* range); |
679 | 683 |
680 const RegisterKind mode_; | |
681 const int num_registers_; | |
682 | |
683 ZoneVector<LiveRange*> unhandled_live_ranges_; | 684 ZoneVector<LiveRange*> unhandled_live_ranges_; |
684 ZoneVector<LiveRange*> active_live_ranges_; | 685 ZoneVector<LiveRange*> active_live_ranges_; |
685 ZoneVector<LiveRange*> inactive_live_ranges_; | 686 ZoneVector<LiveRange*> inactive_live_ranges_; |
686 | 687 |
687 #ifdef DEBUG | 688 #ifdef DEBUG |
688 LifetimePosition allocation_finger_; | 689 LifetimePosition allocation_finger_; |
689 #endif | 690 #endif |
690 | 691 |
691 DISALLOW_COPY_AND_ASSIGN(LinearScanAllocator); | 692 DISALLOW_COPY_AND_ASSIGN(LinearScanAllocator); |
692 }; | 693 }; |
693 | 694 |
| 695 class CoallescedLiveRanges; |
| 696 |
| 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 |
694 | 735 |
695 class OperandAssigner final : public ZoneObject { | 736 class OperandAssigner final : public ZoneObject { |
696 public: | 737 public: |
697 explicit OperandAssigner(RegisterAllocationData* data); | 738 explicit OperandAssigner(RegisterAllocationData* data); |
698 | 739 |
699 // Phase 5: assign spill splots. | 740 // Phase 5: assign spill splots. |
700 void AssignSpillSlots(); | 741 void AssignSpillSlots(); |
701 | 742 |
702 // Phase 6: commit assignment. | 743 // Phase 6: commit assignment. |
703 void CommitAssignment(); | 744 void CommitAssignment(); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
753 RegisterAllocationData* const data_; | 794 RegisterAllocationData* const data_; |
754 | 795 |
755 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); | 796 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); |
756 }; | 797 }; |
757 | 798 |
758 } // namespace compiler | 799 } // namespace compiler |
759 } // namespace internal | 800 } // namespace internal |
760 } // namespace v8 | 801 } // namespace v8 |
761 | 802 |
762 #endif // V8_REGISTER_ALLOCATOR_H_ | 803 #endif // V8_REGISTER_ALLOCATOR_H_ |
OLD | NEW |