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 |