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