OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/register-allocator.h" | 5 #include "src/compiler/register-allocator.h" |
6 | 6 |
7 #include "src/compiler/generic-node-inl.h" | 7 #include "src/compiler/generic-node-inl.h" |
8 #include "src/compiler/linkage.h" | 8 #include "src/compiler/linkage.h" |
9 #include "src/hydrogen.h" | 9 #include "src/hydrogen.h" |
10 #include "src/string-stream.h" | 10 #include "src/string-stream.h" |
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 } | 552 } |
553 } | 553 } |
554 return live_out; | 554 return live_out; |
555 } | 555 } |
556 | 556 |
557 | 557 |
558 void RegisterAllocator::AddInitialIntervals(BasicBlock* block, | 558 void RegisterAllocator::AddInitialIntervals(BasicBlock* block, |
559 BitVector* live_out) { | 559 BitVector* live_out) { |
560 // Add an interval that includes the entire block to the live range for | 560 // Add an interval that includes the entire block to the live range for |
561 // each live_out value. | 561 // each live_out value. |
562 LifetimePosition start = | 562 LifetimePosition start = LifetimePosition::FromInstructionIndex( |
563 LifetimePosition::FromInstructionIndex(block->first_instruction_index()); | 563 code()->first_instruction_index(block)); |
564 LifetimePosition end = LifetimePosition::FromInstructionIndex( | 564 LifetimePosition end = |
565 block->last_instruction_index()).NextInstruction(); | 565 LifetimePosition::FromInstructionIndex( |
| 566 code()->last_instruction_index(block)).NextInstruction(); |
566 BitVector::Iterator iterator(live_out); | 567 BitVector::Iterator iterator(live_out); |
567 while (!iterator.Done()) { | 568 while (!iterator.Done()) { |
568 int operand_index = iterator.Current(); | 569 int operand_index = iterator.Current(); |
569 LiveRange* range = LiveRangeFor(operand_index); | 570 LiveRange* range = LiveRangeFor(operand_index); |
570 range->AddUseInterval(start, end, zone()); | 571 range->AddUseInterval(start, end, zone()); |
571 iterator.Advance(); | 572 iterator.Advance(); |
572 } | 573 } |
573 } | 574 } |
574 | 575 |
575 | 576 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 LiveRange* result = live_ranges_[index]; | 645 LiveRange* result = live_ranges_[index]; |
645 if (result == NULL) { | 646 if (result == NULL) { |
646 result = new (zone()) LiveRange(index, code_zone()); | 647 result = new (zone()) LiveRange(index, code_zone()); |
647 live_ranges_[index] = result; | 648 live_ranges_[index] = result; |
648 } | 649 } |
649 return result; | 650 return result; |
650 } | 651 } |
651 | 652 |
652 | 653 |
653 GapInstruction* RegisterAllocator::GetLastGap(BasicBlock* block) { | 654 GapInstruction* RegisterAllocator::GetLastGap(BasicBlock* block) { |
654 int last_instruction = block->last_instruction_index(); | 655 int last_instruction = code()->last_instruction_index(block); |
655 return code()->GapAt(last_instruction - 1); | 656 return code()->GapAt(last_instruction - 1); |
656 } | 657 } |
657 | 658 |
658 | 659 |
659 LiveRange* RegisterAllocator::LiveRangeFor(InstructionOperand* operand) { | 660 LiveRange* RegisterAllocator::LiveRangeFor(InstructionOperand* operand) { |
660 if (operand->IsUnallocated()) { | 661 if (operand->IsUnallocated()) { |
661 return LiveRangeFor(UnallocatedOperand::cast(operand)->virtual_register()); | 662 return LiveRangeFor(UnallocatedOperand::cast(operand)->virtual_register()); |
662 } else if (operand->IsRegister()) { | 663 } else if (operand->IsRegister()) { |
663 return FixedLiveRangeFor(operand->index()); | 664 return FixedLiveRangeFor(operand->index()); |
664 } else if (operand->IsDoubleRegister()) { | 665 } else if (operand->IsDoubleRegister()) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 return; | 723 return; |
723 } | 724 } |
724 } | 725 } |
725 } | 726 } |
726 } | 727 } |
727 move->AddMove(from, to, code_zone()); | 728 move->AddMove(from, to, code_zone()); |
728 } | 729 } |
729 | 730 |
730 | 731 |
731 void RegisterAllocator::MeetRegisterConstraints(BasicBlock* block) { | 732 void RegisterAllocator::MeetRegisterConstraints(BasicBlock* block) { |
732 int start = block->first_instruction_index(); | 733 int start = code()->first_instruction_index(block); |
733 int end = block->last_instruction_index(); | 734 int end = code()->last_instruction_index(block); |
734 DCHECK_NE(-1, start); | 735 DCHECK_NE(-1, start); |
735 for (int i = start; i <= end; ++i) { | 736 for (int i = start; i <= end; ++i) { |
736 if (code()->IsGapAt(i)) { | 737 if (code()->IsGapAt(i)) { |
737 Instruction* instr = NULL; | 738 Instruction* instr = NULL; |
738 Instruction* prev_instr = NULL; | 739 Instruction* prev_instr = NULL; |
739 if (i < end) instr = InstructionAt(i + 1); | 740 if (i < end) instr = InstructionAt(i + 1); |
740 if (i > start) prev_instr = InstructionAt(i - 1); | 741 if (i > start) prev_instr = InstructionAt(i - 1); |
741 MeetConstraintsBetween(prev_instr, instr, i); | 742 MeetConstraintsBetween(prev_instr, instr, i); |
742 if (!AllocationOk()) return; | 743 if (!AllocationOk()) return; |
743 } | 744 } |
744 } | 745 } |
745 | 746 |
746 // Meet register constraints for the instruction in the end. | 747 // Meet register constraints for the instruction in the end. |
747 if (!code()->IsGapAt(end)) { | 748 if (!code()->IsGapAt(end)) { |
748 MeetRegisterConstraintsForLastInstructionInBlock(block); | 749 MeetRegisterConstraintsForLastInstructionInBlock(block); |
749 } | 750 } |
750 } | 751 } |
751 | 752 |
752 | 753 |
753 void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock( | 754 void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock( |
754 BasicBlock* block) { | 755 BasicBlock* block) { |
755 int end = block->last_instruction_index(); | 756 int end = code()->last_instruction_index(block); |
756 Instruction* last_instruction = InstructionAt(end); | 757 Instruction* last_instruction = InstructionAt(end); |
757 for (size_t i = 0; i < last_instruction->OutputCount(); i++) { | 758 for (size_t i = 0; i < last_instruction->OutputCount(); i++) { |
758 InstructionOperand* output_operand = last_instruction->OutputAt(i); | 759 InstructionOperand* output_operand = last_instruction->OutputAt(i); |
759 DCHECK(!output_operand->IsConstant()); | 760 DCHECK(!output_operand->IsConstant()); |
760 UnallocatedOperand* output = UnallocatedOperand::cast(output_operand); | 761 UnallocatedOperand* output = UnallocatedOperand::cast(output_operand); |
761 int output_vreg = output->virtual_register(); | 762 int output_vreg = output->virtual_register(); |
762 LiveRange* range = LiveRangeFor(output_vreg); | 763 LiveRange* range = LiveRangeFor(output_vreg); |
763 bool assigned = false; | 764 bool assigned = false; |
764 if (output->HasFixedPolicy()) { | 765 if (output->HasFixedPolicy()) { |
765 AllocateFixed(output, -1, false); | 766 AllocateFixed(output, -1, false); |
766 // This value is produced on the stack, we never need to spill it. | 767 // This value is produced on the stack, we never need to spill it. |
767 if (output->IsStackSlot()) { | 768 if (output->IsStackSlot()) { |
768 range->SetSpillOperand(output); | 769 range->SetSpillOperand(output); |
769 range->SetSpillStartIndex(end); | 770 range->SetSpillStartIndex(end); |
770 assigned = true; | 771 assigned = true; |
771 } | 772 } |
772 | 773 |
773 for (BasicBlock::Successors::iterator succ = block->successors_begin(); | 774 for (BasicBlock::Successors::iterator succ = block->successors_begin(); |
774 succ != block->successors_end(); ++succ) { | 775 succ != block->successors_end(); ++succ) { |
775 DCHECK((*succ)->PredecessorCount() == 1); | 776 DCHECK((*succ)->PredecessorCount() == 1); |
776 int gap_index = (*succ)->first_instruction_index() + 1; | 777 int gap_index = code()->first_instruction_index(*succ) + 1; |
777 DCHECK(code()->IsGapAt(gap_index)); | 778 DCHECK(code()->IsGapAt(gap_index)); |
778 | 779 |
779 // Create an unconstrained operand for the same virtual register | 780 // Create an unconstrained operand for the same virtual register |
780 // and insert a gap move from the fixed output to the operand. | 781 // and insert a gap move from the fixed output to the operand. |
781 UnallocatedOperand* output_copy = | 782 UnallocatedOperand* output_copy = |
782 new (code_zone()) UnallocatedOperand(UnallocatedOperand::ANY); | 783 new (code_zone()) UnallocatedOperand(UnallocatedOperand::ANY); |
783 output_copy->set_virtual_register(output_vreg); | 784 output_copy->set_virtual_register(output_vreg); |
784 | 785 |
785 code()->AddGapMove(gap_index, output, output_copy); | 786 code()->AddGapMove(gap_index, output, output_copy); |
786 } | 787 } |
787 } | 788 } |
788 | 789 |
789 if (!assigned) { | 790 if (!assigned) { |
790 for (BasicBlock::Successors::iterator succ = block->successors_begin(); | 791 for (BasicBlock::Successors::iterator succ = block->successors_begin(); |
791 succ != block->successors_end(); ++succ) { | 792 succ != block->successors_end(); ++succ) { |
792 DCHECK((*succ)->PredecessorCount() == 1); | 793 DCHECK((*succ)->PredecessorCount() == 1); |
793 int gap_index = (*succ)->first_instruction_index() + 1; | 794 int gap_index = code()->first_instruction_index(*succ) + 1; |
794 range->SetSpillStartIndex(gap_index); | 795 range->SetSpillStartIndex(gap_index); |
795 | 796 |
796 // This move to spill operand is not a real use. Liveness analysis | 797 // This move to spill operand is not a real use. Liveness analysis |
797 // and splitting of live ranges do not account for it. | 798 // and splitting of live ranges do not account for it. |
798 // Thus it should be inserted to a lifetime position corresponding to | 799 // Thus it should be inserted to a lifetime position corresponding to |
799 // the instruction end. | 800 // the instruction end. |
800 GapInstruction* gap = code()->GapAt(gap_index); | 801 GapInstruction* gap = code()->GapAt(gap_index); |
801 ParallelMove* move = | 802 ParallelMove* move = |
802 gap->GetOrCreateParallelMove(GapInstruction::BEFORE, code_zone()); | 803 gap->GetOrCreateParallelMove(GapInstruction::BEFORE, code_zone()); |
803 move->AddMove(output, range->GetSpillOperand(), code_zone()); | 804 move->AddMove(output, range->GetSpillOperand(), code_zone()); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
930 for (size_t i = 0; i < instr->OutputCount(); i++) { | 931 for (size_t i = 0; i < instr->OutputCount(); i++) { |
931 InstructionOperand* output = instr->OutputAt(i); | 932 InstructionOperand* output = instr->OutputAt(i); |
932 if (output->IsDoubleRegister() && output->index() == index) return true; | 933 if (output->IsDoubleRegister() && output->index() == index) return true; |
933 } | 934 } |
934 return false; | 935 return false; |
935 } | 936 } |
936 | 937 |
937 | 938 |
938 void RegisterAllocator::ProcessInstructions(BasicBlock* block, | 939 void RegisterAllocator::ProcessInstructions(BasicBlock* block, |
939 BitVector* live) { | 940 BitVector* live) { |
940 int block_start = block->first_instruction_index(); | 941 int block_start = code()->first_instruction_index(block); |
941 | 942 |
942 LifetimePosition block_start_position = | 943 LifetimePosition block_start_position = |
943 LifetimePosition::FromInstructionIndex(block_start); | 944 LifetimePosition::FromInstructionIndex(block_start); |
944 | 945 |
945 for (int index = block->last_instruction_index(); index >= block_start; | 946 for (int index = code()->last_instruction_index(block); index >= block_start; |
946 index--) { | 947 index--) { |
947 LifetimePosition curr_position = | 948 LifetimePosition curr_position = |
948 LifetimePosition::FromInstructionIndex(index); | 949 LifetimePosition::FromInstructionIndex(index); |
949 | 950 |
950 Instruction* instr = InstructionAt(index); | 951 Instruction* instr = InstructionAt(index); |
951 DCHECK(instr != NULL); | 952 DCHECK(instr != NULL); |
952 if (instr->IsGapMoves()) { | 953 if (instr->IsGapMoves()) { |
953 // Process the moves of the gap instruction, making their sources live. | 954 // Process the moves of the gap instruction, making their sources live. |
954 GapInstruction* gap = code()->GapAt(index); | 955 GapInstruction* gap = code()->GapAt(index); |
955 | 956 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 ++iter, ++j) { | 1075 ++iter, ++j) { |
1075 Node* op = *iter; | 1076 Node* op = *iter; |
1076 // TODO(mstarzinger): Use a ValueInputIterator instead. | 1077 // TODO(mstarzinger): Use a ValueInputIterator instead. |
1077 if (j >= block->PredecessorCount()) continue; | 1078 if (j >= block->PredecessorCount()) continue; |
1078 UnallocatedOperand* operand = | 1079 UnallocatedOperand* operand = |
1079 new (code_zone()) UnallocatedOperand(UnallocatedOperand::ANY); | 1080 new (code_zone()) UnallocatedOperand(UnallocatedOperand::ANY); |
1080 operand->set_virtual_register(code()->GetVirtualRegister(op)); | 1081 operand->set_virtual_register(code()->GetVirtualRegister(op)); |
1081 BasicBlock* cur_block = block->PredecessorAt(j); | 1082 BasicBlock* cur_block = block->PredecessorAt(j); |
1082 // The gap move must be added without any special processing as in | 1083 // The gap move must be added without any special processing as in |
1083 // the AddConstraintsGapMove. | 1084 // the AddConstraintsGapMove. |
1084 code()->AddGapMove(cur_block->last_instruction_index() - 1, operand, | 1085 code()->AddGapMove(code()->last_instruction_index(cur_block) - 1, operand, |
1085 phi_operand); | 1086 phi_operand); |
1086 | 1087 |
1087 Instruction* branch = InstructionAt(cur_block->last_instruction_index()); | 1088 Instruction* branch = |
| 1089 InstructionAt(code()->last_instruction_index(cur_block)); |
1088 DCHECK(!branch->HasPointerMap()); | 1090 DCHECK(!branch->HasPointerMap()); |
1089 USE(branch); | 1091 USE(branch); |
1090 } | 1092 } |
1091 | 1093 |
1092 LiveRange* live_range = LiveRangeFor(phi_vreg); | 1094 LiveRange* live_range = LiveRangeFor(phi_vreg); |
1093 BlockStartInstruction* block_start = code()->GetBlockStart(block); | 1095 BlockStartInstruction* block_start = |
| 1096 code()->GetBlockStart(block->GetRpoNumber()); |
1094 block_start->GetOrCreateParallelMove(GapInstruction::START, code_zone()) | 1097 block_start->GetOrCreateParallelMove(GapInstruction::START, code_zone()) |
1095 ->AddMove(phi_operand, live_range->GetSpillOperand(), code_zone()); | 1098 ->AddMove(phi_operand, live_range->GetSpillOperand(), code_zone()); |
1096 live_range->SetSpillStartIndex(block->first_instruction_index()); | 1099 live_range->SetSpillStartIndex(code()->first_instruction_index(block)); |
1097 | 1100 |
1098 // We use the phi-ness of some nodes in some later heuristics. | 1101 // We use the phi-ness of some nodes in some later heuristics. |
1099 live_range->set_is_phi(true); | 1102 live_range->set_is_phi(true); |
1100 if (!block->IsLoopHeader()) { | 1103 if (!block->IsLoopHeader()) { |
1101 live_range->set_is_non_loop_phi(true); | 1104 live_range->set_is_non_loop_phi(true); |
1102 } | 1105 } |
1103 } | 1106 } |
1104 } | 1107 } |
1105 | 1108 |
1106 | 1109 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1140 | 1143 |
1141 // Process the blocks in reverse order. | 1144 // Process the blocks in reverse order. |
1142 for (int i = code()->BasicBlockCount() - 1; i >= 0; --i) { | 1145 for (int i = code()->BasicBlockCount() - 1; i >= 0; --i) { |
1143 ResolvePhis(code()->BlockAt(i)); | 1146 ResolvePhis(code()->BlockAt(i)); |
1144 } | 1147 } |
1145 } | 1148 } |
1146 | 1149 |
1147 | 1150 |
1148 void RegisterAllocator::ResolveControlFlow(LiveRange* range, BasicBlock* block, | 1151 void RegisterAllocator::ResolveControlFlow(LiveRange* range, BasicBlock* block, |
1149 BasicBlock* pred) { | 1152 BasicBlock* pred) { |
1150 LifetimePosition pred_end = | 1153 LifetimePosition pred_end = LifetimePosition::FromInstructionIndex( |
1151 LifetimePosition::FromInstructionIndex(pred->last_instruction_index()); | 1154 code()->last_instruction_index(pred)); |
1152 LifetimePosition cur_start = | 1155 LifetimePosition cur_start = LifetimePosition::FromInstructionIndex( |
1153 LifetimePosition::FromInstructionIndex(block->first_instruction_index()); | 1156 code()->first_instruction_index(block)); |
1154 LiveRange* pred_cover = NULL; | 1157 LiveRange* pred_cover = NULL; |
1155 LiveRange* cur_cover = NULL; | 1158 LiveRange* cur_cover = NULL; |
1156 LiveRange* cur_range = range; | 1159 LiveRange* cur_range = range; |
1157 while (cur_range != NULL && (cur_cover == NULL || pred_cover == NULL)) { | 1160 while (cur_range != NULL && (cur_cover == NULL || pred_cover == NULL)) { |
1158 if (cur_range->CanCover(cur_start)) { | 1161 if (cur_range->CanCover(cur_start)) { |
1159 DCHECK(cur_cover == NULL); | 1162 DCHECK(cur_cover == NULL); |
1160 cur_cover = cur_range; | 1163 cur_cover = cur_range; |
1161 } | 1164 } |
1162 if (cur_range->CanCover(pred_end)) { | 1165 if (cur_range->CanCover(pred_end)) { |
1163 DCHECK(pred_cover == NULL); | 1166 DCHECK(pred_cover == NULL); |
1164 pred_cover = cur_range; | 1167 pred_cover = cur_range; |
1165 } | 1168 } |
1166 cur_range = cur_range->next(); | 1169 cur_range = cur_range->next(); |
1167 } | 1170 } |
1168 | 1171 |
1169 if (cur_cover->IsSpilled()) return; | 1172 if (cur_cover->IsSpilled()) return; |
1170 DCHECK(pred_cover != NULL && cur_cover != NULL); | 1173 DCHECK(pred_cover != NULL && cur_cover != NULL); |
1171 if (pred_cover != cur_cover) { | 1174 if (pred_cover != cur_cover) { |
1172 InstructionOperand* pred_op = | 1175 InstructionOperand* pred_op = |
1173 pred_cover->CreateAssignedOperand(code_zone()); | 1176 pred_cover->CreateAssignedOperand(code_zone()); |
1174 InstructionOperand* cur_op = cur_cover->CreateAssignedOperand(code_zone()); | 1177 InstructionOperand* cur_op = cur_cover->CreateAssignedOperand(code_zone()); |
1175 if (!pred_op->Equals(cur_op)) { | 1178 if (!pred_op->Equals(cur_op)) { |
1176 GapInstruction* gap = NULL; | 1179 GapInstruction* gap = NULL; |
1177 if (block->PredecessorCount() == 1) { | 1180 if (block->PredecessorCount() == 1) { |
1178 gap = code()->GapAt(block->first_instruction_index()); | 1181 gap = code()->GapAt(code()->first_instruction_index(block)); |
1179 } else { | 1182 } else { |
1180 DCHECK(pred->SuccessorCount() == 1); | 1183 DCHECK(pred->SuccessorCount() == 1); |
1181 gap = GetLastGap(pred); | 1184 gap = GetLastGap(pred); |
1182 | 1185 |
1183 Instruction* branch = InstructionAt(pred->last_instruction_index()); | 1186 Instruction* branch = |
| 1187 InstructionAt(code()->last_instruction_index(pred)); |
1184 DCHECK(!branch->HasPointerMap()); | 1188 DCHECK(!branch->HasPointerMap()); |
1185 USE(branch); | 1189 USE(branch); |
1186 } | 1190 } |
1187 gap->GetOrCreateParallelMove(GapInstruction::START, code_zone()) | 1191 gap->GetOrCreateParallelMove(GapInstruction::START, code_zone()) |
1188 ->AddMove(pred_op, cur_op, code_zone()); | 1192 ->AddMove(pred_op, cur_op, code_zone()); |
1189 } | 1193 } |
1190 } | 1194 } |
1191 } | 1195 } |
1192 | 1196 |
1193 | 1197 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1313 if (to->IsUnallocated() && | 1317 if (to->IsUnallocated() && |
1314 UnallocatedOperand::cast(to)->virtual_register() == phi_vreg) { | 1318 UnallocatedOperand::cast(to)->virtual_register() == phi_vreg) { |
1315 hint = move->move_operands()->at(j).source(); | 1319 hint = move->move_operands()->at(j).source(); |
1316 phi_operand = to; | 1320 phi_operand = to; |
1317 break; | 1321 break; |
1318 } | 1322 } |
1319 } | 1323 } |
1320 DCHECK(hint != NULL); | 1324 DCHECK(hint != NULL); |
1321 | 1325 |
1322 LifetimePosition block_start = LifetimePosition::FromInstructionIndex( | 1326 LifetimePosition block_start = LifetimePosition::FromInstructionIndex( |
1323 block->first_instruction_index()); | 1327 code()->first_instruction_index(block)); |
1324 Define(block_start, phi_operand, hint); | 1328 Define(block_start, phi_operand, hint); |
1325 } | 1329 } |
1326 | 1330 |
1327 // Now live is live_in for this block except not including values live | 1331 // Now live is live_in for this block except not including values live |
1328 // out on backward successor edges. | 1332 // out on backward successor edges. |
1329 live_in_sets_[block_id] = live; | 1333 live_in_sets_[block_id] = live; |
1330 | 1334 |
1331 if (block->IsLoopHeader()) { | 1335 if (block->IsLoopHeader()) { |
1332 // Add a live range stretching from the first loop instruction to the last | 1336 // Add a live range stretching from the first loop instruction to the last |
1333 // for each value live on entry to the header. | 1337 // for each value live on entry to the header. |
1334 BitVector::Iterator iterator(live); | 1338 BitVector::Iterator iterator(live); |
1335 LifetimePosition start = LifetimePosition::FromInstructionIndex( | 1339 LifetimePosition start = LifetimePosition::FromInstructionIndex( |
1336 block->first_instruction_index()); | 1340 code()->first_instruction_index(block)); |
1337 int end_index = | 1341 int end_index = |
1338 code()->BlockAt(block->loop_end())->last_instruction_index(); | 1342 code()->last_instruction_index(code()->BlockAt(block->loop_end())); |
1339 LifetimePosition end = | 1343 LifetimePosition end = |
1340 LifetimePosition::FromInstructionIndex(end_index).NextInstruction(); | 1344 LifetimePosition::FromInstructionIndex(end_index).NextInstruction(); |
1341 while (!iterator.Done()) { | 1345 while (!iterator.Done()) { |
1342 int operand_index = iterator.Current(); | 1346 int operand_index = iterator.Current(); |
1343 LiveRange* range = LiveRangeFor(operand_index); | 1347 LiveRange* range = LiveRangeFor(operand_index); |
1344 range->EnsureInterval(start, end, zone()); | 1348 range->EnsureInterval(start, end, zone()); |
1345 iterator.Advance(); | 1349 iterator.Advance(); |
1346 } | 1350 } |
1347 | 1351 |
1348 // Insert all values into the live in sets of all blocks in the loop. | 1352 // Insert all values into the live in sets of all blocks in the loop. |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1960 | 1964 |
1961 if (loop_header == NULL) return pos; | 1965 if (loop_header == NULL) return pos; |
1962 | 1966 |
1963 UsePosition* prev_use = range->PreviousUsePositionRegisterIsBeneficial(pos); | 1967 UsePosition* prev_use = range->PreviousUsePositionRegisterIsBeneficial(pos); |
1964 | 1968 |
1965 while (loop_header != NULL) { | 1969 while (loop_header != NULL) { |
1966 // We are going to spill live range inside the loop. | 1970 // We are going to spill live range inside the loop. |
1967 // If possible try to move spilling position backwards to loop header. | 1971 // If possible try to move spilling position backwards to loop header. |
1968 // This will reduce number of memory moves on the back edge. | 1972 // This will reduce number of memory moves on the back edge. |
1969 LifetimePosition loop_start = LifetimePosition::FromInstructionIndex( | 1973 LifetimePosition loop_start = LifetimePosition::FromInstructionIndex( |
1970 loop_header->first_instruction_index()); | 1974 code()->first_instruction_index(loop_header)); |
1971 | 1975 |
1972 if (range->Covers(loop_start)) { | 1976 if (range->Covers(loop_start)) { |
1973 if (prev_use == NULL || prev_use->pos().Value() < loop_start.Value()) { | 1977 if (prev_use == NULL || prev_use->pos().Value() < loop_start.Value()) { |
1974 // No register beneficial use inside the loop before the pos. | 1978 // No register beneficial use inside the loop before the pos. |
1975 pos = loop_start; | 1979 pos = loop_start; |
1976 } | 1980 } |
1977 } | 1981 } |
1978 | 1982 |
1979 // Try hoisting out to an outer loop. | 1983 // Try hoisting out to an outer loop. |
1980 loop_header = code()->GetContainingLoop(loop_header); | 1984 loop_header = code()->GetContainingLoop(loop_header); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2098 code()->GetContainingLoop(block)->rpo_number() > | 2102 code()->GetContainingLoop(block)->rpo_number() > |
2099 start_block->rpo_number()) { | 2103 start_block->rpo_number()) { |
2100 block = code()->GetContainingLoop(block); | 2104 block = code()->GetContainingLoop(block); |
2101 } | 2105 } |
2102 | 2106 |
2103 // We did not find any suitable outer loop. Split at the latest possible | 2107 // We did not find any suitable outer loop. Split at the latest possible |
2104 // position unless end_block is a loop header itself. | 2108 // position unless end_block is a loop header itself. |
2105 if (block == end_block && !end_block->IsLoopHeader()) return end; | 2109 if (block == end_block && !end_block->IsLoopHeader()) return end; |
2106 | 2110 |
2107 return LifetimePosition::FromInstructionIndex( | 2111 return LifetimePosition::FromInstructionIndex( |
2108 block->first_instruction_index()); | 2112 code()->first_instruction_index(block)); |
2109 } | 2113 } |
2110 | 2114 |
2111 | 2115 |
2112 void RegisterAllocator::SpillAfter(LiveRange* range, LifetimePosition pos) { | 2116 void RegisterAllocator::SpillAfter(LiveRange* range, LifetimePosition pos) { |
2113 LiveRange* second_part = SplitRangeAt(range, pos); | 2117 LiveRange* second_part = SplitRangeAt(range, pos); |
2114 if (!AllocationOk()) return; | 2118 if (!AllocationOk()) return; |
2115 Spill(second_part); | 2119 Spill(second_part); |
2116 } | 2120 } |
2117 | 2121 |
2118 | 2122 |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2221 allocator_zone_start_allocation_size_; | 2225 allocator_zone_start_allocation_size_; |
2222 isolate()->GetTStatistics()->SaveTiming(name(), base::TimeDelta(), size); | 2226 isolate()->GetTStatistics()->SaveTiming(name(), base::TimeDelta(), size); |
2223 } | 2227 } |
2224 #ifdef DEBUG | 2228 #ifdef DEBUG |
2225 if (allocator_ != NULL) allocator_->Verify(); | 2229 if (allocator_ != NULL) allocator_->Verify(); |
2226 #endif | 2230 #endif |
2227 } | 2231 } |
2228 } | 2232 } |
2229 } | 2233 } |
2230 } // namespace v8::internal::compiler | 2234 } // namespace v8::internal::compiler |
OLD | NEW |