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 1364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1375 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1375 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
1376 return; | 1376 return; |
1377 } | 1377 } |
1378 // Checked float64 x float64 => float64 | 1378 // Checked float64 x float64 => float64 |
1379 DCHECK_EQ(IrOpcode::kSpeculativeNumberMultiply, node->opcode()); | 1379 DCHECK_EQ(IrOpcode::kSpeculativeNumberMultiply, node->opcode()); |
1380 VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(), | 1380 VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(), |
1381 MachineRepresentation::kFloat64, TypeCheckKind::kNumber); | 1381 MachineRepresentation::kFloat64, TypeCheckKind::kNumber); |
1382 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1382 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
1383 return; | 1383 return; |
1384 } | 1384 } |
1385 case IrOpcode::kSpeculativeNumberDivide: | 1385 case IrOpcode::kSpeculativeNumberDivide: { |
1386 case IrOpcode::kNumberDivide: { | 1386 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { |
| 1387 // => unsigned Uint32Div |
| 1388 VisitWord32TruncatingBinop(node); |
| 1389 if (lower()) DeferReplacement(node, lowering->Uint32Div(node)); |
| 1390 return; |
| 1391 } |
1387 if (BothInputsAreSigned32(node)) { | 1392 if (BothInputsAreSigned32(node)) { |
1388 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { | 1393 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { |
1389 // => signed Int32Div | 1394 // => signed Int32Div |
1390 VisitInt32Binop(node); | 1395 VisitInt32Binop(node); |
1391 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); | 1396 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); |
1392 return; | 1397 return; |
1393 } | 1398 } |
1394 if (truncation.TruncatesToWord32()) { | 1399 if (truncation.TruncatesToWord32()) { |
1395 // => signed Int32Div | 1400 // => signed Int32Div |
1396 VisitWord32TruncatingBinop(node); | 1401 VisitWord32TruncatingBinop(node); |
1397 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); | 1402 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); |
1398 return; | 1403 return; |
1399 } | 1404 } |
1400 } | 1405 } |
| 1406 |
| 1407 // Try to use type feedback. |
| 1408 BinaryOperationHints::Hint hint = BinaryOperationHintOf(node->op()); |
| 1409 |
| 1410 // Handle the case when no int32 checks on inputs are necessary |
| 1411 // (but an overflow check is needed on the output). |
| 1412 if (BothInputsAre(node, Type::Signed32())) { |
| 1413 // If both the inputs the feedback are int32, use the overflow op. |
| 1414 if (hint == BinaryOperationHints::kSignedSmall || |
| 1415 hint == BinaryOperationHints::kSigned32) { |
| 1416 VisitBinop(node, UseInfo::TruncatingWord32(), |
| 1417 MachineRepresentation::kWord32, |
| 1418 TypeCheckKind::kSigned32); |
| 1419 if (lower()) ChangeToInt32OverflowOp(node, Int32OverflowOp(node)); |
| 1420 return; |
| 1421 } |
| 1422 } |
| 1423 |
| 1424 if (hint == BinaryOperationHints::kSignedSmall || |
| 1425 hint == BinaryOperationHints::kSigned32) { |
| 1426 // If the result is truncated, we only need to check the inputs. |
| 1427 if (truncation.TruncatesToWord32()) { |
| 1428 VisitBinop(node, UseInfo::CheckedSigned32AsWord32(), |
| 1429 MachineRepresentation::kWord32); |
| 1430 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); |
| 1431 } else { |
| 1432 VisitBinop(node, UseInfo::CheckedSigned32AsWord32(), |
| 1433 MachineRepresentation::kWord32, |
| 1434 TypeCheckKind::kSigned32); |
| 1435 if (lower()) ChangeToInt32OverflowOp(node, Int32OverflowOp(node)); |
| 1436 } |
| 1437 return; |
| 1438 } |
| 1439 |
| 1440 // default case => Float64Div |
| 1441 VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(), |
| 1442 MachineRepresentation::kFloat64, TypeCheckKind::kNumber); |
| 1443 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
| 1444 return; |
| 1445 } |
| 1446 case IrOpcode::kNumberDivide: { |
1401 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { | 1447 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { |
1402 // => unsigned Uint32Div | 1448 // => unsigned Uint32Div |
1403 VisitWord32TruncatingBinop(node); | 1449 VisitWord32TruncatingBinop(node); |
1404 if (lower()) DeferReplacement(node, lowering->Uint32Div(node)); | 1450 if (lower()) DeferReplacement(node, lowering->Uint32Div(node)); |
1405 return; | 1451 return; |
1406 } | 1452 } |
| 1453 if (BothInputsAreSigned32(node)) { |
| 1454 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { |
| 1455 // => signed Int32Div |
| 1456 VisitInt32Binop(node); |
| 1457 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); |
| 1458 return; |
| 1459 } |
| 1460 if (truncation.TruncatesToWord32()) { |
| 1461 // => signed Int32Div |
| 1462 VisitWord32TruncatingBinop(node); |
| 1463 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); |
| 1464 return; |
| 1465 } |
| 1466 } |
1407 // Number x Number => Float64Div | 1467 // Number x Number => Float64Div |
1408 if (BothInputsAre(node, Type::NumberOrUndefined())) { | 1468 if (BothInputsAre(node, Type::NumberOrUndefined())) { |
1409 VisitFloat64Binop(node); | 1469 VisitFloat64Binop(node); |
1410 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1470 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
1411 return; | 1471 return; |
1412 } | 1472 } |
1413 // Checked float64 x float64 => float64 | 1473 // Checked float64 x float64 => float64 |
1414 DCHECK_EQ(IrOpcode::kSpeculativeNumberDivide, node->opcode()); | 1474 DCHECK_EQ(IrOpcode::kSpeculativeNumberDivide, node->opcode()); |
1415 VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(), | 1475 VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(), |
1416 MachineRepresentation::kFloat64, TypeCheckKind::kNumber); | 1476 MachineRepresentation::kFloat64, TypeCheckKind::kNumber); |
1417 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1477 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
1418 return; | 1478 return; |
1419 } | 1479 } |
1420 case IrOpcode::kSpeculativeNumberModulus: | 1480 case IrOpcode::kSpeculativeNumberModulus: { |
1421 case IrOpcode::kNumberModulus: { | 1481 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { |
| 1482 // => unsigned Uint32Mod |
| 1483 VisitWord32TruncatingBinop(node); |
| 1484 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); |
| 1485 return; |
| 1486 } |
1422 if (BothInputsAreSigned32(node)) { | 1487 if (BothInputsAreSigned32(node)) { |
1423 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { | 1488 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { |
1424 // => signed Int32Mod | 1489 // => signed Int32Mod |
1425 VisitInt32Binop(node); | 1490 VisitInt32Binop(node); |
1426 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); | 1491 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); |
1427 return; | 1492 return; |
1428 } | 1493 } |
1429 if (truncation.TruncatesToWord32()) { | 1494 if (truncation.TruncatesToWord32()) { |
1430 // => signed Int32Mod | 1495 // => signed Int32Mod |
1431 VisitWord32TruncatingBinop(node); | 1496 VisitWord32TruncatingBinop(node); |
1432 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); | 1497 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); |
1433 return; | 1498 return; |
1434 } | 1499 } |
1435 } | 1500 } |
| 1501 |
| 1502 // Try to use type feedback. |
| 1503 BinaryOperationHints::Hint hint = BinaryOperationHintOf(node->op()); |
| 1504 |
| 1505 // Handle the case when no int32 checks on inputs are necessary |
| 1506 // (but an overflow check is needed on the output). |
| 1507 if (BothInputsAre(node, Type::Signed32())) { |
| 1508 // If both the inputs the feedback are int32, use the overflow op. |
| 1509 if (hint == BinaryOperationHints::kSignedSmall || |
| 1510 hint == BinaryOperationHints::kSigned32) { |
| 1511 VisitBinop(node, UseInfo::TruncatingWord32(), |
| 1512 MachineRepresentation::kWord32, |
| 1513 TypeCheckKind::kSigned32); |
| 1514 if (lower()) ChangeToInt32OverflowOp(node, Int32OverflowOp(node)); |
| 1515 return; |
| 1516 } |
| 1517 } |
| 1518 |
| 1519 if (hint == BinaryOperationHints::kSignedSmall || |
| 1520 hint == BinaryOperationHints::kSigned32) { |
| 1521 // If the result is truncated, we only need to check the inputs. |
| 1522 if (truncation.TruncatesToWord32()) { |
| 1523 VisitBinop(node, UseInfo::CheckedSigned32AsWord32(), |
| 1524 MachineRepresentation::kWord32); |
| 1525 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); |
| 1526 } else { |
| 1527 VisitBinop(node, UseInfo::CheckedSigned32AsWord32(), |
| 1528 MachineRepresentation::kWord32, |
| 1529 TypeCheckKind::kSigned32); |
| 1530 if (lower()) ChangeToInt32OverflowOp(node, Int32OverflowOp(node)); |
| 1531 } |
| 1532 return; |
| 1533 } |
| 1534 |
| 1535 // default case => Float64Mod |
| 1536 VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(), |
| 1537 MachineRepresentation::kFloat64, TypeCheckKind::kNumber); |
| 1538 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
| 1539 return; |
| 1540 } |
| 1541 case IrOpcode::kNumberModulus: { |
1436 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { | 1542 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { |
1437 // => unsigned Uint32Mod | 1543 // => unsigned Uint32Mod |
1438 VisitWord32TruncatingBinop(node); | 1544 VisitWord32TruncatingBinop(node); |
1439 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); | 1545 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); |
1440 return; | 1546 return; |
1441 } | 1547 } |
1442 // Number x Number => Float64Mod | 1548 if (BothInputsAreSigned32(node)) { |
1443 if (BothInputsAre(node, Type::NumberOrUndefined())) { | 1549 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { |
1444 // => Float64Mod | 1550 // => signed Int32Mod |
1445 VisitFloat64Binop(node); | 1551 VisitInt32Binop(node); |
1446 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1552 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); |
1447 return; | 1553 return; |
| 1554 } |
| 1555 if (truncation.TruncatesToWord32()) { |
| 1556 // => signed Int32Mod |
| 1557 VisitWord32TruncatingBinop(node); |
| 1558 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); |
| 1559 return; |
| 1560 } |
1448 } | 1561 } |
1449 // Checked float64 x float64 => float64 | 1562 // => Float64Mod |
1450 DCHECK_EQ(IrOpcode::kSpeculativeNumberModulus, node->opcode()); | 1563 VisitFloat64Binop(node); |
1451 VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(), | |
1452 MachineRepresentation::kFloat64, TypeCheckKind::kNumber); | |
1453 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1564 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
1454 return; | 1565 return; |
1455 } | 1566 } |
1456 case IrOpcode::kNumberBitwiseOr: | 1567 case IrOpcode::kNumberBitwiseOr: |
1457 case IrOpcode::kNumberBitwiseXor: | 1568 case IrOpcode::kNumberBitwiseXor: |
1458 case IrOpcode::kNumberBitwiseAnd: { | 1569 case IrOpcode::kNumberBitwiseAnd: { |
1459 VisitInt32Binop(node); | 1570 VisitInt32Binop(node); |
1460 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); | 1571 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
1461 return; | 1572 return; |
1462 } | 1573 } |
(...skipping 1689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3152 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3263 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
3153 Operator::kNoProperties); | 3264 Operator::kNoProperties); |
3154 to_number_operator_.set(common()->Call(desc)); | 3265 to_number_operator_.set(common()->Call(desc)); |
3155 } | 3266 } |
3156 return to_number_operator_.get(); | 3267 return to_number_operator_.get(); |
3157 } | 3268 } |
3158 | 3269 |
3159 } // namespace compiler | 3270 } // namespace compiler |
3160 } // namespace internal | 3271 } // namespace internal |
3161 } // namespace v8 | 3272 } // namespace v8 |
OLD | NEW |