Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(211)

Side by Side Diff: src/compiler/simplified-lowering.cc

Issue 2182003002: [turbofan] Fix overly aggressive dead code elimination. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add comments Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/compiler/typer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 void ChangeToInt32OverflowOp(Node* node) { 1068 void ChangeToInt32OverflowOp(Node* node) {
1069 NodeProperties::ChangeOp(node, Int32OverflowOp(node)); 1069 NodeProperties::ChangeOp(node, Int32OverflowOp(node));
1070 } 1070 }
1071 1071
1072 void ChangeToUint32OverflowOp(Node* node) { 1072 void ChangeToUint32OverflowOp(Node* node) {
1073 NodeProperties::ChangeOp(node, Uint32OverflowOp(node)); 1073 NodeProperties::ChangeOp(node, Uint32OverflowOp(node));
1074 } 1074 }
1075 1075
1076 void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation, 1076 void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation,
1077 SimplifiedLowering* lowering) { 1077 SimplifiedLowering* lowering) {
1078 if (truncation.IsUnused()) return VisitUnused(node); 1078 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we can
1079 // only eliminate an unused speculative number operation if we know that
1080 // the inputs are PlainPrimitive, which excludes everything that's might
1081 // have side effects or throws during a ToNumber conversion.
1082 if (BothInputsAre(node, Type::PlainPrimitive())) {
1083 if (truncation.IsUnused()) return VisitUnused(node);
1084 }
1079 if (BothInputsAre(node, type_cache_.kSigned32OrMinusZero) && 1085 if (BothInputsAre(node, type_cache_.kSigned32OrMinusZero) &&
1080 NodeProperties::GetType(node)->Is(Type::Signed32())) { 1086 NodeProperties::GetType(node)->Is(Type::Signed32())) {
1081 // int32 + int32 = int32 ==> signed Int32Add/Sub 1087 // int32 + int32 = int32 ==> signed Int32Add/Sub
1082 VisitInt32Binop(node); 1088 VisitInt32Binop(node);
1083 if (lower()) ChangeToPureOp(node, Int32Op(node)); 1089 if (lower()) ChangeToPureOp(node, Int32Op(node));
1084 return; 1090 return;
1085 } 1091 }
1086 1092
1087 // Use truncation if available. 1093 // Use truncation if available.
1088 if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) && 1094 if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) &&
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 return; 1135 return;
1130 } 1136 }
1131 1137
1132 // Dispatching routine for visiting the node {node} with the usage {use}. 1138 // Dispatching routine for visiting the node {node} with the usage {use}.
1133 // Depending on the operator, propagate new usage info to the inputs. 1139 // Depending on the operator, propagate new usage info to the inputs.
1134 void VisitNode(Node* node, Truncation truncation, 1140 void VisitNode(Node* node, Truncation truncation,
1135 SimplifiedLowering* lowering) { 1141 SimplifiedLowering* lowering) {
1136 // Unconditionally eliminate unused pure nodes (only relevant if there's 1142 // Unconditionally eliminate unused pure nodes (only relevant if there's
1137 // a pure operation in between two effectful ones, where the last one 1143 // a pure operation in between two effectful ones, where the last one
1138 // is unused). 1144 // is unused).
1139 if (node->op()->HasProperty(Operator::kPure) && truncation.IsUnused()) { 1145 // Note: We must not do this for constants, as they are cached and we
1140 return VisitUnused(node); 1146 // would thus kill the cached {node} during lowering (i.e. replace all
1147 // uses with Dead), but at that point some node lowering might have
1148 // already taken the constant {node} from the cache (while it was in
1149 // a sane state still) and we would afterwards replace that use with
1150 // Dead as well.
1151 if (node->op()->ValueInputCount() > 0 &&
1152 node->op()->HasProperty(Operator::kPure)) {
1153 if (truncation.IsUnused()) return VisitUnused(node);
1141 } 1154 }
1142 switch (node->opcode()) { 1155 switch (node->opcode()) {
1143 //------------------------------------------------------------------ 1156 //------------------------------------------------------------------
1144 // Common operators. 1157 // Common operators.
1145 //------------------------------------------------------------------ 1158 //------------------------------------------------------------------
1146 case IrOpcode::kStart: 1159 case IrOpcode::kStart:
1147 // We use Start as a terminator for the frame state chain, so even 1160 // We use Start as a terminator for the frame state chain, so even
1148 // tho Start doesn't really produce a value, we have to say Tagged 1161 // tho Start doesn't really produce a value, we have to say Tagged
1149 // here, otherwise the input conversion will fail. 1162 // here, otherwise the input conversion will fail.
1150 return VisitLeaf(node, MachineRepresentation::kTagged); 1163 return VisitLeaf(node, MachineRepresentation::kTagged);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1254 return; 1267 return;
1255 } 1268 }
1256 1269
1257 case IrOpcode::kSpeculativeNumberAdd: 1270 case IrOpcode::kSpeculativeNumberAdd:
1258 case IrOpcode::kSpeculativeNumberSubtract: 1271 case IrOpcode::kSpeculativeNumberSubtract:
1259 return VisitSpeculativeAdditiveOp(node, truncation, lowering); 1272 return VisitSpeculativeAdditiveOp(node, truncation, lowering);
1260 1273
1261 case IrOpcode::kSpeculativeNumberLessThan: 1274 case IrOpcode::kSpeculativeNumberLessThan:
1262 case IrOpcode::kSpeculativeNumberLessThanOrEqual: 1275 case IrOpcode::kSpeculativeNumberLessThanOrEqual:
1263 case IrOpcode::kSpeculativeNumberEqual: { 1276 case IrOpcode::kSpeculativeNumberEqual: {
1264 if (truncation.IsUnused()) return VisitUnused(node); 1277 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
1278 // can only eliminate an unused speculative number operation if we know
1279 // that the inputs are PlainPrimitive, which excludes everything that's
1280 // might have side effects or throws during a ToNumber conversion.
1281 if (BothInputsAre(node, Type::PlainPrimitive())) {
1282 if (truncation.IsUnused()) return VisitUnused(node);
1283 }
1265 // Number comparisons reduce to integer comparisons for integer inputs. 1284 // Number comparisons reduce to integer comparisons for integer inputs.
1266 if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) && 1285 if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) &&
1267 TypeOf(node->InputAt(1))->Is(Type::Unsigned32())) { 1286 TypeOf(node->InputAt(1))->Is(Type::Unsigned32())) {
1268 // => unsigned Int32Cmp 1287 // => unsigned Int32Cmp
1269 VisitUint32Cmp(node); 1288 VisitUint32Cmp(node);
1270 if (lower()) ChangeToPureOp(node, Uint32Op(node)); 1289 if (lower()) ChangeToPureOp(node, Uint32Op(node));
1271 return; 1290 return;
1272 } else if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) && 1291 } else if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) &&
1273 TypeOf(node->InputAt(1))->Is(Type::Signed32())) { 1292 TypeOf(node->InputAt(1))->Is(Type::Signed32())) {
1274 // => signed Int32Cmp 1293 // => signed Int32Cmp
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1309 VisitWord32TruncatingBinop(node); 1328 VisitWord32TruncatingBinop(node);
1310 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); 1329 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
1311 } else { 1330 } else {
1312 // => Float64Add/Sub 1331 // => Float64Add/Sub
1313 VisitFloat64Binop(node); 1332 VisitFloat64Binop(node);
1314 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); 1333 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
1315 } 1334 }
1316 return; 1335 return;
1317 } 1336 }
1318 case IrOpcode::kSpeculativeNumberMultiply: { 1337 case IrOpcode::kSpeculativeNumberMultiply: {
1319 if (truncation.IsUnused()) return VisitUnused(node); 1338 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
1339 // can only eliminate an unused speculative number operation if we know
1340 // that the inputs are PlainPrimitive, which excludes everything that's
1341 // might have side effects or throws during a ToNumber conversion.
1342 if (BothInputsAre(node, Type::PlainPrimitive())) {
1343 if (truncation.IsUnused()) return VisitUnused(node);
1344 }
1320 if (BothInputsAre(node, Type::Integral32()) && 1345 if (BothInputsAre(node, Type::Integral32()) &&
1321 (NodeProperties::GetType(node)->Is(Type::Signed32()) || 1346 (NodeProperties::GetType(node)->Is(Type::Signed32()) ||
1322 NodeProperties::GetType(node)->Is(Type::Unsigned32()) || 1347 NodeProperties::GetType(node)->Is(Type::Unsigned32()) ||
1323 (truncation.IsUsedAsWord32() && 1348 (truncation.IsUsedAsWord32() &&
1324 NodeProperties::GetType(node)->Is( 1349 NodeProperties::GetType(node)->Is(
1325 type_cache_.kSafeIntegerOrMinusZero)))) { 1350 type_cache_.kSafeIntegerOrMinusZero)))) {
1326 // Multiply reduces to Int32Mul if the inputs are integers, and 1351 // Multiply reduces to Int32Mul if the inputs are integers, and
1327 // (a) the output is either known to be Signed32, or 1352 // (a) the output is either known to be Signed32, or
1328 // (b) the output is known to be Unsigned32, or 1353 // (b) the output is known to be Unsigned32, or
1329 // (c) the uses are truncating and the result is in the safe 1354 // (c) the uses are truncating and the result is in the safe
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1384 VisitWord32TruncatingBinop(node); 1409 VisitWord32TruncatingBinop(node);
1385 if (lower()) ChangeToPureOp(node, Int32Op(node)); 1410 if (lower()) ChangeToPureOp(node, Int32Op(node));
1386 return; 1411 return;
1387 } 1412 }
1388 // Number x Number => Float64Mul 1413 // Number x Number => Float64Mul
1389 VisitFloat64Binop(node); 1414 VisitFloat64Binop(node);
1390 if (lower()) ChangeToPureOp(node, Float64Op(node)); 1415 if (lower()) ChangeToPureOp(node, Float64Op(node));
1391 return; 1416 return;
1392 } 1417 }
1393 case IrOpcode::kSpeculativeNumberDivide: { 1418 case IrOpcode::kSpeculativeNumberDivide: {
1394 if (truncation.IsUnused()) return VisitUnused(node); 1419 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
1420 // can only eliminate an unused speculative number operation if we know
1421 // that the inputs are PlainPrimitive, which excludes everything that's
1422 // might have side effects or throws during a ToNumber conversion.
1423 if (BothInputsAre(node, Type::PlainPrimitive())) {
1424 if (truncation.IsUnused()) return VisitUnused(node);
1425 }
1395 if (BothInputsAreUnsigned32(node) && truncation.IsUsedAsWord32()) { 1426 if (BothInputsAreUnsigned32(node) && truncation.IsUsedAsWord32()) {
1396 // => unsigned Uint32Div 1427 // => unsigned Uint32Div
1397 VisitWord32TruncatingBinop(node); 1428 VisitWord32TruncatingBinop(node);
1398 if (lower()) DeferReplacement(node, lowering->Uint32Div(node)); 1429 if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
1399 return; 1430 return;
1400 } 1431 }
1401 if (BothInputsAreSigned32(node)) { 1432 if (BothInputsAreSigned32(node)) {
1402 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { 1433 if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
1403 // => signed Int32Div 1434 // => signed Int32Div
1404 VisitInt32Binop(node); 1435 VisitInt32Binop(node);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1490 return; 1521 return;
1491 } 1522 }
1492 // Checked float64 x float64 => float64 1523 // Checked float64 x float64 => float64
1493 DCHECK_EQ(IrOpcode::kSpeculativeNumberDivide, node->opcode()); 1524 DCHECK_EQ(IrOpcode::kSpeculativeNumberDivide, node->opcode());
1494 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(), 1525 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
1495 MachineRepresentation::kFloat64, Type::Number()); 1526 MachineRepresentation::kFloat64, Type::Number());
1496 if (lower()) ChangeToPureOp(node, Float64Op(node)); 1527 if (lower()) ChangeToPureOp(node, Float64Op(node));
1497 return; 1528 return;
1498 } 1529 }
1499 case IrOpcode::kSpeculativeNumberModulus: { 1530 case IrOpcode::kSpeculativeNumberModulus: {
1500 if (truncation.IsUnused()) return VisitUnused(node); 1531 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
1532 // can only eliminate an unused speculative number operation if we know
1533 // that the inputs are PlainPrimitive, which excludes everything that's
1534 // might have side effects or throws during a ToNumber conversion.
1535 if (BothInputsAre(node, Type::PlainPrimitive())) {
1536 if (truncation.IsUnused()) return VisitUnused(node);
1537 }
1501 if (BothInputsAreUnsigned32(node) && truncation.IsUsedAsWord32()) { 1538 if (BothInputsAreUnsigned32(node) && truncation.IsUsedAsWord32()) {
1502 // => unsigned Uint32Mod 1539 // => unsigned Uint32Mod
1503 VisitWord32TruncatingBinop(node); 1540 VisitWord32TruncatingBinop(node);
1504 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); 1541 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
1505 return; 1542 return;
1506 } 1543 }
1507 if (BothInputsAreSigned32(node)) { 1544 if (BothInputsAreSigned32(node)) {
1508 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { 1545 if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
1509 // => signed Int32Mod 1546 // => signed Int32Mod
1510 VisitInt32Binop(node); 1547 VisitInt32Binop(node);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1604 case IrOpcode::kNumberShiftLeft: { 1641 case IrOpcode::kNumberShiftLeft: {
1605 Type* rhs_type = GetUpperBound(node->InputAt(1)); 1642 Type* rhs_type = GetUpperBound(node->InputAt(1));
1606 VisitBinop(node, UseInfo::TruncatingWord32(), 1643 VisitBinop(node, UseInfo::TruncatingWord32(),
1607 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32); 1644 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
1608 if (lower()) { 1645 if (lower()) {
1609 lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type); 1646 lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
1610 } 1647 }
1611 return; 1648 return;
1612 } 1649 }
1613 case IrOpcode::kSpeculativeNumberShiftLeft: { 1650 case IrOpcode::kSpeculativeNumberShiftLeft: {
1614 if (truncation.IsUnused()) return VisitUnused(node); 1651 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
1652 // can only eliminate an unused speculative number operation if we know
1653 // that the inputs are PlainPrimitive, which excludes everything that's
1654 // might have side effects or throws during a ToNumber conversion.
1655 if (BothInputsAre(node, Type::PlainPrimitive())) {
1656 if (truncation.IsUnused()) return VisitUnused(node);
1657 }
1615 if (BothInputsAre(node, Type::NumberOrOddball())) { 1658 if (BothInputsAre(node, Type::NumberOrOddball())) {
1616 Type* rhs_type = GetUpperBound(node->InputAt(1)); 1659 Type* rhs_type = GetUpperBound(node->InputAt(1));
1617 VisitBinop(node, UseInfo::TruncatingWord32(), 1660 VisitBinop(node, UseInfo::TruncatingWord32(),
1618 UseInfo::TruncatingWord32(), 1661 UseInfo::TruncatingWord32(),
1619 MachineRepresentation::kWord32); 1662 MachineRepresentation::kWord32);
1620 if (lower()) { 1663 if (lower()) {
1621 lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type); 1664 lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
1622 } 1665 }
1623 return; 1666 return;
1624 } 1667 }
(...skipping 1836 matching lines...) Expand 10 before | Expand all | Expand 10 after
3461 isolate(), graph()->zone(), callable.descriptor(), 0, flags, 3504 isolate(), graph()->zone(), callable.descriptor(), 0, flags,
3462 Operator::kNoProperties); 3505 Operator::kNoProperties);
3463 to_number_operator_.set(common()->Call(desc)); 3506 to_number_operator_.set(common()->Call(desc));
3464 } 3507 }
3465 return to_number_operator_.get(); 3508 return to_number_operator_.get();
3466 } 3509 }
3467 3510
3468 } // namespace compiler 3511 } // namespace compiler
3469 } // namespace internal 3512 } // namespace internal
3470 } // namespace v8 3513 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/typer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698