| 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 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 | 244 |
| 245 ExplicitOperand::ExplicitOperand(LocationKind kind, MachineRepresentation rep, | 245 ExplicitOperand::ExplicitOperand(LocationKind kind, MachineRepresentation rep, |
| 246 int index) | 246 int index) |
| 247 : LocationOperand(EXPLICIT, kind, rep, index) { | 247 : LocationOperand(EXPLICIT, kind, rep, index) { |
| 248 DCHECK_IMPLIES(kind == REGISTER && !IsFloatingPoint(rep), | 248 DCHECK_IMPLIES(kind == REGISTER && !IsFloatingPoint(rep), |
| 249 Register::from_code(index).IsAllocatable()); | 249 Register::from_code(index).IsAllocatable()); |
| 250 DCHECK_IMPLIES(kind == REGISTER && IsFloatingPoint(rep), | 250 DCHECK_IMPLIES(kind == REGISTER && IsFloatingPoint(rep), |
| 251 DoubleRegister::from_code(index).IsAllocatable()); | 251 DoubleRegister::from_code(index).IsAllocatable()); |
| 252 } | 252 } |
| 253 | 253 |
| 254 | |
| 255 Instruction::Instruction(InstructionCode opcode) | 254 Instruction::Instruction(InstructionCode opcode) |
| 256 : opcode_(opcode), | 255 : opcode_(opcode), |
| 257 bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) | | 256 bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) | |
| 258 TempCountField::encode(0) | IsCallField::encode(false)), | 257 TempCountField::encode(0) | IsCallField::encode(false)), |
| 259 reference_map_(nullptr) { | 258 reference_map_(nullptr), |
| 259 block_(nullptr) { |
| 260 parallel_moves_[0] = nullptr; | 260 parallel_moves_[0] = nullptr; |
| 261 parallel_moves_[1] = nullptr; | 261 parallel_moves_[1] = nullptr; |
| 262 } | 262 } |
| 263 | 263 |
| 264 | |
| 265 Instruction::Instruction(InstructionCode opcode, size_t output_count, | 264 Instruction::Instruction(InstructionCode opcode, size_t output_count, |
| 266 InstructionOperand* outputs, size_t input_count, | 265 InstructionOperand* outputs, size_t input_count, |
| 267 InstructionOperand* inputs, size_t temp_count, | 266 InstructionOperand* inputs, size_t temp_count, |
| 268 InstructionOperand* temps) | 267 InstructionOperand* temps) |
| 269 : opcode_(opcode), | 268 : opcode_(opcode), |
| 270 bit_field_(OutputCountField::encode(output_count) | | 269 bit_field_(OutputCountField::encode(output_count) | |
| 271 InputCountField::encode(input_count) | | 270 InputCountField::encode(input_count) | |
| 272 TempCountField::encode(temp_count) | | 271 TempCountField::encode(temp_count) | |
| 273 IsCallField::encode(false)), | 272 IsCallField::encode(false)), |
| 274 reference_map_(nullptr) { | 273 reference_map_(nullptr), |
| 274 block_(nullptr) { |
| 275 parallel_moves_[0] = nullptr; | 275 parallel_moves_[0] = nullptr; |
| 276 parallel_moves_[1] = nullptr; | 276 parallel_moves_[1] = nullptr; |
| 277 size_t offset = 0; | 277 size_t offset = 0; |
| 278 for (size_t i = 0; i < output_count; ++i) { | 278 for (size_t i = 0; i < output_count; ++i) { |
| 279 DCHECK(!outputs[i].IsInvalid()); | 279 DCHECK(!outputs[i].IsInvalid()); |
| 280 operands_[offset++] = outputs[i]; | 280 operands_[offset++] = outputs[i]; |
| 281 } | 281 } |
| 282 for (size_t i = 0; i < input_count; ++i) { | 282 for (size_t i = 0; i < input_count; ++i) { |
| 283 DCHECK(!inputs[i].IsInvalid()); | 283 DCHECK(!inputs[i].IsInvalid()); |
| 284 operands_[offset++] = inputs[i]; | 284 operands_[offset++] = inputs[i]; |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 for (BasicBlock* successor : block->successors()) { | 604 for (BasicBlock* successor : block->successors()) { |
| 605 instr_block->successors().push_back(GetRpo(successor)); | 605 instr_block->successors().push_back(GetRpo(successor)); |
| 606 } | 606 } |
| 607 instr_block->predecessors().reserve(block->PredecessorCount()); | 607 instr_block->predecessors().reserve(block->PredecessorCount()); |
| 608 for (BasicBlock* predecessor : block->predecessors()) { | 608 for (BasicBlock* predecessor : block->predecessors()) { |
| 609 instr_block->predecessors().push_back(GetRpo(predecessor)); | 609 instr_block->predecessors().push_back(GetRpo(predecessor)); |
| 610 } | 610 } |
| 611 return instr_block; | 611 return instr_block; |
| 612 } | 612 } |
| 613 | 613 |
| 614 | |
| 615 InstructionBlocks* InstructionSequence::InstructionBlocksFor( | 614 InstructionBlocks* InstructionSequence::InstructionBlocksFor( |
| 616 Zone* zone, const Schedule* schedule) { | 615 Zone* zone, const Schedule* schedule) { |
| 617 InstructionBlocks* blocks = zone->NewArray<InstructionBlocks>(1); | 616 InstructionBlocks* blocks = zone->NewArray<InstructionBlocks>(1); |
| 618 new (blocks) InstructionBlocks( | 617 new (blocks) InstructionBlocks( |
| 619 static_cast<int>(schedule->rpo_order()->size()), nullptr, zone); | 618 static_cast<int>(schedule->rpo_order()->size()), nullptr, zone); |
| 620 size_t rpo_number = 0; | 619 size_t rpo_number = 0; |
| 621 for (BasicBlockVector::const_iterator it = schedule->rpo_order()->begin(); | 620 for (BasicBlockVector::const_iterator it = schedule->rpo_order()->begin(); |
| 622 it != schedule->rpo_order()->end(); ++it, ++rpo_number) { | 621 it != schedule->rpo_order()->end(); ++it, ++rpo_number) { |
| 623 DCHECK(!(*blocks)[rpo_number]); | 622 DCHECK(!(*blocks)[rpo_number]); |
| 624 DCHECK(GetRpo(*it).ToSize() == rpo_number); | 623 DCHECK(GetRpo(*it).ToSize() == rpo_number); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 block->set_ao_number(RpoNumber::FromInt(ao++)); | 675 block->set_ao_number(RpoNumber::FromInt(ao++)); |
| 677 } | 676 } |
| 678 } | 677 } |
| 679 for (InstructionBlock* const block : *blocks) { | 678 for (InstructionBlock* const block : *blocks) { |
| 680 if (block->IsDeferred()) { | 679 if (block->IsDeferred()) { |
| 681 block->set_ao_number(RpoNumber::FromInt(ao++)); | 680 block->set_ao_number(RpoNumber::FromInt(ao++)); |
| 682 } | 681 } |
| 683 } | 682 } |
| 684 } | 683 } |
| 685 | 684 |
| 686 | |
| 687 InstructionSequence::InstructionSequence(Isolate* isolate, | 685 InstructionSequence::InstructionSequence(Isolate* isolate, |
| 688 Zone* instruction_zone, | 686 Zone* instruction_zone, |
| 689 InstructionBlocks* instruction_blocks) | 687 InstructionBlocks* instruction_blocks) |
| 690 : isolate_(isolate), | 688 : isolate_(isolate), |
| 691 zone_(instruction_zone), | 689 zone_(instruction_zone), |
| 692 instruction_blocks_(instruction_blocks), | 690 instruction_blocks_(instruction_blocks), |
| 693 source_positions_(zone()), | 691 source_positions_(zone()), |
| 694 block_starts_(zone()), | |
| 695 constants_(ConstantMap::key_compare(), | 692 constants_(ConstantMap::key_compare(), |
| 696 ConstantMap::allocator_type(zone())), | 693 ConstantMap::allocator_type(zone())), |
| 697 immediates_(zone()), | 694 immediates_(zone()), |
| 698 instructions_(zone()), | 695 instructions_(zone()), |
| 699 next_virtual_register_(0), | 696 next_virtual_register_(0), |
| 700 reference_maps_(zone()), | 697 reference_maps_(zone()), |
| 701 representations_(zone()), | 698 representations_(zone()), |
| 702 deoptimization_entries_(zone()) { | 699 deoptimization_entries_(zone()), |
| 703 block_starts_.reserve(instruction_blocks_->size()); | 700 current_block_(nullptr) {} |
| 704 } | |
| 705 | |
| 706 | 701 |
| 707 int InstructionSequence::NextVirtualRegister() { | 702 int InstructionSequence::NextVirtualRegister() { |
| 708 int virtual_register = next_virtual_register_++; | 703 int virtual_register = next_virtual_register_++; |
| 709 CHECK_NE(virtual_register, InstructionOperand::kInvalidVirtualRegister); | 704 CHECK_NE(virtual_register, InstructionOperand::kInvalidVirtualRegister); |
| 710 return virtual_register; | 705 return virtual_register; |
| 711 } | 706 } |
| 712 | 707 |
| 713 | 708 |
| 714 Instruction* InstructionSequence::GetBlockStart(RpoNumber rpo) const { | 709 Instruction* InstructionSequence::GetBlockStart(RpoNumber rpo) const { |
| 715 const InstructionBlock* block = InstructionBlockAt(rpo); | 710 const InstructionBlock* block = InstructionBlockAt(rpo); |
| 716 return InstructionAt(block->code_start()); | 711 return InstructionAt(block->code_start()); |
| 717 } | 712 } |
| 718 | 713 |
| 719 | 714 |
| 720 void InstructionSequence::StartBlock(RpoNumber rpo) { | 715 void InstructionSequence::StartBlock(RpoNumber rpo) { |
| 721 DCHECK(block_starts_.size() == rpo.ToSize()); | 716 DCHECK_NULL(current_block_); |
| 722 InstructionBlock* block = InstructionBlockAt(rpo); | 717 current_block_ = InstructionBlockAt(rpo); |
| 723 int code_start = static_cast<int>(instructions_.size()); | 718 int code_start = static_cast<int>(instructions_.size()); |
| 724 block->set_code_start(code_start); | 719 current_block_->set_code_start(code_start); |
| 725 block_starts_.push_back(code_start); | |
| 726 } | 720 } |
| 727 | 721 |
| 728 | 722 |
| 729 void InstructionSequence::EndBlock(RpoNumber rpo) { | 723 void InstructionSequence::EndBlock(RpoNumber rpo) { |
| 730 int end = static_cast<int>(instructions_.size()); | 724 int end = static_cast<int>(instructions_.size()); |
| 731 InstructionBlock* block = InstructionBlockAt(rpo); | 725 DCHECK_EQ(current_block_->rpo_number(), rpo); |
| 732 if (block->code_start() == end) { // Empty block. Insert a nop. | 726 if (current_block_->code_start() == end) { // Empty block. Insert a nop. |
| 733 AddInstruction(Instruction::New(zone(), kArchNop)); | 727 AddInstruction(Instruction::New(zone(), kArchNop)); |
| 734 end = static_cast<int>(instructions_.size()); | 728 end = static_cast<int>(instructions_.size()); |
| 735 } | 729 } |
| 736 DCHECK(block->code_start() >= 0 && block->code_start() < end); | 730 DCHECK(current_block_->code_start() >= 0 && |
| 737 block->set_code_end(end); | 731 current_block_->code_start() < end); |
| 732 current_block_->set_code_end(end); |
| 733 current_block_ = nullptr; |
| 738 } | 734 } |
| 739 | 735 |
| 740 | 736 |
| 741 int InstructionSequence::AddInstruction(Instruction* instr) { | 737 int InstructionSequence::AddInstruction(Instruction* instr) { |
| 738 DCHECK_NOT_NULL(current_block_); |
| 742 int index = static_cast<int>(instructions_.size()); | 739 int index = static_cast<int>(instructions_.size()); |
| 740 instr->set_block(current_block_); |
| 743 instructions_.push_back(instr); | 741 instructions_.push_back(instr); |
| 744 if (instr->NeedsReferenceMap()) { | 742 if (instr->NeedsReferenceMap()) { |
| 745 DCHECK(instr->reference_map() == nullptr); | 743 DCHECK(instr->reference_map() == nullptr); |
| 746 ReferenceMap* reference_map = new (zone()) ReferenceMap(zone()); | 744 ReferenceMap* reference_map = new (zone()) ReferenceMap(zone()); |
| 747 reference_map->set_instruction_position(index); | 745 reference_map->set_instruction_position(index); |
| 748 instr->set_reference_map(reference_map); | 746 instr->set_reference_map(reference_map); |
| 749 reference_maps_.push_back(reference_map); | 747 reference_maps_.push_back(reference_map); |
| 750 } | 748 } |
| 751 return index; | 749 return index; |
| 752 } | 750 } |
| 753 | 751 |
| 754 | 752 |
| 755 InstructionBlock* InstructionSequence::GetInstructionBlock( | 753 InstructionBlock* InstructionSequence::GetInstructionBlock( |
| 756 int instruction_index) const { | 754 int instruction_index) const { |
| 757 DCHECK(instruction_blocks_->size() == block_starts_.size()); | 755 return instructions()[instruction_index]->block(); |
| 758 auto begin = block_starts_.begin(); | |
| 759 auto end = std::lower_bound(begin, block_starts_.end(), instruction_index); | |
| 760 // Post condition of std::lower_bound: | |
| 761 DCHECK(end == block_starts_.end() || *end >= instruction_index); | |
| 762 if (end == block_starts_.end() || *end > instruction_index) --end; | |
| 763 DCHECK(*end <= instruction_index); | |
| 764 size_t index = std::distance(begin, end); | |
| 765 InstructionBlock* block = instruction_blocks_->at(index); | |
| 766 DCHECK(block->code_start() <= instruction_index && | |
| 767 instruction_index < block->code_end()); | |
| 768 return block; | |
| 769 } | 756 } |
| 770 | 757 |
| 771 | 758 |
| 772 static MachineRepresentation FilterRepresentation(MachineRepresentation rep) { | 759 static MachineRepresentation FilterRepresentation(MachineRepresentation rep) { |
| 773 switch (rep) { | 760 switch (rep) { |
| 774 case MachineRepresentation::kBit: | 761 case MachineRepresentation::kBit: |
| 775 case MachineRepresentation::kWord8: | 762 case MachineRepresentation::kWord8: |
| 776 case MachineRepresentation::kWord16: | 763 case MachineRepresentation::kWord16: |
| 777 return InstructionSequence::DefaultRepresentation(); | 764 return InstructionSequence::DefaultRepresentation(); |
| 778 case MachineRepresentation::kWord32: | 765 case MachineRepresentation::kWord32: |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1012 } | 999 } |
| 1013 for (int i = 0; i < code.InstructionBlockCount(); i++) { | 1000 for (int i = 0; i < code.InstructionBlockCount(); i++) { |
| 1014 printable.sequence_->PrintBlock(printable.register_configuration_, i); | 1001 printable.sequence_->PrintBlock(printable.register_configuration_, i); |
| 1015 } | 1002 } |
| 1016 return os; | 1003 return os; |
| 1017 } | 1004 } |
| 1018 | 1005 |
| 1019 } // namespace compiler | 1006 } // namespace compiler |
| 1020 } // namespace internal | 1007 } // namespace internal |
| 1021 } // namespace v8 | 1008 } // namespace v8 |
| OLD | NEW |