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