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/linkage.h" | 5 #include "src/compiler/linkage.h" |
6 #include "src/compiler/register-allocator.h" | 6 #include "src/compiler/register-allocator.h" |
7 #include "src/string-stream.h" | 7 #include "src/string-stream.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 1053 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1064 if (output->IsStackSlot()) { | 1064 if (output->IsStackSlot()) { |
1065 DCHECK(output->index() < frame_->GetSpillSlotCount()); | 1065 DCHECK(output->index() < frame_->GetSpillSlotCount()); |
1066 range->SetSpillOperand(output); | 1066 range->SetSpillOperand(output); |
1067 range->SetSpillStartIndex(end); | 1067 range->SetSpillStartIndex(end); |
1068 assigned = true; | 1068 assigned = true; |
1069 } | 1069 } |
1070 | 1070 |
1071 for (auto succ : block->successors()) { | 1071 for (auto succ : block->successors()) { |
1072 const InstructionBlock* successor = code()->InstructionBlockAt(succ); | 1072 const InstructionBlock* successor = code()->InstructionBlockAt(succ); |
1073 DCHECK(successor->PredecessorCount() == 1); | 1073 DCHECK(successor->PredecessorCount() == 1); |
1074 int gap_index = successor->first_instruction_index() + 1; | 1074 int gap_index = successor->first_instruction_index(); |
1075 DCHECK(code()->IsGapAt(gap_index)); | 1075 DCHECK(code()->IsGapAt(gap_index)); |
1076 | 1076 |
1077 // Create an unconstrained operand for the same virtual register | 1077 // Create an unconstrained operand for the same virtual register |
1078 // and insert a gap move from the fixed output to the operand. | 1078 // and insert a gap move from the fixed output to the operand. |
1079 UnallocatedOperand* output_copy = | 1079 UnallocatedOperand* output_copy = |
1080 new (code_zone()) UnallocatedOperand(UnallocatedOperand::ANY); | 1080 new (code_zone()) UnallocatedOperand(UnallocatedOperand::ANY); |
1081 output_copy->set_virtual_register(output_vreg); | 1081 output_copy->set_virtual_register(output_vreg); |
1082 | 1082 |
1083 AddGapMove(gap_index, GapInstruction::START, output, output_copy); | 1083 AddGapMove(gap_index, GapInstruction::START, output, output_copy); |
1084 } | 1084 } |
1085 } | 1085 } |
1086 | 1086 |
1087 if (!assigned) { | 1087 if (!assigned) { |
1088 for (auto succ : block->successors()) { | 1088 for (auto succ : block->successors()) { |
1089 const InstructionBlock* successor = code()->InstructionBlockAt(succ); | 1089 const InstructionBlock* successor = code()->InstructionBlockAt(succ); |
1090 DCHECK(successor->PredecessorCount() == 1); | 1090 DCHECK(successor->PredecessorCount() == 1); |
1091 int gap_index = successor->first_instruction_index() + 1; | 1091 int gap_index = successor->first_instruction_index(); |
1092 range->SpillAtDefinition(local_zone(), gap_index, output); | 1092 range->SpillAtDefinition(local_zone(), gap_index, output); |
1093 range->SetSpillStartIndex(gap_index); | 1093 range->SetSpillStartIndex(gap_index); |
1094 } | 1094 } |
1095 } | 1095 } |
1096 } | 1096 } |
1097 } | 1097 } |
1098 | 1098 |
1099 | 1099 |
1100 void RegisterAllocator::MeetConstraintsBetween(Instruction* first, | 1100 void RegisterAllocator::MeetConstraintsBetween(Instruction* first, |
1101 Instruction* second, | 1101 Instruction* second, |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1391 LifetimePosition pos) { | 1391 LifetimePosition pos) { |
1392 int index = pos.InstructionIndex(); | 1392 int index = pos.InstructionIndex(); |
1393 if (code()->IsGapAt(index)) { | 1393 if (code()->IsGapAt(index)) { |
1394 auto gap = code()->GapAt(index); | 1394 auto gap = code()->GapAt(index); |
1395 return gap->GetOrCreateParallelMove( | 1395 return gap->GetOrCreateParallelMove( |
1396 pos.IsInstructionStart() ? GapInstruction::START : GapInstruction::END, | 1396 pos.IsInstructionStart() ? GapInstruction::START : GapInstruction::END, |
1397 code_zone()); | 1397 code_zone()); |
1398 } | 1398 } |
1399 int gap_pos = pos.IsInstructionStart() ? (index - 1) : (index + 1); | 1399 int gap_pos = pos.IsInstructionStart() ? (index - 1) : (index + 1); |
1400 return code()->GapAt(gap_pos)->GetOrCreateParallelMove( | 1400 return code()->GapAt(gap_pos)->GetOrCreateParallelMove( |
1401 (gap_pos < index) ? GapInstruction::AFTER : GapInstruction::BEFORE, | 1401 (gap_pos < index) ? GapInstruction::AFTER : GapInstruction::START, |
1402 code_zone()); | 1402 code_zone()); |
1403 } | 1403 } |
1404 | 1404 |
1405 | 1405 |
1406 const InstructionBlock* RegisterAllocator::GetInstructionBlock( | 1406 const InstructionBlock* RegisterAllocator::GetInstructionBlock( |
1407 LifetimePosition pos) { | 1407 LifetimePosition pos) { |
1408 return code()->GetInstructionBlock(pos.InstructionIndex()); | 1408 return code()->GetInstructionBlock(pos.InstructionIndex()); |
1409 } | 1409 } |
1410 | 1410 |
1411 | 1411 |
(...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2318 InactiveToHandled(range); | 2318 InactiveToHandled(range); |
2319 --i; | 2319 --i; |
2320 } | 2320 } |
2321 } | 2321 } |
2322 } | 2322 } |
2323 } | 2323 } |
2324 | 2324 |
2325 | 2325 |
2326 bool RegisterAllocator::IsBlockBoundary(LifetimePosition pos) { | 2326 bool RegisterAllocator::IsBlockBoundary(LifetimePosition pos) { |
2327 return pos.IsInstructionStart() && | 2327 return pos.IsInstructionStart() && |
2328 InstructionAt(pos.InstructionIndex())->IsBlockStart(); | 2328 code()->GetInstructionBlock(pos.InstructionIndex())->code_start() == |
| 2329 pos.InstructionIndex(); |
2329 } | 2330 } |
2330 | 2331 |
2331 | 2332 |
2332 LiveRange* RegisterAllocator::SplitRangeAt(LiveRange* range, | 2333 LiveRange* RegisterAllocator::SplitRangeAt(LiveRange* range, |
2333 LifetimePosition pos) { | 2334 LifetimePosition pos) { |
2334 DCHECK(!range->IsFixed()); | 2335 DCHECK(!range->IsFixed()); |
2335 TraceAlloc("Splitting live range %d at %d\n", range->id(), pos.Value()); | 2336 TraceAlloc("Splitting live range %d at %d\n", range->id(), pos.Value()); |
2336 | 2337 |
2337 if (pos.Value() <= range->Start().Value()) return range; | 2338 if (pos.Value() <= range->Start().Value()) return range; |
2338 | 2339 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2413 LifetimePosition start, | 2414 LifetimePosition start, |
2414 LifetimePosition until, | 2415 LifetimePosition until, |
2415 LifetimePosition end) { | 2416 LifetimePosition end) { |
2416 CHECK(start.Value() < end.Value()); | 2417 CHECK(start.Value() < end.Value()); |
2417 auto second_part = SplitRangeAt(range, start); | 2418 auto second_part = SplitRangeAt(range, start); |
2418 | 2419 |
2419 if (second_part->Start().Value() < end.Value()) { | 2420 if (second_part->Start().Value() < end.Value()) { |
2420 // The split result intersects with [start, end[. | 2421 // The split result intersects with [start, end[. |
2421 // Split it at position between ]start+1, end[, spill the middle part | 2422 // Split it at position between ]start+1, end[, spill the middle part |
2422 // and put the rest to unhandled. | 2423 // and put the rest to unhandled. |
| 2424 auto third_part_end = end.PrevInstruction().InstructionEnd(); |
| 2425 if (IsBlockBoundary(end.InstructionStart())) { |
| 2426 third_part_end = end.InstructionStart(); |
| 2427 } |
2423 auto third_part = SplitBetween( | 2428 auto third_part = SplitBetween( |
2424 second_part, Max(second_part->Start().InstructionEnd(), until), | 2429 second_part, Max(second_part->Start().InstructionEnd(), until), |
2425 end.PrevInstruction().InstructionEnd()); | 2430 third_part_end); |
2426 | 2431 |
2427 DCHECK(third_part != second_part); | 2432 DCHECK(third_part != second_part); |
2428 | 2433 |
2429 Spill(second_part); | 2434 Spill(second_part); |
2430 AddToUnhandledSorted(third_part); | 2435 AddToUnhandledSorted(third_part); |
2431 } else { | 2436 } else { |
2432 // The split result does not intersect with [start, end[. | 2437 // The split result does not intersect with [start, end[. |
2433 // Nothing to spill. Just put it to unhandled as whole. | 2438 // Nothing to spill. Just put it to unhandled as whole. |
2434 AddToUnhandledSorted(second_part); | 2439 AddToUnhandledSorted(second_part); |
2435 } | 2440 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2470 } else { | 2475 } else { |
2471 DCHECK(range->Kind() == GENERAL_REGISTERS); | 2476 DCHECK(range->Kind() == GENERAL_REGISTERS); |
2472 assigned_registers_->Add(reg); | 2477 assigned_registers_->Add(reg); |
2473 } | 2478 } |
2474 range->set_assigned_register(reg, code_zone()); | 2479 range->set_assigned_register(reg, code_zone()); |
2475 } | 2480 } |
2476 | 2481 |
2477 } // namespace compiler | 2482 } // namespace compiler |
2478 } // namespace internal | 2483 } // namespace internal |
2479 } // namespace v8 | 2484 } // namespace v8 |
OLD | NEW |