| 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 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 DCHECK_IMPLIES(replacement == to_eliminate, replacement == nullptr); | 103 DCHECK_IMPLIES(replacement == to_eliminate, replacement == nullptr); |
| 104 if (replacement != nullptr) move->set_source(replacement->source()); | 104 if (replacement != nullptr) move->set_source(replacement->source()); |
| 105 return to_eliminate; | 105 return to_eliminate; |
| 106 } | 106 } |
| 107 | 107 |
| 108 | 108 |
| 109 Instruction::Instruction(InstructionCode opcode) | 109 Instruction::Instruction(InstructionCode opcode) |
| 110 : opcode_(opcode), | 110 : opcode_(opcode), |
| 111 bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) | | 111 bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) | |
| 112 TempCountField::encode(0) | IsCallField::encode(false)), | 112 TempCountField::encode(0) | IsCallField::encode(false)), |
| 113 pointer_map_(NULL) {} | 113 pointer_map_(NULL) { |
| 114 parallel_moves_[0] = nullptr; |
| 115 parallel_moves_[1] = nullptr; |
| 116 } |
| 114 | 117 |
| 115 | 118 |
| 116 Instruction::Instruction(InstructionCode opcode, size_t output_count, | 119 Instruction::Instruction(InstructionCode opcode, size_t output_count, |
| 117 InstructionOperand* outputs, size_t input_count, | 120 InstructionOperand* outputs, size_t input_count, |
| 118 InstructionOperand* inputs, size_t temp_count, | 121 InstructionOperand* inputs, size_t temp_count, |
| 119 InstructionOperand* temps) | 122 InstructionOperand* temps) |
| 120 : opcode_(opcode), | 123 : opcode_(opcode), |
| 121 bit_field_(OutputCountField::encode(output_count) | | 124 bit_field_(OutputCountField::encode(output_count) | |
| 122 InputCountField::encode(input_count) | | 125 InputCountField::encode(input_count) | |
| 123 TempCountField::encode(temp_count) | | 126 TempCountField::encode(temp_count) | |
| 124 IsCallField::encode(false)), | 127 IsCallField::encode(false)), |
| 125 pointer_map_(NULL) { | 128 pointer_map_(NULL) { |
| 129 parallel_moves_[0] = nullptr; |
| 130 parallel_moves_[1] = nullptr; |
| 126 size_t offset = 0; | 131 size_t offset = 0; |
| 127 for (size_t i = 0; i < output_count; ++i) { | 132 for (size_t i = 0; i < output_count; ++i) { |
| 128 DCHECK(!outputs[i].IsInvalid()); | 133 DCHECK(!outputs[i].IsInvalid()); |
| 129 operands_[offset++] = outputs[i]; | 134 operands_[offset++] = outputs[i]; |
| 130 } | 135 } |
| 131 for (size_t i = 0; i < input_count; ++i) { | 136 for (size_t i = 0; i < input_count; ++i) { |
| 132 DCHECK(!inputs[i].IsInvalid()); | 137 DCHECK(!inputs[i].IsInvalid()); |
| 133 operands_[offset++] = inputs[i]; | 138 operands_[offset++] = inputs[i]; |
| 134 } | 139 } |
| 135 for (size_t i = 0; i < temp_count; ++i) { | 140 for (size_t i = 0; i < temp_count; ++i) { |
| 136 DCHECK(!temps[i].IsInvalid()); | 141 DCHECK(!temps[i].IsInvalid()); |
| 137 operands_[offset++] = temps[i]; | 142 operands_[offset++] = temps[i]; |
| 138 } | 143 } |
| 139 } | 144 } |
| 140 | 145 |
| 141 | 146 |
| 142 bool GapInstruction::IsRedundant() const { | 147 bool Instruction::AreMovesRedundant() const { |
| 143 for (int i = GapInstruction::FIRST_INNER_POSITION; | 148 for (int i = Instruction::FIRST_GAP_POSITION; |
| 144 i <= GapInstruction::LAST_INNER_POSITION; i++) { | 149 i <= Instruction::LAST_GAP_POSITION; i++) { |
| 145 if (parallel_moves_[i] != NULL && !parallel_moves_[i]->IsRedundant()) | 150 if (parallel_moves_[i] != nullptr && !parallel_moves_[i]->IsRedundant()) { |
| 146 return false; | 151 return false; |
| 152 } |
| 147 } | 153 } |
| 148 return true; | 154 return true; |
| 149 } | 155 } |
| 150 | 156 |
| 151 | 157 |
| 152 std::ostream& operator<<(std::ostream& os, | 158 std::ostream& operator<<(std::ostream& os, |
| 153 const PrintableParallelMove& printable) { | 159 const PrintableParallelMove& printable) { |
| 154 const ParallelMove& pm = *printable.parallel_move_; | 160 const ParallelMove& pm = *printable.parallel_move_; |
| 155 bool first = true; | 161 bool first = true; |
| 156 for (ZoneList<MoveOperands>::iterator move = pm.move_operands()->begin(); | 162 for (ZoneList<MoveOperands>::iterator move = pm.move_operands()->begin(); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 UNREACHABLE(); | 288 UNREACHABLE(); |
| 283 return os; | 289 return os; |
| 284 } | 290 } |
| 285 | 291 |
| 286 | 292 |
| 287 std::ostream& operator<<(std::ostream& os, | 293 std::ostream& operator<<(std::ostream& os, |
| 288 const PrintableInstruction& printable) { | 294 const PrintableInstruction& printable) { |
| 289 const Instruction& instr = *printable.instr_; | 295 const Instruction& instr = *printable.instr_; |
| 290 PrintableInstructionOperand printable_op = {printable.register_configuration_, | 296 PrintableInstructionOperand printable_op = {printable.register_configuration_, |
| 291 NULL}; | 297 NULL}; |
| 298 os << "gap "; |
| 299 for (int i = Instruction::FIRST_GAP_POSITION; |
| 300 i <= Instruction::LAST_GAP_POSITION; i++) { |
| 301 os << "("; |
| 302 if (instr.parallel_moves()[i] != NULL) { |
| 303 PrintableParallelMove ppm = {printable.register_configuration_, |
| 304 instr.parallel_moves()[i]}; |
| 305 os << ppm; |
| 306 } |
| 307 os << ") "; |
| 308 } |
| 309 os << "\n "; |
| 310 |
| 292 if (instr.OutputCount() > 1) os << "("; | 311 if (instr.OutputCount() > 1) os << "("; |
| 293 for (size_t i = 0; i < instr.OutputCount(); i++) { | 312 for (size_t i = 0; i < instr.OutputCount(); i++) { |
| 294 if (i > 0) os << ", "; | 313 if (i > 0) os << ", "; |
| 295 printable_op.op_ = instr.OutputAt(i); | 314 printable_op.op_ = instr.OutputAt(i); |
| 296 os << printable_op; | 315 os << printable_op; |
| 297 } | 316 } |
| 298 | 317 |
| 299 if (instr.OutputCount() > 1) os << ") = "; | 318 if (instr.OutputCount() > 1) os << ") = "; |
| 300 if (instr.OutputCount() == 1) os << " = "; | 319 if (instr.OutputCount() == 1) os << " = "; |
| 301 | 320 |
| 302 if (instr.IsGapMoves()) { | 321 if (instr.IsSourcePosition()) { |
| 303 const GapInstruction* gap = GapInstruction::cast(&instr); | |
| 304 os << "gap "; | |
| 305 for (int i = GapInstruction::FIRST_INNER_POSITION; | |
| 306 i <= GapInstruction::LAST_INNER_POSITION; i++) { | |
| 307 os << "("; | |
| 308 if (gap->parallel_moves_[i] != NULL) { | |
| 309 PrintableParallelMove ppm = {printable.register_configuration_, | |
| 310 gap->parallel_moves_[i]}; | |
| 311 os << ppm; | |
| 312 } | |
| 313 os << ") "; | |
| 314 } | |
| 315 } else if (instr.IsSourcePosition()) { | |
| 316 const SourcePositionInstruction* pos = | 322 const SourcePositionInstruction* pos = |
| 317 SourcePositionInstruction::cast(&instr); | 323 SourcePositionInstruction::cast(&instr); |
| 318 os << "position (" << pos->source_position().raw() << ")"; | 324 os << "position (" << pos->source_position().raw() << ")"; |
| 319 } else { | 325 } else { |
| 320 os << ArchOpcodeField::decode(instr.opcode()); | 326 os << ArchOpcodeField::decode(instr.opcode()); |
| 321 AddressingMode am = AddressingModeField::decode(instr.opcode()); | 327 AddressingMode am = AddressingModeField::decode(instr.opcode()); |
| 322 if (am != kMode_None) { | 328 if (am != kMode_None) { |
| 323 os << " : " << AddressingModeField::decode(instr.opcode()); | 329 os << " : " << AddressingModeField::decode(instr.opcode()); |
| 324 } | 330 } |
| 325 FlagsMode fm = FlagsModeField::decode(instr.opcode()); | 331 FlagsMode fm = FlagsModeField::decode(instr.opcode()); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 } | 493 } |
| 488 | 494 |
| 489 | 495 |
| 490 int InstructionSequence::NextVirtualRegister() { | 496 int InstructionSequence::NextVirtualRegister() { |
| 491 int virtual_register = next_virtual_register_++; | 497 int virtual_register = next_virtual_register_++; |
| 492 CHECK_NE(virtual_register, InstructionOperand::kInvalidVirtualRegister); | 498 CHECK_NE(virtual_register, InstructionOperand::kInvalidVirtualRegister); |
| 493 return virtual_register; | 499 return virtual_register; |
| 494 } | 500 } |
| 495 | 501 |
| 496 | 502 |
| 497 GapInstruction* InstructionSequence::GetBlockStart(RpoNumber rpo) const { | 503 Instruction* InstructionSequence::GetBlockStart(RpoNumber rpo) const { |
| 498 const InstructionBlock* block = InstructionBlockAt(rpo); | 504 const InstructionBlock* block = InstructionBlockAt(rpo); |
| 499 return GapInstruction::cast(InstructionAt(block->code_start())); | 505 return InstructionAt(block->code_start()); |
| 500 } | 506 } |
| 501 | 507 |
| 502 | 508 |
| 503 void InstructionSequence::StartBlock(RpoNumber rpo) { | 509 void InstructionSequence::StartBlock(RpoNumber rpo) { |
| 504 DCHECK(block_starts_.size() == rpo.ToSize()); | 510 DCHECK(block_starts_.size() == rpo.ToSize()); |
| 505 InstructionBlock* block = InstructionBlockAt(rpo); | 511 InstructionBlock* block = InstructionBlockAt(rpo); |
| 506 int code_start = static_cast<int>(instructions_.size()); | 512 int code_start = static_cast<int>(instructions_.size()); |
| 507 block->set_code_start(code_start); | 513 block->set_code_start(code_start); |
| 508 block_starts_.push_back(code_start); | 514 block_starts_.push_back(code_start); |
| 509 } | 515 } |
| 510 | 516 |
| 511 | 517 |
| 512 void InstructionSequence::EndBlock(RpoNumber rpo) { | 518 void InstructionSequence::EndBlock(RpoNumber rpo) { |
| 513 int end = static_cast<int>(instructions_.size()); | 519 int end = static_cast<int>(instructions_.size()); |
| 514 InstructionBlock* block = InstructionBlockAt(rpo); | 520 InstructionBlock* block = InstructionBlockAt(rpo); |
| 515 if (block->code_start() == end) { // Empty block. Insert a nop. | 521 if (block->code_start() == end) { // Empty block. Insert a nop. |
| 516 AddInstruction(Instruction::New(zone(), kArchNop)); | 522 AddInstruction(Instruction::New(zone(), kArchNop)); |
| 517 end = static_cast<int>(instructions_.size()); | 523 end = static_cast<int>(instructions_.size()); |
| 518 } | 524 } |
| 519 DCHECK(block->code_start() >= 0 && block->code_start() < end); | 525 DCHECK(block->code_start() >= 0 && block->code_start() < end); |
| 520 block->set_code_end(end); | 526 block->set_code_end(end); |
| 521 } | 527 } |
| 522 | 528 |
| 523 | 529 |
| 524 int InstructionSequence::AddInstruction(Instruction* instr) { | 530 int InstructionSequence::AddInstruction(Instruction* instr) { |
| 525 GapInstruction* gap = GapInstruction::New(zone()); | |
| 526 instructions_.push_back(gap); | |
| 527 int index = static_cast<int>(instructions_.size()); | 531 int index = static_cast<int>(instructions_.size()); |
| 528 instructions_.push_back(instr); | 532 instructions_.push_back(instr); |
| 529 if (instr->NeedsPointerMap()) { | 533 if (instr->NeedsPointerMap()) { |
| 530 DCHECK(instr->pointer_map() == NULL); | 534 DCHECK(instr->pointer_map() == NULL); |
| 531 PointerMap* pointer_map = new (zone()) PointerMap(zone()); | 535 PointerMap* pointer_map = new (zone()) PointerMap(zone()); |
| 532 pointer_map->set_instruction_position(index); | 536 pointer_map->set_instruction_position(index); |
| 533 instr->set_pointer_map(pointer_map); | 537 instr->set_pointer_map(pointer_map); |
| 534 pointer_maps_.push_back(pointer_map); | 538 pointer_maps_.push_back(pointer_map); |
| 535 } | 539 } |
| 536 return index; | 540 return index; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 564 void InstructionSequence::MarkAsReference(int virtual_register) { | 568 void InstructionSequence::MarkAsReference(int virtual_register) { |
| 565 references_.insert(virtual_register); | 569 references_.insert(virtual_register); |
| 566 } | 570 } |
| 567 | 571 |
| 568 | 572 |
| 569 void InstructionSequence::MarkAsDouble(int virtual_register) { | 573 void InstructionSequence::MarkAsDouble(int virtual_register) { |
| 570 doubles_.insert(virtual_register); | 574 doubles_.insert(virtual_register); |
| 571 } | 575 } |
| 572 | 576 |
| 573 | 577 |
| 574 void InstructionSequence::AddGapMove(int index, InstructionOperand* from, | |
| 575 InstructionOperand* to) { | |
| 576 GapAt(index)->GetOrCreateParallelMove(GapInstruction::START, zone())->AddMove( | |
| 577 from, to, zone()); | |
| 578 } | |
| 579 | |
| 580 | |
| 581 InstructionSequence::StateId InstructionSequence::AddFrameStateDescriptor( | 578 InstructionSequence::StateId InstructionSequence::AddFrameStateDescriptor( |
| 582 FrameStateDescriptor* descriptor) { | 579 FrameStateDescriptor* descriptor) { |
| 583 int deoptimization_id = static_cast<int>(deoptimization_entries_.size()); | 580 int deoptimization_id = static_cast<int>(deoptimization_entries_.size()); |
| 584 deoptimization_entries_.push_back(descriptor); | 581 deoptimization_entries_.push_back(descriptor); |
| 585 return StateId::FromInt(deoptimization_id); | 582 return StateId::FromInt(deoptimization_id); |
| 586 } | 583 } |
| 587 | 584 |
| 588 FrameStateDescriptor* InstructionSequence::GetFrameStateDescriptor( | 585 FrameStateDescriptor* InstructionSequence::GetFrameStateDescriptor( |
| 589 InstructionSequence::StateId state_id) { | 586 InstructionSequence::StateId state_id) { |
| 590 return deoptimization_entries_[state_id.ToInt()]; | 587 return deoptimization_entries_[state_id.ToInt()]; |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 os << " B" << succ.ToInt(); | 728 os << " B" << succ.ToInt(); |
| 732 } | 729 } |
| 733 os << "\n"; | 730 os << "\n"; |
| 734 } | 731 } |
| 735 return os; | 732 return os; |
| 736 } | 733 } |
| 737 | 734 |
| 738 } // namespace compiler | 735 } // namespace compiler |
| 739 } // namespace internal | 736 } // namespace internal |
| 740 } // namespace v8 | 737 } // namespace v8 |
| OLD | NEW |