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

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
« 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 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();
2345 if (first->next() == nullptr) continue;
2346
2347 // Consecutive intervals should not end and start in the same block,
2348 // otherwise the intervals should have been joined, because the
2349 // variable is live throughout that block.
2350 CHECK(NextIntervalStartsInDifferentBlocks(first));
2351
2352 for (const UseInterval* i = first->next(); i != nullptr; i = i->next()) {
2353 // Except for the first interval, the other intevals must start at
2354 // a block boundary, otherwise data wouldn't flow to them.
2355 CHECK(IntervalStartsAtBlockBoundary(i));
2356 // The last instruction of the predecessors of the block the interval
2357 // starts must be covered by the range.
2358 CHECK(IntervalPredecessorsCoveredByRange(i, current));
2359 if (i->next() != nullptr) {
2360 // Check the consecutive intervals property, except for the last
2361 // interval, where it doesn't apply.
2362 CHECK(NextIntervalStartsInDifferentBlocks(i));
2363 }
2364 }
2365 }
2341 } 2366 }
2342 } 2367 }
2343 2368
2369 bool LiveRangeBuilder::IntervalStartsAtBlockBoundary(
2370 const UseInterval* interval) const {
2371 LifetimePosition start = interval->start();
2372 if (!start.IsFullStart()) return false;
2373 int instruction_index = start.ToInstructionIndex();
2374 const InstructionBlock* block =
2375 data()->code()->GetInstructionBlock(instruction_index);
2376 return block->first_instruction_index() == instruction_index;
2377 }
2378
2379 bool LiveRangeBuilder::IntervalPredecessorsCoveredByRange(
2380 const UseInterval* interval, const TopLevelLiveRange* range) const {
2381 LifetimePosition start = interval->start();
2382 int instruction_index = start.ToInstructionIndex();
2383 const InstructionBlock* block =
2384 data()->code()->GetInstructionBlock(instruction_index);
2385 for (RpoNumber pred_index : block->predecessors()) {
2386 const InstructionBlock* predecessor =
2387 data()->code()->InstructionBlockAt(pred_index);
2388 LifetimePosition last_pos = LifetimePosition::GapFromInstructionIndex(
2389 predecessor->last_instruction_index());
2390 last_pos = last_pos.NextStart().End();
2391 if (!range->Covers(last_pos)) return false;
2392 }
2393 return true;
2394 }
2395
2396 bool LiveRangeBuilder::NextIntervalStartsInDifferentBlocks(
2397 const UseInterval* interval) const {
2398 DCHECK_NOT_NULL(interval->next());
2399 LifetimePosition end = interval->end();
2400 LifetimePosition next_start = interval->next()->start();
2401 // Since end is not covered, but the previous position is, move back a
2402 // position
2403 end = end.IsStart() ? end.PrevStart().End() : end.Start();
2404 int last_covered_index = end.ToInstructionIndex();
2405 const InstructionBlock* block =
2406 data()->code()->GetInstructionBlock(last_covered_index);
2407 const InstructionBlock* next_block =
2408 data()->code()->GetInstructionBlock(next_start.ToInstructionIndex());
2409 return block->rpo_number() < next_block->rpo_number();
2410 }
2344 2411
2345 RegisterAllocator::RegisterAllocator(RegisterAllocationData* data, 2412 RegisterAllocator::RegisterAllocator(RegisterAllocationData* data,
2346 RegisterKind kind) 2413 RegisterKind kind)
2347 : data_(data), 2414 : data_(data),
2348 mode_(kind), 2415 mode_(kind),
2349 num_registers_(GetRegisterCount(data->config(), kind)), 2416 num_registers_(GetRegisterCount(data->config(), kind)),
2350 num_allocatable_registers_( 2417 num_allocatable_registers_(
2351 GetAllocatableRegisterCount(data->config(), kind)), 2418 GetAllocatableRegisterCount(data->config(), kind)),
2352 allocatable_register_codes_( 2419 allocatable_register_codes_(
2353 GetAllocatableRegisterCodes(data->config(), kind)) {} 2420 GetAllocatableRegisterCodes(data->config(), kind)) {}
(...skipping 1240 matching lines...) Expand 10 before | Expand all | Expand 10 after
3594 spill_operand); 3661 spill_operand);
3595 } 3662 }
3596 } 3663 }
3597 } 3664 }
3598 } 3665 }
3599 3666
3600 3667
3601 } // namespace compiler 3668 } // namespace compiler
3602 } // namespace internal 3669 } // namespace internal
3603 } // namespace v8 3670 } // 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