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

Side by Side Diff: src/lithium-allocator.cc

Issue 6606006: [Isolates] Merge 6500:6700 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « src/lithium-allocator.h ('k') | src/lithium-allocator-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "lithium-allocator.h" 28 #include "lithium-allocator-inl.h"
29 29
30 #include "hydrogen.h" 30 #include "hydrogen.h"
31 #include "string-stream.h" 31 #include "string-stream.h"
32 32
33 #if V8_TARGET_ARCH_IA32 33 #if V8_TARGET_ARCH_IA32
34 #include "ia32/lithium-ia32.h" 34 #include "ia32/lithium-ia32.h"
35 #elif V8_TARGET_ARCH_X64 35 #elif V8_TARGET_ARCH_X64
36 #include "x64/lithium-x64.h" 36 #include "x64/lithium-x64.h"
37 #elif V8_TARGET_ARCH_ARM 37 #elif V8_TARGET_ARCH_ARM
38 #include "arm/lithium-arm.h" 38 #include "arm/lithium-arm.h"
39 #else 39 #else
40 #error "Unknown architecture." 40 #error "Unknown architecture."
41 #endif 41 #endif
42 42
43 namespace v8 { 43 namespace v8 {
44 namespace internal { 44 namespace internal {
45 45
46 46
47 #define DEFINE_OPERAND_CACHE(name, type) \ 47 #define DEFINE_OPERAND_CACHE(name, type) \
48 name name::cache[name::kNumCachedOperands]; \ 48 name name::cache[name::kNumCachedOperands]; \
49 void name::SetupCache() { \ 49 void name::SetupCache() { \
50 for (int i = 0; i < kNumCachedOperands; i++) { \ 50 for (int i = 0; i < kNumCachedOperands; i++) { \
51 cache[i].ConvertTo(type, i); \ 51 cache[i].ConvertTo(type, i); \
52 } \ 52 } \
53 } 53 } \
54 static bool name##_initialize() { \
55 name::SetupCache(); \
56 return true; \
57 } \
58 static bool name##_cache_initialized = name##_initialize();
54 59
55 DEFINE_OPERAND_CACHE(LConstantOperand, CONSTANT_OPERAND) 60 DEFINE_OPERAND_CACHE(LConstantOperand, CONSTANT_OPERAND)
56 DEFINE_OPERAND_CACHE(LStackSlot, STACK_SLOT) 61 DEFINE_OPERAND_CACHE(LStackSlot, STACK_SLOT)
57 DEFINE_OPERAND_CACHE(LDoubleStackSlot, DOUBLE_STACK_SLOT) 62 DEFINE_OPERAND_CACHE(LDoubleStackSlot, DOUBLE_STACK_SLOT)
58 DEFINE_OPERAND_CACHE(LRegister, REGISTER) 63 DEFINE_OPERAND_CACHE(LRegister, REGISTER)
59 DEFINE_OPERAND_CACHE(LDoubleRegister, DOUBLE_REGISTER) 64 DEFINE_OPERAND_CACHE(LDoubleRegister, DOUBLE_REGISTER)
60 65
61 #undef DEFINE_OPERAND_CACHE 66 #undef DEFINE_OPERAND_CACHE
62 67
63 68
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 } else { 530 } else {
526 b = b->next(); 531 b = b->next();
527 } 532 }
528 } 533 }
529 return LifetimePosition::Invalid(); 534 return LifetimePosition::Invalid();
530 } 535 }
531 536
532 537
533 void LAllocator::InitializeLivenessAnalysis() { 538 void LAllocator::InitializeLivenessAnalysis() {
534 // Initialize the live_in sets for each block to NULL. 539 // Initialize the live_in sets for each block to NULL.
535 int block_count = graph()->blocks()->length(); 540 int block_count = graph_->blocks()->length();
536 live_in_sets_.Initialize(block_count); 541 live_in_sets_.Initialize(block_count);
537 live_in_sets_.AddBlock(NULL, block_count); 542 live_in_sets_.AddBlock(NULL, block_count);
538 } 543 }
539 544
540 545
541 BitVector* LAllocator::ComputeLiveOut(HBasicBlock* block) { 546 BitVector* LAllocator::ComputeLiveOut(HBasicBlock* block) {
542 // Compute live out for the given block, except not including backward 547 // Compute live out for the given block, except not including backward
543 // successor edges. 548 // successor edges.
544 BitVector* live_out = new BitVector(next_virtual_register_); 549 BitVector* live_out = new BitVector(next_virtual_register_);
545 550
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 int reg_index = operand->fixed_index(); 611 int reg_index = operand->fixed_index();
607 operand->ConvertTo(LOperand::REGISTER, reg_index); 612 operand->ConvertTo(LOperand::REGISTER, reg_index);
608 } else if (operand->policy() == LUnallocated::FIXED_DOUBLE_REGISTER) { 613 } else if (operand->policy() == LUnallocated::FIXED_DOUBLE_REGISTER) {
609 int reg_index = operand->fixed_index(); 614 int reg_index = operand->fixed_index();
610 operand->ConvertTo(LOperand::DOUBLE_REGISTER, reg_index); 615 operand->ConvertTo(LOperand::DOUBLE_REGISTER, reg_index);
611 } else { 616 } else {
612 UNREACHABLE(); 617 UNREACHABLE();
613 } 618 }
614 if (is_tagged) { 619 if (is_tagged) {
615 TraceAlloc("Fixed reg is tagged at %d\n", pos); 620 TraceAlloc("Fixed reg is tagged at %d\n", pos);
616 LInstruction* instr = chunk_->instructions()->at(pos); 621 LInstruction* instr = InstructionAt(pos);
617 if (instr->HasPointerMap()) { 622 if (instr->HasPointerMap()) {
618 instr->pointer_map()->RecordPointer(operand); 623 instr->pointer_map()->RecordPointer(operand);
619 } 624 }
620 } 625 }
621 return operand; 626 return operand;
622 } 627 }
623 628
624 629
625 LiveRange* LAllocator::FixedLiveRangeFor(int index) { 630 LiveRange* LAllocator::FixedLiveRangeFor(int index) {
626 if (index >= fixed_live_ranges_.length()) { 631 if (index >= fixed_live_ranges_.length()) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 } 666 }
662 LiveRange* result = live_ranges_[index]; 667 LiveRange* result = live_ranges_[index];
663 if (result == NULL) { 668 if (result == NULL) {
664 result = new LiveRange(index); 669 result = new LiveRange(index);
665 live_ranges_[index] = result; 670 live_ranges_[index] = result;
666 } 671 }
667 return result; 672 return result;
668 } 673 }
669 674
670 675
671 LGap* LAllocator::GetLastGap(HBasicBlock* block) const { 676 LGap* LAllocator::GetLastGap(HBasicBlock* block) {
672 int last_instruction = block->last_instruction_index(); 677 int last_instruction = block->last_instruction_index();
673 int index = chunk_->NearestGapPos(last_instruction); 678 int index = chunk_->NearestGapPos(last_instruction);
674 return chunk_->GetGapAt(index); 679 return GapAt(index);
675 } 680 }
676 681
677 682
678 HPhi* LAllocator::LookupPhi(LOperand* operand) const { 683 HPhi* LAllocator::LookupPhi(LOperand* operand) const {
679 if (!operand->IsUnallocated()) return NULL; 684 if (!operand->IsUnallocated()) return NULL;
680 int index = operand->VirtualRegister(); 685 int index = operand->VirtualRegister();
681 HValue* instr = graph()->LookupValue(index); 686 HValue* instr = graph_->LookupValue(index);
682 if (instr != NULL && instr->IsPhi()) { 687 if (instr != NULL && instr->IsPhi()) {
683 return HPhi::cast(instr); 688 return HPhi::cast(instr);
684 } 689 }
685 return NULL; 690 return NULL;
686 } 691 }
687 692
688 693
689 LiveRange* LAllocator::LiveRangeFor(LOperand* operand) { 694 LiveRange* LAllocator::LiveRangeFor(LOperand* operand) {
690 if (operand->IsUnallocated()) { 695 if (operand->IsUnallocated()) {
691 return LiveRangeFor(LUnallocated::cast(operand)->virtual_register()); 696 return LiveRangeFor(LUnallocated::cast(operand)->virtual_register());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 LUnallocated* unalloc_operand = LUnallocated::cast(operand); 735 LUnallocated* unalloc_operand = LUnallocated::cast(operand);
731 range->AddUsePosition(position, unalloc_operand)->set_hint(hint); 736 range->AddUsePosition(position, unalloc_operand)->set_hint(hint);
732 } 737 }
733 range->AddUseInterval(block_start, position); 738 range->AddUseInterval(block_start, position);
734 } 739 }
735 740
736 741
737 void LAllocator::AddConstraintsGapMove(int index, 742 void LAllocator::AddConstraintsGapMove(int index,
738 LOperand* from, 743 LOperand* from,
739 LOperand* to) { 744 LOperand* to) {
740 LGap* gap = chunk_->GetGapAt(index); 745 LGap* gap = GapAt(index);
741 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START); 746 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START);
742 if (from->IsUnallocated()) { 747 if (from->IsUnallocated()) {
743 const ZoneList<LMoveOperands>* move_operands = move->move_operands(); 748 const ZoneList<LMoveOperands>* move_operands = move->move_operands();
744 for (int i = 0; i < move_operands->length(); ++i) { 749 for (int i = 0; i < move_operands->length(); ++i) {
745 LMoveOperands cur = move_operands->at(i); 750 LMoveOperands cur = move_operands->at(i);
746 LOperand* cur_to = cur.destination(); 751 LOperand* cur_to = cur.destination();
747 if (cur_to->IsUnallocated()) { 752 if (cur_to->IsUnallocated()) {
748 if (cur_to->VirtualRegister() == from->VirtualRegister()) { 753 if (cur_to->VirtualRegister() == from->VirtualRegister()) {
749 move->AddMove(cur.source(), to); 754 move->AddMove(cur.source(), to);
750 return; 755 return;
751 } 756 }
752 } 757 }
753 } 758 }
754 } 759 }
755 move->AddMove(from, to); 760 move->AddMove(from, to);
756 } 761 }
757 762
758 763
759 void LAllocator::MeetRegisterConstraints(HBasicBlock* block) { 764 void LAllocator::MeetRegisterConstraints(HBasicBlock* block) {
760 int start = block->first_instruction_index(); 765 int start = block->first_instruction_index();
761 int end = block->last_instruction_index(); 766 int end = block->last_instruction_index();
762 for (int i = start; i <= end; ++i) { 767 for (int i = start; i <= end; ++i) {
763 if (chunk_->IsGapAt(i)) { 768 if (IsGapAt(i)) {
764 InstructionSummary* summary = NULL; 769 LInstruction* instr = NULL;
765 InstructionSummary* prev_summary = NULL; 770 LInstruction* prev_instr = NULL;
766 if (i < end) summary = GetSummary(i + 1); 771 if (i < end) instr = InstructionAt(i + 1);
767 if (i > start) prev_summary = GetSummary(i - 1); 772 if (i > start) prev_instr = InstructionAt(i - 1);
768 MeetConstraintsBetween(prev_summary, summary, i); 773 MeetConstraintsBetween(prev_instr, instr, i);
769 } 774 }
770 } 775 }
771 } 776 }
772 777
773 778
774 void LAllocator::MeetConstraintsBetween(InstructionSummary* first, 779 void LAllocator::MeetConstraintsBetween(LInstruction* first,
775 InstructionSummary* second, 780 LInstruction* second,
776 int gap_index) { 781 int gap_index) {
777 // Handle fixed temporaries. 782 // Handle fixed temporaries.
778 if (first != NULL) { 783 if (first != NULL) {
779 for (int i = 0; i < first->TempCount(); ++i) { 784 for (TempIterator it(first); it.HasNext(); it.Advance()) {
780 LUnallocated* temp = LUnallocated::cast(first->TempAt(i)); 785 LUnallocated* temp = LUnallocated::cast(it.Next());
781 if (temp->HasFixedPolicy()) { 786 if (temp->HasFixedPolicy()) {
782 AllocateFixed(temp, gap_index - 1, false); 787 AllocateFixed(temp, gap_index - 1, false);
783 } 788 }
784 } 789 }
785 } 790 }
786 791
787 // Handle fixed output operand. 792 // Handle fixed output operand.
788 if (first != NULL && first->Output() != NULL) { 793 if (first != NULL && first->Output() != NULL) {
789 LUnallocated* first_output = LUnallocated::cast(first->Output()); 794 LUnallocated* first_output = LUnallocated::cast(first->Output());
790 LiveRange* range = LiveRangeFor(first_output->VirtualRegister()); 795 LiveRange* range = LiveRangeFor(first_output->VirtualRegister());
(...skipping 12 matching lines...) Expand all
803 chunk_->AddGapMove(gap_index, first_output, output_copy); 808 chunk_->AddGapMove(gap_index, first_output, output_copy);
804 } 809 }
805 810
806 if (!assigned) { 811 if (!assigned) {
807 range->SetSpillStartIndex(gap_index); 812 range->SetSpillStartIndex(gap_index);
808 813
809 // This move to spill operand is not a real use. Liveness analysis 814 // This move to spill operand is not a real use. Liveness analysis
810 // and splitting of live ranges do not account for it. 815 // and splitting of live ranges do not account for it.
811 // Thus it should be inserted to a lifetime position corresponding to 816 // Thus it should be inserted to a lifetime position corresponding to
812 // the instruction end. 817 // the instruction end.
813 LGap* gap = chunk_->GetGapAt(gap_index); 818 LGap* gap = GapAt(gap_index);
814 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::BEFORE); 819 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::BEFORE);
815 move->AddMove(first_output, range->GetSpillOperand()); 820 move->AddMove(first_output, range->GetSpillOperand());
816 } 821 }
817 } 822 }
818 823
819 // Handle fixed input operands of second instruction. 824 // Handle fixed input operands of second instruction.
820 if (second != NULL) { 825 if (second != NULL) {
821 for (int i = 0; i < second->InputCount(); ++i) { 826 for (UseIterator it(second); it.HasNext(); it.Advance()) {
822 LUnallocated* cur_input = LUnallocated::cast(second->InputAt(i)); 827 LUnallocated* cur_input = LUnallocated::cast(it.Next());
823 if (cur_input->HasFixedPolicy()) { 828 if (cur_input->HasFixedPolicy()) {
824 LUnallocated* input_copy = cur_input->CopyUnconstrained(); 829 LUnallocated* input_copy = cur_input->CopyUnconstrained();
825 bool is_tagged = HasTaggedValue(cur_input->VirtualRegister()); 830 bool is_tagged = HasTaggedValue(cur_input->VirtualRegister());
826 AllocateFixed(cur_input, gap_index + 1, is_tagged); 831 AllocateFixed(cur_input, gap_index + 1, is_tagged);
827 AddConstraintsGapMove(gap_index, input_copy, cur_input); 832 AddConstraintsGapMove(gap_index, input_copy, cur_input);
828 } else if (cur_input->policy() == LUnallocated::WRITABLE_REGISTER) { 833 } else if (cur_input->policy() == LUnallocated::WRITABLE_REGISTER) {
829 // The live range of writable input registers always goes until the end 834 // The live range of writable input registers always goes until the end
830 // of the instruction. 835 // of the instruction.
831 ASSERT(!cur_input->IsUsedAtStart()); 836 ASSERT(!cur_input->IsUsedAtStart());
832 837
833 LUnallocated* input_copy = cur_input->CopyUnconstrained(); 838 LUnallocated* input_copy = cur_input->CopyUnconstrained();
834 cur_input->set_virtual_register(next_virtual_register_++); 839 cur_input->set_virtual_register(next_virtual_register_++);
835 840
836 if (RequiredRegisterKind(input_copy->virtual_register()) == 841 if (RequiredRegisterKind(input_copy->virtual_register()) ==
837 DOUBLE_REGISTERS) { 842 DOUBLE_REGISTERS) {
838 double_artificial_registers_.Add( 843 double_artificial_registers_.Add(
839 cur_input->virtual_register() - first_artificial_register_); 844 cur_input->virtual_register() - first_artificial_register_);
840 } 845 }
841 846
842 AddConstraintsGapMove(gap_index, input_copy, cur_input); 847 AddConstraintsGapMove(gap_index, input_copy, cur_input);
843 } 848 }
844 } 849 }
845 } 850 }
846 851
847 // Handle "output same as input" for second instruction. 852 // Handle "output same as input" for second instruction.
848 if (second != NULL && second->Output() != NULL) { 853 if (second != NULL && second->Output() != NULL) {
849 LUnallocated* second_output = LUnallocated::cast(second->Output()); 854 LUnallocated* second_output = LUnallocated::cast(second->Output());
850 if (second_output->HasSameAsInputPolicy()) { 855 if (second_output->HasSameAsInputPolicy()) {
851 LUnallocated* cur_input = LUnallocated::cast(second->InputAt(0)); 856 LUnallocated* cur_input = LUnallocated::cast(second->FirstInput());
852 int output_vreg = second_output->VirtualRegister(); 857 int output_vreg = second_output->VirtualRegister();
853 int input_vreg = cur_input->VirtualRegister(); 858 int input_vreg = cur_input->VirtualRegister();
854 859
855 LUnallocated* input_copy = cur_input->CopyUnconstrained(); 860 LUnallocated* input_copy = cur_input->CopyUnconstrained();
856 cur_input->set_virtual_register(second_output->virtual_register()); 861 cur_input->set_virtual_register(second_output->virtual_register());
857 AddConstraintsGapMove(gap_index, input_copy, cur_input); 862 AddConstraintsGapMove(gap_index, input_copy, cur_input);
858 863
859 if (HasTaggedValue(input_vreg) && !HasTaggedValue(output_vreg)) { 864 if (HasTaggedValue(input_vreg) && !HasTaggedValue(output_vreg)) {
860 int index = gap_index + 1; 865 int index = gap_index + 1;
861 LInstruction* instr = chunk_->instructions()->at(index); 866 LInstruction* instr = InstructionAt(index);
862 if (instr->HasPointerMap()) { 867 if (instr->HasPointerMap()) {
863 instr->pointer_map()->RecordPointer(input_copy); 868 instr->pointer_map()->RecordPointer(input_copy);
864 } 869 }
865 } else if (!HasTaggedValue(input_vreg) && HasTaggedValue(output_vreg)) { 870 } else if (!HasTaggedValue(input_vreg) && HasTaggedValue(output_vreg)) {
866 // The input is assumed to immediately have a tagged representation, 871 // The input is assumed to immediately have a tagged representation,
867 // before the pointer map can be used. I.e. the pointer map at the 872 // before the pointer map can be used. I.e. the pointer map at the
868 // instruction will include the output operand (whose value at the 873 // instruction will include the output operand (whose value at the
869 // beginning of the instruction is equal to the input operand). If 874 // beginning of the instruction is equal to the input operand). If
870 // this is not desired, then the pointer map at this instruction needs 875 // this is not desired, then the pointer map at this instruction needs
871 // to be adjusted manually. 876 // to be adjusted manually.
872 } 877 }
873 } 878 }
874 } 879 }
875 } 880 }
876 881
877 882
878 void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) { 883 void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) {
879 int block_start = block->first_instruction_index(); 884 int block_start = block->first_instruction_index();
880 int index = block->last_instruction_index(); 885 int index = block->last_instruction_index();
881 886
882 LifetimePosition block_start_position = 887 LifetimePosition block_start_position =
883 LifetimePosition::FromInstructionIndex(block_start); 888 LifetimePosition::FromInstructionIndex(block_start);
884 889
885 while (index >= block_start) { 890 while (index >= block_start) {
886 LifetimePosition curr_position = 891 LifetimePosition curr_position =
887 LifetimePosition::FromInstructionIndex(index); 892 LifetimePosition::FromInstructionIndex(index);
888 893
889 if (chunk_->IsGapAt(index)) { 894 if (IsGapAt(index)) {
890 // We have a gap at this position. 895 // We have a gap at this position.
891 LGap* gap = chunk_->GetGapAt(index); 896 LGap* gap = GapAt(index);
892 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START); 897 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START);
893 const ZoneList<LMoveOperands>* move_operands = move->move_operands(); 898 const ZoneList<LMoveOperands>* move_operands = move->move_operands();
894 for (int i = 0; i < move_operands->length(); ++i) { 899 for (int i = 0; i < move_operands->length(); ++i) {
895 LMoveOperands* cur = &move_operands->at(i); 900 LMoveOperands* cur = &move_operands->at(i);
896 if (cur->IsIgnored()) continue; 901 if (cur->IsIgnored()) continue;
897 LOperand* from = cur->source(); 902 LOperand* from = cur->source();
898 LOperand* to = cur->destination(); 903 LOperand* to = cur->destination();
899 HPhi* phi = LookupPhi(to); 904 HPhi* phi = LookupPhi(to);
900 LOperand* hint = to; 905 LOperand* hint = to;
901 if (phi != NULL) { 906 if (phi != NULL) {
(...skipping 13 matching lines...) Expand all
915 } else { 920 } else {
916 Define(curr_position, to, from); 921 Define(curr_position, to, from);
917 } 922 }
918 } 923 }
919 Use(block_start_position, curr_position, from, hint); 924 Use(block_start_position, curr_position, from, hint);
920 if (from->IsUnallocated()) { 925 if (from->IsUnallocated()) {
921 live->Add(from->VirtualRegister()); 926 live->Add(from->VirtualRegister());
922 } 927 }
923 } 928 }
924 } else { 929 } else {
925 ASSERT(!chunk_->IsGapAt(index)); 930 ASSERT(!IsGapAt(index));
926 InstructionSummary* summary = GetSummary(index); 931 LInstruction* instr = InstructionAt(index);
927 932
928 if (summary != NULL) { 933 if (instr != NULL) {
929 LOperand* output = summary->Output(); 934 LOperand* output = instr->Output();
930 if (output != NULL) { 935 if (output != NULL) {
931 if (output->IsUnallocated()) live->Remove(output->VirtualRegister()); 936 if (output->IsUnallocated()) live->Remove(output->VirtualRegister());
932 Define(curr_position, output, NULL); 937 Define(curr_position, output, NULL);
933 } 938 }
934 939
935 if (summary->IsCall()) { 940 if (instr->IsMarkedAsCall()) {
936 for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) { 941 for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) {
937 if (output == NULL || !output->IsRegister() || 942 if (output == NULL || !output->IsRegister() ||
938 output->index() != i) { 943 output->index() != i) {
939 LiveRange* range = FixedLiveRangeFor(i); 944 LiveRange* range = FixedLiveRangeFor(i);
940 range->AddUseInterval(curr_position, 945 range->AddUseInterval(curr_position,
941 curr_position.InstructionEnd()); 946 curr_position.InstructionEnd());
942 } 947 }
943 } 948 }
944 } 949 }
945 950
946 if (summary->IsCall() || summary->IsSaveDoubles()) { 951 if (instr->IsMarkedAsCall() || instr->IsMarkedAsSaveDoubles()) {
947 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) { 952 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) {
948 if (output == NULL || !output->IsDoubleRegister() || 953 if (output == NULL || !output->IsDoubleRegister() ||
949 output->index() != i) { 954 output->index() != i) {
950 LiveRange* range = FixedDoubleLiveRangeFor(i); 955 LiveRange* range = FixedDoubleLiveRangeFor(i);
951 range->AddUseInterval(curr_position, 956 range->AddUseInterval(curr_position,
952 curr_position.InstructionEnd()); 957 curr_position.InstructionEnd());
953 } 958 }
954 } 959 }
955 } 960 }
956 961
957 for (int i = 0; i < summary->InputCount(); ++i) { 962 for (UseIterator it(instr); it.HasNext(); it.Advance()) {
958 LOperand* input = summary->InputAt(i); 963 LOperand* input = it.Next();
959 964
960 LifetimePosition use_pos; 965 LifetimePosition use_pos;
961 if (input->IsUnallocated() && 966 if (input->IsUnallocated() &&
962 LUnallocated::cast(input)->IsUsedAtStart()) { 967 LUnallocated::cast(input)->IsUsedAtStart()) {
963 use_pos = curr_position; 968 use_pos = curr_position;
964 } else { 969 } else {
965 use_pos = curr_position.InstructionEnd(); 970 use_pos = curr_position.InstructionEnd();
966 } 971 }
967 972
968 Use(block_start_position, use_pos, input, NULL); 973 Use(block_start_position, use_pos, input, NULL);
969 if (input->IsUnallocated()) live->Add(input->VirtualRegister()); 974 if (input->IsUnallocated()) live->Add(input->VirtualRegister());
970 } 975 }
971 976
972 for (int i = 0; i < summary->TempCount(); ++i) { 977 for (TempIterator it(instr); it.HasNext(); it.Advance()) {
973 LOperand* temp = summary->TempAt(i); 978 LOperand* temp = it.Next();
974 if (summary->IsCall()) { 979 if (instr->IsMarkedAsCall()) {
975 if (temp->IsRegister()) continue; 980 if (temp->IsRegister()) continue;
976 if (temp->IsUnallocated()) { 981 if (temp->IsUnallocated()) {
977 LUnallocated* temp_unalloc = LUnallocated::cast(temp); 982 LUnallocated* temp_unalloc = LUnallocated::cast(temp);
978 if (temp_unalloc->HasFixedPolicy()) { 983 if (temp_unalloc->HasFixedPolicy()) {
979 continue; 984 continue;
980 } 985 }
981 } 986 }
982 } 987 }
983 Use(block_start_position, curr_position.InstructionEnd(), temp, NULL); 988 Use(block_start_position, curr_position.InstructionEnd(), temp, NULL);
984 Define(curr_position, temp, NULL); 989 Define(curr_position, temp, NULL);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 AllocateGeneralRegisters(); 1040 AllocateGeneralRegisters();
1036 AllocateDoubleRegisters(); 1041 AllocateDoubleRegisters();
1037 PopulatePointerMaps(); 1042 PopulatePointerMaps();
1038 if (has_osr_entry_) ProcessOsrEntry(); 1043 if (has_osr_entry_) ProcessOsrEntry();
1039 ConnectRanges(); 1044 ConnectRanges();
1040 ResolveControlFlow(); 1045 ResolveControlFlow();
1041 } 1046 }
1042 1047
1043 1048
1044 void LAllocator::MeetRegisterConstraints() { 1049 void LAllocator::MeetRegisterConstraints() {
1045 HPhase phase("Register constraints", chunk()); 1050 HPhase phase("Register constraints", chunk_);
1046 first_artificial_register_ = next_virtual_register_; 1051 first_artificial_register_ = next_virtual_register_;
1047 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); 1052 const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
1048 for (int i = 0; i < blocks->length(); ++i) { 1053 for (int i = 0; i < blocks->length(); ++i) {
1049 HBasicBlock* block = blocks->at(i); 1054 HBasicBlock* block = blocks->at(i);
1050 MeetRegisterConstraints(block); 1055 MeetRegisterConstraints(block);
1051 } 1056 }
1052 } 1057 }
1053 1058
1054 1059
1055 void LAllocator::ResolvePhis() { 1060 void LAllocator::ResolvePhis() {
1056 HPhase phase("Resolve phis", chunk()); 1061 HPhase phase("Resolve phis", chunk_);
1057 1062
1058 // Process the blocks in reverse order. 1063 // Process the blocks in reverse order.
1059 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); 1064 const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
1060 for (int block_id = blocks->length() - 1; block_id >= 0; --block_id) { 1065 for (int block_id = blocks->length() - 1; block_id >= 0; --block_id) {
1061 HBasicBlock* block = blocks->at(block_id); 1066 HBasicBlock* block = blocks->at(block_id);
1062 ResolvePhis(block); 1067 ResolvePhis(block);
1063 } 1068 }
1064 } 1069 }
1065 1070
1066 1071
1067 void LAllocator::ResolveControlFlow(LiveRange* range, 1072 void LAllocator::ResolveControlFlow(LiveRange* range,
1068 HBasicBlock* block, 1073 HBasicBlock* block,
1069 HBasicBlock* pred) { 1074 HBasicBlock* pred) {
1070 LifetimePosition pred_end = 1075 LifetimePosition pred_end =
1071 LifetimePosition::FromInstructionIndex(pred->last_instruction_index()). 1076 LifetimePosition::FromInstructionIndex(pred->last_instruction_index());
1072 PrevInstruction();
1073
1074 LifetimePosition cur_start = 1077 LifetimePosition cur_start =
1075 LifetimePosition::FromInstructionIndex(block->first_instruction_index()); 1078 LifetimePosition::FromInstructionIndex(block->first_instruction_index());
1076 LiveRange* pred_cover = NULL; 1079 LiveRange* pred_cover = NULL;
1077 LiveRange* cur_cover = NULL; 1080 LiveRange* cur_cover = NULL;
1078 LiveRange* cur_range = range; 1081 LiveRange* cur_range = range;
1079 while (cur_range != NULL && (cur_cover == NULL || pred_cover == NULL)) { 1082 while (cur_range != NULL && (cur_cover == NULL || pred_cover == NULL)) {
1080 if (cur_range->CanCover(cur_start)) { 1083 if (cur_range->CanCover(cur_start)) {
1081 ASSERT(cur_cover == NULL); 1084 ASSERT(cur_cover == NULL);
1082 cur_cover = cur_range; 1085 cur_cover = cur_range;
1083 } 1086 }
1084 if (cur_range->CanCover(pred_end)) { 1087 if (cur_range->CanCover(pred_end)) {
1085 ASSERT(pred_cover == NULL); 1088 ASSERT(pred_cover == NULL);
1086 pred_cover = cur_range; 1089 pred_cover = cur_range;
1087 } 1090 }
1088 cur_range = cur_range->next(); 1091 cur_range = cur_range->next();
1089 } 1092 }
1090 1093
1091 if (cur_cover->IsSpilled()) return; 1094 if (cur_cover->IsSpilled()) return;
1092 ASSERT(pred_cover != NULL && cur_cover != NULL); 1095 ASSERT(pred_cover != NULL && cur_cover != NULL);
1093 if (pred_cover != cur_cover) { 1096 if (pred_cover != cur_cover) {
1094 LOperand* pred_op = pred_cover->CreateAssignedOperand(); 1097 LOperand* pred_op = pred_cover->CreateAssignedOperand();
1095 LOperand* cur_op = cur_cover->CreateAssignedOperand(); 1098 LOperand* cur_op = cur_cover->CreateAssignedOperand();
1096 if (!pred_op->Equals(cur_op)) { 1099 if (!pred_op->Equals(cur_op)) {
1097 LGap* gap = NULL; 1100 LGap* gap = NULL;
1098 if (block->predecessors()->length() == 1) { 1101 if (block->predecessors()->length() == 1) {
1099 gap = chunk_->GetGapAt(block->first_instruction_index()); 1102 gap = GapAt(block->first_instruction_index());
1100 } else { 1103 } else {
1101 ASSERT(pred->end()->SecondSuccessor() == NULL); 1104 ASSERT(pred->end()->SecondSuccessor() == NULL);
1102 gap = GetLastGap(pred); 1105 gap = GetLastGap(pred);
1103 } 1106 }
1104 gap->GetOrCreateParallelMove(LGap::START)->AddMove(pred_op, cur_op); 1107 gap->GetOrCreateParallelMove(LGap::START)->AddMove(pred_op, cur_op);
1105 } 1108 }
1106 } 1109 }
1107 } 1110 }
1108 1111
1109 1112
1110 LParallelMove* LAllocator::GetConnectingParallelMove(LifetimePosition pos) { 1113 LParallelMove* LAllocator::GetConnectingParallelMove(LifetimePosition pos) {
1111 int index = pos.InstructionIndex(); 1114 int index = pos.InstructionIndex();
1112 if (chunk_->IsGapAt(index)) { 1115 if (IsGapAt(index)) {
1113 LGap* gap = chunk_->GetGapAt(index); 1116 LGap* gap = GapAt(index);
1114 return gap->GetOrCreateParallelMove( 1117 return gap->GetOrCreateParallelMove(
1115 pos.IsInstructionStart() ? LGap::START : LGap::END); 1118 pos.IsInstructionStart() ? LGap::START : LGap::END);
1116 } 1119 }
1117 int gap_pos = pos.IsInstructionStart() ? (index - 1) : (index + 1); 1120 int gap_pos = pos.IsInstructionStart() ? (index - 1) : (index + 1);
1118 return chunk_->GetGapAt(gap_pos)->GetOrCreateParallelMove( 1121 return GapAt(gap_pos)->GetOrCreateParallelMove(
1119 (gap_pos < index) ? LGap::AFTER : LGap::BEFORE); 1122 (gap_pos < index) ? LGap::AFTER : LGap::BEFORE);
1120 } 1123 }
1121 1124
1122 1125
1123 HBasicBlock* LAllocator::GetBlock(LifetimePosition pos) { 1126 HBasicBlock* LAllocator::GetBlock(LifetimePosition pos) {
1124 LGap* gap = chunk_->GetGapAt(chunk_->NearestGapPos(pos.InstructionIndex())); 1127 LGap* gap = GapAt(chunk_->NearestGapPos(pos.InstructionIndex()));
1125 return gap->block(); 1128 return gap->block();
1126 } 1129 }
1127 1130
1128 1131
1129 void LAllocator::ConnectRanges() { 1132 void LAllocator::ConnectRanges() {
1130 HPhase phase("Connect ranges", this); 1133 HPhase phase("Connect ranges", this);
1131 for (int i = 0; i < live_ranges()->length(); ++i) { 1134 for (int i = 0; i < live_ranges()->length(); ++i) {
1132 LiveRange* first_range = live_ranges()->at(i); 1135 LiveRange* first_range = live_ranges()->at(i);
1133 if (first_range == NULL || first_range->parent() != NULL) continue; 1136 if (first_range == NULL || first_range->parent() != NULL) continue;
1134 1137
(...skipping 26 matching lines...) Expand all
1161 1164
1162 1165
1163 bool LAllocator::CanEagerlyResolveControlFlow(HBasicBlock* block) const { 1166 bool LAllocator::CanEagerlyResolveControlFlow(HBasicBlock* block) const {
1164 if (block->predecessors()->length() != 1) return false; 1167 if (block->predecessors()->length() != 1) return false;
1165 return block->predecessors()->first()->block_id() == block->block_id() - 1; 1168 return block->predecessors()->first()->block_id() == block->block_id() - 1;
1166 } 1169 }
1167 1170
1168 1171
1169 void LAllocator::ResolveControlFlow() { 1172 void LAllocator::ResolveControlFlow() {
1170 HPhase phase("Resolve control flow", this); 1173 HPhase phase("Resolve control flow", this);
1171 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); 1174 const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
1172 for (int block_id = 1; block_id < blocks->length(); ++block_id) { 1175 for (int block_id = 1; block_id < blocks->length(); ++block_id) {
1173 HBasicBlock* block = blocks->at(block_id); 1176 HBasicBlock* block = blocks->at(block_id);
1174 if (CanEagerlyResolveControlFlow(block)) continue; 1177 if (CanEagerlyResolveControlFlow(block)) continue;
1175 BitVector* live = live_in_sets_[block->block_id()]; 1178 BitVector* live = live_in_sets_[block->block_id()];
1176 BitVector::Iterator iterator(live); 1179 BitVector::Iterator iterator(live);
1177 while (!iterator.Done()) { 1180 while (!iterator.Done()) {
1178 int operand_index = iterator.Current(); 1181 int operand_index = iterator.Current();
1179 for (int i = 0; i < block->predecessors()->length(); ++i) { 1182 for (int i = 0; i < block->predecessors()->length(); ++i) {
1180 HBasicBlock* cur = block->predecessors()->at(i); 1183 HBasicBlock* cur = block->predecessors()->at(i);
1181 LiveRange* cur_range = LiveRangeFor(operand_index); 1184 LiveRange* cur_range = LiveRangeFor(operand_index);
1182 ResolveControlFlow(cur_range, block, cur); 1185 ResolveControlFlow(cur_range, block, cur);
1183 } 1186 }
1184 iterator.Advance(); 1187 iterator.Advance();
1185 } 1188 }
1186 } 1189 }
1187 } 1190 }
1188 1191
1189 1192
1190 void LAllocator::BuildLiveRanges() { 1193 void LAllocator::BuildLiveRanges() {
1191 HPhase phase("Build live ranges", this); 1194 HPhase phase("Build live ranges", this);
1192 InitializeLivenessAnalysis(); 1195 InitializeLivenessAnalysis();
1193 // Process the blocks in reverse order. 1196 // Process the blocks in reverse order.
1194 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); 1197 const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
1195 for (int block_id = blocks->length() - 1; block_id >= 0; --block_id) { 1198 for (int block_id = blocks->length() - 1; block_id >= 0; --block_id) {
1196 HBasicBlock* block = blocks->at(block_id); 1199 HBasicBlock* block = blocks->at(block_id);
1197 BitVector* live = ComputeLiveOut(block); 1200 BitVector* live = ComputeLiveOut(block);
1198 // Initially consider all live_out values live for the entire block. We 1201 // Initially consider all live_out values live for the entire block. We
1199 // will shorten these intervals if necessary. 1202 // will shorten these intervals if necessary.
1200 AddInitialIntervals(block, live); 1203 AddInitialIntervals(block, live);
1201 1204
1202 // Process the instructions in reverse order, generating and killing 1205 // Process the instructions in reverse order, generating and killing
1203 // live values. 1206 // live values.
1204 ProcessInstructions(block, live); 1207 ProcessInstructions(block, live);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1238 if (block->IsLoopHeader()) { 1241 if (block->IsLoopHeader()) {
1239 // TODO(kmillikin): Need to be able to get the last block of the loop 1242 // TODO(kmillikin): Need to be able to get the last block of the loop
1240 // in the loop information. Add a live range stretching from the first 1243 // in the loop information. Add a live range stretching from the first
1241 // loop instruction to the last for each value live on entry to the 1244 // loop instruction to the last for each value live on entry to the
1242 // header. 1245 // header.
1243 HBasicBlock* back_edge = block->loop_information()->GetLastBackEdge(); 1246 HBasicBlock* back_edge = block->loop_information()->GetLastBackEdge();
1244 BitVector::Iterator iterator(live); 1247 BitVector::Iterator iterator(live);
1245 LifetimePosition start = LifetimePosition::FromInstructionIndex( 1248 LifetimePosition start = LifetimePosition::FromInstructionIndex(
1246 block->first_instruction_index()); 1249 block->first_instruction_index());
1247 LifetimePosition end = LifetimePosition::FromInstructionIndex( 1250 LifetimePosition end = LifetimePosition::FromInstructionIndex(
1248 back_edge->last_instruction_index()); 1251 back_edge->last_instruction_index()).NextInstruction();
1249 while (!iterator.Done()) { 1252 while (!iterator.Done()) {
1250 int operand_index = iterator.Current(); 1253 int operand_index = iterator.Current();
1251 LiveRange* range = LiveRangeFor(operand_index); 1254 LiveRange* range = LiveRangeFor(operand_index);
1252 range->EnsureInterval(start, end); 1255 range->EnsureInterval(start, end);
1253 iterator.Advance(); 1256 iterator.Advance();
1254 } 1257 }
1255 1258
1256 for (int i = block->block_id() + 1; i <= back_edge->block_id(); ++i) { 1259 for (int i = block->block_id() + 1; i <= back_edge->block_id(); ++i) {
1257 live_in_sets_[i]->Union(*live); 1260 live_in_sets_[i]->Union(*live);
1258 } 1261 }
1259 } 1262 }
1260 1263
1261 #ifdef DEBUG 1264 #ifdef DEBUG
1262 if (block_id == 0) { 1265 if (block_id == 0) {
1263 BitVector::Iterator iterator(live); 1266 BitVector::Iterator iterator(live);
1264 bool found = false; 1267 bool found = false;
1265 while (!iterator.Done()) { 1268 while (!iterator.Done()) {
1266 found = true; 1269 found = true;
1267 int operand_index = iterator.Current(); 1270 int operand_index = iterator.Current();
1268 PrintF("Function: %s\n", 1271 PrintF("Function: %s\n",
1269 *graph()->info()->function()->debug_name()->ToCString()); 1272 *graph_->info()->function()->debug_name()->ToCString());
1270 PrintF("Value %d used before first definition!\n", operand_index); 1273 PrintF("Value %d used before first definition!\n", operand_index);
1271 LiveRange* range = LiveRangeFor(operand_index); 1274 LiveRange* range = LiveRangeFor(operand_index);
1272 PrintF("First use is at %d\n", range->first_pos()->pos().Value()); 1275 PrintF("First use is at %d\n", range->first_pos()->pos().Value());
1273 iterator.Advance(); 1276 iterator.Advance();
1274 } 1277 }
1275 ASSERT(!found); 1278 ASSERT(!found);
1276 } 1279 }
1277 #endif 1280 #endif
1278 } 1281 }
1279 } 1282 }
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1464 LiveRange* current = unhandled_live_ranges_.RemoveLast(); 1467 LiveRange* current = unhandled_live_ranges_.RemoveLast();
1465 ASSERT(UnhandledIsSorted()); 1468 ASSERT(UnhandledIsSorted());
1466 LifetimePosition position = current->Start(); 1469 LifetimePosition position = current->Start();
1467 TraceAlloc("Processing interval %d start=%d\n", 1470 TraceAlloc("Processing interval %d start=%d\n",
1468 current->id(), 1471 current->id(),
1469 position.Value()); 1472 position.Value());
1470 1473
1471 if (current->HasAllocatedSpillOperand()) { 1474 if (current->HasAllocatedSpillOperand()) {
1472 TraceAlloc("Live range %d already has a spill operand\n", current->id()); 1475 TraceAlloc("Live range %d already has a spill operand\n", current->id());
1473 LifetimePosition next_pos = position; 1476 LifetimePosition next_pos = position;
1474 if (chunk_->IsGapAt(next_pos.InstructionIndex())) { 1477 if (IsGapAt(next_pos.InstructionIndex())) {
1475 next_pos = next_pos.NextInstruction(); 1478 next_pos = next_pos.NextInstruction();
1476 } 1479 }
1477 UsePosition* pos = current->NextUsePositionRegisterIsBeneficial(next_pos); 1480 UsePosition* pos = current->NextUsePositionRegisterIsBeneficial(next_pos);
1478 // If the range already has a spill operand and it doesn't need a 1481 // If the range already has a spill operand and it doesn't need a
1479 // register immediately, split it and spill the first part of the range. 1482 // register immediately, split it and spill the first part of the range.
1480 if (pos == NULL) { 1483 if (pos == NULL) {
1481 Spill(current); 1484 Spill(current);
1482 continue; 1485 continue;
1483 } else if (pos->pos().Value() > 1486 } else if (pos->pos().Value() >
1484 current->Start().NextInstruction().Value()) { 1487 current->Start().NextInstruction().Value()) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1522 if (current->HasRegisterAssigned()) { 1525 if (current->HasRegisterAssigned()) {
1523 AddToActive(current); 1526 AddToActive(current);
1524 } 1527 }
1525 } 1528 }
1526 1529
1527 active_live_ranges_.Clear(); 1530 active_live_ranges_.Clear();
1528 inactive_live_ranges_.Clear(); 1531 inactive_live_ranges_.Clear();
1529 } 1532 }
1530 1533
1531 1534
1532 void LAllocator::Setup() {
1533 LConstantOperand::SetupCache();
1534 LStackSlot::SetupCache();
1535 LDoubleStackSlot::SetupCache();
1536 LRegister::SetupCache();
1537 LDoubleRegister::SetupCache();
1538 }
1539
1540
1541 const char* LAllocator::RegisterName(int allocation_index) { 1535 const char* LAllocator::RegisterName(int allocation_index) {
1542 ASSERT(mode_ != NONE); 1536 ASSERT(mode_ != NONE);
1543 if (mode_ == GENERAL_REGISTERS) { 1537 if (mode_ == GENERAL_REGISTERS) {
1544 return Register::AllocationIndexToString(allocation_index); 1538 return Register::AllocationIndexToString(allocation_index);
1545 } else { 1539 } else {
1546 return DoubleRegister::AllocationIndexToString(allocation_index); 1540 return DoubleRegister::AllocationIndexToString(allocation_index);
1547 } 1541 }
1548 } 1542 }
1549 1543
1550 1544
1551 void LAllocator::TraceAlloc(const char* msg, ...) { 1545 void LAllocator::TraceAlloc(const char* msg, ...) {
1552 if (FLAG_trace_alloc) { 1546 if (FLAG_trace_alloc) {
1553 va_list arguments; 1547 va_list arguments;
1554 va_start(arguments, msg); 1548 va_start(arguments, msg);
1555 OS::VPrint(msg, arguments); 1549 OS::VPrint(msg, arguments);
1556 va_end(arguments); 1550 va_end(arguments);
1557 } 1551 }
1558 } 1552 }
1559 1553
1560 1554
1561 void LAllocator::RecordUse(HValue* value, LUnallocated* operand) {
1562 operand->set_virtual_register(value->id());
1563 current_summary()->AddInput(operand);
1564 }
1565
1566
1567 bool LAllocator::HasTaggedValue(int virtual_register) const { 1555 bool LAllocator::HasTaggedValue(int virtual_register) const {
1568 HValue* value = graph()->LookupValue(virtual_register); 1556 HValue* value = graph_->LookupValue(virtual_register);
1569 if (value == NULL) return false; 1557 if (value == NULL) return false;
1570 return value->representation().IsTagged(); 1558 return value->representation().IsTagged();
1571 } 1559 }
1572 1560
1573 1561
1574 RegisterKind LAllocator::RequiredRegisterKind(int virtual_register) const { 1562 RegisterKind LAllocator::RequiredRegisterKind(int virtual_register) const {
1575 if (virtual_register < first_artificial_register_) { 1563 if (virtual_register < first_artificial_register_) {
1576 HValue* value = graph()->LookupValue(virtual_register); 1564 HValue* value = graph_->LookupValue(virtual_register);
1577 if (value != NULL && value->representation().IsDouble()) { 1565 if (value != NULL && value->representation().IsDouble()) {
1578 return DOUBLE_REGISTERS; 1566 return DOUBLE_REGISTERS;
1579 } 1567 }
1580 } else if (double_artificial_registers_.Contains( 1568 } else if (double_artificial_registers_.Contains(
1581 virtual_register - first_artificial_register_)) { 1569 virtual_register - first_artificial_register_)) {
1582 return DOUBLE_REGISTERS; 1570 return DOUBLE_REGISTERS;
1583 } 1571 }
1584 1572
1585 return GENERAL_REGISTERS; 1573 return GENERAL_REGISTERS;
1586 } 1574 }
1587 1575
1588 1576
1589 void LAllocator::MarkAsCall() {
1590 // Call instructions can use only fixed registers as
1591 // temporaries and outputs because all registers
1592 // are blocked by the calling convention.
1593 // Inputs can use either fixed register or have a short lifetime (be
1594 // used at start of the instruction).
1595 InstructionSummary* summary = current_summary();
1596 #ifdef DEBUG
1597 ASSERT(summary->Output() == NULL ||
1598 LUnallocated::cast(summary->Output())->HasFixedPolicy() ||
1599 !LUnallocated::cast(summary->Output())->HasRegisterPolicy());
1600 for (int i = 0; i < summary->InputCount(); i++) {
1601 ASSERT(LUnallocated::cast(summary->InputAt(i))->HasFixedPolicy() ||
1602 LUnallocated::cast(summary->InputAt(i))->IsUsedAtStart() ||
1603 !LUnallocated::cast(summary->InputAt(i))->HasRegisterPolicy());
1604 }
1605 for (int i = 0; i < summary->TempCount(); i++) {
1606 ASSERT(LUnallocated::cast(summary->TempAt(i))->HasFixedPolicy() ||
1607 !LUnallocated::cast(summary->TempAt(i))->HasRegisterPolicy());
1608 }
1609 #endif
1610 summary->MarkAsCall();
1611 }
1612
1613
1614 void LAllocator::MarkAsSaveDoubles() {
1615 current_summary()->MarkAsSaveDoubles();
1616 }
1617
1618
1619 void LAllocator::RecordDefinition(HInstruction* instr, LUnallocated* operand) { 1577 void LAllocator::RecordDefinition(HInstruction* instr, LUnallocated* operand) {
1620 operand->set_virtual_register(instr->id()); 1578 operand->set_virtual_register(instr->id());
1621 current_summary()->SetOutput(operand);
1622 } 1579 }
1623 1580
1624 1581
1625 void LAllocator::RecordTemporary(LUnallocated* operand) { 1582 void LAllocator::RecordTemporary(LUnallocated* operand) {
1626 ASSERT(next_virtual_register_ < LUnallocated::kMaxVirtualRegisters); 1583 ASSERT(next_virtual_register_ < LUnallocated::kMaxVirtualRegisters);
1627 if (!operand->HasFixedPolicy()) { 1584 if (!operand->HasFixedPolicy()) {
1628 operand->set_virtual_register(next_virtual_register_++); 1585 operand->set_virtual_register(next_virtual_register_++);
1629 } 1586 }
1630 current_summary()->AddTemp(operand); 1587 }
1588
1589
1590 void LAllocator::RecordUse(HValue* value, LUnallocated* operand) {
1591 operand->set_virtual_register(value->id());
1631 } 1592 }
1632 1593
1633 1594
1634 int LAllocator::max_initial_value_ids() { 1595 int LAllocator::max_initial_value_ids() {
1635 return LUnallocated::kMaxVirtualRegisters / 32; 1596 return LUnallocated::kMaxVirtualRegisters / 32;
1636 } 1597 }
1637 1598
1638 1599
1639 void LAllocator::BeginInstruction() {
1640 if (next_summary_ == NULL) {
1641 next_summary_ = new InstructionSummary();
1642 }
1643 summary_stack_.Add(next_summary_);
1644 next_summary_ = NULL;
1645 }
1646
1647
1648 void LAllocator::SummarizeInstruction(int index) {
1649 InstructionSummary* sum = summary_stack_.RemoveLast();
1650 if (summaries_.length() <= index) {
1651 summaries_.AddBlock(NULL, index + 1 - summaries_.length());
1652 }
1653 ASSERT(summaries_[index] == NULL);
1654 if (sum->Output() != NULL || sum->InputCount() > 0 || sum->TempCount() > 0) {
1655 summaries_[index] = sum;
1656 } else {
1657 next_summary_ = sum;
1658 }
1659 }
1660
1661
1662 void LAllocator::OmitInstruction() {
1663 summary_stack_.RemoveLast();
1664 }
1665
1666
1667 void LAllocator::AddToActive(LiveRange* range) { 1600 void LAllocator::AddToActive(LiveRange* range) {
1668 TraceAlloc("Add live range %d to active\n", range->id()); 1601 TraceAlloc("Add live range %d to active\n", range->id());
1669 active_live_ranges_.Add(range); 1602 active_live_ranges_.Add(range);
1670 } 1603 }
1671 1604
1672 1605
1673 void LAllocator::AddToInactive(LiveRange* range) { 1606 void LAllocator::AddToInactive(LiveRange* range) {
1674 TraceAlloc("Add live range %d to inactive\n", range->id()); 1607 TraceAlloc("Add live range %d to inactive\n", range->id());
1675 inactive_live_ranges_.Add(range); 1608 inactive_live_ranges_.Add(range);
1676 } 1609 }
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
2002 InactiveToHandled(range); 1935 InactiveToHandled(range);
2003 --i; 1936 --i;
2004 } 1937 }
2005 } 1938 }
2006 } 1939 }
2007 } 1940 }
2008 1941
2009 1942
2010 bool LAllocator::IsBlockBoundary(LifetimePosition pos) { 1943 bool LAllocator::IsBlockBoundary(LifetimePosition pos) {
2011 return pos.IsInstructionStart() && 1944 return pos.IsInstructionStart() &&
2012 chunk_->instructions()->at(pos.InstructionIndex())->IsLabel(); 1945 InstructionAt(pos.InstructionIndex())->IsLabel();
2013 } 1946 }
2014 1947
2015 1948
2016 LiveRange* LAllocator::SplitAt(LiveRange* range, LifetimePosition pos) { 1949 LiveRange* LAllocator::SplitAt(LiveRange* range, LifetimePosition pos) {
2017 ASSERT(!range->IsFixed()); 1950 ASSERT(!range->IsFixed());
2018 TraceAlloc("Splitting live range %d at %d\n", range->id(), pos.Value()); 1951 TraceAlloc("Splitting live range %d at %d\n", range->id(), pos.Value());
2019 1952
2020 if (pos.Value() <= range->Start().Value()) return range; 1953 if (pos.Value() <= range->Start().Value()) return range;
2021 1954
1955 // We can't properly connect liveranges if split occured at the end
1956 // of control instruction.
1957 ASSERT(pos.IsInstructionStart() ||
1958 !chunk_->instructions()->at(pos.InstructionIndex())->IsControl());
1959
2022 LiveRange* result = LiveRangeFor(next_virtual_register_++); 1960 LiveRange* result = LiveRangeFor(next_virtual_register_++);
2023 range->SplitAt(pos, result); 1961 range->SplitAt(pos, result);
2024 return result; 1962 return result;
2025 } 1963 }
2026 1964
2027 1965
2028 LiveRange* LAllocator::SplitBetween(LiveRange* range, 1966 LiveRange* LAllocator::SplitBetween(LiveRange* range,
2029 LifetimePosition start, 1967 LifetimePosition start,
2030 LifetimePosition end) { 1968 LifetimePosition end) {
2031 ASSERT(!range->IsFixed()); 1969 ASSERT(!range->IsFixed());
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
2132 LiveRange* current = live_ranges()->at(i); 2070 LiveRange* current = live_ranges()->at(i);
2133 if (current != NULL) current->Verify(); 2071 if (current != NULL) current->Verify();
2134 } 2072 }
2135 } 2073 }
2136 2074
2137 2075
2138 #endif 2076 #endif
2139 2077
2140 2078
2141 } } // namespace v8::internal 2079 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/lithium-allocator.h ('k') | src/lithium-allocator-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698