| 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/address-map.h" | 9 #include "src/address-map.h" |
| 10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
| (...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 EnqueueInput(node, i); // Control inputs: just visit | 754 EnqueueInput(node, i); // Control inputs: just visit |
| 755 } | 755 } |
| 756 } | 756 } |
| 757 | 757 |
| 758 // The default, most general visitation case. For {node}, process all value, | 758 // The default, most general visitation case. For {node}, process all value, |
| 759 // context, frame state, effect, and control inputs, assuming that value | 759 // context, frame state, effect, and control inputs, assuming that value |
| 760 // inputs should have {kRepTagged} representation and can observe all output | 760 // inputs should have {kRepTagged} representation and can observe all output |
| 761 // values {kTypeAny}. | 761 // values {kTypeAny}. |
| 762 void VisitInputs(Node* node) { | 762 void VisitInputs(Node* node) { |
| 763 int tagged_count = node->op()->ValueInputCount() + | 763 int tagged_count = node->op()->ValueInputCount() + |
| 764 OperatorProperties::GetContextInputCount(node->op()); | 764 OperatorProperties::GetContextInputCount(node->op()) + |
| 765 // Visit value and context inputs as tagged. | 765 OperatorProperties::GetFrameStateInputCount(node->op()); |
| 766 // Visit value, context and frame state inputs as tagged. |
| 766 for (int i = 0; i < tagged_count; i++) { | 767 for (int i = 0; i < tagged_count; i++) { |
| 767 ProcessInput(node, i, UseInfo::AnyTagged()); | 768 ProcessInput(node, i, UseInfo::AnyTagged()); |
| 768 } | 769 } |
| 769 // Only enqueue other inputs (framestates, effects, control). | 770 // Only enqueue other inputs (effects, control). |
| 770 for (int i = tagged_count; i < node->InputCount(); i++) { | 771 for (int i = tagged_count; i < node->InputCount(); i++) { |
| 771 EnqueueInput(node, i); | 772 EnqueueInput(node, i); |
| 772 } | 773 } |
| 773 } | 774 } |
| 774 | 775 |
| 776 // Helper for an unused node. |
| 777 void VisitUnused(Node* node) { |
| 778 int value_count = node->op()->ValueInputCount() + |
| 779 OperatorProperties::GetContextInputCount(node->op()) + |
| 780 OperatorProperties::GetFrameStateInputCount(node->op()); |
| 781 for (int i = 0; i < value_count; i++) { |
| 782 ProcessInput(node, i, UseInfo::None()); |
| 783 } |
| 784 ProcessRemainingInputs(node, value_count); |
| 785 if (lower()) Kill(node); |
| 786 } |
| 787 |
| 775 // Helper for binops of the R x L -> O variety. | 788 // Helper for binops of the R x L -> O variety. |
| 776 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, | 789 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, |
| 777 MachineRepresentation output, | 790 MachineRepresentation output, |
| 778 Type* restriction_type = Type::Any()) { | 791 Type* restriction_type = Type::Any()) { |
| 779 DCHECK_EQ(2, node->op()->ValueInputCount()); | 792 DCHECK_EQ(2, node->op()->ValueInputCount()); |
| 780 ProcessInput(node, 0, left_use); | 793 ProcessInput(node, 0, left_use); |
| 781 ProcessInput(node, 1, right_use); | 794 ProcessInput(node, 1, right_use); |
| 782 for (int i = 2; i < node->InputCount(); i++) { | 795 for (int i = 2; i < node->InputCount(); i++) { |
| 783 EnqueueInput(node, i); | 796 EnqueueInput(node, i); |
| 784 } | 797 } |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 927 // truncation truncation along. | 940 // truncation truncation along. |
| 928 UseInfo input_use(output, truncation); | 941 UseInfo input_use(output, truncation); |
| 929 for (int i = 0; i < node->InputCount(); i++) { | 942 for (int i = 0; i < node->InputCount(); i++) { |
| 930 ProcessInput(node, i, i < values ? input_use : UseInfo::None()); | 943 ProcessInput(node, i, i < values ? input_use : UseInfo::None()); |
| 931 } | 944 } |
| 932 } | 945 } |
| 933 | 946 |
| 934 void VisitCall(Node* node, SimplifiedLowering* lowering) { | 947 void VisitCall(Node* node, SimplifiedLowering* lowering) { |
| 935 const CallDescriptor* desc = CallDescriptorOf(node->op()); | 948 const CallDescriptor* desc = CallDescriptorOf(node->op()); |
| 936 int params = static_cast<int>(desc->ParameterCount()); | 949 int params = static_cast<int>(desc->ParameterCount()); |
| 950 int value_input_count = node->op()->ValueInputCount(); |
| 937 // Propagate representation information from call descriptor. | 951 // Propagate representation information from call descriptor. |
| 938 for (int i = 0; i < node->InputCount(); i++) { | 952 for (int i = 0; i < value_input_count; i++) { |
| 939 if (i == 0) { | 953 if (i == 0) { |
| 940 // The target of the call. | 954 // The target of the call. |
| 941 ProcessInput(node, i, UseInfo::None()); | 955 ProcessInput(node, i, UseInfo::Any()); |
| 942 } else if ((i - 1) < params) { | 956 } else if ((i - 1) < params) { |
| 943 ProcessInput(node, i, TruncatingUseInfoFromRepresentation( | 957 ProcessInput(node, i, TruncatingUseInfoFromRepresentation( |
| 944 desc->GetInputType(i).representation())); | 958 desc->GetInputType(i).representation())); |
| 945 } else { | 959 } else { |
| 946 ProcessInput(node, i, UseInfo::None()); | 960 ProcessInput(node, i, UseInfo::AnyTagged()); |
| 947 } | 961 } |
| 948 } | 962 } |
| 963 ProcessRemainingInputs(node, value_input_count); |
| 949 | 964 |
| 950 if (desc->ReturnCount() > 0) { | 965 if (desc->ReturnCount() > 0) { |
| 951 SetOutput(node, desc->GetReturnType(0).representation()); | 966 SetOutput(node, desc->GetReturnType(0).representation()); |
| 952 } else { | 967 } else { |
| 953 SetOutput(node, MachineRepresentation::kTagged); | 968 SetOutput(node, MachineRepresentation::kTagged); |
| 954 } | 969 } |
| 955 } | 970 } |
| 956 | 971 |
| 957 MachineSemantic DeoptValueSemanticOf(Type* type) { | 972 MachineSemantic DeoptValueSemanticOf(Type* type) { |
| 958 // We only need signedness to do deopt correctly. | 973 // We only need signedness to do deopt correctly. |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1102 void ChangeToInt32OverflowOp(Node* node) { | 1117 void ChangeToInt32OverflowOp(Node* node) { |
| 1103 NodeProperties::ChangeOp(node, Int32OverflowOp(node)); | 1118 NodeProperties::ChangeOp(node, Int32OverflowOp(node)); |
| 1104 } | 1119 } |
| 1105 | 1120 |
| 1106 void ChangeToUint32OverflowOp(Node* node) { | 1121 void ChangeToUint32OverflowOp(Node* node) { |
| 1107 NodeProperties::ChangeOp(node, Uint32OverflowOp(node)); | 1122 NodeProperties::ChangeOp(node, Uint32OverflowOp(node)); |
| 1108 } | 1123 } |
| 1109 | 1124 |
| 1110 void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation, | 1125 void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation, |
| 1111 SimplifiedLowering* lowering) { | 1126 SimplifiedLowering* lowering) { |
| 1127 if (truncation.IsUnused()) return VisitUnused(node); |
| 1112 if (BothInputsAre(node, type_cache_.kSigned32OrMinusZero) && | 1128 if (BothInputsAre(node, type_cache_.kSigned32OrMinusZero) && |
| 1113 NodeProperties::GetType(node)->Is(Type::Signed32())) { | 1129 NodeProperties::GetType(node)->Is(Type::Signed32())) { |
| 1114 // int32 + int32 = int32 ==> signed Int32Add/Sub | 1130 // int32 + int32 = int32 ==> signed Int32Add/Sub |
| 1115 VisitInt32Binop(node); | 1131 VisitInt32Binop(node); |
| 1116 if (lower()) ChangeToPureOp(node, Int32Op(node)); | 1132 if (lower()) ChangeToPureOp(node, Int32Op(node)); |
| 1117 return; | 1133 return; |
| 1118 } | 1134 } |
| 1119 | 1135 |
| 1120 // Use truncation if available. | 1136 // Use truncation if available. |
| 1121 if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) && | 1137 if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) && |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1159 if (lower()) { | 1175 if (lower()) { |
| 1160 ChangeToPureOp(node, Float64Op(node)); | 1176 ChangeToPureOp(node, Float64Op(node)); |
| 1161 } | 1177 } |
| 1162 return; | 1178 return; |
| 1163 } | 1179 } |
| 1164 | 1180 |
| 1165 // Dispatching routine for visiting the node {node} with the usage {use}. | 1181 // Dispatching routine for visiting the node {node} with the usage {use}. |
| 1166 // Depending on the operator, propagate new usage info to the inputs. | 1182 // Depending on the operator, propagate new usage info to the inputs. |
| 1167 void VisitNode(Node* node, Truncation truncation, | 1183 void VisitNode(Node* node, Truncation truncation, |
| 1168 SimplifiedLowering* lowering) { | 1184 SimplifiedLowering* lowering) { |
| 1185 // Unconditionally eliminate unused pure nodes (only relevant if there's |
| 1186 // a pure operation in between two effectful ones, where the last one |
| 1187 // is unused). |
| 1188 if (node->op()->HasProperty(Operator::kPure) && truncation.IsUnused()) { |
| 1189 return VisitUnused(node); |
| 1190 } |
| 1169 switch (node->opcode()) { | 1191 switch (node->opcode()) { |
| 1170 //------------------------------------------------------------------ | 1192 //------------------------------------------------------------------ |
| 1171 // Common operators. | 1193 // Common operators. |
| 1172 //------------------------------------------------------------------ | 1194 //------------------------------------------------------------------ |
| 1173 case IrOpcode::kStart: | 1195 case IrOpcode::kStart: |
| 1196 // We use Start as a terminator for the frame state chain, so even |
| 1197 // tho Start doesn't really produce a value, we have to say Tagged |
| 1198 // here, otherwise the input conversion will fail. |
| 1199 return VisitLeaf(node, MachineRepresentation::kTagged); |
| 1174 case IrOpcode::kDead: | 1200 case IrOpcode::kDead: |
| 1175 return VisitLeaf(node, MachineRepresentation::kNone); | 1201 return VisitLeaf(node, MachineRepresentation::kNone); |
| 1176 case IrOpcode::kParameter: { | 1202 case IrOpcode::kParameter: { |
| 1177 // TODO(titzer): use representation from linkage. | 1203 // TODO(titzer): use representation from linkage. |
| 1178 ProcessInput(node, 0, UseInfo::None()); | 1204 ProcessInput(node, 0, UseInfo::None()); |
| 1179 SetOutput(node, MachineRepresentation::kTagged); | 1205 SetOutput(node, MachineRepresentation::kTagged); |
| 1180 return; | 1206 return; |
| 1181 } | 1207 } |
| 1182 case IrOpcode::kInt32Constant: | 1208 case IrOpcode::kInt32Constant: |
| 1183 return VisitLeaf(node, MachineRepresentation::kWord32); | 1209 return VisitLeaf(node, MachineRepresentation::kWord32); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1277 return; | 1303 return; |
| 1278 } | 1304 } |
| 1279 | 1305 |
| 1280 case IrOpcode::kSpeculativeNumberAdd: | 1306 case IrOpcode::kSpeculativeNumberAdd: |
| 1281 case IrOpcode::kSpeculativeNumberSubtract: | 1307 case IrOpcode::kSpeculativeNumberSubtract: |
| 1282 return VisitSpeculativeAdditiveOp(node, truncation, lowering); | 1308 return VisitSpeculativeAdditiveOp(node, truncation, lowering); |
| 1283 | 1309 |
| 1284 case IrOpcode::kSpeculativeNumberLessThan: | 1310 case IrOpcode::kSpeculativeNumberLessThan: |
| 1285 case IrOpcode::kSpeculativeNumberLessThanOrEqual: | 1311 case IrOpcode::kSpeculativeNumberLessThanOrEqual: |
| 1286 case IrOpcode::kSpeculativeNumberEqual: { | 1312 case IrOpcode::kSpeculativeNumberEqual: { |
| 1313 if (truncation.IsUnused()) return VisitUnused(node); |
| 1287 // Number comparisons reduce to integer comparisons for integer inputs. | 1314 // Number comparisons reduce to integer comparisons for integer inputs. |
| 1288 if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) && | 1315 if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) && |
| 1289 TypeOf(node->InputAt(1))->Is(Type::Unsigned32())) { | 1316 TypeOf(node->InputAt(1))->Is(Type::Unsigned32())) { |
| 1290 // => unsigned Int32Cmp | 1317 // => unsigned Int32Cmp |
| 1291 VisitUint32Cmp(node); | 1318 VisitUint32Cmp(node); |
| 1292 if (lower()) ChangeToPureOp(node, Uint32Op(node)); | 1319 if (lower()) ChangeToPureOp(node, Uint32Op(node)); |
| 1293 return; | 1320 return; |
| 1294 } else if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) && | 1321 } else if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) && |
| 1295 TypeOf(node->InputAt(1))->Is(Type::Signed32())) { | 1322 TypeOf(node->InputAt(1))->Is(Type::Signed32())) { |
| 1296 // => signed Int32Cmp | 1323 // => signed Int32Cmp |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1331 VisitWord32TruncatingBinop(node); | 1358 VisitWord32TruncatingBinop(node); |
| 1332 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); | 1359 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
| 1333 } else { | 1360 } else { |
| 1334 // => Float64Add/Sub | 1361 // => Float64Add/Sub |
| 1335 VisitFloat64Binop(node); | 1362 VisitFloat64Binop(node); |
| 1336 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); | 1363 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
| 1337 } | 1364 } |
| 1338 return; | 1365 return; |
| 1339 } | 1366 } |
| 1340 case IrOpcode::kSpeculativeNumberMultiply: { | 1367 case IrOpcode::kSpeculativeNumberMultiply: { |
| 1368 if (truncation.IsUnused()) return VisitUnused(node); |
| 1341 if (BothInputsAre(node, Type::Integral32()) && | 1369 if (BothInputsAre(node, Type::Integral32()) && |
| 1342 (NodeProperties::GetType(node)->Is(Type::Signed32()) || | 1370 (NodeProperties::GetType(node)->Is(Type::Signed32()) || |
| 1343 NodeProperties::GetType(node)->Is(Type::Unsigned32()) || | 1371 NodeProperties::GetType(node)->Is(Type::Unsigned32()) || |
| 1344 (truncation.TruncatesToWord32() && | 1372 (truncation.TruncatesToWord32() && |
| 1345 NodeProperties::GetType(node)->Is( | 1373 NodeProperties::GetType(node)->Is( |
| 1346 type_cache_.kSafeIntegerOrMinusZero)))) { | 1374 type_cache_.kSafeIntegerOrMinusZero)))) { |
| 1347 // Multiply reduces to Int32Mul if the inputs are integers, and | 1375 // Multiply reduces to Int32Mul if the inputs are integers, and |
| 1348 // (a) the output is either known to be Signed32, or | 1376 // (a) the output is either known to be Signed32, or |
| 1349 // (b) the output is known to be Unsigned32, or | 1377 // (b) the output is known to be Unsigned32, or |
| 1350 // (c) the uses are truncating and the result is in the safe | 1378 // (c) the uses are truncating and the result is in the safe |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1405 VisitWord32TruncatingBinop(node); | 1433 VisitWord32TruncatingBinop(node); |
| 1406 if (lower()) ChangeToPureOp(node, Int32Op(node)); | 1434 if (lower()) ChangeToPureOp(node, Int32Op(node)); |
| 1407 return; | 1435 return; |
| 1408 } | 1436 } |
| 1409 // Number x Number => Float64Mul | 1437 // Number x Number => Float64Mul |
| 1410 VisitFloat64Binop(node); | 1438 VisitFloat64Binop(node); |
| 1411 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1439 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
| 1412 return; | 1440 return; |
| 1413 } | 1441 } |
| 1414 case IrOpcode::kSpeculativeNumberDivide: { | 1442 case IrOpcode::kSpeculativeNumberDivide: { |
| 1443 if (truncation.IsUnused()) return VisitUnused(node); |
| 1415 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { | 1444 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { |
| 1416 // => unsigned Uint32Div | 1445 // => unsigned Uint32Div |
| 1417 VisitWord32TruncatingBinop(node); | 1446 VisitWord32TruncatingBinop(node); |
| 1418 if (lower()) DeferReplacement(node, lowering->Uint32Div(node)); | 1447 if (lower()) DeferReplacement(node, lowering->Uint32Div(node)); |
| 1419 return; | 1448 return; |
| 1420 } | 1449 } |
| 1421 if (BothInputsAreSigned32(node)) { | 1450 if (BothInputsAreSigned32(node)) { |
| 1422 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { | 1451 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { |
| 1423 // => signed Int32Div | 1452 // => signed Int32Div |
| 1424 VisitInt32Binop(node); | 1453 VisitInt32Binop(node); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1510 return; | 1539 return; |
| 1511 } | 1540 } |
| 1512 // Checked float64 x float64 => float64 | 1541 // Checked float64 x float64 => float64 |
| 1513 DCHECK_EQ(IrOpcode::kSpeculativeNumberDivide, node->opcode()); | 1542 DCHECK_EQ(IrOpcode::kSpeculativeNumberDivide, node->opcode()); |
| 1514 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(), | 1543 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(), |
| 1515 MachineRepresentation::kFloat64, Type::Number()); | 1544 MachineRepresentation::kFloat64, Type::Number()); |
| 1516 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1545 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
| 1517 return; | 1546 return; |
| 1518 } | 1547 } |
| 1519 case IrOpcode::kSpeculativeNumberModulus: { | 1548 case IrOpcode::kSpeculativeNumberModulus: { |
| 1549 if (truncation.IsUnused()) return VisitUnused(node); |
| 1520 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { | 1550 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { |
| 1521 // => unsigned Uint32Mod | 1551 // => unsigned Uint32Mod |
| 1522 VisitWord32TruncatingBinop(node); | 1552 VisitWord32TruncatingBinop(node); |
| 1523 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); | 1553 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); |
| 1524 return; | 1554 return; |
| 1525 } | 1555 } |
| 1526 if (BothInputsAreSigned32(node)) { | 1556 if (BothInputsAreSigned32(node)) { |
| 1527 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { | 1557 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { |
| 1528 // => signed Int32Mod | 1558 // => signed Int32Mod |
| 1529 VisitInt32Binop(node); | 1559 VisitInt32Binop(node); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1623 case IrOpcode::kNumberShiftLeft: { | 1653 case IrOpcode::kNumberShiftLeft: { |
| 1624 Type* rhs_type = GetUpperBound(node->InputAt(1)); | 1654 Type* rhs_type = GetUpperBound(node->InputAt(1)); |
| 1625 VisitBinop(node, UseInfo::TruncatingWord32(), | 1655 VisitBinop(node, UseInfo::TruncatingWord32(), |
| 1626 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32); | 1656 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32); |
| 1627 if (lower()) { | 1657 if (lower()) { |
| 1628 lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type); | 1658 lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type); |
| 1629 } | 1659 } |
| 1630 return; | 1660 return; |
| 1631 } | 1661 } |
| 1632 case IrOpcode::kSpeculativeNumberShiftLeft: { | 1662 case IrOpcode::kSpeculativeNumberShiftLeft: { |
| 1663 if (truncation.IsUnused()) return VisitUnused(node); |
| 1633 if (BothInputsAre(node, Type::NumberOrOddball())) { | 1664 if (BothInputsAre(node, Type::NumberOrOddball())) { |
| 1634 Type* rhs_type = GetUpperBound(node->InputAt(1)); | 1665 Type* rhs_type = GetUpperBound(node->InputAt(1)); |
| 1635 VisitBinop(node, UseInfo::TruncatingWord32(), | 1666 VisitBinop(node, UseInfo::TruncatingWord32(), |
| 1636 UseInfo::TruncatingWord32(), | 1667 UseInfo::TruncatingWord32(), |
| 1637 MachineRepresentation::kWord32); | 1668 MachineRepresentation::kWord32); |
| 1638 if (lower()) { | 1669 if (lower()) { |
| 1639 lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type); | 1670 lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type); |
| 1640 } | 1671 } |
| 1641 return; | 1672 return; |
| 1642 } | 1673 } |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1934 return; | 1965 return; |
| 1935 } | 1966 } |
| 1936 | 1967 |
| 1937 case IrOpcode::kAllocate: { | 1968 case IrOpcode::kAllocate: { |
| 1938 ProcessInput(node, 0, UseInfo::TruncatingWord32()); | 1969 ProcessInput(node, 0, UseInfo::TruncatingWord32()); |
| 1939 ProcessRemainingInputs(node, 1); | 1970 ProcessRemainingInputs(node, 1); |
| 1940 SetOutput(node, MachineRepresentation::kTagged); | 1971 SetOutput(node, MachineRepresentation::kTagged); |
| 1941 return; | 1972 return; |
| 1942 } | 1973 } |
| 1943 case IrOpcode::kLoadField: { | 1974 case IrOpcode::kLoadField: { |
| 1975 if (truncation.IsUnused()) return VisitUnused(node); |
| 1944 FieldAccess access = FieldAccessOf(node->op()); | 1976 FieldAccess access = FieldAccessOf(node->op()); |
| 1945 MachineRepresentation representation = | 1977 MachineRepresentation const representation = |
| 1946 access.machine_type.representation(); | 1978 access.machine_type.representation(); |
| 1947 // If we are loading from a Smi field and truncate the result to Word32, | 1979 // If we are loading from a Smi field and truncate the result to Word32, |
| 1948 // we can instead just load the high word on 64-bit architectures, which | 1980 // we can instead just load the high word on 64-bit architectures, which |
| 1949 // is exactly the Word32 we are looking for, and therefore avoid a nasty | 1981 // is exactly the Word32 we are looking for, and therefore avoid a nasty |
| 1950 // right shift afterwards. | 1982 // right shift afterwards. |
| 1951 // TODO(bmeurer): Introduce an appropriate tagged-signed machine rep. | 1983 // TODO(bmeurer): Introduce an appropriate tagged-signed machine rep. |
| 1952 if (truncation.TruncatesToWord32() && | 1984 if (truncation.TruncatesToWord32() && |
| 1953 representation == MachineRepresentation::kTagged && | 1985 representation == MachineRepresentation::kTagged && |
| 1954 access.type->Is(Type::TaggedSigned()) && SmiValuesAre32Bits()) { | 1986 access.type->Is(Type::TaggedSigned()) && SmiValuesAre32Bits()) { |
| 1955 VisitUnop(node, UseInfoForBasePointer(access), | 1987 VisitUnop(node, UseInfoForBasePointer(access), |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1982 if (lower()) { | 2014 if (lower()) { |
| 1983 if (write_barrier_kind < access.write_barrier_kind) { | 2015 if (write_barrier_kind < access.write_barrier_kind) { |
| 1984 access.write_barrier_kind = write_barrier_kind; | 2016 access.write_barrier_kind = write_barrier_kind; |
| 1985 NodeProperties::ChangeOp( | 2017 NodeProperties::ChangeOp( |
| 1986 node, jsgraph_->simplified()->StoreField(access)); | 2018 node, jsgraph_->simplified()->StoreField(access)); |
| 1987 } | 2019 } |
| 1988 } | 2020 } |
| 1989 return; | 2021 return; |
| 1990 } | 2022 } |
| 1991 case IrOpcode::kLoadBuffer: { | 2023 case IrOpcode::kLoadBuffer: { |
| 2024 if (truncation.IsUnused()) return VisitUnused(node); |
| 1992 BufferAccess access = BufferAccessOf(node->op()); | 2025 BufferAccess access = BufferAccessOf(node->op()); |
| 1993 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer | 2026 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer |
| 1994 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset | 2027 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset |
| 1995 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length | 2028 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length |
| 1996 ProcessRemainingInputs(node, 3); | 2029 ProcessRemainingInputs(node, 3); |
| 1997 | 2030 |
| 1998 MachineRepresentation output; | 2031 MachineRepresentation output; |
| 1999 if (truncation.TruncatesUndefinedToZeroOrNaN()) { | 2032 if (truncation.TruncatesUndefinedToZeroOrNaN()) { |
| 2000 if (truncation.TruncatesNaNToZero()) { | 2033 if (truncation.TruncatesNaNToZero()) { |
| 2001 // If undefined is truncated to a non-NaN number, we can use | 2034 // If undefined is truncated to a non-NaN number, we can use |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2028 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length | 2061 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length |
| 2029 ProcessInput(node, 3, | 2062 ProcessInput(node, 3, |
| 2030 TruncatingUseInfoFromRepresentation( | 2063 TruncatingUseInfoFromRepresentation( |
| 2031 access.machine_type().representation())); // value | 2064 access.machine_type().representation())); // value |
| 2032 ProcessRemainingInputs(node, 4); | 2065 ProcessRemainingInputs(node, 4); |
| 2033 SetOutput(node, MachineRepresentation::kNone); | 2066 SetOutput(node, MachineRepresentation::kNone); |
| 2034 if (lower()) lowering->DoStoreBuffer(node); | 2067 if (lower()) lowering->DoStoreBuffer(node); |
| 2035 return; | 2068 return; |
| 2036 } | 2069 } |
| 2037 case IrOpcode::kLoadElement: { | 2070 case IrOpcode::kLoadElement: { |
| 2071 if (truncation.IsUnused()) return VisitUnused(node); |
| 2038 ElementAccess access = ElementAccessOf(node->op()); | 2072 ElementAccess access = ElementAccessOf(node->op()); |
| 2039 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base | 2073 VisitBinop(node, UseInfoForBasePointer(access), |
| 2040 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index | 2074 UseInfo::TruncatingWord32(), |
| 2041 ProcessRemainingInputs(node, 2); | 2075 access.machine_type.representation()); |
| 2042 SetOutput(node, access.machine_type.representation()); | |
| 2043 return; | 2076 return; |
| 2044 } | 2077 } |
| 2045 case IrOpcode::kStoreElement: { | 2078 case IrOpcode::kStoreElement: { |
| 2046 ElementAccess access = ElementAccessOf(node->op()); | 2079 ElementAccess access = ElementAccessOf(node->op()); |
| 2047 WriteBarrierKind write_barrier_kind = WriteBarrierKindFor( | 2080 WriteBarrierKind write_barrier_kind = WriteBarrierKindFor( |
| 2048 access.base_is_tagged, access.machine_type.representation(), | 2081 access.base_is_tagged, access.machine_type.representation(), |
| 2049 access.type, node->InputAt(2)); | 2082 access.type, node->InputAt(2)); |
| 2050 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base | 2083 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base |
| 2051 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index | 2084 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index |
| 2052 ProcessInput(node, 2, | 2085 ProcessInput(node, 2, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2105 case IrOpcode::kObjectIsNumber: | 2138 case IrOpcode::kObjectIsNumber: |
| 2106 case IrOpcode::kObjectIsReceiver: | 2139 case IrOpcode::kObjectIsReceiver: |
| 2107 case IrOpcode::kObjectIsSmi: | 2140 case IrOpcode::kObjectIsSmi: |
| 2108 case IrOpcode::kObjectIsString: | 2141 case IrOpcode::kObjectIsString: |
| 2109 case IrOpcode::kObjectIsUndetectable: { | 2142 case IrOpcode::kObjectIsUndetectable: { |
| 2110 ProcessInput(node, 0, UseInfo::AnyTagged()); | 2143 ProcessInput(node, 0, UseInfo::AnyTagged()); |
| 2111 SetOutput(node, MachineRepresentation::kBit); | 2144 SetOutput(node, MachineRepresentation::kBit); |
| 2112 return; | 2145 return; |
| 2113 } | 2146 } |
| 2114 case IrOpcode::kCheckFloat64Hole: { | 2147 case IrOpcode::kCheckFloat64Hole: { |
| 2148 if (truncation.IsUnused()) return VisitUnused(node); |
| 2115 CheckFloat64HoleMode mode = CheckFloat64HoleModeOf(node->op()); | 2149 CheckFloat64HoleMode mode = CheckFloat64HoleModeOf(node->op()); |
| 2116 ProcessInput(node, 0, UseInfo::TruncatingFloat64()); | 2150 ProcessInput(node, 0, UseInfo::TruncatingFloat64()); |
| 2117 ProcessRemainingInputs(node, 1); | 2151 ProcessRemainingInputs(node, 1); |
| 2118 SetOutput(node, MachineRepresentation::kFloat64); | 2152 SetOutput(node, MachineRepresentation::kFloat64); |
| 2119 if (truncation.TruncatesToFloat64() && | 2153 if (truncation.TruncatesToFloat64() && |
| 2120 mode == CheckFloat64HoleMode::kAllowReturnHole) { | 2154 mode == CheckFloat64HoleMode::kAllowReturnHole) { |
| 2121 if (lower()) DeferReplacement(node, node->InputAt(0)); | 2155 if (lower()) DeferReplacement(node, node->InputAt(0)); |
| 2122 } | 2156 } |
| 2123 return; | 2157 return; |
| 2124 } | 2158 } |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2341 } else { | 2375 } else { |
| 2342 DCHECK_EQ(0, node->op()->ControlInputCount()); | 2376 DCHECK_EQ(0, node->op()->ControlInputCount()); |
| 2343 } | 2377 } |
| 2344 | 2378 |
| 2345 replacements_.push_back(node); | 2379 replacements_.push_back(node); |
| 2346 replacements_.push_back(replacement); | 2380 replacements_.push_back(replacement); |
| 2347 | 2381 |
| 2348 node->NullAllInputs(); // Node is now dead. | 2382 node->NullAllInputs(); // Node is now dead. |
| 2349 } | 2383 } |
| 2350 | 2384 |
| 2385 void Kill(Node* node) { |
| 2386 TRACE("killing #%d:%s\n", node->id(), node->op()->mnemonic()); |
| 2387 |
| 2388 if (node->op()->EffectInputCount() == 1) { |
| 2389 DCHECK_LT(0, node->op()->ControlInputCount()); |
| 2390 // Disconnect the node from effect and control chains. |
| 2391 Node* control = NodeProperties::GetControlInput(node); |
| 2392 Node* effect = NodeProperties::GetEffectInput(node); |
| 2393 ReplaceEffectControlUses(node, effect, control); |
| 2394 } else { |
| 2395 DCHECK_EQ(0, node->op()->ControlInputCount()); |
| 2396 DCHECK_EQ(0, node->op()->EffectInputCount()); |
| 2397 DCHECK_EQ(0, node->op()->ControlOutputCount()); |
| 2398 DCHECK_EQ(0, node->op()->EffectOutputCount()); |
| 2399 } |
| 2400 |
| 2401 node->ReplaceUses(jsgraph_->Dead()); |
| 2402 |
| 2403 node->NullAllInputs(); // The {node} is now dead. |
| 2404 } |
| 2405 |
| 2351 void PrintOutputInfo(NodeInfo* info) { | 2406 void PrintOutputInfo(NodeInfo* info) { |
| 2352 if (FLAG_trace_representation) { | 2407 if (FLAG_trace_representation) { |
| 2353 OFStream os(stdout); | 2408 OFStream os(stdout); |
| 2354 os << info->representation(); | 2409 os << info->representation(); |
| 2355 } | 2410 } |
| 2356 } | 2411 } |
| 2357 | 2412 |
| 2358 void PrintRepresentation(MachineRepresentation rep) { | 2413 void PrintRepresentation(MachineRepresentation rep) { |
| 2359 if (FLAG_trace_representation) { | 2414 if (FLAG_trace_representation) { |
| 2360 OFStream os(stdout); | 2415 OFStream os(stdout); |
| (...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3379 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3434 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
| 3380 Operator::kNoProperties); | 3435 Operator::kNoProperties); |
| 3381 to_number_operator_.set(common()->Call(desc)); | 3436 to_number_operator_.set(common()->Call(desc)); |
| 3382 } | 3437 } |
| 3383 return to_number_operator_.get(); | 3438 return to_number_operator_.get(); |
| 3384 } | 3439 } |
| 3385 | 3440 |
| 3386 } // namespace compiler | 3441 } // namespace compiler |
| 3387 } // namespace internal | 3442 } // namespace internal |
| 3388 } // namespace v8 | 3443 } // namespace v8 |
| OLD | NEW |