| 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 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 struct LiveRange::SpillAtDefinitionList : ZoneObject { | 230 struct LiveRange::SpillAtDefinitionList : ZoneObject { |
| 231 SpillAtDefinitionList(int gap_index, InstructionOperand* operand, | 231 SpillAtDefinitionList(int gap_index, InstructionOperand* operand, |
| 232 SpillAtDefinitionList* next) | 232 SpillAtDefinitionList* next) |
| 233 : gap_index(gap_index), operand(operand), next(next) {} | 233 : gap_index(gap_index), operand(operand), next(next) {} |
| 234 const int gap_index; | 234 const int gap_index; |
| 235 InstructionOperand* const operand; | 235 InstructionOperand* const operand; |
| 236 SpillAtDefinitionList* const next; | 236 SpillAtDefinitionList* const next; |
| 237 }; | 237 }; |
| 238 | 238 |
| 239 | 239 |
| 240 const float LiveRange::kInvalidWeight = -1; |
| 241 const float LiveRange::kMaxWeight = std::numeric_limits<float>::max(); |
| 242 |
| 243 |
| 240 LiveRange::LiveRange(int id, MachineType machine_type) | 244 LiveRange::LiveRange(int id, MachineType machine_type) |
| 241 : id_(id), | 245 : id_(id), |
| 242 spill_start_index_(kMaxInt), | 246 spill_start_index_(kMaxInt), |
| 243 bits_(0), | 247 bits_(0), |
| 244 last_interval_(nullptr), | 248 last_interval_(nullptr), |
| 245 first_interval_(nullptr), | 249 first_interval_(nullptr), |
| 246 first_pos_(nullptr), | 250 first_pos_(nullptr), |
| 247 parent_(nullptr), | 251 parent_(nullptr), |
| 248 next_(nullptr), | 252 next_(nullptr), |
| 249 spill_operand_(nullptr), | 253 spill_operand_(nullptr), |
| 250 spills_at_definition_(nullptr), | 254 spills_at_definition_(nullptr), |
| 251 current_interval_(nullptr), | 255 current_interval_(nullptr), |
| 252 last_processed_use_(nullptr), | 256 last_processed_use_(nullptr), |
| 253 current_hint_position_(nullptr) { | 257 current_hint_position_(nullptr), |
| 258 size_(kInvalidSize), |
| 259 weight_(kInvalidWeight) { |
| 254 DCHECK(AllocatedOperand::IsSupportedMachineType(machine_type)); | 260 DCHECK(AllocatedOperand::IsSupportedMachineType(machine_type)); |
| 255 bits_ = SpillTypeField::encode(SpillType::kNoSpillType) | | 261 bits_ = SpillTypeField::encode(SpillType::kNoSpillType) | |
| 256 AssignedRegisterField::encode(kUnassignedRegister) | | 262 AssignedRegisterField::encode(kUnassignedRegister) | |
| 257 MachineTypeField::encode(machine_type); | 263 MachineTypeField::encode(machine_type); |
| 258 } | 264 } |
| 259 | 265 |
| 260 | 266 |
| 261 void LiveRange::Verify() const { | 267 void LiveRange::Verify() const { |
| 262 // Walk the positions, verifying that each is in an interval. | 268 // Walk the positions, verifying that each is in an interval. |
| 263 auto interval = first_interval_; | 269 auto interval = first_interval_; |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 // to the use that no longer belongs to this live range. | 558 // to the use that no longer belongs to this live range. |
| 553 last_processed_use_ = nullptr; | 559 last_processed_use_ = nullptr; |
| 554 current_interval_ = nullptr; | 560 current_interval_ = nullptr; |
| 555 | 561 |
| 556 // Link the new live range in the chain before any of the other | 562 // Link the new live range in the chain before any of the other |
| 557 // ranges linked from the range before the split. | 563 // ranges linked from the range before the split. |
| 558 result->parent_ = (parent_ == nullptr) ? this : parent_; | 564 result->parent_ = (parent_ == nullptr) ? this : parent_; |
| 559 result->next_ = next_; | 565 result->next_ = next_; |
| 560 next_ = result; | 566 next_ = result; |
| 561 | 567 |
| 568 // Invalidate size and weight of this range. The child range has them |
| 569 // invalid at construction. |
| 570 size_ = kInvalidSize; |
| 571 weight_ = kInvalidWeight; |
| 562 #ifdef DEBUG | 572 #ifdef DEBUG |
| 563 Verify(); | 573 Verify(); |
| 564 result->Verify(); | 574 result->Verify(); |
| 565 #endif | 575 #endif |
| 566 } | 576 } |
| 567 | 577 |
| 568 | 578 |
| 569 // This implements an ordering on live ranges so that they are ordered by their | 579 // This implements an ordering on live ranges so that they are ordered by their |
| 570 // start positions. This is needed for the correctness of the register | 580 // start positions. This is needed for the correctness of the register |
| 571 // allocation algorithm. If two live ranges start at the same offset then there | 581 // allocation algorithm. If two live ranges start at the same offset then there |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 if (a == nullptr || a->start() > other->End()) break; | 752 if (a == nullptr || a->start() > other->End()) break; |
| 743 AdvanceLastProcessedMarker(a, advance_last_processed_up_to); | 753 AdvanceLastProcessedMarker(a, advance_last_processed_up_to); |
| 744 } else { | 754 } else { |
| 745 b = b->next(); | 755 b = b->next(); |
| 746 } | 756 } |
| 747 } | 757 } |
| 748 return LifetimePosition::Invalid(); | 758 return LifetimePosition::Invalid(); |
| 749 } | 759 } |
| 750 | 760 |
| 751 | 761 |
| 762 unsigned LiveRange::GetSize() { |
| 763 if (size_ == kInvalidSize) { |
| 764 size_ = 0; |
| 765 for (auto interval = first_interval(); interval != nullptr; |
| 766 interval = interval->next()) { |
| 767 size_ += (interval->end().value() - interval->start().value()); |
| 768 } |
| 769 } |
| 770 |
| 771 return static_cast<unsigned>(size_); |
| 772 } |
| 773 |
| 774 |
| 752 static bool AreUseIntervalsIntersecting(UseInterval* interval1, | 775 static bool AreUseIntervalsIntersecting(UseInterval* interval1, |
| 753 UseInterval* interval2) { | 776 UseInterval* interval2) { |
| 754 while (interval1 != nullptr && interval2 != nullptr) { | 777 while (interval1 != nullptr && interval2 != nullptr) { |
| 755 if (interval1->start() < interval2->start()) { | 778 if (interval1->start() < interval2->start()) { |
| 756 if (interval1->end() > interval2->start()) { | 779 if (interval1->end() > interval2->start()) { |
| 757 return true; | 780 return true; |
| 758 } | 781 } |
| 759 interval1 = interval1->next(); | 782 interval1 = interval1->next(); |
| 760 } else { | 783 } else { |
| 761 if (interval2->end() > interval1->start()) { | 784 if (interval2->end() > interval1->start()) { |
| (...skipping 1083 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1845 range->Spill(); | 1868 range->Spill(); |
| 1846 } | 1869 } |
| 1847 | 1870 |
| 1848 | 1871 |
| 1849 const ZoneVector<LiveRange*>& RegisterAllocator::GetFixedRegisters() const { | 1872 const ZoneVector<LiveRange*>& RegisterAllocator::GetFixedRegisters() const { |
| 1850 return mode() == DOUBLE_REGISTERS ? data()->fixed_double_live_ranges() | 1873 return mode() == DOUBLE_REGISTERS ? data()->fixed_double_live_ranges() |
| 1851 : data()->fixed_live_ranges(); | 1874 : data()->fixed_live_ranges(); |
| 1852 } | 1875 } |
| 1853 | 1876 |
| 1854 | 1877 |
| 1878 const char* RegisterAllocator::RegisterName(int allocation_index) const { |
| 1879 if (mode() == GENERAL_REGISTERS) { |
| 1880 return data()->config()->general_register_name(allocation_index); |
| 1881 } else { |
| 1882 return data()->config()->double_register_name(allocation_index); |
| 1883 } |
| 1884 } |
| 1885 |
| 1886 |
| 1855 LinearScanAllocator::LinearScanAllocator(RegisterAllocationData* data, | 1887 LinearScanAllocator::LinearScanAllocator(RegisterAllocationData* data, |
| 1856 RegisterKind kind, Zone* local_zone) | 1888 RegisterKind kind, Zone* local_zone) |
| 1857 : RegisterAllocator(data, kind), | 1889 : RegisterAllocator(data, kind), |
| 1858 unhandled_live_ranges_(local_zone), | 1890 unhandled_live_ranges_(local_zone), |
| 1859 active_live_ranges_(local_zone), | 1891 active_live_ranges_(local_zone), |
| 1860 inactive_live_ranges_(local_zone) { | 1892 inactive_live_ranges_(local_zone) { |
| 1861 unhandled_live_ranges().reserve( | 1893 unhandled_live_ranges().reserve( |
| 1862 static_cast<size_t>(code()->VirtualRegisterCount() * 2)); | 1894 static_cast<size_t>(code()->VirtualRegisterCount() * 2)); |
| 1863 active_live_ranges().reserve(8); | 1895 active_live_ranges().reserve(8); |
| 1864 inactive_live_ranges().reserve(8); | 1896 inactive_live_ranges().reserve(8); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1951 | 1983 |
| 1952 bool result = TryAllocateFreeReg(current); | 1984 bool result = TryAllocateFreeReg(current); |
| 1953 if (!result) AllocateBlockedReg(current); | 1985 if (!result) AllocateBlockedReg(current); |
| 1954 if (current->HasRegisterAssigned()) { | 1986 if (current->HasRegisterAssigned()) { |
| 1955 AddToActive(current); | 1987 AddToActive(current); |
| 1956 } | 1988 } |
| 1957 } | 1989 } |
| 1958 } | 1990 } |
| 1959 | 1991 |
| 1960 | 1992 |
| 1961 const char* LinearScanAllocator::RegisterName(int allocation_index) const { | |
| 1962 if (mode() == GENERAL_REGISTERS) { | |
| 1963 return data()->config()->general_register_name(allocation_index); | |
| 1964 } else { | |
| 1965 return data()->config()->double_register_name(allocation_index); | |
| 1966 } | |
| 1967 } | |
| 1968 | |
| 1969 | |
| 1970 void LinearScanAllocator::SetLiveRangeAssignedRegister(LiveRange* range, | 1993 void LinearScanAllocator::SetLiveRangeAssignedRegister(LiveRange* range, |
| 1971 int reg) { | 1994 int reg) { |
| 1972 data()->MarkAllocated(range->kind(), reg); | 1995 data()->MarkAllocated(range->kind(), reg); |
| 1973 range->set_assigned_register(reg); | 1996 range->set_assigned_register(reg); |
| 1974 range->SetUseHints(reg); | 1997 range->SetUseHints(reg); |
| 1975 if (range->is_phi()) { | 1998 if (range->is_phi()) { |
| 1976 data()->GetPhiMapValueFor(range->id())->set_assigned_register(reg); | 1999 data()->GetPhiMapValueFor(range->id())->set_assigned_register(reg); |
| 1977 } | 2000 } |
| 1978 } | 2001 } |
| 1979 | 2002 |
| (...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2861 auto eliminate = moves->PrepareInsertAfter(move); | 2884 auto eliminate = moves->PrepareInsertAfter(move); |
| 2862 to_insert.push_back(move); | 2885 to_insert.push_back(move); |
| 2863 if (eliminate != nullptr) to_eliminate.push_back(eliminate); | 2886 if (eliminate != nullptr) to_eliminate.push_back(eliminate); |
| 2864 } | 2887 } |
| 2865 } | 2888 } |
| 2866 | 2889 |
| 2867 | 2890 |
| 2868 } // namespace compiler | 2891 } // namespace compiler |
| 2869 } // namespace internal | 2892 } // namespace internal |
| 2870 } // namespace v8 | 2893 } // namespace v8 |
| OLD | NEW |