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