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 1183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1194 RegisterAllocationData::RegisterAllocationData( | 1194 RegisterAllocationData::RegisterAllocationData( |
1195 const RegisterConfiguration* config, Zone* zone, Frame* frame, | 1195 const RegisterConfiguration* config, Zone* zone, Frame* frame, |
1196 InstructionSequence* code, const char* debug_name) | 1196 InstructionSequence* code, const char* debug_name) |
1197 : allocation_zone_(zone), | 1197 : allocation_zone_(zone), |
1198 frame_(frame), | 1198 frame_(frame), |
1199 code_(code), | 1199 code_(code), |
1200 debug_name_(debug_name), | 1200 debug_name_(debug_name), |
1201 config_(config), | 1201 config_(config), |
1202 phi_map_(allocation_zone()), | 1202 phi_map_(allocation_zone()), |
1203 live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()), | 1203 live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()), |
| 1204 live_out_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()), |
1204 live_ranges_(code->VirtualRegisterCount() * 2, nullptr, | 1205 live_ranges_(code->VirtualRegisterCount() * 2, nullptr, |
1205 allocation_zone()), | 1206 allocation_zone()), |
1206 fixed_live_ranges_(this->config()->num_general_registers(), nullptr, | 1207 fixed_live_ranges_(this->config()->num_general_registers(), nullptr, |
1207 allocation_zone()), | 1208 allocation_zone()), |
1208 fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr, | 1209 fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr, |
1209 allocation_zone()), | 1210 allocation_zone()), |
1210 spill_ranges_(allocation_zone()), | 1211 spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()), |
1211 delayed_references_(allocation_zone()), | 1212 delayed_references_(allocation_zone()), |
1212 assigned_registers_(nullptr), | 1213 assigned_registers_(nullptr), |
1213 assigned_double_registers_(nullptr), | 1214 assigned_double_registers_(nullptr), |
1214 virtual_register_count_(code->VirtualRegisterCount()) { | 1215 virtual_register_count_(code->VirtualRegisterCount()) { |
1215 DCHECK(this->config()->num_general_registers() <= | 1216 DCHECK(this->config()->num_general_registers() <= |
1216 RegisterConfiguration::kMaxGeneralRegisters); | 1217 RegisterConfiguration::kMaxGeneralRegisters); |
1217 DCHECK(this->config()->num_double_registers() <= | 1218 DCHECK(this->config()->num_double_registers() <= |
1218 RegisterConfiguration::kMaxDoubleRegisters); | 1219 RegisterConfiguration::kMaxDoubleRegisters); |
1219 assigned_registers_ = new (code_zone()) | 1220 assigned_registers_ = new (code_zone()) |
1220 BitVector(this->config()->num_general_registers(), code_zone()); | 1221 BitVector(this->config()->num_general_registers(), code_zone()); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1327 TopLevelLiveRange* range) { | 1328 TopLevelLiveRange* range) { |
1328 DCHECK(!range->HasSpillOperand()); | 1329 DCHECK(!range->HasSpillOperand()); |
1329 | 1330 |
1330 SpillRange* spill_range = range->GetAllocatedSpillRange(); | 1331 SpillRange* spill_range = range->GetAllocatedSpillRange(); |
1331 if (spill_range == nullptr) { | 1332 if (spill_range == nullptr) { |
1332 DCHECK(!range->IsSplinter()); | 1333 DCHECK(!range->IsSplinter()); |
1333 spill_range = new (allocation_zone()) SpillRange(range, allocation_zone()); | 1334 spill_range = new (allocation_zone()) SpillRange(range, allocation_zone()); |
1334 } | 1335 } |
1335 range->set_spill_type(TopLevelLiveRange::SpillType::kSpillRange); | 1336 range->set_spill_type(TopLevelLiveRange::SpillType::kSpillRange); |
1336 | 1337 |
1337 spill_ranges().insert(spill_range); | 1338 int spill_range_index = |
| 1339 range->IsSplinter() ? range->splintered_from()->vreg() : range->vreg(); |
| 1340 |
| 1341 spill_ranges()[spill_range_index] = spill_range; |
| 1342 |
1338 return spill_range; | 1343 return spill_range; |
1339 } | 1344 } |
1340 | 1345 |
1341 | 1346 |
1342 SpillRange* RegisterAllocationData::CreateSpillRangeForLiveRange( | 1347 SpillRange* RegisterAllocationData::CreateSpillRangeForLiveRange( |
1343 TopLevelLiveRange* range) { | 1348 TopLevelLiveRange* range) { |
1344 DCHECK(!range->HasSpillOperand()); | 1349 DCHECK(!range->HasSpillOperand()); |
1345 DCHECK(!range->IsSplinter()); | 1350 DCHECK(!range->IsSplinter()); |
1346 auto spill_range = | 1351 auto spill_range = |
1347 new (allocation_zone()) SpillRange(range, allocation_zone()); | 1352 new (allocation_zone()) SpillRange(range, allocation_zone()); |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1676 } | 1681 } |
1677 | 1682 |
1678 | 1683 |
1679 LiveRangeBuilder::LiveRangeBuilder(RegisterAllocationData* data, | 1684 LiveRangeBuilder::LiveRangeBuilder(RegisterAllocationData* data, |
1680 Zone* local_zone) | 1685 Zone* local_zone) |
1681 : data_(data), phi_hints_(local_zone) {} | 1686 : data_(data), phi_hints_(local_zone) {} |
1682 | 1687 |
1683 | 1688 |
1684 BitVector* LiveRangeBuilder::ComputeLiveOut(const InstructionBlock* block, | 1689 BitVector* LiveRangeBuilder::ComputeLiveOut(const InstructionBlock* block, |
1685 RegisterAllocationData* data) { | 1690 RegisterAllocationData* data) { |
1686 // Compute live out for the given block, except not including backward | 1691 size_t block_index = block->rpo_number().ToSize(); |
1687 // successor edges. | 1692 BitVector* live_out = data->live_out_sets()[block_index]; |
1688 Zone* zone = data->allocation_zone(); | 1693 if (live_out == nullptr) { |
1689 const InstructionSequence* code = data->code(); | 1694 // Compute live out for the given block, except not including backward |
| 1695 // successor edges. |
| 1696 Zone* zone = data->allocation_zone(); |
| 1697 const InstructionSequence* code = data->code(); |
1690 | 1698 |
1691 auto live_out = new (zone) BitVector(code->VirtualRegisterCount(), zone); | 1699 live_out = new (zone) BitVector(code->VirtualRegisterCount(), zone); |
1692 | 1700 |
1693 // Process all successor blocks. | 1701 // Process all successor blocks. |
1694 for (auto succ : block->successors()) { | 1702 for (const RpoNumber& succ : block->successors()) { |
1695 // Add values live on entry to the successor. | 1703 // Add values live on entry to the successor. |
1696 if (succ <= block->rpo_number()) continue; | 1704 if (succ <= block->rpo_number()) continue; |
1697 auto live_in = data->live_in_sets()[succ.ToSize()]; | 1705 BitVector* live_in = data->live_in_sets()[succ.ToSize()]; |
1698 if (live_in != nullptr) live_out->Union(*live_in); | 1706 if (live_in != nullptr) live_out->Union(*live_in); |
1699 | 1707 |
1700 // All phi input operands corresponding to this successor edge are live | 1708 // All phi input operands corresponding to this successor edge are live |
1701 // out from this block. | 1709 // out from this block. |
1702 auto successor = code->InstructionBlockAt(succ); | 1710 auto successor = code->InstructionBlockAt(succ); |
1703 size_t index = successor->PredecessorIndexOf(block->rpo_number()); | 1711 size_t index = successor->PredecessorIndexOf(block->rpo_number()); |
1704 DCHECK(index < successor->PredecessorCount()); | 1712 DCHECK(index < successor->PredecessorCount()); |
1705 for (auto phi : successor->phis()) { | 1713 for (PhiInstruction* phi : successor->phis()) { |
1706 live_out->Add(phi->operands()[index]); | 1714 live_out->Add(phi->operands()[index]); |
| 1715 } |
1707 } | 1716 } |
| 1717 data->live_out_sets()[block_index] = live_out; |
1708 } | 1718 } |
1709 return live_out; | 1719 return live_out; |
1710 } | 1720 } |
1711 | 1721 |
1712 | 1722 |
1713 void LiveRangeBuilder::AddInitialIntervals(const InstructionBlock* block, | 1723 void LiveRangeBuilder::AddInitialIntervals(const InstructionBlock* block, |
1714 BitVector* live_out) { | 1724 BitVector* live_out) { |
1715 // Add an interval that includes the entire block to the live range for | 1725 // Add an interval that includes the entire block to the live range for |
1716 // each live_out value. | 1726 // each live_out value. |
1717 auto start = LifetimePosition::GapFromInstructionIndex( | 1727 auto start = LifetimePosition::GapFromInstructionIndex( |
(...skipping 1104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2822 code->GetInstructionBlock(spills->gap_index)->mark_needs_frame(); | 2832 code->GetInstructionBlock(spills->gap_index)->mark_needs_frame(); |
2823 } | 2833 } |
2824 } | 2834 } |
2825 } | 2835 } |
2826 | 2836 |
2827 | 2837 |
2828 OperandAssigner::OperandAssigner(RegisterAllocationData* data) : data_(data) {} | 2838 OperandAssigner::OperandAssigner(RegisterAllocationData* data) : data_(data) {} |
2829 | 2839 |
2830 | 2840 |
2831 void OperandAssigner::AssignSpillSlots() { | 2841 void OperandAssigner::AssignSpillSlots() { |
2832 ZoneSet<SpillRange*>& spill_ranges = data()->spill_ranges(); | 2842 ZoneVector<SpillRange*>& spill_ranges = data()->spill_ranges(); |
2833 // Merge disjoint spill ranges | 2843 // Merge disjoint spill ranges |
2834 for (auto i = spill_ranges.begin(), end = spill_ranges.end(); i != end; ++i) { | 2844 for (size_t i = 0; i < spill_ranges.size(); ++i) { |
2835 SpillRange* range = *i; | 2845 SpillRange* range = spill_ranges[i]; |
| 2846 if (range == nullptr) continue; |
2836 if (range->IsEmpty()) continue; | 2847 if (range->IsEmpty()) continue; |
2837 auto j = i; | 2848 for (size_t j = i + 1; j < spill_ranges.size(); ++j) { |
2838 j++; | 2849 SpillRange* other = spill_ranges[j]; |
2839 for (; j != end; ++j) { | 2850 if (other != nullptr && !other->IsEmpty()) { |
2840 SpillRange* other = *j; | |
2841 if (!other->IsEmpty()) { | |
2842 range->TryMerge(other); | 2851 range->TryMerge(other); |
2843 } | 2852 } |
2844 } | 2853 } |
2845 } | 2854 } |
2846 // Allocate slots for the merged spill ranges. | 2855 // Allocate slots for the merged spill ranges. |
2847 for (auto range : spill_ranges) { | 2856 for (SpillRange* range : spill_ranges) { |
2848 if (range->IsEmpty()) continue; | 2857 if (range == nullptr || range->IsEmpty()) continue; |
2849 // Allocate a new operand referring to the spill slot. | 2858 // Allocate a new operand referring to the spill slot. |
2850 int byte_width = range->ByteWidth(); | 2859 int byte_width = range->ByteWidth(); |
2851 int index = data()->frame()->AllocateSpillSlot(byte_width); | 2860 int index = data()->frame()->AllocateSpillSlot(byte_width); |
2852 range->set_assigned_slot(index); | 2861 range->set_assigned_slot(index); |
2853 } | 2862 } |
2854 } | 2863 } |
2855 | 2864 |
2856 | 2865 |
2857 void OperandAssigner::CommitAssignment() { | 2866 void OperandAssigner::CommitAssignment() { |
2858 for (TopLevelLiveRange* top_range : data()->live_ranges()) { | 2867 for (TopLevelLiveRange* top_range : data()->live_ranges()) { |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3298 auto eliminate = moves->PrepareInsertAfter(move); | 3307 auto eliminate = moves->PrepareInsertAfter(move); |
3299 to_insert.push_back(move); | 3308 to_insert.push_back(move); |
3300 if (eliminate != nullptr) to_eliminate.push_back(eliminate); | 3309 if (eliminate != nullptr) to_eliminate.push_back(eliminate); |
3301 } | 3310 } |
3302 } | 3311 } |
3303 | 3312 |
3304 | 3313 |
3305 } // namespace compiler | 3314 } // namespace compiler |
3306 } // namespace internal | 3315 } // namespace internal |
3307 } // namespace v8 | 3316 } // namespace v8 |
OLD | NEW |