| 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 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1071 if (output->IsStackSlot()) { | 1071 if (output->IsStackSlot()) { |
| 1072 DCHECK(output->index() < 0); | 1072 DCHECK(output->index() < 0); |
| 1073 range->SetSpillOperand(output); | 1073 range->SetSpillOperand(output); |
| 1074 range->SetSpillStartIndex(end); | 1074 range->SetSpillStartIndex(end); |
| 1075 assigned = true; | 1075 assigned = true; |
| 1076 } | 1076 } |
| 1077 | 1077 |
| 1078 for (auto succ : block->successors()) { | 1078 for (auto succ : block->successors()) { |
| 1079 const InstructionBlock* successor = code()->InstructionBlockAt(succ); | 1079 const InstructionBlock* successor = code()->InstructionBlockAt(succ); |
| 1080 DCHECK(successor->PredecessorCount() == 1); | 1080 DCHECK(successor->PredecessorCount() == 1); |
| 1081 int gap_index = successor->first_instruction_index() + 1; | 1081 int gap_index = successor->first_instruction_index(); |
| 1082 DCHECK(code()->IsGapAt(gap_index)); | 1082 DCHECK(code()->IsGapAt(gap_index)); |
| 1083 | 1083 |
| 1084 // Create an unconstrained operand for the same virtual register | 1084 // Create an unconstrained operand for the same virtual register |
| 1085 // and insert a gap move from the fixed output to the operand. | 1085 // and insert a gap move from the fixed output to the operand. |
| 1086 UnallocatedOperand* output_copy = | 1086 UnallocatedOperand* output_copy = |
| 1087 new (code_zone()) UnallocatedOperand(UnallocatedOperand::ANY); | 1087 new (code_zone()) UnallocatedOperand(UnallocatedOperand::ANY); |
| 1088 output_copy->set_virtual_register(output_vreg); | 1088 output_copy->set_virtual_register(output_vreg); |
| 1089 | 1089 |
| 1090 AddGapMove(gap_index, GapInstruction::START, output, output_copy); | 1090 AddGapMove(gap_index, GapInstruction::START, output, output_copy); |
| 1091 } | 1091 } |
| 1092 } | 1092 } |
| 1093 | 1093 |
| 1094 if (!assigned) { | 1094 if (!assigned) { |
| 1095 for (auto succ : block->successors()) { | 1095 for (auto succ : block->successors()) { |
| 1096 const InstructionBlock* successor = code()->InstructionBlockAt(succ); | 1096 const InstructionBlock* successor = code()->InstructionBlockAt(succ); |
| 1097 DCHECK(successor->PredecessorCount() == 1); | 1097 DCHECK(successor->PredecessorCount() == 1); |
| 1098 int gap_index = successor->first_instruction_index() + 1; | 1098 int gap_index = successor->first_instruction_index(); |
| 1099 range->SpillAtDefinition(local_zone(), gap_index, output); | 1099 range->SpillAtDefinition(local_zone(), gap_index, output); |
| 1100 range->SetSpillStartIndex(gap_index); | 1100 range->SetSpillStartIndex(gap_index); |
| 1101 } | 1101 } |
| 1102 } | 1102 } |
| 1103 } | 1103 } |
| 1104 } | 1104 } |
| 1105 | 1105 |
| 1106 | 1106 |
| 1107 void RegisterAllocator::MeetConstraintsBetween(Instruction* first, | 1107 void RegisterAllocator::MeetConstraintsBetween(Instruction* first, |
| 1108 Instruction* second, | 1108 Instruction* second, |
| (...skipping 1260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2369 InactiveToHandled(range); | 2369 InactiveToHandled(range); |
| 2370 --i; | 2370 --i; |
| 2371 } | 2371 } |
| 2372 } | 2372 } |
| 2373 } | 2373 } |
| 2374 } | 2374 } |
| 2375 | 2375 |
| 2376 | 2376 |
| 2377 bool RegisterAllocator::IsBlockBoundary(LifetimePosition pos) { | 2377 bool RegisterAllocator::IsBlockBoundary(LifetimePosition pos) { |
| 2378 return pos.IsInstructionStart() && | 2378 return pos.IsInstructionStart() && |
| 2379 InstructionAt(pos.InstructionIndex())->IsBlockStart(); | 2379 code()->GetInstructionBlock(pos.InstructionIndex())->code_start() == |
| 2380 pos.InstructionIndex(); |
| 2380 } | 2381 } |
| 2381 | 2382 |
| 2382 | 2383 |
| 2383 LiveRange* RegisterAllocator::SplitRangeAt(LiveRange* range, | 2384 LiveRange* RegisterAllocator::SplitRangeAt(LiveRange* range, |
| 2384 LifetimePosition pos) { | 2385 LifetimePosition pos) { |
| 2385 DCHECK(!range->IsFixed()); | 2386 DCHECK(!range->IsFixed()); |
| 2386 TraceAlloc("Splitting live range %d at %d\n", range->id(), pos.Value()); | 2387 TraceAlloc("Splitting live range %d at %d\n", range->id(), pos.Value()); |
| 2387 | 2388 |
| 2388 if (pos.Value() <= range->Start().Value()) return range; | 2389 if (pos.Value() <= range->Start().Value()) return range; |
| 2389 | 2390 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2467 LifetimePosition until, | 2468 LifetimePosition until, |
| 2468 LifetimePosition end) { | 2469 LifetimePosition end) { |
| 2469 CHECK(start.Value() < end.Value()); | 2470 CHECK(start.Value() < end.Value()); |
| 2470 auto second_part = SplitRangeAt(range, start); | 2471 auto second_part = SplitRangeAt(range, start); |
| 2471 if (!AllocationOk()) return; | 2472 if (!AllocationOk()) return; |
| 2472 | 2473 |
| 2473 if (second_part->Start().Value() < end.Value()) { | 2474 if (second_part->Start().Value() < end.Value()) { |
| 2474 // The split result intersects with [start, end[. | 2475 // The split result intersects with [start, end[. |
| 2475 // Split it at position between ]start+1, end[, spill the middle part | 2476 // Split it at position between ]start+1, end[, spill the middle part |
| 2476 // and put the rest to unhandled. | 2477 // and put the rest to unhandled. |
| 2478 auto third_part_end = end.PrevInstruction().InstructionEnd(); |
| 2479 if (IsBlockBoundary(end.InstructionStart())) { |
| 2480 third_part_end = end.InstructionStart(); |
| 2481 } |
| 2477 auto third_part = SplitBetween( | 2482 auto third_part = SplitBetween( |
| 2478 second_part, Max(second_part->Start().InstructionEnd(), until), | 2483 second_part, Max(second_part->Start().InstructionEnd(), until), |
| 2479 end.PrevInstruction().InstructionEnd()); | 2484 third_part_end); |
| 2480 if (!AllocationOk()) return; | 2485 if (!AllocationOk()) return; |
| 2481 | 2486 |
| 2482 DCHECK(third_part != second_part); | 2487 DCHECK(third_part != second_part); |
| 2483 | 2488 |
| 2484 Spill(second_part); | 2489 Spill(second_part); |
| 2485 AddToUnhandledSorted(third_part); | 2490 AddToUnhandledSorted(third_part); |
| 2486 } else { | 2491 } else { |
| 2487 // The split result does not intersect with [start, end[. | 2492 // The split result does not intersect with [start, end[. |
| 2488 // Nothing to spill. Just put it to unhandled as whole. | 2493 // Nothing to spill. Just put it to unhandled as whole. |
| 2489 AddToUnhandledSorted(second_part); | 2494 AddToUnhandledSorted(second_part); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2539 } else { | 2544 } else { |
| 2540 DCHECK(range->Kind() == GENERAL_REGISTERS); | 2545 DCHECK(range->Kind() == GENERAL_REGISTERS); |
| 2541 assigned_registers_->Add(reg); | 2546 assigned_registers_->Add(reg); |
| 2542 } | 2547 } |
| 2543 range->set_assigned_register(reg, code_zone()); | 2548 range->set_assigned_register(reg, code_zone()); |
| 2544 } | 2549 } |
| 2545 | 2550 |
| 2546 } // namespace compiler | 2551 } // namespace compiler |
| 2547 } // namespace internal | 2552 } // namespace internal |
| 2548 } // namespace v8 | 2553 } // namespace v8 |
| OLD | NEW |