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

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

Issue 1426583002: [turbofan] Centralize splitting for memory operands. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 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/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 686 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 spills_at_definition_(nullptr), 697 spills_at_definition_(nullptr),
698 spilled_in_deferred_blocks_(false), 698 spilled_in_deferred_blocks_(false),
699 spill_start_index_(kMaxInt), 699 spill_start_index_(kMaxInt),
700 last_child_(this), 700 last_child_(this),
701 last_pos_(nullptr), 701 last_pos_(nullptr),
702 splinter_(nullptr) { 702 splinter_(nullptr) {
703 bits_ |= SpillTypeField::encode(SpillType::kNoSpillType); 703 bits_ |= SpillTypeField::encode(SpillType::kNoSpillType);
704 } 704 }
705 705
706 706
707 #if DEBUG
708 int TopLevelLiveRange::debug_virt_reg() const {
709 return IsSplinter() ? splintered_from()->vreg() : vreg();
710 }
711 #endif
712
713
707 void TopLevelLiveRange::SpillAtDefinition(Zone* zone, int gap_index, 714 void TopLevelLiveRange::SpillAtDefinition(Zone* zone, int gap_index,
708 InstructionOperand* operand) { 715 InstructionOperand* operand) {
709 DCHECK(HasNoSpillType()); 716 DCHECK(HasNoSpillType());
710 spills_at_definition_ = new (zone) 717 spills_at_definition_ = new (zone)
711 SpillAtDefinitionList(gap_index, operand, spills_at_definition_); 718 SpillAtDefinitionList(gap_index, operand, spills_at_definition_);
712 } 719 }
713 720
714 721
715 bool TopLevelLiveRange::TryCommitSpillInDeferredBlock( 722 bool TopLevelLiveRange::TryCommitSpillInDeferredBlock(
716 InstructionSequence* code, const InstructionOperand& spill_operand) { 723 InstructionSequence* code, const InstructionOperand& spill_operand) {
(...skipping 1489 matching lines...) Expand 10 before | Expand all | Expand 10 after
2206 RegisterKind kind) 2213 RegisterKind kind)
2207 : data_(data), 2214 : data_(data),
2208 mode_(kind), 2215 mode_(kind),
2209 num_registers_(GetRegisterCount(data->config(), kind)), 2216 num_registers_(GetRegisterCount(data->config(), kind)),
2210 num_allocatable_registers_( 2217 num_allocatable_registers_(
2211 GetAllocatableRegisterCount(data->config(), kind)), 2218 GetAllocatableRegisterCount(data->config(), kind)),
2212 allocatable_register_codes_( 2219 allocatable_register_codes_(
2213 GetAllocatableRegisterCodes(data->config(), kind)) {} 2220 GetAllocatableRegisterCodes(data->config(), kind)) {}
2214 2221
2215 2222
2223 LifetimePosition RegisterAllocator::GetSplitPositionForInstruction(
2224 const LiveRange* range, int instruction_index) {
2225 LifetimePosition ret = LifetimePosition::Invalid();
2226
2227 ret = LifetimePosition::GapFromInstructionIndex(instruction_index);
2228 if (range->Start() >= ret || ret >= range->End()) {
2229 return LifetimePosition::Invalid();
2230 }
2231 return ret;
2232 }
2233
2234
2235 void RegisterAllocator::SplitAndSpillRangesDefinedByMemoryOperand() {
2236 size_t initial_range_count = data()->live_ranges().size();
2237 for (size_t i = 0; i < initial_range_count; ++i) {
2238 TopLevelLiveRange* range = data()->live_ranges()[i];
2239 if (!CanProcessRange(range)) continue;
2240 if (!range->HasSpillOperand()) continue;
2241
2242 LifetimePosition start = range->Start();
2243 TRACE("Live range %d:%d is defined by a spill operand.\n",
2244 range->TopLevel()->vreg(), range->relative_id());
2245 LifetimePosition next_pos = start;
2246 if (next_pos.IsGapPosition()) {
2247 next_pos = next_pos.NextStart();
2248 }
2249 UsePosition* pos = range->NextUsePositionRegisterIsBeneficial(next_pos);
2250 // If the range already has a spill operand and it doesn't need a
2251 // register immediately, split it and spill the first part of the range.
2252 if (pos == nullptr) {
2253 Spill(range);
2254 } else if (pos->pos() > range->Start().NextStart()) {
2255 // Do not spill live range eagerly if use position that can benefit from
2256 // the register is too close to the start of live range.
2257 LifetimePosition split_pos = GetSplitPositionForInstruction(
2258 range, pos->pos().ToInstructionIndex());
2259 // There is no place to split, so we can't split and spill.
2260 if (!split_pos.IsValid()) continue;
2261
2262 split_pos =
2263 FindOptimalSplitPos(range->Start().NextFullStart(), split_pos);
2264
2265 SplitRangeAt(range, split_pos);
2266 Spill(range);
2267 }
2268 }
2269 }
2270
2271
2216 LiveRange* RegisterAllocator::SplitRangeAt(LiveRange* range, 2272 LiveRange* RegisterAllocator::SplitRangeAt(LiveRange* range,
2217 LifetimePosition pos) { 2273 LifetimePosition pos) {
2218 DCHECK(!range->TopLevel()->IsFixed()); 2274 DCHECK(!range->TopLevel()->IsFixed());
2219 TRACE("Splitting live range %d:%d at %d\n", range->TopLevel()->vreg(), 2275 TRACE("Splitting live range %d:%d at %d\n", range->TopLevel()->vreg(),
2220 range->relative_id(), pos.value()); 2276 range->relative_id(), pos.value());
2221 2277
2222 if (pos <= range->Start()) return range; 2278 if (pos <= range->Start()) return range;
2223 2279
2224 // We can't properly connect liveranges if splitting occurred at the end 2280 // We can't properly connect liveranges if splitting occurred at the end
2225 // a block. 2281 // a block.
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
2357 DCHECK(RegisterConfiguration::kMaxDoubleRegisters >= 2413 DCHECK(RegisterConfiguration::kMaxDoubleRegisters >=
2358 this->data()->config()->num_general_registers()); 2414 this->data()->config()->num_general_registers());
2359 } 2415 }
2360 2416
2361 2417
2362 void LinearScanAllocator::AllocateRegisters() { 2418 void LinearScanAllocator::AllocateRegisters() {
2363 DCHECK(unhandled_live_ranges().empty()); 2419 DCHECK(unhandled_live_ranges().empty());
2364 DCHECK(active_live_ranges().empty()); 2420 DCHECK(active_live_ranges().empty());
2365 DCHECK(inactive_live_ranges().empty()); 2421 DCHECK(inactive_live_ranges().empty());
2366 2422
2367 for (LiveRange* range : data()->live_ranges()) { 2423 SplitAndSpillRangesDefinedByMemoryOperand();
2368 if (range == nullptr) continue; 2424
2369 if (range->kind() == mode()) { 2425 for (TopLevelLiveRange* range : data()->live_ranges()) {
2370 AddToUnhandledUnsorted(range); 2426 if (!CanProcessRange(range)) continue;
2427 for (LiveRange* to_add = range; to_add != nullptr;
2428 to_add = to_add->next()) {
2429 if (!to_add->spilled()) {
2430 AddToUnhandledUnsorted(to_add);
2431 }
2371 } 2432 }
2372 } 2433 }
2373 SortUnhandled(); 2434 SortUnhandled();
2374 DCHECK(UnhandledIsSorted()); 2435 DCHECK(UnhandledIsSorted());
2375 2436
2376 auto& fixed_ranges = GetFixedRegisters(); 2437 auto& fixed_ranges = GetFixedRegisters();
2377 for (auto current : fixed_ranges) { 2438 for (auto current : fixed_ranges) {
2378 if (current != nullptr) { 2439 if (current != nullptr) {
2379 DCHECK_EQ(mode(), current->kind()); 2440 DCHECK_EQ(mode(), current->kind());
2380 AddToInactive(current); 2441 AddToInactive(current);
(...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after
3393 auto eliminate = moves->PrepareInsertAfter(move); 3454 auto eliminate = moves->PrepareInsertAfter(move);
3394 to_insert.push_back(move); 3455 to_insert.push_back(move);
3395 if (eliminate != nullptr) to_eliminate.push_back(eliminate); 3456 if (eliminate != nullptr) to_eliminate.push_back(eliminate);
3396 } 3457 }
3397 } 3458 }
3398 3459
3399 3460
3400 } // namespace compiler 3461 } // namespace compiler
3401 } // namespace internal 3462 } // namespace internal
3402 } // namespace v8 3463 } // namespace v8
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