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/compiler/common-operator.h" | 5 #include "src/compiler/common-operator.h" |
6 #include "src/compiler/graph.h" | 6 #include "src/compiler/graph.h" |
7 #include "src/compiler/instruction.h" | 7 #include "src/compiler/instruction.h" |
8 #include "src/compiler/schedule.h" | 8 #include "src/compiler/schedule.h" |
9 #include "src/compiler/state-values-utils.h" | 9 #include "src/compiler/state-values-utils.h" |
10 | 10 |
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 for (BasicBlockVector::const_iterator it = schedule->rpo_order()->begin(); | 621 for (BasicBlockVector::const_iterator it = schedule->rpo_order()->begin(); |
622 it != schedule->rpo_order()->end(); ++it, ++rpo_number) { | 622 it != schedule->rpo_order()->end(); ++it, ++rpo_number) { |
623 DCHECK(!(*blocks)[rpo_number]); | 623 DCHECK(!(*blocks)[rpo_number]); |
624 DCHECK(GetRpo(*it).ToSize() == rpo_number); | 624 DCHECK(GetRpo(*it).ToSize() == rpo_number); |
625 (*blocks)[rpo_number] = InstructionBlockFor(zone, *it); | 625 (*blocks)[rpo_number] = InstructionBlockFor(zone, *it); |
626 } | 626 } |
627 ComputeAssemblyOrder(blocks); | 627 ComputeAssemblyOrder(blocks); |
628 return blocks; | 628 return blocks; |
629 } | 629 } |
630 | 630 |
631 void InstructionSequence::ValidateEdgeSplitForm() { | 631 void InstructionSequence::ValidateEdgeSplitForm() const { |
632 // Validate blocks are in edge-split form: no block with multiple successors | 632 // Validate blocks are in edge-split form: no block with multiple successors |
633 // has an edge to a block (== a successor) with more than one predecessors. | 633 // has an edge to a block (== a successor) with more than one predecessors. |
634 for (const InstructionBlock* block : instruction_blocks()) { | 634 for (const InstructionBlock* block : instruction_blocks()) { |
635 if (block->SuccessorCount() > 1) { | 635 if (block->SuccessorCount() > 1) { |
636 for (const RpoNumber& successor_id : block->successors()) { | 636 for (const RpoNumber& successor_id : block->successors()) { |
637 const InstructionBlock* successor = InstructionBlockAt(successor_id); | 637 const InstructionBlock* successor = InstructionBlockAt(successor_id); |
638 // Expect precisely one predecessor: "block". | 638 // Expect precisely one predecessor: "block". |
639 CHECK(successor->PredecessorCount() == 1 && | 639 CHECK(successor->PredecessorCount() == 1 && |
640 successor->predecessors()[0] == block->rpo_number()); | 640 successor->predecessors()[0] == block->rpo_number()); |
641 } | 641 } |
642 } | 642 } |
643 } | 643 } |
644 } | 644 } |
645 | 645 |
646 void InstructionSequence::ValidateDeferredBlockExitPaths() { | 646 void InstructionSequence::ValidateDeferredBlockExitPaths() const { |
647 // A deferred block with more than one successor must have all its successors | 647 // A deferred block with more than one successor must have all its successors |
648 // deferred. | 648 // deferred. |
649 for (const InstructionBlock* block : instruction_blocks()) { | 649 for (const InstructionBlock* block : instruction_blocks()) { |
650 if (!block->IsDeferred() || block->SuccessorCount() <= 1) continue; | 650 if (!block->IsDeferred() || block->SuccessorCount() <= 1) continue; |
651 for (RpoNumber successor_id : block->successors()) { | 651 for (RpoNumber successor_id : block->successors()) { |
652 CHECK(InstructionBlockAt(successor_id)->IsDeferred()); | 652 CHECK(InstructionBlockAt(successor_id)->IsDeferred()); |
653 } | 653 } |
654 } | 654 } |
655 } | 655 } |
656 | 656 |
657 void InstructionSequence::ValidateSSA() { | 657 void InstructionSequence::ValidateDeferredBlockEntryPaths() const { |
| 658 // If a deferred block has multiple predecessors, they have to |
| 659 // all be deferred. Otherwise, we can run into a situation where a range |
| 660 // that spills only in deferred blocks inserts its spill in the block, but |
| 661 // other ranges need moves inserted by ResolveControlFlow in the predecessors, |
| 662 // which may clobber the register of this range. |
| 663 for (const InstructionBlock* block : instruction_blocks()) { |
| 664 if (!block->IsDeferred() || block->PredecessorCount() <= 1) continue; |
| 665 for (RpoNumber predecessor_id : block->predecessors()) { |
| 666 CHECK(InstructionBlockAt(predecessor_id)->IsDeferred()); |
| 667 } |
| 668 } |
| 669 } |
| 670 |
| 671 void InstructionSequence::ValidateSSA() const { |
658 // TODO(mtrofin): We could use a local zone here instead. | 672 // TODO(mtrofin): We could use a local zone here instead. |
659 BitVector definitions(VirtualRegisterCount(), zone()); | 673 BitVector definitions(VirtualRegisterCount(), zone()); |
660 for (const Instruction* instruction : *this) { | 674 for (const Instruction* instruction : *this) { |
661 for (size_t i = 0; i < instruction->OutputCount(); ++i) { | 675 for (size_t i = 0; i < instruction->OutputCount(); ++i) { |
662 const InstructionOperand* output = instruction->OutputAt(i); | 676 const InstructionOperand* output = instruction->OutputAt(i); |
663 int vreg = (output->IsConstant()) | 677 int vreg = (output->IsConstant()) |
664 ? ConstantOperand::cast(output)->virtual_register() | 678 ? ConstantOperand::cast(output)->virtual_register() |
665 : UnallocatedOperand::cast(output)->virtual_register(); | 679 : UnallocatedOperand::cast(output)->virtual_register(); |
666 CHECK(!definitions.Contains(vreg)); | 680 CHECK(!definitions.Contains(vreg)); |
667 definitions.Add(vreg); | 681 definitions.Add(vreg); |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1012 } | 1026 } |
1013 for (int i = 0; i < code.InstructionBlockCount(); i++) { | 1027 for (int i = 0; i < code.InstructionBlockCount(); i++) { |
1014 printable.sequence_->PrintBlock(printable.register_configuration_, i); | 1028 printable.sequence_->PrintBlock(printable.register_configuration_, i); |
1015 } | 1029 } |
1016 return os; | 1030 return os; |
1017 } | 1031 } |
1018 | 1032 |
1019 } // namespace compiler | 1033 } // namespace compiler |
1020 } // namespace internal | 1034 } // namespace internal |
1021 } // namespace v8 | 1035 } // namespace v8 |
OLD | NEW |