| 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/instruction-selector.h" | 5 #include "src/compiler/instruction-selector.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "src/base/adapters.h" | 9 #include "src/base/adapters.h" |
| 10 #include "src/compiler/instruction-selector-impl.h" | 10 #include "src/compiler/instruction-selector-impl.h" |
| (...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 // Filter out the outputs that aren't live because no projection uses them. | 567 // Filter out the outputs that aren't live because no projection uses them. |
| 568 size_t outputs_needed_by_framestate = | 568 size_t outputs_needed_by_framestate = |
| 569 buffer->frame_state_descriptor == nullptr | 569 buffer->frame_state_descriptor == nullptr |
| 570 ? 0 | 570 ? 0 |
| 571 : buffer->frame_state_descriptor->state_combine() | 571 : buffer->frame_state_descriptor->state_combine() |
| 572 .ConsumedOutputCount(); | 572 .ConsumedOutputCount(); |
| 573 for (size_t i = 0; i < buffer->output_nodes.size(); i++) { | 573 for (size_t i = 0; i < buffer->output_nodes.size(); i++) { |
| 574 bool output_is_live = buffer->output_nodes[i] != nullptr || | 574 bool output_is_live = buffer->output_nodes[i] != nullptr || |
| 575 i < outputs_needed_by_framestate; | 575 i < outputs_needed_by_framestate; |
| 576 if (output_is_live) { | 576 if (output_is_live) { |
| 577 MachineType type = | 577 MachineRepresentation rep = |
| 578 buffer->descriptor->GetReturnType(static_cast<int>(i)); | 578 buffer->descriptor->GetReturnType(static_cast<int>(i)) |
| 579 .representation(); |
| 579 LinkageLocation location = | 580 LinkageLocation location = |
| 580 buffer->descriptor->GetReturnLocation(static_cast<int>(i)); | 581 buffer->descriptor->GetReturnLocation(static_cast<int>(i)); |
| 581 | 582 |
| 582 Node* output = buffer->output_nodes[i]; | 583 Node* output = buffer->output_nodes[i]; |
| 583 InstructionOperand op = | 584 InstructionOperand op = output == nullptr |
| 584 output == nullptr | 585 ? g.TempLocation(location) |
| 585 ? g.TempLocation(location, type.representation()) | 586 : g.DefineAsLocation(output, location); |
| 586 : g.DefineAsLocation(output, location, type.representation()); | 587 MarkAsRepresentation(rep, op); |
| 587 MarkAsRepresentation(type.representation(), op); | |
| 588 | 588 |
| 589 buffer->outputs.push_back(op); | 589 buffer->outputs.push_back(op); |
| 590 } | 590 } |
| 591 } | 591 } |
| 592 } | 592 } |
| 593 | 593 |
| 594 // The first argument is always the callee code. | 594 // The first argument is always the callee code. |
| 595 Node* callee = call->InputAt(0); | 595 Node* callee = call->InputAt(0); |
| 596 bool call_code_immediate = (flags & kCallCodeImmediate) != 0; | 596 bool call_code_immediate = (flags & kCallCodeImmediate) != 0; |
| 597 bool call_address_immediate = (flags & kCallAddressImmediate) != 0; | 597 bool call_address_immediate = (flags & kCallAddressImmediate) != 0; |
| 598 switch (buffer->descriptor->kind()) { | 598 switch (buffer->descriptor->kind()) { |
| 599 case CallDescriptor::kCallCodeObject: | 599 case CallDescriptor::kCallCodeObject: |
| 600 buffer->instruction_args.push_back( | 600 buffer->instruction_args.push_back( |
| 601 (call_code_immediate && callee->opcode() == IrOpcode::kHeapConstant) | 601 (call_code_immediate && callee->opcode() == IrOpcode::kHeapConstant) |
| 602 ? g.UseImmediate(callee) | 602 ? g.UseImmediate(callee) |
| 603 : g.UseRegister(callee)); | 603 : g.UseRegister(callee)); |
| 604 break; | 604 break; |
| 605 case CallDescriptor::kCallAddress: | 605 case CallDescriptor::kCallAddress: |
| 606 buffer->instruction_args.push_back( | 606 buffer->instruction_args.push_back( |
| 607 (call_address_immediate && | 607 (call_address_immediate && |
| 608 callee->opcode() == IrOpcode::kExternalConstant) | 608 callee->opcode() == IrOpcode::kExternalConstant) |
| 609 ? g.UseImmediate(callee) | 609 ? g.UseImmediate(callee) |
| 610 : g.UseRegister(callee)); | 610 : g.UseRegister(callee)); |
| 611 break; | 611 break; |
| 612 case CallDescriptor::kCallJSFunction: | 612 case CallDescriptor::kCallJSFunction: |
| 613 buffer->instruction_args.push_back( | 613 buffer->instruction_args.push_back( |
| 614 g.UseLocation(callee, buffer->descriptor->GetInputLocation(0), | 614 g.UseLocation(callee, buffer->descriptor->GetInputLocation(0))); |
| 615 buffer->descriptor->GetInputType(0).representation())); | |
| 616 break; | 615 break; |
| 617 } | 616 } |
| 618 DCHECK_EQ(1u, buffer->instruction_args.size()); | 617 DCHECK_EQ(1u, buffer->instruction_args.size()); |
| 619 | 618 |
| 620 // If the call needs a frame state, we insert the state information as | 619 // If the call needs a frame state, we insert the state information as |
| 621 // follows (n is the number of value inputs to the frame state): | 620 // follows (n is the number of value inputs to the frame state): |
| 622 // arg 1 : deoptimization id. | 621 // arg 1 : deoptimization id. |
| 623 // arg 2 - arg (n + 1) : value inputs to the frame state. | 622 // arg 2 - arg (n + 1) : value inputs to the frame state. |
| 624 size_t frame_state_entries = 0; | 623 size_t frame_state_entries = 0; |
| 625 USE(frame_state_entries); // frame_state_entries is only used for debug. | 624 USE(frame_state_entries); // frame_state_entries is only used for debug. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 for (size_t index = 0; index < input_count; ++iter, ++index) { | 671 for (size_t index = 0; index < input_count; ++iter, ++index) { |
| 673 DCHECK(iter != call->inputs().end()); | 672 DCHECK(iter != call->inputs().end()); |
| 674 DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState); | 673 DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState); |
| 675 if (index == 0) continue; // The first argument (callee) is already done. | 674 if (index == 0) continue; // The first argument (callee) is already done. |
| 676 | 675 |
| 677 LinkageLocation location = buffer->descriptor->GetInputLocation(index); | 676 LinkageLocation location = buffer->descriptor->GetInputLocation(index); |
| 678 if (call_tail) { | 677 if (call_tail) { |
| 679 location = LinkageLocation::ConvertToTailCallerLocation( | 678 location = LinkageLocation::ConvertToTailCallerLocation( |
| 680 location, stack_param_delta); | 679 location, stack_param_delta); |
| 681 } | 680 } |
| 682 InstructionOperand op = | 681 InstructionOperand op = g.UseLocation(*iter, location); |
| 683 g.UseLocation(*iter, location, | |
| 684 buffer->descriptor->GetInputType(index).representation()); | |
| 685 if (UnallocatedOperand::cast(op).HasFixedSlotPolicy() && !call_tail) { | 682 if (UnallocatedOperand::cast(op).HasFixedSlotPolicy() && !call_tail) { |
| 686 int stack_index = -UnallocatedOperand::cast(op).fixed_slot_index() - 1; | 683 int stack_index = -UnallocatedOperand::cast(op).fixed_slot_index() - 1; |
| 687 if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) { | 684 if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) { |
| 688 buffer->pushed_nodes.resize(stack_index + 1); | 685 buffer->pushed_nodes.resize(stack_index + 1); |
| 689 } | 686 } |
| 690 PushParameter parameter(*iter, buffer->descriptor->GetInputType(index)); | 687 PushParameter parameter(*iter, buffer->descriptor->GetInputType(index)); |
| 691 buffer->pushed_nodes[stack_index] = parameter; | 688 buffer->pushed_nodes[stack_index] = parameter; |
| 692 pushed_count++; | 689 pushed_count++; |
| 693 } else { | 690 } else { |
| 694 buffer->instruction_args.push_back(op); | 691 buffer->instruction_args.push_back(op); |
| (...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1599 void InstructionSelector::VisitFinishRegion(Node* node) { EmitIdentity(node); } | 1596 void InstructionSelector::VisitFinishRegion(Node* node) { EmitIdentity(node); } |
| 1600 | 1597 |
| 1601 void InstructionSelector::VisitParameter(Node* node) { | 1598 void InstructionSelector::VisitParameter(Node* node) { |
| 1602 OperandGenerator g(this); | 1599 OperandGenerator g(this); |
| 1603 int index = ParameterIndexOf(node->op()); | 1600 int index = ParameterIndexOf(node->op()); |
| 1604 InstructionOperand op = | 1601 InstructionOperand op = |
| 1605 linkage()->ParameterHasSecondaryLocation(index) | 1602 linkage()->ParameterHasSecondaryLocation(index) |
| 1606 ? g.DefineAsDualLocation( | 1603 ? g.DefineAsDualLocation( |
| 1607 node, linkage()->GetParameterLocation(index), | 1604 node, linkage()->GetParameterLocation(index), |
| 1608 linkage()->GetParameterSecondaryLocation(index)) | 1605 linkage()->GetParameterSecondaryLocation(index)) |
| 1609 : g.DefineAsLocation( | 1606 : g.DefineAsLocation(node, linkage()->GetParameterLocation(index)); |
| 1610 node, linkage()->GetParameterLocation(index), | |
| 1611 linkage()->GetParameterType(index).representation()); | |
| 1612 | 1607 |
| 1613 Emit(kArchNop, op); | 1608 Emit(kArchNop, op); |
| 1614 } | 1609 } |
| 1615 | 1610 |
| 1616 | 1611 |
| 1617 void InstructionSelector::VisitIfException(Node* node) { | 1612 void InstructionSelector::VisitIfException(Node* node) { |
| 1618 OperandGenerator g(this); | 1613 OperandGenerator g(this); |
| 1619 Node* call = node->InputAt(1); | 1614 Node* call = node->InputAt(1); |
| 1620 DCHECK_EQ(IrOpcode::kCall, call->opcode()); | 1615 DCHECK_EQ(IrOpcode::kCall, call->opcode()); |
| 1621 const CallDescriptor* descriptor = CallDescriptorOf(call->op()); | 1616 const CallDescriptor* descriptor = CallDescriptorOf(call->op()); |
| 1622 Emit(kArchNop, | 1617 Emit(kArchNop, g.DefineAsLocation(node, descriptor->GetReturnLocation(0))); |
| 1623 g.DefineAsLocation(node, descriptor->GetReturnLocation(0), | |
| 1624 descriptor->GetReturnType(0).representation())); | |
| 1625 } | 1618 } |
| 1626 | 1619 |
| 1627 | 1620 |
| 1628 void InstructionSelector::VisitOsrValue(Node* node) { | 1621 void InstructionSelector::VisitOsrValue(Node* node) { |
| 1629 OperandGenerator g(this); | 1622 OperandGenerator g(this); |
| 1630 int index = OpParameter<int>(node); | 1623 int index = OpParameter<int>(node); |
| 1631 Emit(kArchNop, g.DefineAsLocation(node, linkage()->GetOsrValueLocation(index), | 1624 Emit(kArchNop, |
| 1632 MachineRepresentation::kTagged)); | 1625 g.DefineAsLocation(node, linkage()->GetOsrValueLocation(index))); |
| 1633 } | 1626 } |
| 1634 | 1627 |
| 1635 | 1628 |
| 1636 void InstructionSelector::VisitPhi(Node* node) { | 1629 void InstructionSelector::VisitPhi(Node* node) { |
| 1637 const int input_count = node->op()->ValueInputCount(); | 1630 const int input_count = node->op()->ValueInputCount(); |
| 1638 PhiInstruction* phi = new (instruction_zone()) | 1631 PhiInstruction* phi = new (instruction_zone()) |
| 1639 PhiInstruction(instruction_zone(), GetVirtualRegister(node), | 1632 PhiInstruction(instruction_zone(), GetVirtualRegister(node), |
| 1640 static_cast<size_t>(input_count)); | 1633 static_cast<size_t>(input_count)); |
| 1641 sequence() | 1634 sequence() |
| 1642 ->InstructionBlockAt(RpoNumber::FromInt(current_block_->rpo_number())) | 1635 ->InstructionBlockAt(RpoNumber::FromInt(current_block_->rpo_number())) |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1730 flags |= to_native_stack ? CallDescriptor::kRestoreJSSP | 1723 flags |= to_native_stack ? CallDescriptor::kRestoreJSSP |
| 1731 : CallDescriptor::kRestoreCSP; | 1724 : CallDescriptor::kRestoreCSP; |
| 1732 } | 1725 } |
| 1733 | 1726 |
| 1734 // Select the appropriate opcode based on the call type. | 1727 // Select the appropriate opcode based on the call type. |
| 1735 InstructionCode opcode = kArchNop; | 1728 InstructionCode opcode = kArchNop; |
| 1736 switch (descriptor->kind()) { | 1729 switch (descriptor->kind()) { |
| 1737 case CallDescriptor::kCallAddress: | 1730 case CallDescriptor::kCallAddress: |
| 1738 opcode = | 1731 opcode = |
| 1739 kArchCallCFunction | | 1732 kArchCallCFunction | |
| 1740 MiscField::encode(static_cast<int>(descriptor->CParameterCount())); | 1733 MiscField::encode(static_cast<int>(descriptor->ParameterCount())); |
| 1741 break; | 1734 break; |
| 1742 case CallDescriptor::kCallCodeObject: | 1735 case CallDescriptor::kCallCodeObject: |
| 1743 opcode = kArchCallCodeObject | MiscField::encode(flags); | 1736 opcode = kArchCallCodeObject | MiscField::encode(flags); |
| 1744 break; | 1737 break; |
| 1745 case CallDescriptor::kCallJSFunction: | 1738 case CallDescriptor::kCallJSFunction: |
| 1746 opcode = kArchCallJSFunction | MiscField::encode(flags); | 1739 opcode = kArchCallJSFunction | MiscField::encode(flags); |
| 1747 break; | 1740 break; |
| 1748 } | 1741 } |
| 1749 | 1742 |
| 1750 // Emit the call instruction. | 1743 // Emit the call instruction. |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1876 | 1869 |
| 1877 void InstructionSelector::VisitReturn(Node* ret) { | 1870 void InstructionSelector::VisitReturn(Node* ret) { |
| 1878 OperandGenerator g(this); | 1871 OperandGenerator g(this); |
| 1879 if (linkage()->GetIncomingDescriptor()->ReturnCount() == 0) { | 1872 if (linkage()->GetIncomingDescriptor()->ReturnCount() == 0) { |
| 1880 Emit(kArchRet, g.NoOutput()); | 1873 Emit(kArchRet, g.NoOutput()); |
| 1881 } else { | 1874 } else { |
| 1882 const int ret_count = ret->op()->ValueInputCount(); | 1875 const int ret_count = ret->op()->ValueInputCount(); |
| 1883 auto value_locations = zone()->NewArray<InstructionOperand>(ret_count); | 1876 auto value_locations = zone()->NewArray<InstructionOperand>(ret_count); |
| 1884 for (int i = 0; i < ret_count; ++i) { | 1877 for (int i = 0; i < ret_count; ++i) { |
| 1885 value_locations[i] = | 1878 value_locations[i] = |
| 1886 g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i), | 1879 g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i)); |
| 1887 linkage()->GetReturnType(i).representation()); | |
| 1888 } | 1880 } |
| 1889 Emit(kArchRet, 0, nullptr, ret_count, value_locations); | 1881 Emit(kArchRet, 0, nullptr, ret_count, value_locations); |
| 1890 } | 1882 } |
| 1891 } | 1883 } |
| 1892 | 1884 |
| 1893 Instruction* InstructionSelector::EmitDeoptimize(InstructionCode opcode, | 1885 Instruction* InstructionSelector::EmitDeoptimize(InstructionCode opcode, |
| 1894 InstructionOperand output, | 1886 InstructionOperand output, |
| 1895 InstructionOperand a, | 1887 InstructionOperand a, |
| 1896 InstructionOperand b, | 1888 InstructionOperand b, |
| 1897 Node* frame_state) { | 1889 Node* frame_state) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1995 return new (instruction_zone()) FrameStateDescriptor( | 1987 return new (instruction_zone()) FrameStateDescriptor( |
| 1996 instruction_zone(), state_info.type(), state_info.bailout_id(), | 1988 instruction_zone(), state_info.type(), state_info.bailout_id(), |
| 1997 state_info.state_combine(), parameters, locals, stack, | 1989 state_info.state_combine(), parameters, locals, stack, |
| 1998 state_info.shared_info(), outer_state); | 1990 state_info.shared_info(), outer_state); |
| 1999 } | 1991 } |
| 2000 | 1992 |
| 2001 | 1993 |
| 2002 } // namespace compiler | 1994 } // namespace compiler |
| 2003 } // namespace internal | 1995 } // namespace internal |
| 2004 } // namespace v8 | 1996 } // namespace v8 |
| OLD | NEW |