| 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/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| 11 #include "src/compiler/access-builder.h" |
| 11 #include "src/compiler/common-operator.h" | 12 #include "src/compiler/common-operator.h" |
| 12 #include "src/compiler/diamond.h" | 13 #include "src/compiler/diamond.h" |
| 13 #include "src/compiler/linkage.h" | 14 #include "src/compiler/linkage.h" |
| 14 #include "src/compiler/node-matchers.h" | 15 #include "src/compiler/node-matchers.h" |
| 15 #include "src/compiler/node-properties.h" | 16 #include "src/compiler/node-properties.h" |
| 16 #include "src/compiler/operator-properties.h" | 17 #include "src/compiler/operator-properties.h" |
| 17 #include "src/compiler/representation-change.h" | 18 #include "src/compiler/representation-change.h" |
| 18 #include "src/compiler/simplified-lowering.h" | 19 #include "src/compiler/simplified-lowering.h" |
| 19 #include "src/compiler/simplified-operator.h" | 20 #include "src/compiler/simplified-operator.h" |
| 20 #include "src/compiler/source-position.h" | 21 #include "src/compiler/source-position.h" |
| (...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 ProcessInput(node, 2, access.machine_type); // value | 863 ProcessInput(node, 2, access.machine_type); // value |
| 863 ProcessRemainingInputs(node, 3); | 864 ProcessRemainingInputs(node, 3); |
| 864 SetOutput(node, 0); | 865 SetOutput(node, 0); |
| 865 if (lower()) lowering->DoStoreElement(node); | 866 if (lower()) lowering->DoStoreElement(node); |
| 866 break; | 867 break; |
| 867 } | 868 } |
| 868 case IrOpcode::kObjectIsSmi: { | 869 case IrOpcode::kObjectIsSmi: { |
| 869 ProcessInput(node, 0, kMachAnyTagged); | 870 ProcessInput(node, 0, kMachAnyTagged); |
| 870 SetOutput(node, kRepBit | kTypeBool); | 871 SetOutput(node, kRepBit | kTypeBool); |
| 871 if (lower()) { | 872 if (lower()) { |
| 872 Node* is_tagged = jsgraph_->graph()->NewNode( | 873 Node* is_smi = lowering->IsSmi(node->InputAt(0)); |
| 873 jsgraph_->machine()->WordAnd(), node->InputAt(0), | |
| 874 jsgraph_->IntPtrConstant(kSmiTagMask)); | |
| 875 Node* is_smi = jsgraph_->graph()->NewNode( | |
| 876 jsgraph_->machine()->WordEqual(), is_tagged, | |
| 877 jsgraph_->IntPtrConstant(kSmiTag)); | |
| 878 DeferReplacement(node, is_smi); | 874 DeferReplacement(node, is_smi); |
| 879 } | 875 } |
| 880 break; | 876 break; |
| 881 } | 877 } |
| 882 case IrOpcode::kObjectIsNonNegativeSmi: { | 878 case IrOpcode::kObjectIsNonNegativeSmi: { |
| 883 ProcessInput(node, 0, kMachAnyTagged); | 879 ProcessInput(node, 0, kMachAnyTagged); |
| 884 SetOutput(node, kRepBit | kTypeBool); | 880 SetOutput(node, kRepBit | kTypeBool); |
| 885 if (lower()) { | 881 if (lower()) { |
| 886 Node* is_tagged = jsgraph_->graph()->NewNode( | 882 Node* is_smi = lowering->IsSmi(node->InputAt(0)); |
| 887 jsgraph_->machine()->WordAnd(), node->InputAt(0), | |
| 888 jsgraph_->IntPtrConstant(kSmiTagMask)); | |
| 889 Node* is_smi = jsgraph_->graph()->NewNode( | |
| 890 jsgraph_->machine()->WordEqual(), is_tagged, | |
| 891 jsgraph_->IntPtrConstant(kSmiTag)); | |
| 892 Node* is_non_neg = jsgraph_->graph()->NewNode( | 883 Node* is_non_neg = jsgraph_->graph()->NewNode( |
| 893 jsgraph_->machine()->IntLessThanOrEqual(), | 884 jsgraph_->machine()->IntLessThanOrEqual(), |
| 894 jsgraph_->IntPtrConstant(0), node->InputAt(0)); | 885 jsgraph_->IntPtrConstant(0), node->InputAt(0)); |
| 895 Node* is_non_neg_smi = jsgraph_->graph()->NewNode( | 886 Node* is_non_neg_smi = jsgraph_->graph()->NewNode( |
| 896 jsgraph_->machine()->Word32And(), is_smi, is_non_neg); | 887 jsgraph_->machine()->Word32And(), is_smi, is_non_neg); |
| 897 DeferReplacement(node, is_non_neg_smi); | 888 DeferReplacement(node, is_non_neg_smi); |
| 898 } | 889 } |
| 899 break; | 890 break; |
| 900 } | 891 } |
| 892 case IrOpcode::kCheckMaps: { |
| 893 // TODO(titzer): don't require tagged input to CheckMaps. |
| 894 VisitInputs(node); |
| 895 if (lower()) lowering->DoCheckMaps(node); |
| 896 break; |
| 897 } |
| 901 | 898 |
| 902 //------------------------------------------------------------------ | 899 //------------------------------------------------------------------ |
| 903 // Machine-level operators. | 900 // Machine-level operators. |
| 904 //------------------------------------------------------------------ | 901 //------------------------------------------------------------------ |
| 905 case IrOpcode::kLoad: { | 902 case IrOpcode::kLoad: { |
| 906 // TODO(titzer): machine loads/stores need to know BaseTaggedness!? | 903 // TODO(titzer): machine loads/stores need to know BaseTaggedness!? |
| 907 MachineTypeUnion tBase = kRepTagged | kMachPtr; | 904 MachineTypeUnion tBase = kRepTagged | kMachPtr; |
| 908 LoadRepresentation rep = OpParameter<LoadRepresentation>(node); | 905 LoadRepresentation rep = OpParameter<LoadRepresentation>(node); |
| 909 ProcessInput(node, 0, tBase); // pointer or object | 906 ProcessInput(node, 0, tBase); // pointer or object |
| 910 ProcessInput(node, 1, kMachIntPtr); // index | 907 ProcessInput(node, 1, kMachIntPtr); // index |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1113 | 1110 |
| 1114 | 1111 |
| 1115 Node* SimplifiedLowering::IsTagged(Node* node) { | 1112 Node* SimplifiedLowering::IsTagged(Node* node) { |
| 1116 // TODO(titzer): factor this out to a TaggingScheme abstraction. | 1113 // TODO(titzer): factor this out to a TaggingScheme abstraction. |
| 1117 STATIC_ASSERT(kSmiTagMask == 1); // Only works if tag is the low bit. | 1114 STATIC_ASSERT(kSmiTagMask == 1); // Only works if tag is the low bit. |
| 1118 return graph()->NewNode(machine()->WordAnd(), node, | 1115 return graph()->NewNode(machine()->WordAnd(), node, |
| 1119 jsgraph()->Int32Constant(kSmiTagMask)); | 1116 jsgraph()->Int32Constant(kSmiTagMask)); |
| 1120 } | 1117 } |
| 1121 | 1118 |
| 1122 | 1119 |
| 1120 Node* SimplifiedLowering::IsSmi(Node* node) { |
| 1121 Node* is_tagged = jsgraph_->graph()->NewNode( |
| 1122 machine()->WordAnd(), node, jsgraph()->IntPtrConstant(kSmiTagMask)); |
| 1123 Node* is_smi = |
| 1124 jsgraph_->graph()->NewNode(jsgraph()->machine()->WordEqual(), is_tagged, |
| 1125 jsgraph()->IntPtrConstant(kSmiTag)); |
| 1126 return is_smi; |
| 1127 } |
| 1128 |
| 1129 |
| 1123 void SimplifiedLowering::LowerAllNodes() { | 1130 void SimplifiedLowering::LowerAllNodes() { |
| 1124 SimplifiedOperatorBuilder simplified(graph()->zone()); | 1131 SimplifiedOperatorBuilder simplified(graph()->zone()); |
| 1125 RepresentationChanger changer(jsgraph(), &simplified, jsgraph()->isolate()); | 1132 RepresentationChanger changer(jsgraph(), &simplified, jsgraph()->isolate()); |
| 1126 RepresentationSelector selector(jsgraph(), zone_, &changer, | 1133 RepresentationSelector selector(jsgraph(), zone_, &changer, |
| 1127 source_positions_); | 1134 source_positions_); |
| 1128 selector.Run(this); | 1135 selector.Run(this); |
| 1129 } | 1136 } |
| 1130 | 1137 |
| 1131 | 1138 |
| 1132 Node* SimplifiedLowering::Untag(Node* node) { | 1139 Node* SimplifiedLowering::Untag(Node* node) { |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1608 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1615 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
| 1609 } | 1616 } |
| 1610 | 1617 |
| 1611 | 1618 |
| 1612 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { | 1619 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { |
| 1613 node->set_op(machine()->IntLessThanOrEqual()); | 1620 node->set_op(machine()->IntLessThanOrEqual()); |
| 1614 node->ReplaceInput(0, StringComparison(node, true)); | 1621 node->ReplaceInput(0, StringComparison(node, true)); |
| 1615 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1622 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
| 1616 } | 1623 } |
| 1617 | 1624 |
| 1625 |
| 1626 void SimplifiedLowering::DoCheckMaps(Node* node) { |
| 1627 bool smi_check = true; |
| 1628 |
| 1629 Node* receiver = node->InputAt(0); |
| 1630 Node* control = NodeProperties::GetControlInput(node); |
| 1631 Node* effect = NodeProperties::GetEffectInput(node); |
| 1632 int map_count = OpParameter<int32_t>(node->op()); |
| 1633 Node* frame_state = node->InputAt(1 + map_count); |
| 1634 |
| 1635 if (smi_check) { |
| 1636 // Inline a smi check first. |
| 1637 Node* branch_smi = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| 1638 IsSmi(receiver), control); |
| 1639 Node* if_smi = graph()->NewNode(common()->IfTrue(), branch_smi); |
| 1640 AddDeoptimize(frame_state, effect, if_smi); |
| 1641 control = graph()->NewNode(common()->IfFalse(), branch_smi); |
| 1642 } |
| 1643 |
| 1644 // Add checks against the maps. |
| 1645 NodeVector checks(zone()); |
| 1646 checks.reserve(map_count); |
| 1647 FieldAccess map_access = AccessBuilder::ForMap(); |
| 1648 Node* offset = |
| 1649 jsgraph()->IntPtrConstant(map_access.offset - map_access.tag()); |
| 1650 Node* receiver_map = |
| 1651 graph()->NewNode(machine()->Load(map_access.machine_type), receiver, |
| 1652 offset, effect, control); |
| 1653 for (int i = 1; i <= map_count; i++) { |
| 1654 Node* map = node->InputAt(i); |
| 1655 Node* cmp = graph()->NewNode(machine()->WordEqual(), receiver_map, map); |
| 1656 Node* branch = |
| 1657 graph()->NewNode(common()->Branch(BranchHint::kTrue), cmp, control); |
| 1658 Node* fail = graph()->NewNode(common()->IfFalse(), branch); |
| 1659 AddDeoptimize(frame_state, effect, fail); |
| 1660 Node* success = graph()->NewNode(common()->IfTrue(), branch); |
| 1661 checks.push_back(success); |
| 1662 } |
| 1663 |
| 1664 // Create a merge of the checks if necessary. |
| 1665 Node* success = |
| 1666 checks.size() == 1 |
| 1667 ? checks[0] |
| 1668 : graph()->NewNode(common()->Merge(map_count), map_count, &checks[0]); |
| 1669 |
| 1670 node->ReplaceUses(success); |
| 1671 } |
| 1672 |
| 1673 |
| 1674 void SimplifiedLowering::AddDeoptimize(Node* frame_state_before, Node* effect, |
| 1675 Node* control) { |
| 1676 Node* deopt = graph()->NewNode(common()->Deoptimize(), frame_state_before, |
| 1677 effect, control); |
| 1678 NodeProperties::MergeControlToEnd(graph(), common(), deopt); |
| 1679 } |
| 1680 |
| 1618 } // namespace compiler | 1681 } // namespace compiler |
| 1619 } // namespace internal | 1682 } // namespace internal |
| 1620 } // namespace v8 | 1683 } // namespace v8 |
| OLD | NEW |