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

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: rebase 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 529 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 local_zone()), 540 local_zone()),
541 fixed_double_live_ranges_(this->config()->num_double_registers(), NULL, 541 fixed_double_live_ranges_(this->config()->num_double_registers(), NULL,
542 local_zone()), 542 local_zone()),
543 unhandled_live_ranges_(code->VirtualRegisterCount() * 2, local_zone()), 543 unhandled_live_ranges_(code->VirtualRegisterCount() * 2, local_zone()),
544 active_live_ranges_(8, local_zone()), 544 active_live_ranges_(8, local_zone()),
545 inactive_live_ranges_(8, local_zone()), 545 inactive_live_ranges_(8, local_zone()),
546 reusable_slots_(8, local_zone()), 546 reusable_slots_(8, local_zone()),
547 spill_ranges_(8, local_zone()), 547 spill_ranges_(8, local_zone()),
548 mode_(UNALLOCATED_REGISTERS), 548 mode_(UNALLOCATED_REGISTERS),
549 num_registers_(-1), 549 num_registers_(-1),
550 first_register_to_try_(0),
550 allocation_ok_(true) { 551 allocation_ok_(true) {
551 DCHECK(this->config()->num_general_registers() <= 552 DCHECK(this->config()->num_general_registers() <=
552 RegisterConfiguration::kMaxGeneralRegisters); 553 RegisterConfiguration::kMaxGeneralRegisters);
553 DCHECK(this->config()->num_double_registers() <= 554 DCHECK(this->config()->num_double_registers() <=
554 RegisterConfiguration::kMaxDoubleRegisters); 555 RegisterConfiguration::kMaxDoubleRegisters);
555 // TryAllocateFreeReg and AllocateBlockedReg assume this 556 // TryAllocateFreeReg and AllocateBlockedReg assume this
556 // when allocating local arrays. 557 // when allocating local arrays.
557 DCHECK(this->config()->num_double_registers() >= 558 DCHECK(this->config()->num_double_registers() >=
558 this->config()->num_general_registers()); 559 this->config()->num_general_registers());
559 assigned_registers_ = 560 assigned_registers_ =
(...skipping 1494 matching lines...) Expand 10 before | Expand all | Expand 10 after
2054 2055
2055 2056
2056 void RegisterAllocator::InactiveToActive(LiveRange* range) { 2057 void RegisterAllocator::InactiveToActive(LiveRange* range) {
2057 DCHECK(inactive_live_ranges_.Contains(range)); 2058 DCHECK(inactive_live_ranges_.Contains(range));
2058 inactive_live_ranges_.RemoveElement(range); 2059 inactive_live_ranges_.RemoveElement(range);
2059 active_live_ranges_.Add(range, local_zone()); 2060 active_live_ranges_.Add(range, local_zone());
2060 TraceAlloc("Moving live range %d from inactive to active\n", range->id()); 2061 TraceAlloc("Moving live range %d from inactive to active\n", range->id());
2061 } 2062 }
2062 2063
2063 2064
2065 // Pick the index of the maximum position, starting at offset start.
2066 static int MaximalIndex(const LifetimePosition* positions, const uint8_t start,
2067 const int count) {
2068 int reg = start % count;
2069 for (int i = 1; i < count; ++i) {
2070 int index = (i + start) % count;
2071 if (positions[index].Value() > positions[reg].Value()) {
2072 reg = index;
2073 }
2074 }
2075 return reg;
2076 }
2077
2078
2064 bool RegisterAllocator::TryAllocateFreeReg(LiveRange* current) { 2079 bool RegisterAllocator::TryAllocateFreeReg(LiveRange* current) {
2065 LifetimePosition free_until_pos[RegisterConfiguration::kMaxDoubleRegisters]; 2080 LifetimePosition free_until_pos[RegisterConfiguration::kMaxDoubleRegisters];
2066 2081
2067 for (int i = 0; i < num_registers_; i++) { 2082 for (int i = 0; i < num_registers_; i++) {
2068 free_until_pos[i] = LifetimePosition::MaxPosition(); 2083 free_until_pos[i] = LifetimePosition::MaxPosition();
2069 } 2084 }
2070 2085
2071 for (int i = 0; i < active_live_ranges_.length(); ++i) { 2086 for (int i = 0; i < active_live_ranges_.length(); ++i) {
2072 LiveRange* cur_active = active_live_ranges_.at(i); 2087 LiveRange* cur_active = active_live_ranges_.at(i);
2073 free_until_pos[cur_active->assigned_register()] = 2088 free_until_pos[cur_active->assigned_register()] =
(...skipping 21 matching lines...) Expand all
2095 // The desired register is free until the end of the current live range. 2110 // The desired register is free until the end of the current live range.
2096 if (free_until_pos[register_index].Value() >= current->End().Value()) { 2111 if (free_until_pos[register_index].Value() >= current->End().Value()) {
2097 TraceAlloc("Assigning preferred reg %s to live range %d\n", 2112 TraceAlloc("Assigning preferred reg %s to live range %d\n",
2098 RegisterName(register_index), current->id()); 2113 RegisterName(register_index), current->id());
2099 SetLiveRangeAssignedRegister(current, register_index); 2114 SetLiveRangeAssignedRegister(current, register_index);
2100 return true; 2115 return true;
2101 } 2116 }
2102 } 2117 }
2103 2118
2104 // Find the register which stays free for the longest time. 2119 // Find the register which stays free for the longest time.
2105 int reg = 0; 2120 int reg =
2106 for (int i = 1; i < RegisterCount(); ++i) { 2121 MaximalIndex(free_until_pos, first_register_to_try_++, RegisterCount());
2107 if (free_until_pos[i].Value() > free_until_pos[reg].Value()) {
2108 reg = i;
2109 }
2110 }
2111
2112 LifetimePosition pos = free_until_pos[reg]; 2122 LifetimePosition pos = free_until_pos[reg];
2113 2123
2114 if (pos.Value() <= current->Start().Value()) { 2124 if (pos.Value() <= current->Start().Value()) {
2115 // All registers are blocked. 2125 // All registers are blocked.
2116 return false; 2126 return false;
2117 } 2127 }
2118 2128
2119 if (pos.Value() < current->End().Value()) { 2129 if (pos.Value() < current->End().Value()) {
2120 // Register reg is available at the range start but becomes blocked before 2130 // Register reg is available at the range start but becomes blocked before
2121 // the range end. Split current at position where it becomes blocked. 2131 // the range end. Split current at position where it becomes blocked.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2176 if (!next_intersection.IsValid()) continue; 2186 if (!next_intersection.IsValid()) continue;
2177 int cur_reg = range->assigned_register(); 2187 int cur_reg = range->assigned_register();
2178 if (range->IsFixed()) { 2188 if (range->IsFixed()) {
2179 block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); 2189 block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection);
2180 use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]); 2190 use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]);
2181 } else { 2191 } else {
2182 use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection); 2192 use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection);
2183 } 2193 }
2184 } 2194 }
2185 2195
2186 int reg = 0; 2196 int reg = MaximalIndex(use_pos, first_register_to_try_++, RegisterCount());
2187 for (int i = 1; i < RegisterCount(); ++i) {
2188 if (use_pos[i].Value() > use_pos[reg].Value()) {
2189 reg = i;
2190 }
2191 }
2192
2193 LifetimePosition pos = use_pos[reg]; 2197 LifetimePosition pos = use_pos[reg];
2194 2198
2195 if (pos.Value() < register_use->pos().Value()) { 2199 if (pos.Value() < register_use->pos().Value()) {
2196 // All registers are blocked before the first use that requires a register. 2200 // All registers are blocked before the first use that requires a register.
2197 // Spill starting part of live range up to that use. 2201 // Spill starting part of live range up to that use.
2198 SpillBetween(current, current->Start(), register_use->pos()); 2202 SpillBetween(current, current->Start(), register_use->pos());
2199 return; 2203 return;
2200 } 2204 }
2201 2205
2202 if (block_pos[reg].Value() < current->End().Value()) { 2206 if (block_pos[reg].Value() < current->End().Value()) {
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
2479 } else { 2483 } else {
2480 DCHECK(range->Kind() == GENERAL_REGISTERS); 2484 DCHECK(range->Kind() == GENERAL_REGISTERS);
2481 assigned_registers_->Add(reg); 2485 assigned_registers_->Add(reg);
2482 } 2486 }
2483 range->set_assigned_register(reg, code_zone()); 2487 range->set_assigned_register(reg, code_zone());
2484 } 2488 }
2485 2489
2486 } 2490 }
2487 } 2491 }
2488 } // namespace v8::internal::compiler 2492 } // 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