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

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

Issue 2202413002: [turbofan] Improve typing rule for modulus. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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 | « src/compiler/operation-typer.cc ('k') | src/type-cache.h » ('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 659 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/operation-typer.cc ('k') | src/type-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698