Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: src/compiler/register-allocator.cc

Issue 948033002: [turbofan] only use two gaps (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 1397 matching lines...) Expand 10 before | Expand all | Expand 10 after
1408 1408
1409 void RegisterAllocator::ResolvePhis() { 1409 void RegisterAllocator::ResolvePhis() {
1410 // Process the blocks in reverse order. 1410 // Process the blocks in reverse order.
1411 for (auto i = code()->instruction_blocks().rbegin(); 1411 for (auto i = code()->instruction_blocks().rbegin();
1412 i != code()->instruction_blocks().rend(); ++i) { 1412 i != code()->instruction_blocks().rend(); ++i) {
1413 ResolvePhis(*i); 1413 ResolvePhis(*i);
1414 } 1414 }
1415 } 1415 }
1416 1416
1417 1417
1418 ParallelMove* RegisterAllocator::GetConnectingParallelMove(
1419 LifetimePosition pos) {
1420 int index = pos.InstructionIndex();
1421 if (code()->IsGapAt(index)) {
1422 auto gap = code()->GapAt(index);
1423 return gap->GetOrCreateParallelMove(
1424 pos.IsInstructionStart() ? GapInstruction::START : GapInstruction::END,
1425 code_zone());
1426 }
1427 int gap_pos = pos.IsInstructionStart() ? (index - 1) : (index + 1);
1428 return code()->GapAt(gap_pos)->GetOrCreateParallelMove(
1429 (gap_pos < index) ? GapInstruction::AFTER : GapInstruction::START,
1430 code_zone());
1431 }
1432
1433
1434 const InstructionBlock* RegisterAllocator::GetInstructionBlock( 1418 const InstructionBlock* RegisterAllocator::GetInstructionBlock(
1435 LifetimePosition pos) { 1419 LifetimePosition pos) {
1436 return code()->GetInstructionBlock(pos.InstructionIndex()); 1420 return code()->GetInstructionBlock(pos.InstructionIndex());
1437 } 1421 }
1438 1422
1439 1423
1440 void RegisterAllocator::ConnectRanges() { 1424 void RegisterAllocator::ConnectRanges() {
1425 ZoneMap<std::pair<ParallelMove*, InstructionOperand*>, InstructionOperand*>
1426 delayed_insertion_map(local_zone());
1441 for (auto first_range : live_ranges()) { 1427 for (auto first_range : live_ranges()) {
1442 if (first_range == nullptr || first_range->IsChild()) continue; 1428 if (first_range == nullptr || first_range->IsChild()) continue;
1443 auto second_range = first_range->next(); 1429 for (auto second_range = first_range->next(); second_range != nullptr;
1444 while (second_range != nullptr) { 1430 first_range = second_range, second_range = second_range->next()) {
1445 auto pos = second_range->Start(); 1431 auto pos = second_range->Start();
1446 if (!second_range->IsSpilled()) { 1432 // Add gap move if the two live ranges touch and there is no block
1447 // Add gap move if the two live ranges touch and there is no block 1433 // boundary.
1448 // boundary. 1434 if (second_range->IsSpilled()) continue;
1449 if (first_range->End().Value() == pos.Value()) { 1435 if (first_range->End().Value() != pos.Value()) continue;
1450 bool should_insert = true; 1436 if (IsBlockBoundary(pos) &&
1451 if (IsBlockBoundary(pos)) { 1437 !CanEagerlyResolveControlFlow(GetInstructionBlock(pos))) {
1452 should_insert = 1438 continue;
1453 CanEagerlyResolveControlFlow(GetInstructionBlock(pos));
1454 }
1455 if (should_insert) {
1456 auto move = GetConnectingParallelMove(pos);
1457 auto prev_operand =
1458 first_range->GetAssignedOperand(operand_cache());
1459 auto cur_operand =
1460 second_range->GetAssignedOperand(operand_cache());
1461 move->AddMove(prev_operand, cur_operand, code_zone());
1462 }
1463 }
1464 } 1439 }
1465 first_range = second_range; 1440 auto prev_operand = first_range->GetAssignedOperand(operand_cache());
1466 second_range = second_range->next(); 1441 auto cur_operand = second_range->GetAssignedOperand(operand_cache());
1442 if (prev_operand->Equals(cur_operand)) continue;
1443 int index = pos.InstructionIndex();
1444 bool delay_insertion = false;
1445 GapInstruction::InnerPosition gap_pos;
1446 int gap_index = index;
1447 if (code()->IsGapAt(index)) {
1448 gap_pos = pos.IsInstructionStart() ? GapInstruction::START
1449 : GapInstruction::END;
1450 } else {
1451 gap_index = pos.IsInstructionStart() ? (index - 1) : (index + 1);
1452 delay_insertion = gap_index < index;
1453 gap_pos = delay_insertion ? GapInstruction::END : GapInstruction::START;
1454 }
1455 auto move = code()->GapAt(gap_index)->GetOrCreateParallelMove(
1456 gap_pos, code_zone());
1457 if (!delay_insertion) {
1458 move->AddMove(prev_operand, cur_operand, code_zone());
1459 } else {
1460 delayed_insertion_map.insert(
1461 std::make_pair(std::make_pair(move, prev_operand), cur_operand));
1462 }
1467 } 1463 }
1468 } 1464 }
1465 if (delayed_insertion_map.empty()) return;
1466 // Insert all the moves which should occur after the stored move.
1467 ZoneVector<MoveOperands> to_insert(local_zone());
1468 ZoneVector<MoveOperands*> to_eliminate(local_zone());
1469 to_insert.reserve(4);
1470 to_eliminate.reserve(4);
1471 auto move = delayed_insertion_map.begin()->first.first;
1472 for (auto it = delayed_insertion_map.begin();; ++it) {
1473 bool done = it == delayed_insertion_map.end();
1474 if (done || it->first.first != move) {
1475 // Commit the MoveOperands for current ParallelMove.
1476 for (auto move_ops : to_eliminate) {
1477 move_ops->Eliminate();
1478 }
1479 for (auto move_ops : to_insert) {
1480 move->AddMove(move_ops.source(), move_ops.destination(), code_zone());
1481 }
1482 if (done) break;
1483 // Reset state.
1484 to_eliminate.clear();
1485 to_insert.clear();
1486 move = it->first.first;
1487 }
1488 // Gather all MoveOperands for a single ParallelMove.
1489 MoveOperands move_ops(it->first.second, it->second);
1490 auto eliminate = move->PrepareInsertAfter(&move_ops);
1491 to_insert.push_back(move_ops);
1492 if (eliminate != nullptr) to_eliminate.push_back(eliminate);
1493 }
1469 } 1494 }
1470 1495
1471 1496
1472 bool RegisterAllocator::CanEagerlyResolveControlFlow( 1497 bool RegisterAllocator::CanEagerlyResolveControlFlow(
1473 const InstructionBlock* block) const { 1498 const InstructionBlock* block) const {
1474 if (block->PredecessorCount() != 1) return false; 1499 if (block->PredecessorCount() != 1) return false;
1475 return block->predecessors()[0].IsNext(block->rpo_number()); 1500 return block->predecessors()[0].IsNext(block->rpo_number());
1476 } 1501 }
1477 1502
1478 1503
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after
2504 } else { 2529 } else {
2505 DCHECK(range->Kind() == GENERAL_REGISTERS); 2530 DCHECK(range->Kind() == GENERAL_REGISTERS);
2506 assigned_registers_->Add(reg); 2531 assigned_registers_->Add(reg);
2507 } 2532 }
2508 range->set_assigned_register(reg, operand_cache()); 2533 range->set_assigned_register(reg, operand_cache());
2509 } 2534 }
2510 2535
2511 } // namespace compiler 2536 } // namespace compiler
2512 } // namespace internal 2537 } // namespace internal
2513 } // namespace v8 2538 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/register-allocator.h ('k') | test/unittests/compiler/instruction-sequence-unittest.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698