| 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 2210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2221 LifetimePosition ret = LifetimePosition::Invalid(); | 2221 LifetimePosition ret = LifetimePosition::Invalid(); |
| 2222 | 2222 |
| 2223 ret = LifetimePosition::GapFromInstructionIndex(instruction_index); | 2223 ret = LifetimePosition::GapFromInstructionIndex(instruction_index); |
| 2224 if (range->Start() >= ret || ret >= range->End()) { | 2224 if (range->Start() >= ret || ret >= range->End()) { |
| 2225 return LifetimePosition::Invalid(); | 2225 return LifetimePosition::Invalid(); |
| 2226 } | 2226 } |
| 2227 return ret; | 2227 return ret; |
| 2228 } | 2228 } |
| 2229 | 2229 |
| 2230 | 2230 |
| 2231 void RegisterAllocator::SplitAndSpillRangesDefinedByMemoryOperand() { | 2231 void RegisterAllocator::SplitAndSpillRangesDefinedByMemoryOperand( |
| 2232 bool operands_only) { |
| 2232 size_t initial_range_count = data()->live_ranges().size(); | 2233 size_t initial_range_count = data()->live_ranges().size(); |
| 2233 for (size_t i = 0; i < initial_range_count; ++i) { | 2234 for (size_t i = 0; i < initial_range_count; ++i) { |
| 2234 TopLevelLiveRange* range = data()->live_ranges()[i]; | 2235 TopLevelLiveRange* range = data()->live_ranges()[i]; |
| 2235 if (!CanProcessRange(range)) continue; | 2236 if (!CanProcessRange(range)) continue; |
| 2236 if (!range->HasSpillOperand()) continue; | 2237 if (range->HasNoSpillType() || (operands_only && range->HasSpillRange())) { |
| 2238 continue; |
| 2239 } |
| 2237 | 2240 |
| 2238 LifetimePosition start = range->Start(); | 2241 LifetimePosition start = range->Start(); |
| 2239 TRACE("Live range %d:%d is defined by a spill operand.\n", | 2242 TRACE("Live range %d:%d is defined by a spill operand.\n", |
| 2240 range->TopLevel()->vreg(), range->relative_id()); | 2243 range->TopLevel()->vreg(), range->relative_id()); |
| 2241 LifetimePosition next_pos = start; | 2244 LifetimePosition next_pos = start; |
| 2242 if (next_pos.IsGapPosition()) { | 2245 if (next_pos.IsGapPosition()) { |
| 2243 next_pos = next_pos.NextStart(); | 2246 next_pos = next_pos.NextStart(); |
| 2244 } | 2247 } |
| 2245 UsePosition* pos = range->NextUsePositionRegisterIsBeneficial(next_pos); | 2248 UsePosition* pos = range->NextUsePositionRegisterIsBeneficial(next_pos); |
| 2246 // If the range already has a spill operand and it doesn't need a | 2249 // If the range already has a spill operand and it doesn't need a |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2409 DCHECK(RegisterConfiguration::kMaxDoubleRegisters >= | 2412 DCHECK(RegisterConfiguration::kMaxDoubleRegisters >= |
| 2410 this->data()->config()->num_general_registers()); | 2413 this->data()->config()->num_general_registers()); |
| 2411 } | 2414 } |
| 2412 | 2415 |
| 2413 | 2416 |
| 2414 void LinearScanAllocator::AllocateRegisters() { | 2417 void LinearScanAllocator::AllocateRegisters() { |
| 2415 DCHECK(unhandled_live_ranges().empty()); | 2418 DCHECK(unhandled_live_ranges().empty()); |
| 2416 DCHECK(active_live_ranges().empty()); | 2419 DCHECK(active_live_ranges().empty()); |
| 2417 DCHECK(inactive_live_ranges().empty()); | 2420 DCHECK(inactive_live_ranges().empty()); |
| 2418 | 2421 |
| 2419 SplitAndSpillRangesDefinedByMemoryOperand(); | 2422 SplitAndSpillRangesDefinedByMemoryOperand(false); |
| 2420 | 2423 |
| 2421 for (TopLevelLiveRange* range : data()->live_ranges()) { | 2424 for (TopLevelLiveRange* range : data()->live_ranges()) { |
| 2422 if (!CanProcessRange(range)) continue; | 2425 if (!CanProcessRange(range)) continue; |
| 2423 for (LiveRange* to_add = range; to_add != nullptr; | 2426 for (LiveRange* to_add = range; to_add != nullptr; |
| 2424 to_add = to_add->next()) { | 2427 to_add = to_add->next()) { |
| 2425 if (!to_add->spilled()) { | 2428 if (!to_add->spilled()) { |
| 2426 AddToUnhandledUnsorted(to_add); | 2429 AddToUnhandledUnsorted(to_add); |
| 2427 } | 2430 } |
| 2428 } | 2431 } |
| 2429 } | 2432 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2443 auto current = unhandled_live_ranges().back(); | 2446 auto current = unhandled_live_ranges().back(); |
| 2444 unhandled_live_ranges().pop_back(); | 2447 unhandled_live_ranges().pop_back(); |
| 2445 DCHECK(UnhandledIsSorted()); | 2448 DCHECK(UnhandledIsSorted()); |
| 2446 auto position = current->Start(); | 2449 auto position = current->Start(); |
| 2447 #ifdef DEBUG | 2450 #ifdef DEBUG |
| 2448 allocation_finger_ = position; | 2451 allocation_finger_ = position; |
| 2449 #endif | 2452 #endif |
| 2450 TRACE("Processing interval %d:%d start=%d\n", current->TopLevel()->vreg(), | 2453 TRACE("Processing interval %d:%d start=%d\n", current->TopLevel()->vreg(), |
| 2451 current->relative_id(), position.value()); | 2454 current->relative_id(), position.value()); |
| 2452 | 2455 |
| 2453 if (current->IsTopLevel() && !current->TopLevel()->HasNoSpillType()) { | |
| 2454 TRACE("Live range %d:%d already has a spill operand\n", | |
| 2455 current->TopLevel()->vreg(), current->relative_id()); | |
| 2456 auto next_pos = position; | |
| 2457 if (next_pos.IsGapPosition()) { | |
| 2458 next_pos = next_pos.NextStart(); | |
| 2459 } | |
| 2460 auto pos = current->NextUsePositionRegisterIsBeneficial(next_pos); | |
| 2461 // If the range already has a spill operand and it doesn't need a | |
| 2462 // register immediately, split it and spill the first part of the range. | |
| 2463 if (pos == nullptr) { | |
| 2464 Spill(current); | |
| 2465 continue; | |
| 2466 } else if (pos->pos() > current->Start().NextStart()) { | |
| 2467 // Do not spill live range eagerly if use position that can benefit from | |
| 2468 // the register is too close to the start of live range. | |
| 2469 SpillBetween(current, current->Start(), pos->pos()); | |
| 2470 DCHECK(UnhandledIsSorted()); | |
| 2471 continue; | |
| 2472 } | |
| 2473 } | |
| 2474 | |
| 2475 if (current->IsTopLevel() && TryReuseSpillForPhi(current->TopLevel())) | 2456 if (current->IsTopLevel() && TryReuseSpillForPhi(current->TopLevel())) |
| 2476 continue; | 2457 continue; |
| 2477 | 2458 |
| 2478 for (size_t i = 0; i < active_live_ranges().size(); ++i) { | 2459 for (size_t i = 0; i < active_live_ranges().size(); ++i) { |
| 2479 auto cur_active = active_live_ranges()[i]; | 2460 auto cur_active = active_live_ranges()[i]; |
| 2480 if (cur_active->End() <= position) { | 2461 if (cur_active->End() <= position) { |
| 2481 ActiveToHandled(cur_active); | 2462 ActiveToHandled(cur_active); |
| 2482 --i; // The live range was removed from the list of active live ranges. | 2463 --i; // The live range was removed from the list of active live ranges. |
| 2483 } else if (!cur_active->Covers(position)) { | 2464 } else if (!cur_active->Covers(position)) { |
| 2484 ActiveToInactive(cur_active); | 2465 ActiveToInactive(cur_active); |
| (...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3460 auto eliminate = moves->PrepareInsertAfter(move); | 3441 auto eliminate = moves->PrepareInsertAfter(move); |
| 3461 to_insert.push_back(move); | 3442 to_insert.push_back(move); |
| 3462 if (eliminate != nullptr) to_eliminate.push_back(eliminate); | 3443 if (eliminate != nullptr) to_eliminate.push_back(eliminate); |
| 3463 } | 3444 } |
| 3464 } | 3445 } |
| 3465 | 3446 |
| 3466 | 3447 |
| 3467 } // namespace compiler | 3448 } // namespace compiler |
| 3468 } // namespace internal | 3449 } // namespace internal |
| 3469 } // namespace v8 | 3450 } // namespace v8 |
| OLD | NEW |