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 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 new (code_zone()) BitVector(config->num_general_registers(), code_zone()); | 560 new (code_zone()) BitVector(config->num_general_registers(), code_zone()); |
561 assigned_double_registers_ = new (code_zone()) | 561 assigned_double_registers_ = new (code_zone()) |
562 BitVector(config->num_aliased_double_registers(), code_zone()); | 562 BitVector(config->num_aliased_double_registers(), code_zone()); |
563 frame->SetAllocatedRegisters(assigned_registers_); | 563 frame->SetAllocatedRegisters(assigned_registers_); |
564 frame->SetAllocatedDoubleRegisters(assigned_double_registers_); | 564 frame->SetAllocatedDoubleRegisters(assigned_double_registers_); |
565 } | 565 } |
566 | 566 |
567 | 567 |
568 void RegisterAllocator::InitializeLivenessAnalysis() { | 568 void RegisterAllocator::InitializeLivenessAnalysis() { |
569 // Initialize the live_in sets for each block to NULL. | 569 // Initialize the live_in sets for each block to NULL. |
570 int block_count = code()->InstructionBlockCount(); | 570 std::fill(live_in_sets_.begin(), live_in_sets_.end(), nullptr); |
571 live_in_sets_.Initialize(block_count, local_zone()); | |
572 live_in_sets_.AddBlock(NULL, block_count, local_zone()); | |
573 } | 571 } |
574 | 572 |
575 | 573 |
576 BitVector* RegisterAllocator::ComputeLiveOut(const InstructionBlock* block) { | 574 BitVector* RegisterAllocator::ComputeLiveOut(const InstructionBlock* block) { |
577 // Compute live out for the given block, except not including backward | 575 // Compute live out for the given block, except not including backward |
578 // successor edges. | 576 // successor edges. |
579 BitVector* live_out = new (local_zone()) | 577 BitVector* live_out = new (local_zone()) |
580 BitVector(code()->VirtualRegisterCount(), local_zone()); | 578 BitVector(code()->VirtualRegisterCount(), local_zone()); |
581 | 579 |
582 // Process all successor blocks. | 580 // Process all successor blocks. |
583 for (auto succ : block->successors()) { | 581 for (auto succ : block->successors()) { |
584 // Add values live on entry to the successor. Note the successor's | 582 // Add values live on entry to the successor. Note the successor's |
585 // live_in will not be computed yet for backwards edges. | 583 // live_in will not be computed yet for backwards edges. |
586 BitVector* live_in = live_in_sets_[static_cast<int>(succ.ToSize())]; | 584 BitVector* live_in = live_in_sets_[succ.ToSize()]; |
587 if (live_in != NULL) live_out->Union(*live_in); | 585 if (live_in != NULL) live_out->Union(*live_in); |
588 | 586 |
589 // All phi input operands corresponding to this successor edge are live | 587 // All phi input operands corresponding to this successor edge are live |
590 // out from this block. | 588 // out from this block. |
591 const InstructionBlock* successor = code()->InstructionBlockAt(succ); | 589 const InstructionBlock* successor = code()->InstructionBlockAt(succ); |
592 size_t index = successor->PredecessorIndexOf(block->rpo_number()); | 590 size_t index = successor->PredecessorIndexOf(block->rpo_number()); |
593 DCHECK(index < successor->PredecessorCount()); | 591 DCHECK(index < successor->PredecessorCount()); |
594 for (auto phi : successor->phis()) { | 592 for (auto phi : successor->phis()) { |
595 live_out->Add(phi->operands()[index]); | 593 live_out->Add(phi->operands()[index]); |
596 } | 594 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 DCHECK(result->IsFixed()); | 674 DCHECK(result->IsFixed()); |
677 result->kind_ = DOUBLE_REGISTERS; | 675 result->kind_ = DOUBLE_REGISTERS; |
678 SetLiveRangeAssignedRegister(result, index); | 676 SetLiveRangeAssignedRegister(result, index); |
679 fixed_double_live_ranges_[index] = result; | 677 fixed_double_live_ranges_[index] = result; |
680 } | 678 } |
681 return result; | 679 return result; |
682 } | 680 } |
683 | 681 |
684 | 682 |
685 LiveRange* RegisterAllocator::LiveRangeFor(int index) { | 683 LiveRange* RegisterAllocator::LiveRangeFor(int index) { |
686 if (index >= live_ranges_.length()) { | 684 if (index >= static_cast<int>(live_ranges_.size())) { |
687 live_ranges_.AddBlock(NULL, index - live_ranges_.length() + 1, | 685 live_ranges_.resize(index + 1, NULL); |
688 local_zone()); | |
689 } | 686 } |
690 LiveRange* result = live_ranges_[index]; | 687 LiveRange* result = live_ranges_[index]; |
691 if (result == NULL) { | 688 if (result == NULL) { |
692 result = new (local_zone()) LiveRange(index, code_zone()); | 689 result = new (local_zone()) LiveRange(index, code_zone()); |
693 live_ranges_[index] = result; | 690 live_ranges_[index] = result; |
694 } | 691 } |
695 return result; | 692 return result; |
696 } | 693 } |
697 | 694 |
698 | 695 |
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1321 } | 1318 } |
1322 | 1319 |
1323 | 1320 |
1324 const InstructionBlock* RegisterAllocator::GetInstructionBlock( | 1321 const InstructionBlock* RegisterAllocator::GetInstructionBlock( |
1325 LifetimePosition pos) { | 1322 LifetimePosition pos) { |
1326 return code()->GetInstructionBlock(pos.InstructionIndex()); | 1323 return code()->GetInstructionBlock(pos.InstructionIndex()); |
1327 } | 1324 } |
1328 | 1325 |
1329 | 1326 |
1330 void RegisterAllocator::ConnectRanges() { | 1327 void RegisterAllocator::ConnectRanges() { |
1331 for (int i = 0; i < live_ranges().length(); ++i) { | 1328 for (size_t i = 0; i < live_ranges().size(); ++i) { |
1332 LiveRange* first_range = live_ranges().at(i); | 1329 LiveRange* first_range = live_ranges().at(i); |
1333 if (first_range == NULL || first_range->parent() != NULL) continue; | 1330 if (first_range == NULL || first_range->parent() != NULL) continue; |
1334 | 1331 |
1335 LiveRange* second_range = first_range->next(); | 1332 LiveRange* second_range = first_range->next(); |
1336 while (second_range != NULL) { | 1333 while (second_range != NULL) { |
1337 LifetimePosition pos = second_range->Start(); | 1334 LifetimePosition pos = second_range->Start(); |
1338 | 1335 |
1339 if (!second_range->IsSpilled()) { | 1336 if (!second_range->IsSpilled()) { |
1340 // Add gap move if the two live ranges touch and there is no block | 1337 // Add gap move if the two live ranges touch and there is no block |
1341 // boundary. | 1338 // boundary. |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1467 LiveRangeBound* start_; | 1464 LiveRangeBound* start_; |
1468 | 1465 |
1469 DISALLOW_COPY_AND_ASSIGN(LiveRangeBoundArray); | 1466 DISALLOW_COPY_AND_ASSIGN(LiveRangeBoundArray); |
1470 }; | 1467 }; |
1471 | 1468 |
1472 | 1469 |
1473 class LiveRangeFinder { | 1470 class LiveRangeFinder { |
1474 public: | 1471 public: |
1475 explicit LiveRangeFinder(const RegisterAllocator& allocator) | 1472 explicit LiveRangeFinder(const RegisterAllocator& allocator) |
1476 : allocator_(allocator), | 1473 : allocator_(allocator), |
1477 bounds_length_(allocator.live_ranges().length()), | 1474 bounds_length_(static_cast<int>(allocator.live_ranges().size())), |
1478 bounds_(allocator.local_zone()->NewArray<LiveRangeBoundArray>( | 1475 bounds_(allocator.local_zone()->NewArray<LiveRangeBoundArray>( |
1479 bounds_length_)) { | 1476 bounds_length_)) { |
1480 for (int i = 0; i < bounds_length_; ++i) { | 1477 for (int i = 0; i < bounds_length_; ++i) { |
1481 new (&bounds_[i]) LiveRangeBoundArray(); | 1478 new (&bounds_[i]) LiveRangeBoundArray(); |
1482 } | 1479 } |
1483 } | 1480 } |
1484 | 1481 |
1485 LiveRangeBoundArray* ArrayFor(int operand_index) { | 1482 LiveRangeBoundArray* ArrayFor(int operand_index) { |
1486 DCHECK(operand_index < bounds_length_); | 1483 DCHECK(operand_index < bounds_length_); |
1487 const LiveRange* range = allocator_.live_ranges()[operand_index]; | 1484 const LiveRange* range = allocator_.live_ranges()[operand_index]; |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1638 } | 1635 } |
1639 | 1636 |
1640 // Insert all values into the live in sets of all blocks in the loop. | 1637 // Insert all values into the live in sets of all blocks in the loop. |
1641 for (int i = block->rpo_number().ToInt() + 1; | 1638 for (int i = block->rpo_number().ToInt() + 1; |
1642 i < block->loop_end().ToInt(); ++i) { | 1639 i < block->loop_end().ToInt(); ++i) { |
1643 live_in_sets_[i]->Union(*live); | 1640 live_in_sets_[i]->Union(*live); |
1644 } | 1641 } |
1645 } | 1642 } |
1646 } | 1643 } |
1647 | 1644 |
1648 for (int i = 0; i < live_ranges_.length(); ++i) { | 1645 for (size_t i = 0; i < live_ranges_.size(); ++i) { |
1649 if (live_ranges_[i] != NULL) { | 1646 if (live_ranges_[i] != NULL) { |
1650 live_ranges_[i]->kind_ = RequiredRegisterKind(live_ranges_[i]->id()); | 1647 live_ranges_[i]->kind_ = RequiredRegisterKind(live_ranges_[i]->id()); |
1651 | 1648 |
1652 // TODO(bmeurer): This is a horrible hack to make sure that for constant | 1649 // TODO(bmeurer): This is a horrible hack to make sure that for constant |
1653 // live ranges, every use requires the constant to be in a register. | 1650 // live ranges, every use requires the constant to be in a register. |
1654 // Without this hack, all uses with "any" policy would get the constant | 1651 // Without this hack, all uses with "any" policy would get the constant |
1655 // operand assigned. | 1652 // operand assigned. |
1656 LiveRange* range = live_ranges_[i]; | 1653 LiveRange* range = live_ranges_[i]; |
1657 if (range->HasAllocatedSpillOperand() && | 1654 if (range->HasAllocatedSpillOperand() && |
1658 range->GetSpillOperand()->IsConstant()) { | 1655 range->GetSpillOperand()->IsConstant()) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1708 | 1705 |
1709 | 1706 |
1710 void RegisterAllocator::PopulatePointerMaps() { | 1707 void RegisterAllocator::PopulatePointerMaps() { |
1711 DCHECK(SafePointsAreInOrder()); | 1708 DCHECK(SafePointsAreInOrder()); |
1712 | 1709 |
1713 // Iterate over all safe point positions and record a pointer | 1710 // Iterate over all safe point positions and record a pointer |
1714 // for all spilled live ranges at this point. | 1711 // for all spilled live ranges at this point. |
1715 int last_range_start = 0; | 1712 int last_range_start = 0; |
1716 const PointerMapDeque* pointer_maps = code()->pointer_maps(); | 1713 const PointerMapDeque* pointer_maps = code()->pointer_maps(); |
1717 PointerMapDeque::const_iterator first_it = pointer_maps->begin(); | 1714 PointerMapDeque::const_iterator first_it = pointer_maps->begin(); |
1718 for (int range_idx = 0; range_idx < live_ranges().length(); ++range_idx) { | 1715 for (size_t range_idx = 0; range_idx < live_ranges().size(); ++range_idx) { |
1719 LiveRange* range = live_ranges().at(range_idx); | 1716 LiveRange* range = live_ranges().at(range_idx); |
1720 if (range == NULL) continue; | 1717 if (range == NULL) continue; |
1721 // Iterate over the first parts of multi-part live ranges. | 1718 // Iterate over the first parts of multi-part live ranges. |
1722 if (range->parent() != NULL) continue; | 1719 if (range->parent() != NULL) continue; |
1723 // Skip non-reference values. | 1720 // Skip non-reference values. |
1724 if (!HasTaggedValue(range->id())) continue; | 1721 if (!HasTaggedValue(range->id())) continue; |
1725 // Skip empty live ranges. | 1722 // Skip empty live ranges. |
1726 if (range->IsEmpty()) continue; | 1723 if (range->IsEmpty()) continue; |
1727 | 1724 |
1728 // Find the extent of the range and its children. | 1725 // Find the extent of the range and its children. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1799 void RegisterAllocator::AllocateDoubleRegisters() { | 1796 void RegisterAllocator::AllocateDoubleRegisters() { |
1800 num_registers_ = config()->num_aliased_double_registers(); | 1797 num_registers_ = config()->num_aliased_double_registers(); |
1801 mode_ = DOUBLE_REGISTERS; | 1798 mode_ = DOUBLE_REGISTERS; |
1802 AllocateRegisters(); | 1799 AllocateRegisters(); |
1803 } | 1800 } |
1804 | 1801 |
1805 | 1802 |
1806 void RegisterAllocator::AllocateRegisters() { | 1803 void RegisterAllocator::AllocateRegisters() { |
1807 DCHECK(unhandled_live_ranges_.is_empty()); | 1804 DCHECK(unhandled_live_ranges_.is_empty()); |
1808 | 1805 |
1809 for (int i = 0; i < live_ranges_.length(); ++i) { | 1806 for (size_t i = 0; i < live_ranges_.size(); ++i) { |
1810 if (live_ranges_[i] != NULL) { | 1807 if (live_ranges_[i] != NULL) { |
1811 if (live_ranges_[i]->Kind() == mode_) { | 1808 if (live_ranges_[i]->Kind() == mode_) { |
1812 AddToUnhandledUnsorted(live_ranges_[i]); | 1809 AddToUnhandledUnsorted(live_ranges_[i]); |
1813 } | 1810 } |
1814 } | 1811 } |
1815 } | 1812 } |
1816 SortUnhandled(); | 1813 SortUnhandled(); |
1817 DCHECK(UnhandledIsSorted()); | 1814 DCHECK(UnhandledIsSorted()); |
1818 | 1815 |
1819 DCHECK(reusable_slots_.is_empty()); | 1816 DCHECK(reusable_slots_.is_empty()); |
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2479 } else { | 2476 } else { |
2480 DCHECK(range->Kind() == GENERAL_REGISTERS); | 2477 DCHECK(range->Kind() == GENERAL_REGISTERS); |
2481 assigned_registers_->Add(reg); | 2478 assigned_registers_->Add(reg); |
2482 } | 2479 } |
2483 range->set_assigned_register(reg, code_zone()); | 2480 range->set_assigned_register(reg, code_zone()); |
2484 } | 2481 } |
2485 | 2482 |
2486 } // namespace compiler | 2483 } // namespace compiler |
2487 } // namespace internal | 2484 } // namespace internal |
2488 } // namespace v8 | 2485 } // namespace v8 |
OLD | NEW |