| 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 << "]"; | 46 << "]"; |
| 47 case InstructionOperand::IMMEDIATE: { | 47 case InstructionOperand::IMMEDIATE: { |
| 48 auto imm = ImmediateOperand::cast(op); | 48 auto imm = ImmediateOperand::cast(op); |
| 49 switch (imm.type()) { | 49 switch (imm.type()) { |
| 50 case ImmediateOperand::INLINE: | 50 case ImmediateOperand::INLINE: |
| 51 return os << "#" << imm.inline_value(); | 51 return os << "#" << imm.inline_value(); |
| 52 case ImmediateOperand::INDEXED: | 52 case ImmediateOperand::INDEXED: |
| 53 return os << "[immediate:" << imm.indexed_value() << "]"; | 53 return os << "[immediate:" << imm.indexed_value() << "]"; |
| 54 } | 54 } |
| 55 } | 55 } |
| 56 case InstructionOperand::ALLOCATED: { | 56 case InstructionOperand::ALLOCATED: |
| 57 auto allocated = AllocatedOperand::cast(op); | 57 switch (AllocatedOperand::cast(op).allocated_kind()) { |
| 58 switch (allocated.allocated_kind()) { | |
| 59 case AllocatedOperand::STACK_SLOT: | 58 case AllocatedOperand::STACK_SLOT: |
| 60 os << "[stack:" << StackSlotOperand::cast(op).index(); | 59 return os << "[stack:" << StackSlotOperand::cast(op).index() << "]"; |
| 61 break; | |
| 62 case AllocatedOperand::DOUBLE_STACK_SLOT: | 60 case AllocatedOperand::DOUBLE_STACK_SLOT: |
| 63 os << "[double_stack:" << DoubleStackSlotOperand::cast(op).index(); | 61 return os << "[double_stack:" |
| 64 break; | 62 << DoubleStackSlotOperand::cast(op).index() << "]"; |
| 65 case AllocatedOperand::REGISTER: | 63 case AllocatedOperand::REGISTER: |
| 66 os << "[" | 64 return os << "[" |
| 67 << conf->general_register_name(RegisterOperand::cast(op).index()) | 65 << conf->general_register_name( |
| 68 << "|R"; | 66 RegisterOperand::cast(op).index()) << "|R]"; |
| 69 break; | |
| 70 case AllocatedOperand::DOUBLE_REGISTER: | 67 case AllocatedOperand::DOUBLE_REGISTER: |
| 71 os << "[" | 68 return os << "[" |
| 72 << conf->double_register_name( | 69 << conf->double_register_name( |
| 73 DoubleRegisterOperand::cast(op).index()) << "|R"; | 70 DoubleRegisterOperand::cast(op).index()) << "|R]"; |
| 74 break; | |
| 75 } | 71 } |
| 76 switch (allocated.machine_type()) { | |
| 77 case kRepWord32: | |
| 78 os << "|w32"; | |
| 79 break; | |
| 80 case kRepWord64: | |
| 81 os << "|w64"; | |
| 82 break; | |
| 83 case kRepFloat32: | |
| 84 os << "|f32"; | |
| 85 break; | |
| 86 case kRepFloat64: | |
| 87 os << "|f64"; | |
| 88 break; | |
| 89 case kRepTagged: | |
| 90 os << "|t"; | |
| 91 break; | |
| 92 default: | |
| 93 os << "|?"; | |
| 94 break; | |
| 95 } | |
| 96 return os << "]"; | |
| 97 } | |
| 98 case InstructionOperand::INVALID: | 72 case InstructionOperand::INVALID: |
| 99 return os << "(x)"; | 73 return os << "(x)"; |
| 100 } | 74 } |
| 101 UNREACHABLE(); | 75 UNREACHABLE(); |
| 102 return os; | 76 return os; |
| 103 } | 77 } |
| 104 | 78 |
| 105 | 79 |
| 106 std::ostream& operator<<(std::ostream& os, | 80 std::ostream& operator<<(std::ostream& os, |
| 107 const PrintableMoveOperands& printable) { | 81 const PrintableMoveOperands& printable) { |
| 108 const MoveOperands& mo = *printable.move_operands_; | 82 const MoveOperands& mo = *printable.move_operands_; |
| 109 PrintableInstructionOperand printable_op = {printable.register_configuration_, | 83 PrintableInstructionOperand printable_op = {printable.register_configuration_, |
| 110 mo.destination()}; | 84 mo.destination()}; |
| 111 os << printable_op; | 85 os << printable_op; |
| 112 if (!mo.source().Equals(mo.destination())) { | 86 if (mo.source() != mo.destination()) { |
| 113 printable_op.op_ = mo.source(); | 87 printable_op.op_ = mo.source(); |
| 114 os << " = " << printable_op; | 88 os << " = " << printable_op; |
| 115 } | 89 } |
| 116 return os << ";"; | 90 return os << ";"; |
| 117 } | 91 } |
| 118 | 92 |
| 119 | 93 |
| 120 bool ParallelMove::IsRedundant() const { | 94 bool ParallelMove::IsRedundant() const { |
| 121 for (auto move : *this) { | 95 for (auto move : *this) { |
| 122 if (!move->IsRedundant()) return false; | 96 if (!move->IsRedundant()) return false; |
| 123 } | 97 } |
| 124 return true; | 98 return true; |
| 125 } | 99 } |
| 126 | 100 |
| 127 | 101 |
| 128 MoveOperands* ParallelMove::PrepareInsertAfter(MoveOperands* move) const { | 102 MoveOperands* ParallelMove::PrepareInsertAfter(MoveOperands* move) const { |
| 129 MoveOperands* replacement = nullptr; | 103 MoveOperands* replacement = nullptr; |
| 130 MoveOperands* to_eliminate = nullptr; | 104 MoveOperands* to_eliminate = nullptr; |
| 131 for (auto curr : *this) { | 105 for (auto curr : *this) { |
| 132 if (curr->IsEliminated()) continue; | 106 if (curr->IsEliminated()) continue; |
| 133 if (curr->destination().EqualsModuloType(move->source())) { | 107 if (curr->destination() == move->source()) { |
| 134 DCHECK(!replacement); | 108 DCHECK(!replacement); |
| 135 replacement = curr; | 109 replacement = curr; |
| 136 if (to_eliminate != nullptr) break; | 110 if (to_eliminate != nullptr) break; |
| 137 } else if (curr->destination().EqualsModuloType(move->destination())) { | 111 } else if (curr->destination() == move->destination()) { |
| 138 DCHECK(!to_eliminate); | 112 DCHECK(!to_eliminate); |
| 139 to_eliminate = curr; | 113 to_eliminate = curr; |
| 140 if (replacement != nullptr) break; | 114 if (replacement != nullptr) break; |
| 141 } | 115 } |
| 142 } | 116 } |
| 143 DCHECK_IMPLIES(replacement == to_eliminate, replacement == nullptr); | 117 DCHECK_IMPLIES(replacement == to_eliminate, replacement == nullptr); |
| 144 if (replacement != nullptr) move->set_source(replacement->source()); | 118 if (replacement != nullptr) move->set_source(replacement->source()); |
| 145 return to_eliminate; | 119 return to_eliminate; |
| 146 } | 120 } |
| 147 | 121 |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 zone_(instruction_zone), | 472 zone_(instruction_zone), |
| 499 instruction_blocks_(instruction_blocks), | 473 instruction_blocks_(instruction_blocks), |
| 500 source_positions_(zone()), | 474 source_positions_(zone()), |
| 501 block_starts_(zone()), | 475 block_starts_(zone()), |
| 502 constants_(ConstantMap::key_compare(), | 476 constants_(ConstantMap::key_compare(), |
| 503 ConstantMap::allocator_type(zone())), | 477 ConstantMap::allocator_type(zone())), |
| 504 immediates_(zone()), | 478 immediates_(zone()), |
| 505 instructions_(zone()), | 479 instructions_(zone()), |
| 506 next_virtual_register_(0), | 480 next_virtual_register_(0), |
| 507 reference_maps_(zone()), | 481 reference_maps_(zone()), |
| 508 representations_(zone()), | 482 doubles_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), |
| 483 references_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())), |
| 509 deoptimization_entries_(zone()) { | 484 deoptimization_entries_(zone()) { |
| 510 block_starts_.reserve(instruction_blocks_->size()); | 485 block_starts_.reserve(instruction_blocks_->size()); |
| 511 } | 486 } |
| 512 | 487 |
| 513 | 488 |
| 514 int InstructionSequence::NextVirtualRegister() { | 489 int InstructionSequence::NextVirtualRegister() { |
| 515 int virtual_register = next_virtual_register_++; | 490 int virtual_register = next_virtual_register_++; |
| 516 CHECK_NE(virtual_register, InstructionOperand::kInvalidVirtualRegister); | 491 CHECK_NE(virtual_register, InstructionOperand::kInvalidVirtualRegister); |
| 517 return virtual_register; | 492 return virtual_register; |
| 518 } | 493 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 auto end = std::lower_bound(begin, block_starts_.end(), instruction_index, | 541 auto end = std::lower_bound(begin, block_starts_.end(), instruction_index, |
| 567 std::less_equal<int>()); | 542 std::less_equal<int>()); |
| 568 size_t index = std::distance(begin, end) - 1; | 543 size_t index = std::distance(begin, end) - 1; |
| 569 auto block = instruction_blocks_->at(index); | 544 auto block = instruction_blocks_->at(index); |
| 570 DCHECK(block->code_start() <= instruction_index && | 545 DCHECK(block->code_start() <= instruction_index && |
| 571 instruction_index < block->code_end()); | 546 instruction_index < block->code_end()); |
| 572 return block; | 547 return block; |
| 573 } | 548 } |
| 574 | 549 |
| 575 | 550 |
| 576 static MachineType FilterRepresentation(MachineType rep) { | 551 bool InstructionSequence::IsReference(int virtual_register) const { |
| 577 DCHECK_EQ(rep, RepresentationOf(rep)); | 552 return references_.find(virtual_register) != references_.end(); |
| 578 switch (rep) { | |
| 579 case kRepBit: | |
| 580 case kRepWord8: | |
| 581 case kRepWord16: | |
| 582 return InstructionSequence::DefaultRepresentation(); | |
| 583 case kRepWord32: | |
| 584 case kRepWord64: | |
| 585 case kRepFloat32: | |
| 586 case kRepFloat64: | |
| 587 case kRepTagged: | |
| 588 return rep; | |
| 589 default: | |
| 590 break; | |
| 591 } | |
| 592 UNREACHABLE(); | |
| 593 return kMachNone; | |
| 594 } | 553 } |
| 595 | 554 |
| 596 | 555 |
| 597 MachineType InstructionSequence::GetRepresentation(int virtual_register) const { | 556 bool InstructionSequence::IsDouble(int virtual_register) const { |
| 598 DCHECK_LE(0, virtual_register); | 557 return doubles_.find(virtual_register) != doubles_.end(); |
| 599 DCHECK_LT(virtual_register, VirtualRegisterCount()); | |
| 600 if (virtual_register >= static_cast<int>(representations_.size())) { | |
| 601 return DefaultRepresentation(); | |
| 602 } | |
| 603 return representations_[virtual_register]; | |
| 604 } | 558 } |
| 605 | 559 |
| 606 | 560 |
| 607 void InstructionSequence::MarkAsRepresentation(MachineType machine_type, | 561 void InstructionSequence::MarkAsReference(int virtual_register) { |
| 608 int virtual_register) { | 562 references_.insert(virtual_register); |
| 609 DCHECK_LE(0, virtual_register); | |
| 610 DCHECK_LT(virtual_register, VirtualRegisterCount()); | |
| 611 if (virtual_register >= static_cast<int>(representations_.size())) { | |
| 612 representations_.resize(VirtualRegisterCount(), DefaultRepresentation()); | |
| 613 } | |
| 614 machine_type = FilterRepresentation(machine_type); | |
| 615 DCHECK_IMPLIES(representations_[virtual_register] != machine_type, | |
| 616 representations_[virtual_register] == DefaultRepresentation()); | |
| 617 representations_[virtual_register] = machine_type; | |
| 618 } | 563 } |
| 619 | 564 |
| 620 | 565 |
| 566 void InstructionSequence::MarkAsDouble(int virtual_register) { |
| 567 doubles_.insert(virtual_register); |
| 568 } |
| 569 |
| 570 |
| 621 InstructionSequence::StateId InstructionSequence::AddFrameStateDescriptor( | 571 InstructionSequence::StateId InstructionSequence::AddFrameStateDescriptor( |
| 622 FrameStateDescriptor* descriptor) { | 572 FrameStateDescriptor* descriptor) { |
| 623 int deoptimization_id = static_cast<int>(deoptimization_entries_.size()); | 573 int deoptimization_id = static_cast<int>(deoptimization_entries_.size()); |
| 624 deoptimization_entries_.push_back(descriptor); | 574 deoptimization_entries_.push_back(descriptor); |
| 625 return StateId::FromInt(deoptimization_id); | 575 return StateId::FromInt(deoptimization_id); |
| 626 } | 576 } |
| 627 | 577 |
| 628 FrameStateDescriptor* InstructionSequence::GetFrameStateDescriptor( | 578 FrameStateDescriptor* InstructionSequence::GetFrameStateDescriptor( |
| 629 InstructionSequence::StateId state_id) { | 579 InstructionSequence::StateId state_id) { |
| 630 return deoptimization_entries_[state_id.ToInt()]; | 580 return deoptimization_entries_[state_id.ToInt()]; |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 797 os << " B" << succ.ToInt(); | 747 os << " B" << succ.ToInt(); |
| 798 } | 748 } |
| 799 os << "\n"; | 749 os << "\n"; |
| 800 } | 750 } |
| 801 return os; | 751 return os; |
| 802 } | 752 } |
| 803 | 753 |
| 804 } // namespace compiler | 754 } // namespace compiler |
| 805 } // namespace internal | 755 } // namespace internal |
| 806 } // namespace v8 | 756 } // namespace v8 |
| OLD | NEW |