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

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

Issue 1758033002: [turbofan] LiveRange structure validation (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 months 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
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 1543 matching lines...) Expand 10 before | Expand all | Expand 10 after
1554 for (int instr = first; instr <= last;) { 1554 for (int instr = first; instr <= last;) {
1555 const InstructionBlock* block = code()->GetInstructionBlock(instr); 1555 const InstructionBlock* block = code()->GetInstructionBlock(instr);
1556 if (!block->IsDeferred()) return false; 1556 if (!block->IsDeferred()) return false;
1557 instr = block->last_instruction_index() + 1; 1557 instr = block->last_instruction_index() + 1;
1558 } 1558 }
1559 } 1559 }
1560 } 1560 }
1561 return true; 1561 return true;
1562 } 1562 }
1563 1563
1564
1565 SpillRange* RegisterAllocationData::AssignSpillRangeToLiveRange( 1564 SpillRange* RegisterAllocationData::AssignSpillRangeToLiveRange(
1566 TopLevelLiveRange* range) { 1565 TopLevelLiveRange* range) {
1567 DCHECK(!range->HasSpillOperand()); 1566 DCHECK(!range->HasSpillOperand());
1568 1567
1569 SpillRange* spill_range = range->GetAllocatedSpillRange(); 1568 SpillRange* spill_range = range->GetAllocatedSpillRange();
1570 if (spill_range == nullptr) { 1569 if (spill_range == nullptr) {
1571 DCHECK(!range->IsSplinter()); 1570 DCHECK(!range->IsSplinter());
1572 spill_range = new (allocation_zone()) SpillRange(range, allocation_zone()); 1571 spill_range = new (allocation_zone()) SpillRange(range, allocation_zone());
1573 } 1572 }
1574 range->set_spill_type(TopLevelLiveRange::SpillType::kSpillRange); 1573 range->set_spill_type(TopLevelLiveRange::SpillType::kSpillRange);
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after
2329 if (it == phi_hints_.end()) return; 2328 if (it == phi_hints_.end()) return;
2330 DCHECK(!it->second->IsResolved()); 2329 DCHECK(!it->second->IsResolved());
2331 it->second->ResolveHint(use_pos); 2330 it->second->ResolveHint(use_pos);
2332 } 2331 }
2333 2332
2334 2333
2335 void LiveRangeBuilder::Verify() const { 2334 void LiveRangeBuilder::Verify() const {
2336 for (auto& hint : phi_hints_) { 2335 for (auto& hint : phi_hints_) {
2337 CHECK(hint.second->IsResolved()); 2336 CHECK(hint.second->IsResolved());
2338 } 2337 }
2339 for (TopLevelLiveRange* current : data()->live_ranges()) { 2338 for (const TopLevelLiveRange* current : data()->live_ranges()) {
2340 if (current != nullptr && !current->IsEmpty()) current->Verify(); 2339 if (current != nullptr && !current->IsEmpty()) {
2340 // New LiveRanges should not be split.
2341 CHECK_NULL(current->next());
2342 // General integrity check.
2343 current->Verify();
2344 const UseInterval* first = current->first_interval();
titzer 2016/03/04 19:43:59 I think you can simplify this code a bit. E.g. ju
Mircea Trofin 2016/03/04 20:02:00 Done.
2345 if (first->next() == nullptr) continue;
2346
2347 for (const UseInterval* i = first; i != nullptr; i = i->next()) {
2348 if (i != first) {
2349 // Except for the first interval, the other intevals must start at
2350 // a block boundary, otherwise data wouldn't flow to them.
2351 DCHECK(IntervalStartsAtBlockBoundary(i));
2352 // The last instruction of the predecessors of the block the interval
2353 // starts must be covered by the range.
2354 DCHECK(IntervalPredecessorsCoveredByRange(i, current));
2355 }
2356 if (i->next() != nullptr) {
2357 // Consecutive intervals should not end and start in the same block,
2358 // otherwise the intervals should have been joined, because the
2359 // variable is live throughout that block.
2360 DCHECK(NextIntervalStartsInDifferenbBlocks(i));
2361 }
2362 }
2363 }
2341 } 2364 }
2342 } 2365 }
2343 2366
2367 bool LiveRangeBuilder::IntervalStartsAtBlockBoundary(
2368 const UseInterval* interval) const {
2369 LifetimePosition start = interval->start();
2370 if (!start.IsFullStart()) return false;
2371 int instruction_index = start.ToInstructionIndex();
2372 const InstructionBlock* block =
2373 data()->code()->GetInstructionBlock(instruction_index);
2374 return block->first_instruction_index() == instruction_index;
2375 }
2376
2377 bool LiveRangeBuilder::IntervalPredecessorsCoveredByRange(
2378 const UseInterval* interval, const TopLevelLiveRange* range) const {
2379 LifetimePosition start = interval->start();
2380 int instruction_index = start.ToInstructionIndex();
2381 const InstructionBlock* block =
2382 data()->code()->GetInstructionBlock(instruction_index);
2383 for (RpoNumber pred_index : block->predecessors()) {
2384 const InstructionBlock* predecessor =
2385 data()->code()->InstructionBlockAt(pred_index);
2386 LifetimePosition last_pos = LifetimePosition::GapFromInstructionIndex(
2387 predecessor->last_instruction_index());
2388 last_pos = last_pos.NextStart().End();
2389 if (!range->Covers(last_pos)) return false;
2390 }
2391 return true;
2392 }
2393
2394 bool LiveRangeBuilder::NextIntervalStartsInDifferenbBlocks(
2395 const UseInterval* interval) const {
2396 DCHECK_NOT_NULL(interval->next());
2397 LifetimePosition end = interval->end();
2398 LifetimePosition next_start = interval->next()->start();
2399 const InstructionBlock* block =
2400 data()->code()->GetInstructionBlock(end.ToInstructionIndex());
2401 const InstructionBlock* next_block =
2402 data()->code()->GetInstructionBlock(next_start.ToInstructionIndex());
2403 return block->rpo_number() < next_block->rpo_number();
2404 }
2344 2405
2345 RegisterAllocator::RegisterAllocator(RegisterAllocationData* data, 2406 RegisterAllocator::RegisterAllocator(RegisterAllocationData* data,
2346 RegisterKind kind) 2407 RegisterKind kind)
2347 : data_(data), 2408 : data_(data),
2348 mode_(kind), 2409 mode_(kind),
2349 num_registers_(GetRegisterCount(data->config(), kind)), 2410 num_registers_(GetRegisterCount(data->config(), kind)),
2350 num_allocatable_registers_( 2411 num_allocatable_registers_(
2351 GetAllocatableRegisterCount(data->config(), kind)), 2412 GetAllocatableRegisterCount(data->config(), kind)),
2352 allocatable_register_codes_( 2413 allocatable_register_codes_(
2353 GetAllocatableRegisterCodes(data->config(), kind)) {} 2414 GetAllocatableRegisterCodes(data->config(), kind)) {}
(...skipping 1240 matching lines...) Expand 10 before | Expand all | Expand 10 after
3594 spill_operand); 3655 spill_operand);
3595 } 3656 }
3596 } 3657 }
3597 } 3658 }
3598 } 3659 }
3599 3660
3600 3661
3601 } // namespace compiler 3662 } // namespace compiler
3602 } // namespace internal 3663 } // namespace internal
3603 } // namespace v8 3664 } // namespace v8
OLDNEW
« src/compiler/register-allocator.h ('K') | « src/compiler/register-allocator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698