Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/compiler/register-allocator.cc

Issue 728553003: [turbofan] round robin register picking (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/register-allocator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/register-allocator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698