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