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 |