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 |