Chromium Code Reviews| 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_id_(RpoNumber::kInvalidRpoNumber) { | |
| 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_id_(RpoNumber::kInvalidRpoNumber) { | |
| 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 void InstructionSequence::FinishInstructionMap() { | |
| 615 for (int block_id = 0; block_id < InstructionBlockCount(); ++block_id) { | |
| 616 const InstructionBlock* block = instruction_blocks()[block_id]; | |
| 617 for (int instr_index = block->first_instruction_index(); | |
| 618 instr_index <= block->last_instruction_index(); ++instr_index) { | |
| 619 instructions()[instr_index]->set_block_id(block_id); | |
|
titzer
2016/04/19 08:05:17
Can you pull instructions() out of the loop? This
Mircea Trofin
2016/04/19 15:39:13
Done.
| |
| 620 } | |
| 621 } | |
| 622 } | |
| 614 | 623 |
| 615 InstructionBlocks* InstructionSequence::InstructionBlocksFor( | 624 InstructionBlocks* InstructionSequence::InstructionBlocksFor( |
| 616 Zone* zone, const Schedule* schedule) { | 625 Zone* zone, const Schedule* schedule) { |
| 617 InstructionBlocks* blocks = zone->NewArray<InstructionBlocks>(1); | 626 InstructionBlocks* blocks = zone->NewArray<InstructionBlocks>(1); |
| 618 new (blocks) InstructionBlocks( | 627 new (blocks) InstructionBlocks( |
| 619 static_cast<int>(schedule->rpo_order()->size()), nullptr, zone); | 628 static_cast<int>(schedule->rpo_order()->size()), nullptr, zone); |
| 620 size_t rpo_number = 0; | 629 size_t rpo_number = 0; |
| 621 for (BasicBlockVector::const_iterator it = schedule->rpo_order()->begin(); | 630 for (BasicBlockVector::const_iterator it = schedule->rpo_order()->begin(); |
| 622 it != schedule->rpo_order()->end(); ++it, ++rpo_number) { | 631 it != schedule->rpo_order()->end(); ++it, ++rpo_number) { |
| 623 DCHECK(!(*blocks)[rpo_number]); | 632 DCHECK(!(*blocks)[rpo_number]); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 676 block->set_ao_number(RpoNumber::FromInt(ao++)); | 685 block->set_ao_number(RpoNumber::FromInt(ao++)); |
| 677 } | 686 } |
| 678 } | 687 } |
| 679 for (InstructionBlock* const block : *blocks) { | 688 for (InstructionBlock* const block : *blocks) { |
| 680 if (block->IsDeferred()) { | 689 if (block->IsDeferred()) { |
| 681 block->set_ao_number(RpoNumber::FromInt(ao++)); | 690 block->set_ao_number(RpoNumber::FromInt(ao++)); |
| 682 } | 691 } |
| 683 } | 692 } |
| 684 } | 693 } |
| 685 | 694 |
| 686 | |
| 687 InstructionSequence::InstructionSequence(Isolate* isolate, | 695 InstructionSequence::InstructionSequence(Isolate* isolate, |
| 688 Zone* instruction_zone, | 696 Zone* instruction_zone, |
| 689 InstructionBlocks* instruction_blocks) | 697 InstructionBlocks* instruction_blocks) |
| 690 : isolate_(isolate), | 698 : isolate_(isolate), |
| 691 zone_(instruction_zone), | 699 zone_(instruction_zone), |
| 692 instruction_blocks_(instruction_blocks), | 700 instruction_blocks_(instruction_blocks), |
| 693 source_positions_(zone()), | 701 source_positions_(zone()), |
| 694 block_starts_(zone()), | |
| 695 constants_(ConstantMap::key_compare(), | 702 constants_(ConstantMap::key_compare(), |
| 696 ConstantMap::allocator_type(zone())), | 703 ConstantMap::allocator_type(zone())), |
| 697 immediates_(zone()), | 704 immediates_(zone()), |
| 698 instructions_(zone()), | 705 instructions_(zone()), |
| 699 next_virtual_register_(0), | 706 next_virtual_register_(0), |
| 700 reference_maps_(zone()), | 707 reference_maps_(zone()), |
| 701 representations_(zone()), | 708 representations_(zone()), |
| 702 deoptimization_entries_(zone()) { | 709 deoptimization_entries_(zone()) {} |
| 703 block_starts_.reserve(instruction_blocks_->size()); | |
| 704 } | |
| 705 | |
| 706 | 710 |
| 707 int InstructionSequence::NextVirtualRegister() { | 711 int InstructionSequence::NextVirtualRegister() { |
| 708 int virtual_register = next_virtual_register_++; | 712 int virtual_register = next_virtual_register_++; |
| 709 CHECK_NE(virtual_register, InstructionOperand::kInvalidVirtualRegister); | 713 CHECK_NE(virtual_register, InstructionOperand::kInvalidVirtualRegister); |
| 710 return virtual_register; | 714 return virtual_register; |
| 711 } | 715 } |
| 712 | 716 |
| 713 | 717 |
| 714 Instruction* InstructionSequence::GetBlockStart(RpoNumber rpo) const { | 718 Instruction* InstructionSequence::GetBlockStart(RpoNumber rpo) const { |
| 715 const InstructionBlock* block = InstructionBlockAt(rpo); | 719 const InstructionBlock* block = InstructionBlockAt(rpo); |
| 716 return InstructionAt(block->code_start()); | 720 return InstructionAt(block->code_start()); |
| 717 } | 721 } |
| 718 | 722 |
| 719 | 723 |
| 720 void InstructionSequence::StartBlock(RpoNumber rpo) { | 724 void InstructionSequence::StartBlock(RpoNumber rpo) { |
| 721 DCHECK(block_starts_.size() == rpo.ToSize()); | |
| 722 InstructionBlock* block = InstructionBlockAt(rpo); | 725 InstructionBlock* block = InstructionBlockAt(rpo); |
| 723 int code_start = static_cast<int>(instructions_.size()); | 726 int code_start = static_cast<int>(instructions_.size()); |
| 724 block->set_code_start(code_start); | 727 block->set_code_start(code_start); |
| 725 block_starts_.push_back(code_start); | |
| 726 } | 728 } |
| 727 | 729 |
| 728 | 730 |
| 729 void InstructionSequence::EndBlock(RpoNumber rpo) { | 731 void InstructionSequence::EndBlock(RpoNumber rpo) { |
| 730 int end = static_cast<int>(instructions_.size()); | 732 int end = static_cast<int>(instructions_.size()); |
| 731 InstructionBlock* block = InstructionBlockAt(rpo); | 733 InstructionBlock* block = InstructionBlockAt(rpo); |
| 732 if (block->code_start() == end) { // Empty block. Insert a nop. | 734 if (block->code_start() == end) { // Empty block. Insert a nop. |
| 733 AddInstruction(Instruction::New(zone(), kArchNop)); | 735 AddInstruction(Instruction::New(zone(), kArchNop)); |
| 734 end = static_cast<int>(instructions_.size()); | 736 end = static_cast<int>(instructions_.size()); |
| 735 } | 737 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 747 reference_map->set_instruction_position(index); | 749 reference_map->set_instruction_position(index); |
| 748 instr->set_reference_map(reference_map); | 750 instr->set_reference_map(reference_map); |
| 749 reference_maps_.push_back(reference_map); | 751 reference_maps_.push_back(reference_map); |
| 750 } | 752 } |
| 751 return index; | 753 return index; |
| 752 } | 754 } |
| 753 | 755 |
| 754 | 756 |
| 755 InstructionBlock* InstructionSequence::GetInstructionBlock( | 757 InstructionBlock* InstructionSequence::GetInstructionBlock( |
| 756 int instruction_index) const { | 758 int instruction_index) const { |
| 757 DCHECK(instruction_blocks_->size() == block_starts_.size()); | 759 return instruction_blocks()[instructions()[instruction_index]->block_id()]; |
| 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 } | 760 } |
| 770 | 761 |
| 771 | 762 |
| 772 static MachineRepresentation FilterRepresentation(MachineRepresentation rep) { | 763 static MachineRepresentation FilterRepresentation(MachineRepresentation rep) { |
| 773 switch (rep) { | 764 switch (rep) { |
| 774 case MachineRepresentation::kBit: | 765 case MachineRepresentation::kBit: |
| 775 case MachineRepresentation::kWord8: | 766 case MachineRepresentation::kWord8: |
| 776 case MachineRepresentation::kWord16: | 767 case MachineRepresentation::kWord16: |
| 777 return InstructionSequence::DefaultRepresentation(); | 768 return InstructionSequence::DefaultRepresentation(); |
| 778 case MachineRepresentation::kWord32: | 769 case MachineRepresentation::kWord32: |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1012 } | 1003 } |
| 1013 for (int i = 0; i < code.InstructionBlockCount(); i++) { | 1004 for (int i = 0; i < code.InstructionBlockCount(); i++) { |
| 1014 printable.sequence_->PrintBlock(printable.register_configuration_, i); | 1005 printable.sequence_->PrintBlock(printable.register_configuration_, i); |
| 1015 } | 1006 } |
| 1016 return os; | 1007 return os; |
| 1017 } | 1008 } |
| 1018 | 1009 |
| 1019 } // namespace compiler | 1010 } // namespace compiler |
| 1020 } // namespace internal | 1011 } // namespace internal |
| 1021 } // namespace v8 | 1012 } // namespace v8 |
| OLD | NEW |