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 |