Chromium Code Reviews| 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 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 519 fixed_live_ranges_(this->config()->num_general_registers(), NULL, | 519 fixed_live_ranges_(this->config()->num_general_registers(), NULL, |
| 520 local_zone()), | 520 local_zone()), |
| 521 fixed_double_live_ranges_(this->config()->num_double_registers(), NULL, | 521 fixed_double_live_ranges_(this->config()->num_double_registers(), NULL, |
| 522 local_zone()), | 522 local_zone()), |
| 523 unhandled_live_ranges_(code->VirtualRegisterCount() * 2, local_zone()), | 523 unhandled_live_ranges_(code->VirtualRegisterCount() * 2, local_zone()), |
| 524 active_live_ranges_(8, local_zone()), | 524 active_live_ranges_(8, local_zone()), |
| 525 inactive_live_ranges_(8, local_zone()), | 525 inactive_live_ranges_(8, local_zone()), |
| 526 reusable_slots_(8, local_zone()), | 526 reusable_slots_(8, local_zone()), |
| 527 mode_(UNALLOCATED_REGISTERS), | 527 mode_(UNALLOCATED_REGISTERS), |
| 528 num_registers_(-1), | 528 num_registers_(-1), |
| 529 first_register_to_try_(0), | |
| 529 allocation_ok_(true) { | 530 allocation_ok_(true) { |
| 530 DCHECK(this->config()->num_general_registers() <= | 531 DCHECK(this->config()->num_general_registers() <= |
| 531 RegisterConfiguration::kMaxGeneralRegisters); | 532 RegisterConfiguration::kMaxGeneralRegisters); |
| 532 DCHECK(this->config()->num_double_registers() <= | 533 DCHECK(this->config()->num_double_registers() <= |
| 533 RegisterConfiguration::kMaxDoubleRegisters); | 534 RegisterConfiguration::kMaxDoubleRegisters); |
| 534 // TryAllocateFreeReg and AllocateBlockedReg assume this | 535 // TryAllocateFreeReg and AllocateBlockedReg assume this |
| 535 // when allocating local arrays. | 536 // when allocating local arrays. |
| 536 DCHECK(this->config()->num_double_registers() >= | 537 DCHECK(this->config()->num_double_registers() >= |
| 537 this->config()->num_general_registers()); | 538 this->config()->num_general_registers()); |
| 538 assigned_registers_ = | 539 assigned_registers_ = |
| (...skipping 1316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1855 | 1856 |
| 1856 | 1857 |
| 1857 void RegisterAllocator::InactiveToActive(LiveRange* range) { | 1858 void RegisterAllocator::InactiveToActive(LiveRange* range) { |
| 1858 DCHECK(inactive_live_ranges_.Contains(range)); | 1859 DCHECK(inactive_live_ranges_.Contains(range)); |
| 1859 inactive_live_ranges_.RemoveElement(range); | 1860 inactive_live_ranges_.RemoveElement(range); |
| 1860 active_live_ranges_.Add(range, local_zone()); | 1861 active_live_ranges_.Add(range, local_zone()); |
| 1861 TraceAlloc("Moving live range %d from inactive to active\n", range->id()); | 1862 TraceAlloc("Moving live range %d from inactive to active\n", range->id()); |
| 1862 } | 1863 } |
| 1863 | 1864 |
| 1864 | 1865 |
| 1866 // Pick the index of the maximum position, starting at offset start. | |
| 1867 static int MaximalIndex(const LifetimePosition* positions, const uint8_t start, | |
| 1868 const int count) { | |
| 1869 int reg = start % count; | |
|
titzer
2014/11/19 14:02:08
On second thought, can we get rid of the modulus?
| |
| 1870 for (int i = 1; i < count; ++i) { | |
| 1871 int index = (i + start) % count; | |
| 1872 if (positions[index].Value() > positions[reg].Value()) { | |
| 1873 reg = index; | |
| 1874 } | |
| 1875 } | |
| 1876 return reg; | |
| 1877 } | |
| 1878 | |
| 1879 | |
| 1865 bool RegisterAllocator::TryAllocateFreeReg(LiveRange* current) { | 1880 bool RegisterAllocator::TryAllocateFreeReg(LiveRange* current) { |
| 1866 LifetimePosition free_until_pos[RegisterConfiguration::kMaxDoubleRegisters]; | 1881 LifetimePosition free_until_pos[RegisterConfiguration::kMaxDoubleRegisters]; |
| 1867 | 1882 |
| 1868 for (int i = 0; i < num_registers_; i++) { | 1883 for (int i = 0; i < num_registers_; i++) { |
| 1869 free_until_pos[i] = LifetimePosition::MaxPosition(); | 1884 free_until_pos[i] = LifetimePosition::MaxPosition(); |
| 1870 } | 1885 } |
| 1871 | 1886 |
| 1872 for (int i = 0; i < active_live_ranges_.length(); ++i) { | 1887 for (int i = 0; i < active_live_ranges_.length(); ++i) { |
| 1873 LiveRange* cur_active = active_live_ranges_.at(i); | 1888 LiveRange* cur_active = active_live_ranges_.at(i); |
| 1874 free_until_pos[cur_active->assigned_register()] = | 1889 free_until_pos[cur_active->assigned_register()] = |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1896 // The desired register is free until the end of the current live range. | 1911 // The desired register is free until the end of the current live range. |
| 1897 if (free_until_pos[register_index].Value() >= current->End().Value()) { | 1912 if (free_until_pos[register_index].Value() >= current->End().Value()) { |
| 1898 TraceAlloc("Assigning preferred reg %s to live range %d\n", | 1913 TraceAlloc("Assigning preferred reg %s to live range %d\n", |
| 1899 RegisterName(register_index), current->id()); | 1914 RegisterName(register_index), current->id()); |
| 1900 SetLiveRangeAssignedRegister(current, register_index); | 1915 SetLiveRangeAssignedRegister(current, register_index); |
| 1901 return true; | 1916 return true; |
| 1902 } | 1917 } |
| 1903 } | 1918 } |
| 1904 | 1919 |
| 1905 // Find the register which stays free for the longest time. | 1920 // Find the register which stays free for the longest time. |
| 1906 int reg = 0; | 1921 int reg = |
| 1907 for (int i = 1; i < RegisterCount(); ++i) { | 1922 MaximalIndex(free_until_pos, first_register_to_try_++, RegisterCount()); |
| 1908 if (free_until_pos[i].Value() > free_until_pos[reg].Value()) { | |
| 1909 reg = i; | |
| 1910 } | |
| 1911 } | |
| 1912 | |
| 1913 LifetimePosition pos = free_until_pos[reg]; | 1923 LifetimePosition pos = free_until_pos[reg]; |
| 1914 | 1924 |
| 1915 if (pos.Value() <= current->Start().Value()) { | 1925 if (pos.Value() <= current->Start().Value()) { |
| 1916 // All registers are blocked. | 1926 // All registers are blocked. |
| 1917 return false; | 1927 return false; |
| 1918 } | 1928 } |
| 1919 | 1929 |
| 1920 if (pos.Value() < current->End().Value()) { | 1930 if (pos.Value() < current->End().Value()) { |
| 1921 // Register reg is available at the range start but becomes blocked before | 1931 // Register reg is available at the range start but becomes blocked before |
| 1922 // the range end. Split current at position where it becomes blocked. | 1932 // the range end. Split current at position where it becomes blocked. |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1977 if (!next_intersection.IsValid()) continue; | 1987 if (!next_intersection.IsValid()) continue; |
| 1978 int cur_reg = range->assigned_register(); | 1988 int cur_reg = range->assigned_register(); |
| 1979 if (range->IsFixed()) { | 1989 if (range->IsFixed()) { |
| 1980 block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); | 1990 block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); |
| 1981 use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]); | 1991 use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]); |
| 1982 } else { | 1992 } else { |
| 1983 use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection); | 1993 use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection); |
| 1984 } | 1994 } |
| 1985 } | 1995 } |
| 1986 | 1996 |
| 1987 int reg = 0; | 1997 int reg = MaximalIndex(use_pos, first_register_to_try_++, RegisterCount()); |
| 1988 for (int i = 1; i < RegisterCount(); ++i) { | |
| 1989 if (use_pos[i].Value() > use_pos[reg].Value()) { | |
| 1990 reg = i; | |
| 1991 } | |
| 1992 } | |
| 1993 | |
| 1994 LifetimePosition pos = use_pos[reg]; | 1998 LifetimePosition pos = use_pos[reg]; |
| 1995 | 1999 |
| 1996 if (pos.Value() < register_use->pos().Value()) { | 2000 if (pos.Value() < register_use->pos().Value()) { |
| 1997 // All registers are blocked before the first use that requires a register. | 2001 // All registers are blocked before the first use that requires a register. |
| 1998 // Spill starting part of live range up to that use. | 2002 // Spill starting part of live range up to that use. |
| 1999 SpillBetween(current, current->Start(), register_use->pos()); | 2003 SpillBetween(current, current->Start(), register_use->pos()); |
| 2000 return; | 2004 return; |
| 2001 } | 2005 } |
| 2002 | 2006 |
| 2003 if (block_pos[reg].Value() < current->End().Value()) { | 2007 if (block_pos[reg].Value() < current->End().Value()) { |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2276 } else { | 2280 } else { |
| 2277 DCHECK(range->Kind() == GENERAL_REGISTERS); | 2281 DCHECK(range->Kind() == GENERAL_REGISTERS); |
| 2278 assigned_registers_->Add(reg); | 2282 assigned_registers_->Add(reg); |
| 2279 } | 2283 } |
| 2280 range->set_assigned_register(reg, code_zone()); | 2284 range->set_assigned_register(reg, code_zone()); |
| 2281 } | 2285 } |
| 2282 | 2286 |
| 2283 } | 2287 } |
| 2284 } | 2288 } |
| 2285 } // namespace v8::internal::compiler | 2289 } // namespace v8::internal::compiler |
| OLD | NEW |