OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 |
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
690 | 690 |
691 LGap* LAllocator::GetLastGap(HBasicBlock* block) { | 691 LGap* LAllocator::GetLastGap(HBasicBlock* block) { |
692 int last_instruction = block->last_instruction_index(); | 692 int last_instruction = block->last_instruction_index(); |
693 int index = chunk_->NearestGapPos(last_instruction); | 693 int index = chunk_->NearestGapPos(last_instruction); |
694 return GapAt(index); | 694 return GapAt(index); |
695 } | 695 } |
696 | 696 |
697 | 697 |
698 HPhi* LAllocator::LookupPhi(LOperand* operand) const { | 698 HPhi* LAllocator::LookupPhi(LOperand* operand) const { |
699 if (!operand->IsUnallocated()) return NULL; | 699 if (!operand->IsUnallocated()) return NULL; |
700 int index = operand->VirtualRegister(); | 700 int index = LUnallocated::cast(operand)->virtual_register(); |
701 HValue* instr = graph_->LookupValue(index); | 701 HValue* instr = graph_->LookupValue(index); |
702 if (instr != NULL && instr->IsPhi()) { | 702 if (instr != NULL && instr->IsPhi()) { |
703 return HPhi::cast(instr); | 703 return HPhi::cast(instr); |
704 } | 704 } |
705 return NULL; | 705 return NULL; |
706 } | 706 } |
707 | 707 |
708 | 708 |
709 LiveRange* LAllocator::LiveRangeFor(LOperand* operand) { | 709 LiveRange* LAllocator::LiveRangeFor(LOperand* operand) { |
710 if (operand->IsUnallocated()) { | 710 if (operand->IsUnallocated()) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 LOperand* from, | 758 LOperand* from, |
759 LOperand* to) { | 759 LOperand* to) { |
760 LGap* gap = GapAt(index); | 760 LGap* gap = GapAt(index); |
761 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START); | 761 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START); |
762 if (from->IsUnallocated()) { | 762 if (from->IsUnallocated()) { |
763 const ZoneList<LMoveOperands>* move_operands = move->move_operands(); | 763 const ZoneList<LMoveOperands>* move_operands = move->move_operands(); |
764 for (int i = 0; i < move_operands->length(); ++i) { | 764 for (int i = 0; i < move_operands->length(); ++i) { |
765 LMoveOperands cur = move_operands->at(i); | 765 LMoveOperands cur = move_operands->at(i); |
766 LOperand* cur_to = cur.destination(); | 766 LOperand* cur_to = cur.destination(); |
767 if (cur_to->IsUnallocated()) { | 767 if (cur_to->IsUnallocated()) { |
768 if (cur_to->VirtualRegister() == from->VirtualRegister()) { | 768 if (LUnallocated::cast(cur_to)->virtual_register() == |
| 769 LUnallocated::cast(from)->virtual_register()) { |
769 move->AddMove(cur.source(), to); | 770 move->AddMove(cur.source(), to); |
770 return; | 771 return; |
771 } | 772 } |
772 } | 773 } |
773 } | 774 } |
774 } | 775 } |
775 move->AddMove(from, to); | 776 move->AddMove(from, to); |
776 } | 777 } |
777 | 778 |
778 | 779 |
(...skipping 21 matching lines...) Expand all Loading... |
800 LUnallocated* temp = LUnallocated::cast(it.Current()); | 801 LUnallocated* temp = LUnallocated::cast(it.Current()); |
801 if (temp->HasFixedPolicy()) { | 802 if (temp->HasFixedPolicy()) { |
802 AllocateFixed(temp, gap_index - 1, false); | 803 AllocateFixed(temp, gap_index - 1, false); |
803 } | 804 } |
804 } | 805 } |
805 } | 806 } |
806 | 807 |
807 // Handle fixed output operand. | 808 // Handle fixed output operand. |
808 if (first != NULL && first->Output() != NULL) { | 809 if (first != NULL && first->Output() != NULL) { |
809 LUnallocated* first_output = LUnallocated::cast(first->Output()); | 810 LUnallocated* first_output = LUnallocated::cast(first->Output()); |
810 LiveRange* range = LiveRangeFor(first_output->VirtualRegister()); | 811 LiveRange* range = LiveRangeFor(first_output->virtual_register()); |
811 bool assigned = false; | 812 bool assigned = false; |
812 if (first_output->HasFixedPolicy()) { | 813 if (first_output->HasFixedPolicy()) { |
813 LUnallocated* output_copy = first_output->CopyUnconstrained(); | 814 LUnallocated* output_copy = first_output->CopyUnconstrained(); |
814 bool is_tagged = HasTaggedValue(first_output->VirtualRegister()); | 815 bool is_tagged = HasTaggedValue(first_output->virtual_register()); |
815 AllocateFixed(first_output, gap_index, is_tagged); | 816 AllocateFixed(first_output, gap_index, is_tagged); |
816 | 817 |
817 // This value is produced on the stack, we never need to spill it. | 818 // This value is produced on the stack, we never need to spill it. |
818 if (first_output->IsStackSlot()) { | 819 if (first_output->IsStackSlot()) { |
819 range->SetSpillOperand(first_output); | 820 range->SetSpillOperand(first_output); |
820 range->SetSpillStartIndex(gap_index - 1); | 821 range->SetSpillStartIndex(gap_index - 1); |
821 assigned = true; | 822 assigned = true; |
822 } | 823 } |
823 chunk_->AddGapMove(gap_index, first_output, output_copy); | 824 chunk_->AddGapMove(gap_index, first_output, output_copy); |
824 } | 825 } |
(...skipping 10 matching lines...) Expand all Loading... |
835 move->AddMove(first_output, range->GetSpillOperand()); | 836 move->AddMove(first_output, range->GetSpillOperand()); |
836 } | 837 } |
837 } | 838 } |
838 | 839 |
839 // Handle fixed input operands of second instruction. | 840 // Handle fixed input operands of second instruction. |
840 if (second != NULL) { | 841 if (second != NULL) { |
841 for (UseIterator it(second); !it.Done(); it.Advance()) { | 842 for (UseIterator it(second); !it.Done(); it.Advance()) { |
842 LUnallocated* cur_input = LUnallocated::cast(it.Current()); | 843 LUnallocated* cur_input = LUnallocated::cast(it.Current()); |
843 if (cur_input->HasFixedPolicy()) { | 844 if (cur_input->HasFixedPolicy()) { |
844 LUnallocated* input_copy = cur_input->CopyUnconstrained(); | 845 LUnallocated* input_copy = cur_input->CopyUnconstrained(); |
845 bool is_tagged = HasTaggedValue(cur_input->VirtualRegister()); | 846 bool is_tagged = HasTaggedValue(cur_input->virtual_register()); |
846 AllocateFixed(cur_input, gap_index + 1, is_tagged); | 847 AllocateFixed(cur_input, gap_index + 1, is_tagged); |
847 AddConstraintsGapMove(gap_index, input_copy, cur_input); | 848 AddConstraintsGapMove(gap_index, input_copy, cur_input); |
848 } else if (cur_input->policy() == LUnallocated::WRITABLE_REGISTER) { | 849 } else if (cur_input->policy() == LUnallocated::WRITABLE_REGISTER) { |
849 // The live range of writable input registers always goes until the end | 850 // The live range of writable input registers always goes until the end |
850 // of the instruction. | 851 // of the instruction. |
851 ASSERT(!cur_input->IsUsedAtStart()); | 852 ASSERT(!cur_input->IsUsedAtStart()); |
852 | 853 |
853 LUnallocated* input_copy = cur_input->CopyUnconstrained(); | 854 LUnallocated* input_copy = cur_input->CopyUnconstrained(); |
854 cur_input->set_virtual_register(next_virtual_register_++); | 855 cur_input->set_virtual_register(next_virtual_register_++); |
855 | 856 |
856 if (RequiredRegisterKind(input_copy->virtual_register()) == | 857 if (RequiredRegisterKind(input_copy->virtual_register()) == |
857 DOUBLE_REGISTERS) { | 858 DOUBLE_REGISTERS) { |
858 double_artificial_registers_.Add( | 859 double_artificial_registers_.Add( |
859 cur_input->virtual_register() - first_artificial_register_); | 860 cur_input->virtual_register() - first_artificial_register_); |
860 } | 861 } |
861 | 862 |
862 AddConstraintsGapMove(gap_index, input_copy, cur_input); | 863 AddConstraintsGapMove(gap_index, input_copy, cur_input); |
863 } | 864 } |
864 } | 865 } |
865 } | 866 } |
866 | 867 |
867 // Handle "output same as input" for second instruction. | 868 // Handle "output same as input" for second instruction. |
868 if (second != NULL && second->Output() != NULL) { | 869 if (second != NULL && second->Output() != NULL) { |
869 LUnallocated* second_output = LUnallocated::cast(second->Output()); | 870 LUnallocated* second_output = LUnallocated::cast(second->Output()); |
870 if (second_output->HasSameAsInputPolicy()) { | 871 if (second_output->HasSameAsInputPolicy()) { |
871 LUnallocated* cur_input = LUnallocated::cast(second->FirstInput()); | 872 LUnallocated* cur_input = LUnallocated::cast(second->FirstInput()); |
872 int output_vreg = second_output->VirtualRegister(); | 873 int output_vreg = second_output->virtual_register(); |
873 int input_vreg = cur_input->VirtualRegister(); | 874 int input_vreg = cur_input->virtual_register(); |
874 | 875 |
875 LUnallocated* input_copy = cur_input->CopyUnconstrained(); | 876 LUnallocated* input_copy = cur_input->CopyUnconstrained(); |
876 cur_input->set_virtual_register(second_output->virtual_register()); | 877 cur_input->set_virtual_register(second_output->virtual_register()); |
877 AddConstraintsGapMove(gap_index, input_copy, cur_input); | 878 AddConstraintsGapMove(gap_index, input_copy, cur_input); |
878 | 879 |
879 if (HasTaggedValue(input_vreg) && !HasTaggedValue(output_vreg)) { | 880 if (HasTaggedValue(input_vreg) && !HasTaggedValue(output_vreg)) { |
880 int index = gap_index + 1; | 881 int index = gap_index + 1; |
881 LInstruction* instr = InstructionAt(index); | 882 LInstruction* instr = InstructionAt(index); |
882 if (instr->HasPointerMap()) { | 883 if (instr->HasPointerMap()) { |
883 instr->pointer_map()->RecordPointer(input_copy); | 884 instr->pointer_map()->RecordPointer(input_copy); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
918 LOperand* to = cur->destination(); | 919 LOperand* to = cur->destination(); |
919 HPhi* phi = LookupPhi(to); | 920 HPhi* phi = LookupPhi(to); |
920 LOperand* hint = to; | 921 LOperand* hint = to; |
921 if (phi != NULL) { | 922 if (phi != NULL) { |
922 // This is a phi resolving move. | 923 // This is a phi resolving move. |
923 if (!phi->block()->IsLoopHeader()) { | 924 if (!phi->block()->IsLoopHeader()) { |
924 hint = LiveRangeFor(phi->id())->FirstHint(); | 925 hint = LiveRangeFor(phi->id())->FirstHint(); |
925 } | 926 } |
926 } else { | 927 } else { |
927 if (to->IsUnallocated()) { | 928 if (to->IsUnallocated()) { |
928 if (live->Contains(to->VirtualRegister())) { | 929 if (live->Contains(LUnallocated::cast(to)->virtual_register())) { |
929 Define(curr_position, to, from); | 930 Define(curr_position, to, from); |
930 live->Remove(to->VirtualRegister()); | 931 live->Remove(LUnallocated::cast(to)->virtual_register()); |
931 } else { | 932 } else { |
932 cur->Eliminate(); | 933 cur->Eliminate(); |
933 continue; | 934 continue; |
934 } | 935 } |
935 } else { | 936 } else { |
936 Define(curr_position, to, from); | 937 Define(curr_position, to, from); |
937 } | 938 } |
938 } | 939 } |
939 Use(block_start_position, curr_position, from, hint); | 940 Use(block_start_position, curr_position, from, hint); |
940 if (from->IsUnallocated()) { | 941 if (from->IsUnallocated()) { |
941 live->Add(from->VirtualRegister()); | 942 live->Add(LUnallocated::cast(from)->virtual_register()); |
942 } | 943 } |
943 } | 944 } |
944 } else { | 945 } else { |
945 ASSERT(!IsGapAt(index)); | 946 ASSERT(!IsGapAt(index)); |
946 LInstruction* instr = InstructionAt(index); | 947 LInstruction* instr = InstructionAt(index); |
947 | 948 |
948 if (instr != NULL) { | 949 if (instr != NULL) { |
949 LOperand* output = instr->Output(); | 950 LOperand* output = instr->Output(); |
950 if (output != NULL) { | 951 if (output != NULL) { |
951 if (output->IsUnallocated()) live->Remove(output->VirtualRegister()); | 952 if (output->IsUnallocated()) { |
| 953 live->Remove(LUnallocated::cast(output)->virtual_register()); |
| 954 } |
952 Define(curr_position, output, NULL); | 955 Define(curr_position, output, NULL); |
953 } | 956 } |
954 | 957 |
955 if (instr->IsMarkedAsCall()) { | 958 if (instr->IsMarkedAsCall()) { |
956 for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) { | 959 for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) { |
957 if (output == NULL || !output->IsRegister() || | 960 if (output == NULL || !output->IsRegister() || |
958 output->index() != i) { | 961 output->index() != i) { |
959 LiveRange* range = FixedLiveRangeFor(i); | 962 LiveRange* range = FixedLiveRangeFor(i); |
960 range->AddUseInterval(curr_position, | 963 range->AddUseInterval(curr_position, |
961 curr_position.InstructionEnd()); | 964 curr_position.InstructionEnd()); |
(...skipping 17 matching lines...) Expand all Loading... |
979 | 982 |
980 LifetimePosition use_pos; | 983 LifetimePosition use_pos; |
981 if (input->IsUnallocated() && | 984 if (input->IsUnallocated() && |
982 LUnallocated::cast(input)->IsUsedAtStart()) { | 985 LUnallocated::cast(input)->IsUsedAtStart()) { |
983 use_pos = curr_position; | 986 use_pos = curr_position; |
984 } else { | 987 } else { |
985 use_pos = curr_position.InstructionEnd(); | 988 use_pos = curr_position.InstructionEnd(); |
986 } | 989 } |
987 | 990 |
988 Use(block_start_position, use_pos, input, NULL); | 991 Use(block_start_position, use_pos, input, NULL); |
989 if (input->IsUnallocated()) live->Add(input->VirtualRegister()); | 992 if (input->IsUnallocated()) { |
| 993 live->Add(LUnallocated::cast(input)->virtual_register()); |
| 994 } |
990 } | 995 } |
991 | 996 |
992 for (TempIterator it(instr); !it.Done(); it.Advance()) { | 997 for (TempIterator it(instr); !it.Done(); it.Advance()) { |
993 LOperand* temp = it.Current(); | 998 LOperand* temp = it.Current(); |
994 if (instr->IsMarkedAsCall()) { | 999 if (instr->IsMarkedAsCall()) { |
995 if (temp->IsRegister()) continue; | 1000 if (temp->IsRegister()) continue; |
996 if (temp->IsUnallocated()) { | 1001 if (temp->IsUnallocated()) { |
997 LUnallocated* temp_unalloc = LUnallocated::cast(temp); | 1002 LUnallocated* temp_unalloc = LUnallocated::cast(temp); |
998 if (temp_unalloc->HasFixedPolicy()) { | 1003 if (temp_unalloc->HasFixedPolicy()) { |
999 continue; | 1004 continue; |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1263 // block. | 1268 // block. |
1264 HPhi* phi = phis->at(i); | 1269 HPhi* phi = phis->at(i); |
1265 live->Remove(phi->id()); | 1270 live->Remove(phi->id()); |
1266 | 1271 |
1267 LOperand* hint = NULL; | 1272 LOperand* hint = NULL; |
1268 LOperand* phi_operand = NULL; | 1273 LOperand* phi_operand = NULL; |
1269 LGap* gap = GetLastGap(phi->block()->predecessors()->at(0)); | 1274 LGap* gap = GetLastGap(phi->block()->predecessors()->at(0)); |
1270 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START); | 1275 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START); |
1271 for (int j = 0; j < move->move_operands()->length(); ++j) { | 1276 for (int j = 0; j < move->move_operands()->length(); ++j) { |
1272 LOperand* to = move->move_operands()->at(j).destination(); | 1277 LOperand* to = move->move_operands()->at(j).destination(); |
1273 if (to->IsUnallocated() && to->VirtualRegister() == phi->id()) { | 1278 if (to->IsUnallocated() && |
| 1279 LUnallocated::cast(to)->virtual_register() == phi->id()) { |
1274 hint = move->move_operands()->at(j).source(); | 1280 hint = move->move_operands()->at(j).source(); |
1275 phi_operand = to; | 1281 phi_operand = to; |
1276 break; | 1282 break; |
1277 } | 1283 } |
1278 } | 1284 } |
1279 ASSERT(hint != NULL); | 1285 ASSERT(hint != NULL); |
1280 | 1286 |
1281 LifetimePosition block_start = LifetimePosition::FromInstructionIndex( | 1287 LifetimePosition block_start = LifetimePosition::FromInstructionIndex( |
1282 block->first_instruction_index()); | 1288 block->first_instruction_index()); |
1283 Define(block_start, phi_operand, hint); | 1289 Define(block_start, phi_operand, hint); |
(...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2122 LiveRange* current = live_ranges()->at(i); | 2128 LiveRange* current = live_ranges()->at(i); |
2123 if (current != NULL) current->Verify(); | 2129 if (current != NULL) current->Verify(); |
2124 } | 2130 } |
2125 } | 2131 } |
2126 | 2132 |
2127 | 2133 |
2128 #endif | 2134 #endif |
2129 | 2135 |
2130 | 2136 |
2131 } } // namespace v8::internal | 2137 } } // namespace v8::internal |
OLD | NEW |