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 |