| 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 |