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/base/adapters.h" | 5 #include "src/base/adapters.h" |
6 #include "src/compiler/linkage.h" | 6 #include "src/compiler/linkage.h" |
7 #include "src/compiler/register-allocator.h" | 7 #include "src/compiler/register-allocator.h" |
8 #include "src/string-stream.h" | 8 #include "src/string-stream.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 1408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1419 bool RegisterAllocationData::RangesDefinedInDeferredStayInDeferred() { | 1419 bool RegisterAllocationData::RangesDefinedInDeferredStayInDeferred() { |
1420 for (const TopLevelLiveRange* range : live_ranges()) { | 1420 for (const TopLevelLiveRange* range : live_ranges()) { |
1421 if (range == nullptr || range->IsEmpty() || | 1421 if (range == nullptr || range->IsEmpty() || |
1422 !code() | 1422 !code() |
1423 ->GetInstructionBlock(range->Start().ToInstructionIndex()) | 1423 ->GetInstructionBlock(range->Start().ToInstructionIndex()) |
1424 ->IsDeferred()) { | 1424 ->IsDeferred()) { |
1425 continue; | 1425 continue; |
1426 } | 1426 } |
1427 for (const UseInterval* i = range->first_interval(); i != nullptr; | 1427 for (const UseInterval* i = range->first_interval(); i != nullptr; |
1428 i = i->next()) { | 1428 i = i->next()) { |
1429 int first = i->FirstInstructionIndex(); | 1429 int first = i->FirstGapIndex(); |
1430 int last = i->LastInstructionIndex(); | 1430 int last = i->LastGapIndex(); |
1431 for (int instr = first; instr <= last;) { | 1431 for (int instr = first; instr <= last;) { |
1432 const InstructionBlock* block = code()->GetInstructionBlock(instr); | 1432 const InstructionBlock* block = code()->GetInstructionBlock(instr); |
1433 if (!block->IsDeferred()) return false; | 1433 if (!block->IsDeferred()) return false; |
1434 instr = block->last_instruction_index() + 1; | 1434 instr = block->last_instruction_index() + 1; |
1435 } | 1435 } |
1436 } | 1436 } |
1437 } | 1437 } |
1438 return true; | 1438 return true; |
1439 } | 1439 } |
1440 | 1440 |
(...skipping 1935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3376 LiveRangeBoundArray* array = finder.ArrayFor(iterator.Current()); | 3376 LiveRangeBoundArray* array = finder.ArrayFor(iterator.Current()); |
3377 for (const RpoNumber& pred : block->predecessors()) { | 3377 for (const RpoNumber& pred : block->predecessors()) { |
3378 FindResult result; | 3378 FindResult result; |
3379 const InstructionBlock* pred_block = code()->InstructionBlockAt(pred); | 3379 const InstructionBlock* pred_block = code()->InstructionBlockAt(pred); |
3380 if (!array->FindConnectableSubranges(block, pred_block, &result)) { | 3380 if (!array->FindConnectableSubranges(block, pred_block, &result)) { |
3381 continue; | 3381 continue; |
3382 } | 3382 } |
3383 InstructionOperand pred_op = result.pred_cover_->GetAssignedOperand(); | 3383 InstructionOperand pred_op = result.pred_cover_->GetAssignedOperand(); |
3384 InstructionOperand cur_op = result.cur_cover_->GetAssignedOperand(); | 3384 InstructionOperand cur_op = result.cur_cover_->GetAssignedOperand(); |
3385 if (pred_op.Equals(cur_op)) continue; | 3385 if (pred_op.Equals(cur_op)) continue; |
3386 ResolveControlFlow(block, cur_op, pred_block, pred_op); | 3386 int move_loc = ResolveControlFlow(block, cur_op, pred_block, pred_op); |
| 3387 USE(move_loc); |
| 3388 DCHECK_IMPLIES( |
| 3389 result.cur_cover_->TopLevel()->IsSpilledOnlyInDeferredBlocks() && |
| 3390 !(pred_op.IsAnyRegister() && cur_op.IsAnyRegister()), |
| 3391 code()->GetInstructionBlock(move_loc)->IsDeferred()); |
3387 } | 3392 } |
3388 iterator.Advance(); | 3393 iterator.Advance(); |
3389 } | 3394 } |
3390 } | 3395 } |
3391 } | 3396 } |
3392 | 3397 |
3393 | 3398 |
3394 void LiveRangeConnector::ResolveControlFlow(const InstructionBlock* block, | 3399 int LiveRangeConnector::ResolveControlFlow(const InstructionBlock* block, |
3395 const InstructionOperand& cur_op, | 3400 const InstructionOperand& cur_op, |
3396 const InstructionBlock* pred, | 3401 const InstructionBlock* pred, |
3397 const InstructionOperand& pred_op) { | 3402 const InstructionOperand& pred_op) { |
3398 DCHECK(!pred_op.Equals(cur_op)); | 3403 DCHECK(!pred_op.Equals(cur_op)); |
3399 int gap_index; | 3404 int gap_index; |
3400 Instruction::GapPosition position; | 3405 Instruction::GapPosition position; |
3401 if (block->PredecessorCount() == 1) { | 3406 if (block->PredecessorCount() == 1) { |
3402 gap_index = block->first_instruction_index(); | 3407 gap_index = block->first_instruction_index(); |
3403 position = Instruction::START; | 3408 position = Instruction::START; |
3404 } else { | 3409 } else { |
3405 DCHECK(pred->SuccessorCount() == 1); | 3410 DCHECK(pred->SuccessorCount() == 1); |
3406 DCHECK(!code() | 3411 DCHECK(!code() |
3407 ->InstructionAt(pred->last_instruction_index()) | 3412 ->InstructionAt(pred->last_instruction_index()) |
3408 ->HasReferenceMap()); | 3413 ->HasReferenceMap()); |
3409 gap_index = pred->last_instruction_index(); | 3414 gap_index = pred->last_instruction_index(); |
3410 position = Instruction::END; | 3415 position = Instruction::END; |
3411 } | 3416 } |
3412 data()->AddGapMove(gap_index, position, pred_op, cur_op); | 3417 data()->AddGapMove(gap_index, position, pred_op, cur_op); |
| 3418 return gap_index; |
3413 } | 3419 } |
3414 | 3420 |
3415 | 3421 |
3416 void LiveRangeConnector::ConnectRanges(Zone* local_zone) { | 3422 void LiveRangeConnector::ConnectRanges(Zone* local_zone) { |
3417 DelayedInsertionMap delayed_insertion_map(local_zone); | 3423 DelayedInsertionMap delayed_insertion_map(local_zone); |
3418 for (TopLevelLiveRange* top_range : data()->live_ranges()) { | 3424 for (TopLevelLiveRange* top_range : data()->live_ranges()) { |
3419 if (top_range == nullptr) continue; | 3425 if (top_range == nullptr) continue; |
3420 bool connect_spilled = top_range->IsSpilledOnlyInDeferredBlocks(); | 3426 bool connect_spilled = top_range->IsSpilledOnlyInDeferredBlocks(); |
3421 LiveRange* first_range = top_range; | 3427 LiveRange* first_range = top_range; |
3422 for (LiveRange *second_range = first_range->next(); second_range != nullptr; | 3428 for (LiveRange *second_range = first_range->next(); second_range != nullptr; |
(...skipping 16 matching lines...) Expand all Loading... |
3439 if (pos.IsGapPosition()) { | 3445 if (pos.IsGapPosition()) { |
3440 gap_pos = pos.IsStart() ? Instruction::START : Instruction::END; | 3446 gap_pos = pos.IsStart() ? Instruction::START : Instruction::END; |
3441 } else { | 3447 } else { |
3442 if (pos.IsStart()) { | 3448 if (pos.IsStart()) { |
3443 delay_insertion = true; | 3449 delay_insertion = true; |
3444 } else { | 3450 } else { |
3445 gap_index++; | 3451 gap_index++; |
3446 } | 3452 } |
3447 gap_pos = delay_insertion ? Instruction::END : Instruction::START; | 3453 gap_pos = delay_insertion ? Instruction::END : Instruction::START; |
3448 } | 3454 } |
| 3455 // Fills or spills for spilled in deferred blocks ranges must happen |
| 3456 // only in deferred blocks. |
| 3457 DCHECK_IMPLIES( |
| 3458 connect_spilled && |
| 3459 !(prev_operand.IsAnyRegister() && cur_operand.IsAnyRegister()), |
| 3460 code()->GetInstructionBlock(gap_index)->IsDeferred()); |
| 3461 |
3449 ParallelMove* move = | 3462 ParallelMove* move = |
3450 code()->InstructionAt(gap_index)->GetOrCreateParallelMove( | 3463 code()->InstructionAt(gap_index)->GetOrCreateParallelMove( |
3451 gap_pos, code_zone()); | 3464 gap_pos, code_zone()); |
3452 if (!delay_insertion) { | 3465 if (!delay_insertion) { |
3453 move->AddMove(prev_operand, cur_operand); | 3466 move->AddMove(prev_operand, cur_operand); |
3454 } else { | 3467 } else { |
3455 delayed_insertion_map.insert( | 3468 delayed_insertion_map.insert( |
3456 std::make_pair(std::make_pair(move, prev_operand), cur_operand)); | 3469 std::make_pair(std::make_pair(move, prev_operand), cur_operand)); |
3457 } | 3470 } |
3458 } | 3471 } |
(...skipping 27 matching lines...) Expand all Loading... |
3486 MoveOperands* eliminate = moves->PrepareInsertAfter(move); | 3499 MoveOperands* eliminate = moves->PrepareInsertAfter(move); |
3487 to_insert.push_back(move); | 3500 to_insert.push_back(move); |
3488 if (eliminate != nullptr) to_eliminate.push_back(eliminate); | 3501 if (eliminate != nullptr) to_eliminate.push_back(eliminate); |
3489 } | 3502 } |
3490 } | 3503 } |
3491 | 3504 |
3492 | 3505 |
3493 } // namespace compiler | 3506 } // namespace compiler |
3494 } // namespace internal | 3507 } // namespace internal |
3495 } // namespace v8 | 3508 } // namespace v8 |
OLD | NEW |