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 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 670 bool BothInputsAreUnsigned32(Node* node) { | 670 bool BothInputsAreUnsigned32(Node* node) { |
| 671 return BothInputsAre(node, Type::Unsigned32()); | 671 return BothInputsAre(node, Type::Unsigned32()); |
| 672 } | 672 } |
| 673 | 673 |
| 674 bool BothInputsAre(Node* node, Type* type) { | 674 bool BothInputsAre(Node* node, Type* type) { |
| 675 DCHECK_EQ(2, node->op()->ValueInputCount()); | 675 DCHECK_EQ(2, node->op()->ValueInputCount()); |
| 676 return GetUpperBound(node->InputAt(0))->Is(type) && | 676 return GetUpperBound(node->InputAt(0))->Is(type) && |
| 677 GetUpperBound(node->InputAt(1))->Is(type); | 677 GetUpperBound(node->InputAt(1))->Is(type); |
| 678 } | 678 } |
| 679 | 679 |
| 680 bool OneInputCannotBe(Node* node, Type* type) { | |
|
Jarin
2016/08/02 20:02:09
I have to say this: Somehow, I see you adding new
| |
| 681 DCHECK_EQ(2, node->op()->ValueInputCount()); | |
| 682 return !GetUpperBound(node->InputAt(0))->Maybe(type) || | |
| 683 !GetUpperBound(node->InputAt(1))->Maybe(type); | |
| 684 } | |
| 685 | |
| 680 void ConvertInput(Node* node, int index, UseInfo use) { | 686 void ConvertInput(Node* node, int index, UseInfo use) { |
| 681 Node* input = node->InputAt(index); | 687 Node* input = node->InputAt(index); |
| 682 // In the change phase, insert a change before the use if necessary. | 688 // In the change phase, insert a change before the use if necessary. |
| 683 if (use.representation() == MachineRepresentation::kNone) | 689 if (use.representation() == MachineRepresentation::kNone) |
| 684 return; // No input requirement on the use. | 690 return; // No input requirement on the use. |
| 685 DCHECK_NOT_NULL(input); | 691 DCHECK_NOT_NULL(input); |
| 686 NodeInfo* input_info = GetInfo(input); | 692 NodeInfo* input_info = GetInfo(input); |
| 687 MachineRepresentation input_rep = input_info->representation(); | 693 MachineRepresentation input_rep = input_info->representation(); |
| 688 if (input_rep != use.representation() || | 694 if (input_rep != use.representation() || |
| 689 use.type_check() != TypeCheckKind::kNone) { | 695 use.type_check() != TypeCheckKind::kNone) { |
| (...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1283 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant()); | 1289 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant()); |
| 1284 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); | 1290 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
| 1285 } | 1291 } |
| 1286 } else { | 1292 } else { |
| 1287 // No input representation requirement; adapt during lowering. | 1293 // No input representation requirement; adapt during lowering. |
| 1288 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); | 1294 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); |
| 1289 SetOutput(node, MachineRepresentation::kBit); | 1295 SetOutput(node, MachineRepresentation::kBit); |
| 1290 } | 1296 } |
| 1291 return; | 1297 return; |
| 1292 } | 1298 } |
| 1293 case IrOpcode::kNumberEqual: | 1299 case IrOpcode::kNumberEqual: { |
| 1300 // Number comparisons reduce to integer comparisons for integer inputs. | |
| 1301 if ((TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) && | |
| 1302 TypeOf(node->InputAt(1))->Is(Type::Unsigned32())) || | |
| 1303 (BothInputsAre(node, type_cache_.kUnsigned32OrMinusZeroOrNaN) && | |
| 1304 OneInputCannotBe(node, type_cache_.kZeroish))) { | |
| 1305 // => unsigned Int32Cmp | |
| 1306 VisitUint32Cmp(node); | |
| 1307 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); | |
| 1308 return; | |
| 1309 } | |
| 1310 if ((TypeOf(node->InputAt(0))->Is(Type::Signed32()) && | |
| 1311 TypeOf(node->InputAt(1))->Is(Type::Signed32())) || | |
| 1312 (BothInputsAre(node, type_cache_.kSigned32OrMinusZeroOrNaN) && | |
| 1313 OneInputCannotBe(node, type_cache_.kZeroish))) { | |
| 1314 // => signed Int32Cmp | |
| 1315 VisitInt32Cmp(node); | |
| 1316 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); | |
| 1317 return; | |
| 1318 } | |
| 1319 // => Float64Cmp | |
| 1320 VisitFloat64Cmp(node); | |
| 1321 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); | |
| 1322 return; | |
| 1323 } | |
| 1294 case IrOpcode::kNumberLessThan: | 1324 case IrOpcode::kNumberLessThan: |
| 1295 case IrOpcode::kNumberLessThanOrEqual: { | 1325 case IrOpcode::kNumberLessThanOrEqual: { |
| 1296 // Number comparisons reduce to integer comparisons for integer inputs. | 1326 // Number comparisons reduce to integer comparisons for integer inputs. |
| 1297 if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) && | 1327 if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) && |
| 1298 TypeOf(node->InputAt(1))->Is(Type::Unsigned32())) { | 1328 TypeOf(node->InputAt(1))->Is(Type::Unsigned32())) { |
| 1299 // => unsigned Int32Cmp | 1329 // => unsigned Int32Cmp |
| 1300 VisitUint32Cmp(node); | 1330 VisitUint32Cmp(node); |
| 1301 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); | 1331 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); |
| 1302 } else if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) && | 1332 } else if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) && |
| 1303 TypeOf(node->InputAt(1))->Is(Type::Signed32())) { | 1333 TypeOf(node->InputAt(1))->Is(Type::Signed32())) { |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1573 return; | 1603 return; |
| 1574 } | 1604 } |
| 1575 case IrOpcode::kSpeculativeNumberModulus: { | 1605 case IrOpcode::kSpeculativeNumberModulus: { |
| 1576 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we | 1606 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we |
| 1577 // can only eliminate an unused speculative number operation if we know | 1607 // can only eliminate an unused speculative number operation if we know |
| 1578 // that the inputs are PlainPrimitive, which excludes everything that's | 1608 // that the inputs are PlainPrimitive, which excludes everything that's |
| 1579 // might have side effects or throws during a ToNumber conversion. | 1609 // might have side effects or throws during a ToNumber conversion. |
| 1580 if (BothInputsAre(node, Type::PlainPrimitive())) { | 1610 if (BothInputsAre(node, Type::PlainPrimitive())) { |
| 1581 if (truncation.IsUnused()) return VisitUnused(node); | 1611 if (truncation.IsUnused()) return VisitUnused(node); |
| 1582 } | 1612 } |
| 1583 if (BothInputsAreUnsigned32(node) && truncation.IsUsedAsWord32()) { | 1613 if (BothInputsAre(node, type_cache_.kUnsigned32OrMinusZeroOrNaN) && |
| 1614 (truncation.IsUsedAsWord32() || | |
| 1615 NodeProperties::GetType(node)->Is(Type::Unsigned32()))) { | |
| 1584 // => unsigned Uint32Mod | 1616 // => unsigned Uint32Mod |
| 1585 VisitWord32TruncatingBinop(node); | 1617 VisitWord32TruncatingBinop(node); |
| 1586 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); | 1618 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); |
| 1587 return; | 1619 return; |
| 1588 } | 1620 } |
| 1589 if (BothInputsAreSigned32(node)) { | 1621 if (BothInputsAre(node, type_cache_.kSigned32OrMinusZeroOrNaN) && |
| 1590 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { | 1622 (truncation.IsUsedAsWord32() || |
| 1591 // => signed Int32Mod | 1623 NodeProperties::GetType(node)->Is(Type::Signed32()))) { |
| 1592 VisitInt32Binop(node); | 1624 // => signed Int32Mod |
| 1593 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); | 1625 VisitWord32TruncatingBinop(node); |
| 1594 return; | 1626 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); |
| 1595 } | 1627 return; |
| 1596 if (truncation.IsUsedAsWord32()) { | |
| 1597 // => signed Int32Mod | |
| 1598 VisitWord32TruncatingBinop(node); | |
| 1599 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); | |
| 1600 return; | |
| 1601 } | |
| 1602 } | 1628 } |
| 1603 | 1629 |
| 1604 // Try to use type feedback. | 1630 // Try to use type feedback. |
| 1605 BinaryOperationHints::Hint hint = BinaryOperationHintOf(node->op()); | 1631 BinaryOperationHints::Hint hint = BinaryOperationHintOf(node->op()); |
| 1606 | 1632 |
| 1607 // Handle the case when no uint32 checks on inputs are necessary | 1633 // Handle the case when no uint32 checks on inputs are necessary |
| 1608 // (but an overflow check is needed on the output). | 1634 // (but an overflow check is needed on the output). |
| 1609 if (BothInputsAreUnsigned32(node)) { | 1635 if (BothInputsAreUnsigned32(node)) { |
| 1610 if (hint == BinaryOperationHints::kSignedSmall || | 1636 if (hint == BinaryOperationHints::kSignedSmall || |
| 1611 hint == BinaryOperationHints::kSigned32) { | 1637 hint == BinaryOperationHints::kSigned32) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1644 return; | 1670 return; |
| 1645 } | 1671 } |
| 1646 | 1672 |
| 1647 // default case => Float64Mod | 1673 // default case => Float64Mod |
| 1648 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(), | 1674 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(), |
| 1649 MachineRepresentation::kFloat64, Type::Number()); | 1675 MachineRepresentation::kFloat64, Type::Number()); |
| 1650 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1676 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
| 1651 return; | 1677 return; |
| 1652 } | 1678 } |
| 1653 case IrOpcode::kNumberModulus: { | 1679 case IrOpcode::kNumberModulus: { |
| 1654 if (BothInputsAreUnsigned32(node) && truncation.IsUsedAsWord32()) { | 1680 if (BothInputsAre(node, type_cache_.kUnsigned32OrMinusZeroOrNaN) && |
| 1681 (truncation.IsUsedAsWord32() || | |
| 1682 NodeProperties::GetType(node)->Is(Type::Unsigned32()))) { | |
| 1655 // => unsigned Uint32Mod | 1683 // => unsigned Uint32Mod |
| 1656 VisitWord32TruncatingBinop(node); | 1684 VisitWord32TruncatingBinop(node); |
| 1657 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); | 1685 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); |
| 1658 return; | 1686 return; |
| 1659 } | 1687 } |
| 1660 if (BothInputsAreSigned32(node)) { | 1688 if (BothInputsAre(node, type_cache_.kSigned32OrMinusZeroOrNaN) && |
| 1661 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { | 1689 (truncation.IsUsedAsWord32() || |
| 1662 // => signed Int32Mod | 1690 NodeProperties::GetType(node)->Is(Type::Signed32()))) { |
| 1663 VisitInt32Binop(node); | 1691 // => signed Int32Mod |
| 1664 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); | 1692 VisitWord32TruncatingBinop(node); |
| 1665 return; | 1693 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); |
| 1666 } | 1694 return; |
| 1667 if (truncation.IsUsedAsWord32()) { | |
| 1668 // => signed Int32Mod | |
| 1669 VisitWord32TruncatingBinop(node); | |
| 1670 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); | |
| 1671 return; | |
| 1672 } | |
| 1673 } | 1695 } |
| 1674 // => Float64Mod | 1696 // => Float64Mod |
| 1675 VisitFloat64Binop(node); | 1697 VisitFloat64Binop(node); |
| 1676 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1698 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
| 1677 return; | 1699 return; |
| 1678 } | 1700 } |
| 1679 case IrOpcode::kNumberBitwiseOr: | 1701 case IrOpcode::kNumberBitwiseOr: |
| 1680 case IrOpcode::kNumberBitwiseXor: | 1702 case IrOpcode::kNumberBitwiseXor: |
| 1681 case IrOpcode::kNumberBitwiseAnd: { | 1703 case IrOpcode::kNumberBitwiseAnd: { |
| 1682 VisitInt32Binop(node); | 1704 VisitInt32Binop(node); |
| (...skipping 1959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3642 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3664 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
| 3643 Operator::kNoProperties); | 3665 Operator::kNoProperties); |
| 3644 to_number_operator_.set(common()->Call(desc)); | 3666 to_number_operator_.set(common()->Call(desc)); |
| 3645 } | 3667 } |
| 3646 return to_number_operator_.get(); | 3668 return to_number_operator_.get(); |
| 3647 } | 3669 } |
| 3648 | 3670 |
| 3649 } // namespace compiler | 3671 } // namespace compiler |
| 3650 } // namespace internal | 3672 } // namespace internal |
| 3651 } // namespace v8 | 3673 } // namespace v8 |
| OLD | NEW |