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

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

Issue 6352006: Remove instruction summaries and provide a LIR-interface for the register all... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: addressed comments, rebased and ported to ARM and x64 Created 9 years, 11 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"
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 } else { 525 } else {
526 b = b->next(); 526 b = b->next();
527 } 527 }
528 } 528 }
529 return LifetimePosition::Invalid(); 529 return LifetimePosition::Invalid();
530 } 530 }
531 531
532 532
533 void LAllocator::InitializeLivenessAnalysis() { 533 void LAllocator::InitializeLivenessAnalysis() {
534 // Initialize the live_in sets for each block to NULL. 534 // Initialize the live_in sets for each block to NULL.
535 int block_count = graph()->blocks()->length(); 535 int block_count = graph_->blocks()->length();
536 live_in_sets_.Initialize(block_count); 536 live_in_sets_.Initialize(block_count);
537 live_in_sets_.AddBlock(NULL, block_count); 537 live_in_sets_.AddBlock(NULL, block_count);
538 } 538 }
539 539
540 540
541 BitVector* LAllocator::ComputeLiveOut(HBasicBlock* block) { 541 BitVector* LAllocator::ComputeLiveOut(HBasicBlock* block) {
542 // Compute live out for the given block, except not including backward 542 // Compute live out for the given block, except not including backward
543 // successor edges. 543 // successor edges.
544 BitVector* live_out = new BitVector(next_virtual_register_); 544 BitVector* live_out = new BitVector(next_virtual_register_);
545 545
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 int reg_index = operand->fixed_index(); 606 int reg_index = operand->fixed_index();
607 operand->ConvertTo(LOperand::REGISTER, reg_index); 607 operand->ConvertTo(LOperand::REGISTER, reg_index);
608 } else if (operand->policy() == LUnallocated::FIXED_DOUBLE_REGISTER) { 608 } else if (operand->policy() == LUnallocated::FIXED_DOUBLE_REGISTER) {
609 int reg_index = operand->fixed_index(); 609 int reg_index = operand->fixed_index();
610 operand->ConvertTo(LOperand::DOUBLE_REGISTER, reg_index); 610 operand->ConvertTo(LOperand::DOUBLE_REGISTER, reg_index);
611 } else { 611 } else {
612 UNREACHABLE(); 612 UNREACHABLE();
613 } 613 }
614 if (is_tagged) { 614 if (is_tagged) {
615 TraceAlloc("Fixed reg is tagged at %d\n", pos); 615 TraceAlloc("Fixed reg is tagged at %d\n", pos);
616 LInstruction* instr = chunk_->instructions()->at(pos); 616 LInstruction* instr = InstructionAt(pos);
617 if (instr->HasPointerMap()) { 617 if (instr->HasPointerMap()) {
618 instr->pointer_map()->RecordPointer(operand); 618 instr->pointer_map()->RecordPointer(operand);
619 } 619 }
620 } 620 }
621 return operand; 621 return operand;
622 } 622 }
623 623
624 624
625 LiveRange* LAllocator::FixedLiveRangeFor(int index) { 625 LiveRange* LAllocator::FixedLiveRangeFor(int index) {
626 if (index >= fixed_live_ranges_.length()) { 626 if (index >= fixed_live_ranges_.length()) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 } 661 }
662 LiveRange* result = live_ranges_[index]; 662 LiveRange* result = live_ranges_[index];
663 if (result == NULL) { 663 if (result == NULL) {
664 result = new LiveRange(index); 664 result = new LiveRange(index);
665 live_ranges_[index] = result; 665 live_ranges_[index] = result;
666 } 666 }
667 return result; 667 return result;
668 } 668 }
669 669
670 670
671 LGap* LAllocator::GetLastGap(HBasicBlock* block) const { 671 LGap* LAllocator::GetLastGap(HBasicBlock* block) {
672 int last_instruction = block->last_instruction_index(); 672 int last_instruction = block->last_instruction_index();
673 int index = chunk_->NearestGapPos(last_instruction); 673 int index = chunk_->NearestGapPos(last_instruction);
674 return chunk_->GetGapAt(index); 674 return GapAt(index);
675 } 675 }
676 676
677 677
678 HPhi* LAllocator::LookupPhi(LOperand* operand) const { 678 HPhi* LAllocator::LookupPhi(LOperand* operand) const {
679 if (!operand->IsUnallocated()) return NULL; 679 if (!operand->IsUnallocated()) return NULL;
680 int index = operand->VirtualRegister(); 680 int index = operand->VirtualRegister();
681 HValue* instr = graph()->LookupValue(index); 681 HValue* instr = graph_->LookupValue(index);
682 if (instr != NULL && instr->IsPhi()) { 682 if (instr != NULL && instr->IsPhi()) {
683 return HPhi::cast(instr); 683 return HPhi::cast(instr);
684 } 684 }
685 return NULL; 685 return NULL;
686 } 686 }
687 687
688 688
689 LiveRange* LAllocator::LiveRangeFor(LOperand* operand) { 689 LiveRange* LAllocator::LiveRangeFor(LOperand* operand) {
690 if (operand->IsUnallocated()) { 690 if (operand->IsUnallocated()) {
691 return LiveRangeFor(LUnallocated::cast(operand)->virtual_register()); 691 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); 730 LUnallocated* unalloc_operand = LUnallocated::cast(operand);
731 range->AddUsePosition(position, unalloc_operand)->set_hint(hint); 731 range->AddUsePosition(position, unalloc_operand)->set_hint(hint);
732 } 732 }
733 range->AddUseInterval(block_start, position); 733 range->AddUseInterval(block_start, position);
734 } 734 }
735 735
736 736
737 void LAllocator::AddConstraintsGapMove(int index, 737 void LAllocator::AddConstraintsGapMove(int index,
738 LOperand* from, 738 LOperand* from,
739 LOperand* to) { 739 LOperand* to) {
740 LGap* gap = chunk_->GetGapAt(index); 740 LGap* gap = GapAt(index);
741 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START); 741 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START);
742 if (from->IsUnallocated()) { 742 if (from->IsUnallocated()) {
743 const ZoneList<LMoveOperands>* move_operands = move->move_operands(); 743 const ZoneList<LMoveOperands>* move_operands = move->move_operands();
744 for (int i = 0; i < move_operands->length(); ++i) { 744 for (int i = 0; i < move_operands->length(); ++i) {
745 LMoveOperands cur = move_operands->at(i); 745 LMoveOperands cur = move_operands->at(i);
746 LOperand* cur_to = cur.destination(); 746 LOperand* cur_to = cur.destination();
747 if (cur_to->IsUnallocated()) { 747 if (cur_to->IsUnallocated()) {
748 if (cur_to->VirtualRegister() == from->VirtualRegister()) { 748 if (cur_to->VirtualRegister() == from->VirtualRegister()) {
749 move->AddMove(cur.source(), to); 749 move->AddMove(cur.source(), to);
750 return; 750 return;
751 } 751 }
752 } 752 }
753 } 753 }
754 } 754 }
755 move->AddMove(from, to); 755 move->AddMove(from, to);
756 } 756 }
757 757
758 758
759 void LAllocator::MeetRegisterConstraints(HBasicBlock* block) { 759 void LAllocator::MeetRegisterConstraints(HBasicBlock* block) {
760 int start = block->first_instruction_index(); 760 int start = block->first_instruction_index();
761 int end = block->last_instruction_index(); 761 int end = block->last_instruction_index();
762 for (int i = start; i <= end; ++i) { 762 for (int i = start; i <= end; ++i) {
763 if (chunk_->IsGapAt(i)) { 763 if (IsGapAt(i)) {
764 InstructionSummary* summary = NULL; 764 LInstruction* instr = NULL;
765 InstructionSummary* prev_summary = NULL; 765 LInstruction* prev_instr = NULL;
766 if (i < end) summary = GetSummary(i + 1); 766 if (i < end) instr = InstructionAt(i + 1);
767 if (i > start) prev_summary = GetSummary(i - 1); 767 if (i > start) prev_instr = InstructionAt(i - 1);
768 MeetConstraintsBetween(prev_summary, summary, i); 768 MeetConstraintsBetween(prev_instr, instr, i);
769 } 769 }
770 } 770 }
771 } 771 }
772 772
773 773
774 void LAllocator::MeetConstraintsBetween(InstructionSummary* first, 774 void LAllocator::MeetConstraintsBetween(LInstruction* first,
775 InstructionSummary* second, 775 LInstruction* second,
776 int gap_index) { 776 int gap_index) {
777 // Handle fixed temporaries. 777 // Handle fixed temporaries.
778 if (first != NULL) { 778 if (first != NULL) {
779 for (int i = 0; i < first->TempCount(); ++i) { 779 for (TempIterator it(first); it.HasNext(); it.Advance()) {
780 LUnallocated* temp = LUnallocated::cast(first->TempAt(i)); 780 LUnallocated* temp = LUnallocated::cast(it.Next());
781 if (temp->HasFixedPolicy()) { 781 if (temp->HasFixedPolicy()) {
782 AllocateFixed(temp, gap_index - 1, false); 782 AllocateFixed(temp, gap_index - 1, false);
783 } 783 }
784 } 784 }
785 } 785 }
786 786
787 // Handle fixed output operand. 787 // Handle fixed output operand.
788 if (first != NULL && first->Output() != NULL) { 788 if (first != NULL && first->Output() != NULL) {
789 LUnallocated* first_output = LUnallocated::cast(first->Output()); 789 LUnallocated* first_output = LUnallocated::cast(first->Output());
790 LiveRange* range = LiveRangeFor(first_output->VirtualRegister()); 790 LiveRange* range = LiveRangeFor(first_output->VirtualRegister());
(...skipping 12 matching lines...) Expand all
803 chunk_->AddGapMove(gap_index, first_output, output_copy); 803 chunk_->AddGapMove(gap_index, first_output, output_copy);
804 } 804 }
805 805
806 if (!assigned) { 806 if (!assigned) {
807 range->SetSpillStartIndex(gap_index); 807 range->SetSpillStartIndex(gap_index);
808 808
809 // This move to spill operand is not a real use. Liveness analysis 809 // This move to spill operand is not a real use. Liveness analysis
810 // and splitting of live ranges do not account for it. 810 // and splitting of live ranges do not account for it.
811 // Thus it should be inserted to a lifetime position corresponding to 811 // Thus it should be inserted to a lifetime position corresponding to
812 // the instruction end. 812 // the instruction end.
813 LGap* gap = chunk_->GetGapAt(gap_index); 813 LGap* gap = GapAt(gap_index);
814 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::BEFORE); 814 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::BEFORE);
815 move->AddMove(first_output, range->GetSpillOperand()); 815 move->AddMove(first_output, range->GetSpillOperand());
816 } 816 }
817 } 817 }
818 818
819 // Handle fixed input operands of second instruction. 819 // Handle fixed input operands of second instruction.
820 if (second != NULL) { 820 if (second != NULL) {
821 for (int i = 0; i < second->InputCount(); ++i) { 821 for (UseIterator it(second); it.HasNext(); it.Advance()) {
822 LUnallocated* cur_input = LUnallocated::cast(second->InputAt(i)); 822 LUnallocated* cur_input = LUnallocated::cast(it.Next());
823 if (cur_input->HasFixedPolicy()) { 823 if (cur_input->HasFixedPolicy()) {
824 LUnallocated* input_copy = cur_input->CopyUnconstrained(); 824 LUnallocated* input_copy = cur_input->CopyUnconstrained();
825 bool is_tagged = HasTaggedValue(cur_input->VirtualRegister()); 825 bool is_tagged = HasTaggedValue(cur_input->VirtualRegister());
826 AllocateFixed(cur_input, gap_index + 1, is_tagged); 826 AllocateFixed(cur_input, gap_index + 1, is_tagged);
827 AddConstraintsGapMove(gap_index, input_copy, cur_input); 827 AddConstraintsGapMove(gap_index, input_copy, cur_input);
828 } else if (cur_input->policy() == LUnallocated::WRITABLE_REGISTER) { 828 } else if (cur_input->policy() == LUnallocated::WRITABLE_REGISTER) {
829 // The live range of writable input registers always goes until the end 829 // The live range of writable input registers always goes until the end
830 // of the instruction. 830 // of the instruction.
831 ASSERT(!cur_input->IsUsedAtStart()); 831 ASSERT(!cur_input->IsUsedAtStart());
832 832
833 LUnallocated* input_copy = cur_input->CopyUnconstrained(); 833 LUnallocated* input_copy = cur_input->CopyUnconstrained();
834 cur_input->set_virtual_register(next_virtual_register_++); 834 cur_input->set_virtual_register(next_virtual_register_++);
835 835
836 if (RequiredRegisterKind(input_copy->virtual_register()) == 836 if (RequiredRegisterKind(input_copy->virtual_register()) ==
837 DOUBLE_REGISTERS) { 837 DOUBLE_REGISTERS) {
838 double_artificial_registers_.Add( 838 double_artificial_registers_.Add(
839 cur_input->virtual_register() - first_artificial_register_); 839 cur_input->virtual_register() - first_artificial_register_);
840 } 840 }
841 841
842 AddConstraintsGapMove(gap_index, input_copy, cur_input); 842 AddConstraintsGapMove(gap_index, input_copy, cur_input);
843 } 843 }
844 } 844 }
845 } 845 }
846 846
847 // Handle "output same as input" for second instruction. 847 // Handle "output same as input" for second instruction.
848 if (second != NULL && second->Output() != NULL) { 848 if (second != NULL && second->Output() != NULL) {
849 LUnallocated* second_output = LUnallocated::cast(second->Output()); 849 LUnallocated* second_output = LUnallocated::cast(second->Output());
850 if (second_output->HasSameAsInputPolicy()) { 850 if (second_output->HasSameAsInputPolicy()) {
851 LUnallocated* cur_input = LUnallocated::cast(second->InputAt(0)); 851 LUnallocated* cur_input = LUnallocated::cast(second->FirstInput());
852 int output_vreg = second_output->VirtualRegister(); 852 int output_vreg = second_output->VirtualRegister();
853 int input_vreg = cur_input->VirtualRegister(); 853 int input_vreg = cur_input->VirtualRegister();
854 854
855 LUnallocated* input_copy = cur_input->CopyUnconstrained(); 855 LUnallocated* input_copy = cur_input->CopyUnconstrained();
856 cur_input->set_virtual_register(second_output->virtual_register()); 856 cur_input->set_virtual_register(second_output->virtual_register());
857 AddConstraintsGapMove(gap_index, input_copy, cur_input); 857 AddConstraintsGapMove(gap_index, input_copy, cur_input);
858 858
859 if (HasTaggedValue(input_vreg) && !HasTaggedValue(output_vreg)) { 859 if (HasTaggedValue(input_vreg) && !HasTaggedValue(output_vreg)) {
860 int index = gap_index + 1; 860 int index = gap_index + 1;
861 LInstruction* instr = chunk_->instructions()->at(index); 861 LInstruction* instr = InstructionAt(index);
862 if (instr->HasPointerMap()) { 862 if (instr->HasPointerMap()) {
863 instr->pointer_map()->RecordPointer(input_copy); 863 instr->pointer_map()->RecordPointer(input_copy);
864 } 864 }
865 } else if (!HasTaggedValue(input_vreg) && HasTaggedValue(output_vreg)) { 865 } else if (!HasTaggedValue(input_vreg) && HasTaggedValue(output_vreg)) {
866 // The input is assumed to immediately have a tagged representation, 866 // 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 867 // 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 868 // instruction will include the output operand (whose value at the
869 // beginning of the instruction is equal to the input operand). If 869 // beginning of the instruction is equal to the input operand). If
870 // this is not desired, then the pointer map at this instruction needs 870 // this is not desired, then the pointer map at this instruction needs
871 // to be adjusted manually. 871 // to be adjusted manually.
872 } 872 }
873 } 873 }
874 } 874 }
875 } 875 }
876 876
877 877
878 void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) { 878 void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) {
879 int block_start = block->first_instruction_index(); 879 int block_start = block->first_instruction_index();
880 int index = block->last_instruction_index(); 880 int index = block->last_instruction_index();
881 881
882 LifetimePosition block_start_position = 882 LifetimePosition block_start_position =
883 LifetimePosition::FromInstructionIndex(block_start); 883 LifetimePosition::FromInstructionIndex(block_start);
884 884
885 while (index >= block_start) { 885 while (index >= block_start) {
886 LifetimePosition curr_position = 886 LifetimePosition curr_position =
887 LifetimePosition::FromInstructionIndex(index); 887 LifetimePosition::FromInstructionIndex(index);
888 888
889 if (chunk_->IsGapAt(index)) { 889 if (IsGapAt(index)) {
890 // We have a gap at this position. 890 // We have a gap at this position.
891 LGap* gap = chunk_->GetGapAt(index); 891 LGap* gap = GapAt(index);
892 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START); 892 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START);
893 const ZoneList<LMoveOperands>* move_operands = move->move_operands(); 893 const ZoneList<LMoveOperands>* move_operands = move->move_operands();
894 for (int i = 0; i < move_operands->length(); ++i) { 894 for (int i = 0; i < move_operands->length(); ++i) {
895 LMoveOperands* cur = &move_operands->at(i); 895 LMoveOperands* cur = &move_operands->at(i);
896 if (cur->IsIgnored()) continue; 896 if (cur->IsIgnored()) continue;
897 LOperand* from = cur->source(); 897 LOperand* from = cur->source();
898 LOperand* to = cur->destination(); 898 LOperand* to = cur->destination();
899 HPhi* phi = LookupPhi(to); 899 HPhi* phi = LookupPhi(to);
900 LOperand* hint = to; 900 LOperand* hint = to;
901 if (phi != NULL) { 901 if (phi != NULL) {
(...skipping 13 matching lines...) Expand all
915 } else { 915 } else {
916 Define(curr_position, to, from); 916 Define(curr_position, to, from);
917 } 917 }
918 } 918 }
919 Use(block_start_position, curr_position, from, hint); 919 Use(block_start_position, curr_position, from, hint);
920 if (from->IsUnallocated()) { 920 if (from->IsUnallocated()) {
921 live->Add(from->VirtualRegister()); 921 live->Add(from->VirtualRegister());
922 } 922 }
923 } 923 }
924 } else { 924 } else {
925 ASSERT(!chunk_->IsGapAt(index)); 925 ASSERT(!IsGapAt(index));
926 InstructionSummary* summary = GetSummary(index); 926 LInstruction* instr = InstructionAt(index);
927 927
928 if (summary != NULL) { 928 if (instr != NULL) {
929 LOperand* output = summary->Output(); 929 LOperand* output = instr->Output();
930 if (output != NULL) { 930 if (output != NULL) {
931 if (output->IsUnallocated()) live->Remove(output->VirtualRegister()); 931 if (output->IsUnallocated()) live->Remove(output->VirtualRegister());
932 Define(curr_position, output, NULL); 932 Define(curr_position, output, NULL);
933 } 933 }
934 934
935 if (summary->IsCall()) { 935 if (instr->IsMarkedAsCall()) {
936 for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) { 936 for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) {
937 if (output == NULL || !output->IsRegister() || 937 if (output == NULL || !output->IsRegister() ||
938 output->index() != i) { 938 output->index() != i) {
939 LiveRange* range = FixedLiveRangeFor(i); 939 LiveRange* range = FixedLiveRangeFor(i);
940 range->AddUseInterval(curr_position, 940 range->AddUseInterval(curr_position,
941 curr_position.InstructionEnd()); 941 curr_position.InstructionEnd());
942 } 942 }
943 } 943 }
944 } 944 }
945 945
946 if (summary->IsCall() || summary->IsSaveDoubles()) { 946 if (instr->IsMarkedAsCall() || instr->IsMarkedAsSaveDoubles()) {
947 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) { 947 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) {
948 if (output == NULL || !output->IsDoubleRegister() || 948 if (output == NULL || !output->IsDoubleRegister() ||
949 output->index() != i) { 949 output->index() != i) {
950 LiveRange* range = FixedDoubleLiveRangeFor(i); 950 LiveRange* range = FixedDoubleLiveRangeFor(i);
951 range->AddUseInterval(curr_position, 951 range->AddUseInterval(curr_position,
952 curr_position.InstructionEnd()); 952 curr_position.InstructionEnd());
953 } 953 }
954 } 954 }
955 } 955 }
956 956
957 for (int i = 0; i < summary->InputCount(); ++i) { 957 for (UseIterator it(instr); it.HasNext(); it.Advance()) {
958 LOperand* input = summary->InputAt(i); 958 LOperand* input = it.Next();
959 959
960 LifetimePosition use_pos; 960 LifetimePosition use_pos;
961 if (input->IsUnallocated() && 961 if (input->IsUnallocated() &&
962 LUnallocated::cast(input)->IsUsedAtStart()) { 962 LUnallocated::cast(input)->IsUsedAtStart()) {
963 use_pos = curr_position; 963 use_pos = curr_position;
964 } else { 964 } else {
965 use_pos = curr_position.InstructionEnd(); 965 use_pos = curr_position.InstructionEnd();
966 } 966 }
967 967
968 Use(block_start_position, use_pos, input, NULL); 968 Use(block_start_position, use_pos, input, NULL);
969 if (input->IsUnallocated()) live->Add(input->VirtualRegister()); 969 if (input->IsUnallocated()) live->Add(input->VirtualRegister());
970 } 970 }
971 971
972 for (int i = 0; i < summary->TempCount(); ++i) { 972 for (TempIterator it(instr); it.HasNext(); it.Advance()) {
973 LOperand* temp = summary->TempAt(i); 973 LOperand* temp = it.Next();
974 if (summary->IsCall()) { 974 if (instr->IsMarkedAsCall()) {
975 if (temp->IsRegister()) continue; 975 if (temp->IsRegister()) continue;
976 if (temp->IsUnallocated()) { 976 if (temp->IsUnallocated()) {
977 LUnallocated* temp_unalloc = LUnallocated::cast(temp); 977 LUnallocated* temp_unalloc = LUnallocated::cast(temp);
978 if (temp_unalloc->HasFixedPolicy()) { 978 if (temp_unalloc->HasFixedPolicy()) {
979 continue; 979 continue;
980 } 980 }
981 } 981 }
982 } 982 }
983 Use(block_start_position, curr_position.InstructionEnd(), temp, NULL); 983 Use(block_start_position, curr_position.InstructionEnd(), temp, NULL);
984 Define(curr_position, temp, NULL); 984 Define(curr_position, temp, NULL);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 AllocateGeneralRegisters(); 1035 AllocateGeneralRegisters();
1036 AllocateDoubleRegisters(); 1036 AllocateDoubleRegisters();
1037 PopulatePointerMaps(); 1037 PopulatePointerMaps();
1038 if (has_osr_entry_) ProcessOsrEntry(); 1038 if (has_osr_entry_) ProcessOsrEntry();
1039 ConnectRanges(); 1039 ConnectRanges();
1040 ResolveControlFlow(); 1040 ResolveControlFlow();
1041 } 1041 }
1042 1042
1043 1043
1044 void LAllocator::MeetRegisterConstraints() { 1044 void LAllocator::MeetRegisterConstraints() {
1045 HPhase phase("Register constraints", chunk()); 1045 HPhase phase("Register constraints", chunk_);
1046 first_artificial_register_ = next_virtual_register_; 1046 first_artificial_register_ = next_virtual_register_;
1047 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); 1047 const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
1048 for (int i = 0; i < blocks->length(); ++i) { 1048 for (int i = 0; i < blocks->length(); ++i) {
1049 HBasicBlock* block = blocks->at(i); 1049 HBasicBlock* block = blocks->at(i);
1050 MeetRegisterConstraints(block); 1050 MeetRegisterConstraints(block);
1051 } 1051 }
1052 } 1052 }
1053 1053
1054 1054
1055 void LAllocator::ResolvePhis() { 1055 void LAllocator::ResolvePhis() {
1056 HPhase phase("Resolve phis", chunk()); 1056 HPhase phase("Resolve phis", chunk_);
1057 1057
1058 // Process the blocks in reverse order. 1058 // Process the blocks in reverse order.
1059 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); 1059 const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
1060 for (int block_id = blocks->length() - 1; block_id >= 0; --block_id) { 1060 for (int block_id = blocks->length() - 1; block_id >= 0; --block_id) {
1061 HBasicBlock* block = blocks->at(block_id); 1061 HBasicBlock* block = blocks->at(block_id);
1062 ResolvePhis(block); 1062 ResolvePhis(block);
1063 } 1063 }
1064 } 1064 }
1065 1065
1066 1066
1067 void LAllocator::ResolveControlFlow(LiveRange* range, 1067 void LAllocator::ResolveControlFlow(LiveRange* range,
1068 HBasicBlock* block, 1068 HBasicBlock* block,
1069 HBasicBlock* pred) { 1069 HBasicBlock* pred) {
(...skipping 19 matching lines...) Expand all
1089 } 1089 }
1090 1090
1091 if (cur_cover->IsSpilled()) return; 1091 if (cur_cover->IsSpilled()) return;
1092 ASSERT(pred_cover != NULL && cur_cover != NULL); 1092 ASSERT(pred_cover != NULL && cur_cover != NULL);
1093 if (pred_cover != cur_cover) { 1093 if (pred_cover != cur_cover) {
1094 LOperand* pred_op = pred_cover->CreateAssignedOperand(); 1094 LOperand* pred_op = pred_cover->CreateAssignedOperand();
1095 LOperand* cur_op = cur_cover->CreateAssignedOperand(); 1095 LOperand* cur_op = cur_cover->CreateAssignedOperand();
1096 if (!pred_op->Equals(cur_op)) { 1096 if (!pred_op->Equals(cur_op)) {
1097 LGap* gap = NULL; 1097 LGap* gap = NULL;
1098 if (block->predecessors()->length() == 1) { 1098 if (block->predecessors()->length() == 1) {
1099 gap = chunk_->GetGapAt(block->first_instruction_index()); 1099 gap = GapAt(block->first_instruction_index());
1100 } else { 1100 } else {
1101 ASSERT(pred->end()->SecondSuccessor() == NULL); 1101 ASSERT(pred->end()->SecondSuccessor() == NULL);
1102 gap = GetLastGap(pred); 1102 gap = GetLastGap(pred);
1103 } 1103 }
1104 gap->GetOrCreateParallelMove(LGap::START)->AddMove(pred_op, cur_op); 1104 gap->GetOrCreateParallelMove(LGap::START)->AddMove(pred_op, cur_op);
1105 } 1105 }
1106 } 1106 }
1107 } 1107 }
1108 1108
1109 1109
1110 LParallelMove* LAllocator::GetConnectingParallelMove(LifetimePosition pos) { 1110 LParallelMove* LAllocator::GetConnectingParallelMove(LifetimePosition pos) {
1111 int index = pos.InstructionIndex(); 1111 int index = pos.InstructionIndex();
1112 if (chunk_->IsGapAt(index)) { 1112 if (IsGapAt(index)) {
1113 LGap* gap = chunk_->GetGapAt(index); 1113 LGap* gap = GapAt(index);
1114 return gap->GetOrCreateParallelMove( 1114 return gap->GetOrCreateParallelMove(
1115 pos.IsInstructionStart() ? LGap::START : LGap::END); 1115 pos.IsInstructionStart() ? LGap::START : LGap::END);
1116 } 1116 }
1117 int gap_pos = pos.IsInstructionStart() ? (index - 1) : (index + 1); 1117 int gap_pos = pos.IsInstructionStart() ? (index - 1) : (index + 1);
1118 return chunk_->GetGapAt(gap_pos)->GetOrCreateParallelMove( 1118 return GapAt(gap_pos)->GetOrCreateParallelMove(
1119 (gap_pos < index) ? LGap::AFTER : LGap::BEFORE); 1119 (gap_pos < index) ? LGap::AFTER : LGap::BEFORE);
1120 } 1120 }
1121 1121
1122 1122
1123 HBasicBlock* LAllocator::GetBlock(LifetimePosition pos) { 1123 HBasicBlock* LAllocator::GetBlock(LifetimePosition pos) {
1124 LGap* gap = chunk_->GetGapAt(chunk_->NearestGapPos(pos.InstructionIndex())); 1124 LGap* gap = GapAt(chunk_->NearestGapPos(pos.InstructionIndex()));
1125 return gap->block(); 1125 return gap->block();
1126 } 1126 }
1127 1127
1128 1128
1129 void LAllocator::ConnectRanges() { 1129 void LAllocator::ConnectRanges() {
1130 HPhase phase("Connect ranges", this); 1130 HPhase phase("Connect ranges", this);
1131 for (int i = 0; i < live_ranges()->length(); ++i) { 1131 for (int i = 0; i < live_ranges()->length(); ++i) {
1132 LiveRange* first_range = live_ranges()->at(i); 1132 LiveRange* first_range = live_ranges()->at(i);
1133 if (first_range == NULL || first_range->parent() != NULL) continue; 1133 if (first_range == NULL || first_range->parent() != NULL) continue;
1134 1134
(...skipping 26 matching lines...) Expand all
1161 1161
1162 1162
1163 bool LAllocator::CanEagerlyResolveControlFlow(HBasicBlock* block) const { 1163 bool LAllocator::CanEagerlyResolveControlFlow(HBasicBlock* block) const {
1164 if (block->predecessors()->length() != 1) return false; 1164 if (block->predecessors()->length() != 1) return false;
1165 return block->predecessors()->first()->block_id() == block->block_id() - 1; 1165 return block->predecessors()->first()->block_id() == block->block_id() - 1;
1166 } 1166 }
1167 1167
1168 1168
1169 void LAllocator::ResolveControlFlow() { 1169 void LAllocator::ResolveControlFlow() {
1170 HPhase phase("Resolve control flow", this); 1170 HPhase phase("Resolve control flow", this);
1171 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); 1171 const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
1172 for (int block_id = 1; block_id < blocks->length(); ++block_id) { 1172 for (int block_id = 1; block_id < blocks->length(); ++block_id) {
1173 HBasicBlock* block = blocks->at(block_id); 1173 HBasicBlock* block = blocks->at(block_id);
1174 if (CanEagerlyResolveControlFlow(block)) continue; 1174 if (CanEagerlyResolveControlFlow(block)) continue;
1175 BitVector* live = live_in_sets_[block->block_id()]; 1175 BitVector* live = live_in_sets_[block->block_id()];
1176 BitVector::Iterator iterator(live); 1176 BitVector::Iterator iterator(live);
1177 while (!iterator.Done()) { 1177 while (!iterator.Done()) {
1178 int operand_index = iterator.Current(); 1178 int operand_index = iterator.Current();
1179 for (int i = 0; i < block->predecessors()->length(); ++i) { 1179 for (int i = 0; i < block->predecessors()->length(); ++i) {
1180 HBasicBlock* cur = block->predecessors()->at(i); 1180 HBasicBlock* cur = block->predecessors()->at(i);
1181 LiveRange* cur_range = LiveRangeFor(operand_index); 1181 LiveRange* cur_range = LiveRangeFor(operand_index);
1182 ResolveControlFlow(cur_range, block, cur); 1182 ResolveControlFlow(cur_range, block, cur);
1183 } 1183 }
1184 iterator.Advance(); 1184 iterator.Advance();
1185 } 1185 }
1186 } 1186 }
1187 } 1187 }
1188 1188
1189 1189
1190 void LAllocator::BuildLiveRanges() { 1190 void LAllocator::BuildLiveRanges() {
1191 HPhase phase("Build live ranges", this); 1191 HPhase phase("Build live ranges", this);
1192 InitializeLivenessAnalysis(); 1192 InitializeLivenessAnalysis();
1193 // Process the blocks in reverse order. 1193 // Process the blocks in reverse order.
1194 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); 1194 const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
1195 for (int block_id = blocks->length() - 1; block_id >= 0; --block_id) { 1195 for (int block_id = blocks->length() - 1; block_id >= 0; --block_id) {
1196 HBasicBlock* block = blocks->at(block_id); 1196 HBasicBlock* block = blocks->at(block_id);
1197 BitVector* live = ComputeLiveOut(block); 1197 BitVector* live = ComputeLiveOut(block);
1198 // Initially consider all live_out values live for the entire block. We 1198 // Initially consider all live_out values live for the entire block. We
1199 // will shorten these intervals if necessary. 1199 // will shorten these intervals if necessary.
1200 AddInitialIntervals(block, live); 1200 AddInitialIntervals(block, live);
1201 1201
1202 // Process the instructions in reverse order, generating and killing 1202 // Process the instructions in reverse order, generating and killing
1203 // live values. 1203 // live values.
1204 ProcessInstructions(block, live); 1204 ProcessInstructions(block, live);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1259 } 1259 }
1260 1260
1261 #ifdef DEBUG 1261 #ifdef DEBUG
1262 if (block_id == 0) { 1262 if (block_id == 0) {
1263 BitVector::Iterator iterator(live); 1263 BitVector::Iterator iterator(live);
1264 bool found = false; 1264 bool found = false;
1265 while (!iterator.Done()) { 1265 while (!iterator.Done()) {
1266 found = true; 1266 found = true;
1267 int operand_index = iterator.Current(); 1267 int operand_index = iterator.Current();
1268 PrintF("Function: %s\n", 1268 PrintF("Function: %s\n",
1269 *graph()->info()->function()->debug_name()->ToCString()); 1269 *graph_->info()->function()->debug_name()->ToCString());
1270 PrintF("Value %d used before first definition!\n", operand_index); 1270 PrintF("Value %d used before first definition!\n", operand_index);
1271 LiveRange* range = LiveRangeFor(operand_index); 1271 LiveRange* range = LiveRangeFor(operand_index);
1272 PrintF("First use is at %d\n", range->first_pos()->pos().Value()); 1272 PrintF("First use is at %d\n", range->first_pos()->pos().Value());
1273 iterator.Advance(); 1273 iterator.Advance();
1274 } 1274 }
1275 ASSERT(!found); 1275 ASSERT(!found);
1276 } 1276 }
1277 #endif 1277 #endif
1278 } 1278 }
1279 } 1279 }
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1464 LiveRange* current = unhandled_live_ranges_.RemoveLast(); 1464 LiveRange* current = unhandled_live_ranges_.RemoveLast();
1465 ASSERT(UnhandledIsSorted()); 1465 ASSERT(UnhandledIsSorted());
1466 LifetimePosition position = current->Start(); 1466 LifetimePosition position = current->Start();
1467 TraceAlloc("Processing interval %d start=%d\n", 1467 TraceAlloc("Processing interval %d start=%d\n",
1468 current->id(), 1468 current->id(),
1469 position.Value()); 1469 position.Value());
1470 1470
1471 if (current->HasAllocatedSpillOperand()) { 1471 if (current->HasAllocatedSpillOperand()) {
1472 TraceAlloc("Live range %d already has a spill operand\n", current->id()); 1472 TraceAlloc("Live range %d already has a spill operand\n", current->id());
1473 LifetimePosition next_pos = position; 1473 LifetimePosition next_pos = position;
1474 if (chunk_->IsGapAt(next_pos.InstructionIndex())) { 1474 if (IsGapAt(next_pos.InstructionIndex())) {
1475 next_pos = next_pos.NextInstruction(); 1475 next_pos = next_pos.NextInstruction();
1476 } 1476 }
1477 UsePosition* pos = current->NextUsePositionRegisterIsBeneficial(next_pos); 1477 UsePosition* pos = current->NextUsePositionRegisterIsBeneficial(next_pos);
1478 // If the range already has a spill operand and it doesn't need a 1478 // 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. 1479 // register immediately, split it and spill the first part of the range.
1480 if (pos == NULL) { 1480 if (pos == NULL) {
1481 Spill(current); 1481 Spill(current);
1482 continue; 1482 continue;
1483 } else if (pos->pos().Value() > 1483 } else if (pos->pos().Value() >
1484 current->Start().NextInstruction().Value()) { 1484 current->Start().NextInstruction().Value()) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1551 void LAllocator::TraceAlloc(const char* msg, ...) { 1551 void LAllocator::TraceAlloc(const char* msg, ...) {
1552 if (FLAG_trace_alloc) { 1552 if (FLAG_trace_alloc) {
1553 va_list arguments; 1553 va_list arguments;
1554 va_start(arguments, msg); 1554 va_start(arguments, msg);
1555 OS::VPrint(msg, arguments); 1555 OS::VPrint(msg, arguments);
1556 va_end(arguments); 1556 va_end(arguments);
1557 } 1557 }
1558 } 1558 }
1559 1559
1560 1560
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 { 1561 bool LAllocator::HasTaggedValue(int virtual_register) const {
1568 HValue* value = graph()->LookupValue(virtual_register); 1562 HValue* value = graph_->LookupValue(virtual_register);
1569 if (value == NULL) return false; 1563 if (value == NULL) return false;
1570 return value->representation().IsTagged(); 1564 return value->representation().IsTagged();
1571 } 1565 }
1572 1566
1573 1567
1574 RegisterKind LAllocator::RequiredRegisterKind(int virtual_register) const { 1568 RegisterKind LAllocator::RequiredRegisterKind(int virtual_register) const {
1575 if (virtual_register < first_artificial_register_) { 1569 if (virtual_register < first_artificial_register_) {
1576 HValue* value = graph()->LookupValue(virtual_register); 1570 HValue* value = graph_->LookupValue(virtual_register);
1577 if (value != NULL && value->representation().IsDouble()) { 1571 if (value != NULL && value->representation().IsDouble()) {
1578 return DOUBLE_REGISTERS; 1572 return DOUBLE_REGISTERS;
1579 } 1573 }
1580 } else if (double_artificial_registers_.Contains( 1574 } else if (double_artificial_registers_.Contains(
1581 virtual_register - first_artificial_register_)) { 1575 virtual_register - first_artificial_register_)) {
1582 return DOUBLE_REGISTERS; 1576 return DOUBLE_REGISTERS;
1583 } 1577 }
1584 1578
1585 return GENERAL_REGISTERS; 1579 return GENERAL_REGISTERS;
1586 } 1580 }
1587 1581
1588 1582
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) { 1583 void LAllocator::RecordDefinition(HInstruction* instr, LUnallocated* operand) {
1620 operand->set_virtual_register(instr->id()); 1584 operand->set_virtual_register(instr->id());
1621 current_summary()->SetOutput(operand);
1622 } 1585 }
1623 1586
1624 1587
1625 void LAllocator::RecordTemporary(LUnallocated* operand) { 1588 void LAllocator::RecordTemporary(LUnallocated* operand) {
1626 ASSERT(next_virtual_register_ < LUnallocated::kMaxVirtualRegisters); 1589 ASSERT(next_virtual_register_ < LUnallocated::kMaxVirtualRegisters);
1627 if (!operand->HasFixedPolicy()) { 1590 if (!operand->HasFixedPolicy()) {
1628 operand->set_virtual_register(next_virtual_register_++); 1591 operand->set_virtual_register(next_virtual_register_++);
1629 } 1592 }
1630 current_summary()->AddTemp(operand); 1593 }
1594
1595
1596 void LAllocator::RecordUse(HValue* value, LUnallocated* operand) {
1597 operand->set_virtual_register(value->id());
1631 } 1598 }
1632 1599
1633 1600
1634 int LAllocator::max_initial_value_ids() { 1601 int LAllocator::max_initial_value_ids() {
1635 return LUnallocated::kMaxVirtualRegisters / 32; 1602 return LUnallocated::kMaxVirtualRegisters / 32;
1636 } 1603 }
1637 1604
1638 1605
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) { 1606 void LAllocator::AddToActive(LiveRange* range) {
1668 TraceAlloc("Add live range %d to active\n", range->id()); 1607 TraceAlloc("Add live range %d to active\n", range->id());
1669 active_live_ranges_.Add(range); 1608 active_live_ranges_.Add(range);
1670 } 1609 }
1671 1610
1672 1611
1673 void LAllocator::AddToInactive(LiveRange* range) { 1612 void LAllocator::AddToInactive(LiveRange* range) {
1674 TraceAlloc("Add live range %d to inactive\n", range->id()); 1613 TraceAlloc("Add live range %d to inactive\n", range->id());
1675 inactive_live_ranges_.Add(range); 1614 inactive_live_ranges_.Add(range);
1676 } 1615 }
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
2002 InactiveToHandled(range); 1941 InactiveToHandled(range);
2003 --i; 1942 --i;
2004 } 1943 }
2005 } 1944 }
2006 } 1945 }
2007 } 1946 }
2008 1947
2009 1948
2010 bool LAllocator::IsBlockBoundary(LifetimePosition pos) { 1949 bool LAllocator::IsBlockBoundary(LifetimePosition pos) {
2011 return pos.IsInstructionStart() && 1950 return pos.IsInstructionStart() &&
2012 chunk_->instructions()->at(pos.InstructionIndex())->IsLabel(); 1951 InstructionAt(pos.InstructionIndex())->IsLabel();
2013 } 1952 }
2014 1953
2015 1954
2016 LiveRange* LAllocator::SplitAt(LiveRange* range, LifetimePosition pos) { 1955 LiveRange* LAllocator::SplitAt(LiveRange* range, LifetimePosition pos) {
2017 ASSERT(!range->IsFixed()); 1956 ASSERT(!range->IsFixed());
2018 TraceAlloc("Splitting live range %d at %d\n", range->id(), pos.Value()); 1957 TraceAlloc("Splitting live range %d at %d\n", range->id(), pos.Value());
2019 1958
2020 if (pos.Value() <= range->Start().Value()) return range; 1959 if (pos.Value() <= range->Start().Value()) return range;
2021 1960
2022 LiveRange* result = LiveRangeFor(next_virtual_register_++); 1961 LiveRange* result = LiveRangeFor(next_virtual_register_++);
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
2132 LiveRange* current = live_ranges()->at(i); 2071 LiveRange* current = live_ranges()->at(i);
2133 if (current != NULL) current->Verify(); 2072 if (current != NULL) current->Verify();
2134 } 2073 }
2135 } 2074 }
2136 2075
2137 2076
2138 #endif 2077 #endif
2139 2078
2140 2079
2141 } } // namespace v8::internal 2080 } } // 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