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 |