Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: src/compiler/register-allocator.h

Issue 1061923005: Reland: Introducing the LLVM greedy register allocator. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Redo after refactoring Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 471 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 } 482 }
483 483
484 bool IsReference(int virtual_register) const { 484 bool IsReference(int virtual_register) const {
485 return code()->IsReference(virtual_register); 485 return code()->IsReference(virtual_register);
486 } 486 }
487 487
488 bool ExistsUseWithoutDefinition(); 488 bool ExistsUseWithoutDefinition();
489 489
490 // Creates a new live range. 490 // Creates a new live range.
491 LiveRange* NewLiveRange(int index); 491 LiveRange* NewLiveRange(int index);
492 void Spill(LiveRange* range);
493 int GetVirtualRegister() { return code()->NextVirtualRegister(); }
494 // Live range splitting helpers.
495
496 // Split the given range in a position from the interval [start, end].
497 LiveRange* SplitBetween(LiveRange* range, LifetimePosition start,
498 LifetimePosition end);
499
500 // Split the given range at the given position.
501 // If range starts at or after the given position then the
502 // original range is returned.
503 // Otherwise returns the live range that starts at pos and contains
504 // all uses from the original range that follow pos. Uses at pos will
505 // still be owned by the original range after splitting.
506 LiveRange* SplitRangeAt(LiveRange* range, LifetimePosition pos);
507 // Find a lifetime position in the interval [start, end] which
508 // is optimal for splitting: it is either header of the outermost
509 // loop covered by this interval or the latest possible position.
510 LifetimePosition FindOptimalSplitPos(LifetimePosition start,
511 LifetimePosition end);
492 512
493 private: 513 private:
494 Zone* const allocation_zone_; 514 Zone* const allocation_zone_;
495 Frame* const frame_; 515 Frame* const frame_;
496 InstructionSequence* const code_; 516 InstructionSequence* const code_;
497 const char* const debug_name_; 517 const char* const debug_name_;
498 const RegisterConfiguration* const config_; 518 const RegisterConfiguration* const config_;
499 PhiMap phi_map_; 519 PhiMap phi_map_;
500 ZoneVector<BitVector*> live_in_sets_; 520 ZoneVector<BitVector*> live_in_sets_;
501 ZoneVector<LiveRange*> live_ranges_; 521 ZoneVector<LiveRange*> live_ranges_;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 616
597 private: 617 private:
598 RegisterAllocationData* data() const { return data_; } 618 RegisterAllocationData* data() const { return data_; }
599 InstructionSequence* code() const { return data()->code(); } 619 InstructionSequence* code() const { return data()->code(); }
600 Zone* allocation_zone() const { return data()->allocation_zone(); } 620 Zone* allocation_zone() const { return data()->allocation_zone(); }
601 Zone* code_zone() const { return code()->zone(); } 621 Zone* code_zone() const { return code()->zone(); }
602 const RegisterConfiguration* config() const { return data()->config(); } 622 const RegisterConfiguration* config() const { return data()->config(); }
603 623
604 Instruction* InstructionAt(int index) { return code()->InstructionAt(index); } 624 Instruction* InstructionAt(int index) { return code()->InstructionAt(index); }
605 625
606 int GetVirtualRegister() { return code()->NextVirtualRegister(); }
607
608 bool IsReference(int virtual_register) const { 626 bool IsReference(int virtual_register) const {
609 return data()->IsReference(virtual_register); 627 return data()->IsReference(virtual_register);
610 } 628 }
611 629
612 LiveRange* LiveRangeFor(int index) { return data()->LiveRangeFor(index); } 630 LiveRange* LiveRangeFor(int index) { return data()->LiveRangeFor(index); }
613 631
614 // Helper methods for updating the life range lists. 632 // Helper methods for updating the life range lists.
615 void AddToActive(LiveRange* range); 633 void AddToActive(LiveRange* range);
616 void AddToInactive(LiveRange* range); 634 void AddToInactive(LiveRange* range);
617 void AddToUnhandledSorted(LiveRange* range); 635 void AddToUnhandledSorted(LiveRange* range);
618 void AddToUnhandledUnsorted(LiveRange* range); 636 void AddToUnhandledUnsorted(LiveRange* range);
619 void SortUnhandled(); 637 void SortUnhandled();
620 bool UnhandledIsSorted(); 638 bool UnhandledIsSorted();
621 void ActiveToHandled(LiveRange* range); 639 void ActiveToHandled(LiveRange* range);
622 void ActiveToInactive(LiveRange* range); 640 void ActiveToInactive(LiveRange* range);
623 void InactiveToHandled(LiveRange* range); 641 void InactiveToHandled(LiveRange* range);
624 void InactiveToActive(LiveRange* range); 642 void InactiveToActive(LiveRange* range);
625 643
626 // Helper methods for allocating registers. 644 // Helper methods for allocating registers.
627 bool TryReuseSpillForPhi(LiveRange* range); 645 bool TryReuseSpillForPhi(LiveRange* range);
628 bool TryAllocateFreeReg(LiveRange* range); 646 bool TryAllocateFreeReg(LiveRange* range);
629 void AllocateBlockedReg(LiveRange* range); 647 void AllocateBlockedReg(LiveRange* range);
630 648
631 // Live range splitting helpers.
632
633 // Split the given range at the given position.
634 // If range starts at or after the given position then the
635 // original range is returned.
636 // Otherwise returns the live range that starts at pos and contains
637 // all uses from the original range that follow pos. Uses at pos will
638 // still be owned by the original range after splitting.
639 LiveRange* SplitRangeAt(LiveRange* range, LifetimePosition pos);
640
641 // Split the given range in a position from the interval [start, end].
642 LiveRange* SplitBetween(LiveRange* range, LifetimePosition start,
643 LifetimePosition end);
644
645 // Find a lifetime position in the interval [start, end] which
646 // is optimal for splitting: it is either header of the outermost
647 // loop covered by this interval or the latest possible position.
648 LifetimePosition FindOptimalSplitPos(LifetimePosition start,
649 LifetimePosition end);
650
651 // Spill the given life range after position pos. 649 // Spill the given life range after position pos.
652 void SpillAfter(LiveRange* range, LifetimePosition pos); 650 void SpillAfter(LiveRange* range, LifetimePosition pos);
653 651
654 // Spill the given life range after position [start] and up to position [end]. 652 // Spill the given life range after position [start] and up to position [end].
655 void SpillBetween(LiveRange* range, LifetimePosition start, 653 void SpillBetween(LiveRange* range, LifetimePosition start,
656 LifetimePosition end); 654 LifetimePosition end);
657 655
658 // Spill the given life range after position [start] and up to position [end]. 656 // 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]. 657 // Range is guaranteed to be spilled at least until position [until].
660 void SpillBetweenUntil(LiveRange* range, LifetimePosition start, 658 void SpillBetweenUntil(LiveRange* range, LifetimePosition start,
661 LifetimePosition until, LifetimePosition end); 659 LifetimePosition until, LifetimePosition end);
662 660
663 void SplitAndSpillIntersecting(LiveRange* range); 661 void SplitAndSpillIntersecting(LiveRange* range);
664 662
665 // If we are trying to spill a range inside the loop try to 663 // 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. 664 // hoist spill position out to the point just before the loop.
667 LifetimePosition FindOptimalSpillingPos(LiveRange* range, 665 LifetimePosition FindOptimalSpillingPos(LiveRange* range,
668 LifetimePosition pos); 666 LifetimePosition pos);
669 667
670 void Spill(LiveRange* range);
671
672 // Return the block which contains give lifetime position. 668 // Return the block which contains give lifetime position.
673 const InstructionBlock* GetInstructionBlock(LifetimePosition pos) const { 669 const InstructionBlock* GetInstructionBlock(LifetimePosition pos) const {
674 return data()->GetInstructionBlock(pos); 670 return data()->GetInstructionBlock(pos);
675 } 671 }
676 672
677 void SetLiveRangeAssignedRegister(LiveRange* range, int reg) { 673 void SetLiveRangeAssignedRegister(LiveRange* range, int reg) {
678 data()->SetLiveRangeAssignedRegister(range, reg); 674 data()->SetLiveRangeAssignedRegister(range, reg);
679 } 675 }
680 676
681 // Helper methods for the fixed registers. 677 // Helper methods for the fixed registers.
682 int RegisterCount() const { return num_registers_; } 678 int RegisterCount() const { return num_registers_; }
683 const char* RegisterName(int allocation_index); 679 const char* RegisterName(int allocation_index);
684 680
685 ZoneVector<LiveRange*>& live_ranges() { return data()->live_ranges(); } 681 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() { 682 ZoneVector<LiveRange*>& unhandled_live_ranges() {
693 return unhandled_live_ranges_; 683 return unhandled_live_ranges_;
694 } 684 }
695 ZoneVector<LiveRange*>& active_live_ranges() { return active_live_ranges_; } 685 ZoneVector<LiveRange*>& active_live_ranges() { return active_live_ranges_; }
696 ZoneVector<LiveRange*>& inactive_live_ranges() { 686 ZoneVector<LiveRange*>& inactive_live_ranges() {
697 return inactive_live_ranges_; 687 return inactive_live_ranges_;
698 } 688 }
699 ZoneVector<SpillRange*>& spill_ranges() { return data()->spill_ranges(); } 689 ZoneVector<SpillRange*>& spill_ranges() { return data()->spill_ranges(); }
700 RegisterAllocationData::PhiMap& phi_map() { return data()->phi_map(); } 690 RegisterAllocationData::PhiMap& phi_map() { return data()->phi_map(); }
701 691
702 RegisterAllocationData* const data_; 692 RegisterAllocationData* const data_;
703 const RegisterKind mode_; 693 const RegisterKind mode_;
704 const int num_registers_; 694 const int num_registers_;
705 695
706 ZoneVector<LiveRange*> unhandled_live_ranges_; 696 ZoneVector<LiveRange*> unhandled_live_ranges_;
707 ZoneVector<LiveRange*> active_live_ranges_; 697 ZoneVector<LiveRange*> active_live_ranges_;
708 ZoneVector<LiveRange*> inactive_live_ranges_; 698 ZoneVector<LiveRange*> inactive_live_ranges_;
709 699
710 #ifdef DEBUG 700 #ifdef DEBUG
711 LifetimePosition allocation_finger_; 701 LifetimePosition allocation_finger_;
712 #endif 702 #endif
713 703
714 DISALLOW_COPY_AND_ASSIGN(LinearScanAllocator); 704 DISALLOW_COPY_AND_ASSIGN(LinearScanAllocator);
715 }; 705 };
716 706
717 707
708 class CoallescedLiveRanges;
709
710
jvoung (off chromium) 2015/04/21 23:34:06 I don't know if v8 style would say to include a co
Mircea Trofin 2015/04/22 04:37:33 Done.
711 class GreedyAllocator final : public ZoneObject {
712 public:
713 explicit GreedyAllocator(RegisterAllocationData* data, RegisterKind kind);
714
715 void AllocateRegisters();
716
717 private:
718 RegisterAllocationData* data() const { return data_; }
719 InstructionSequence* code() const { return data()->code(); }
720 const RegisterConfiguration* config() const { return data()->config(); }
721
722 typedef ZonePriorityQueue<std::pair<unsigned, LiveRange*>> PQueue;
723
724 unsigned GetLiveRangeSize(LiveRange* range);
725 void Enqueue(LiveRange* range);
726
727 void Evict(LiveRange* range);
728 float CalculateSpillWeight(LiveRange* range);
729 float CalculateMaxSpillWeight(const ZoneSet<LiveRange*>& ranges);
730
731
732 bool TryAllocate(LiveRange* current, ZoneSet<LiveRange*>* conflicting);
733 bool TryAllocatePhysicalRegister(unsigned reg_id, LiveRange* range,
734 ZoneSet<LiveRange*>* conflicting);
735 bool HandleSpillOperands(LiveRange* range);
736 bool AllocateBlockedRange(LiveRange*, const ZoneSet<LiveRange*>&);
737
738 LiveRange* SpillBetweenUntil(LiveRange* range, LifetimePosition start,
739 LifetimePosition until, LifetimePosition end);
740 void AssignRangeToRegister(int reg_id, LiveRange* range);
741
742 RegisterAllocationData* const data_;
743 const RegisterKind mode_;
744 const int num_registers_;
745
746 ZoneVector<CoallescedLiveRanges*> allocations_;
747 PQueue queue_;
748 DISALLOW_COPY_AND_ASSIGN(GreedyAllocator);
749 };
750
751
718 class OperandAssigner final : public ZoneObject { 752 class OperandAssigner final : public ZoneObject {
719 public: 753 public:
720 explicit OperandAssigner(RegisterAllocationData* data); 754 explicit OperandAssigner(RegisterAllocationData* data);
721 755
722 // Phase 5: assign spill splots. 756 // Phase 5: assign spill splots.
723 void AssignSpillSlots(); 757 void AssignSpillSlots();
724 758
725 // Phase 6: commit assignment. 759 // Phase 6: commit assignment.
726 void CommitAssignment(); 760 void CommitAssignment();
727 761
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 RegisterAllocationData* const data_; 816 RegisterAllocationData* const data_;
783 817
784 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); 818 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector);
785 }; 819 };
786 820
787 } // namespace compiler 821 } // namespace compiler
788 } // namespace internal 822 } // namespace internal
789 } // namespace v8 823 } // namespace v8
790 824
791 #endif // V8_REGISTER_ALLOCATOR_H_ 825 #endif // V8_REGISTER_ALLOCATOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698