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

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

Issue 2287303002: [turbofan] More efficient code generation for unsigned modulus. (Closed)
Patch Set: Created 4 years, 3 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 | no next file » | 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 1157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 1168
1169 // default case => Float64Add/Sub 1169 // default case => Float64Add/Sub
1170 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(), 1170 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
1171 MachineRepresentation::kFloat64, Type::Number()); 1171 MachineRepresentation::kFloat64, Type::Number());
1172 if (lower()) { 1172 if (lower()) {
1173 ChangeToPureOp(node, Float64Op(node)); 1173 ChangeToPureOp(node, Float64Op(node));
1174 } 1174 }
1175 return; 1175 return;
1176 } 1176 }
1177 1177
1178 void VisitSpeculativeNumberModulus(Node* node, Truncation truncation,
1179 SimplifiedLowering* lowering) {
1180 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
1181 // can only eliminate an unused speculative number operation if we know
1182 // that the inputs are PlainPrimitive, which excludes everything that's
1183 // might have side effects or throws during a ToNumber conversion.
1184 if (BothInputsAre(node, Type::PlainPrimitive())) {
1185 if (truncation.IsUnused()) return VisitUnused(node);
1186 }
1187 if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) &&
1188 (truncation.IsUsedAsWord32() ||
1189 NodeProperties::GetType(node)->Is(Type::Unsigned32()))) {
1190 // => unsigned Uint32Mod
1191 VisitWord32TruncatingBinop(node);
1192 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
1193 return;
1194 }
1195 if (BothInputsAre(node, Type::Signed32OrMinusZeroOrNaN()) &&
1196 (truncation.IsUsedAsWord32() ||
1197 NodeProperties::GetType(node)->Is(Type::Signed32()))) {
1198 // => signed Int32Mod
1199 VisitWord32TruncatingBinop(node);
1200 if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
1201 return;
1202 }
1203
1204 // Try to use type feedback.
1205 NumberOperationHint hint = NumberOperationHintOf(node->op());
1206
1207 // Handle the case when no uint32 checks on inputs are necessary
1208 // (but an overflow check is needed on the output).
1209 if (BothInputsAreUnsigned32(node)) {
1210 if (hint == NumberOperationHint::kSignedSmall ||
1211 hint == NumberOperationHint::kSigned32) {
1212 VisitBinop(node, UseInfo::TruncatingWord32(),
1213 MachineRepresentation::kWord32, Type::Unsigned32());
1214 if (lower()) ChangeToUint32OverflowOp(node);
1215 return;
1216 }
1217 }
1218
1219 // Handle the case when no int32 checks on inputs are necessary
1220 // (but an overflow check is needed on the output).
1221 if (BothInputsAre(node, Type::Signed32())) {
1222 // If both the inputs the feedback are int32, use the overflow op.
1223 if (hint == NumberOperationHint::kSignedSmall ||
1224 hint == NumberOperationHint::kSigned32) {
1225 VisitBinop(node, UseInfo::TruncatingWord32(),
1226 MachineRepresentation::kWord32, Type::Signed32());
1227 if (lower()) ChangeToInt32OverflowOp(node);
1228 return;
1229 }
1230 }
1231
1232 if (hint == NumberOperationHint::kSignedSmall ||
1233 hint == NumberOperationHint::kSigned32) {
1234 // If the result is truncated, we only need to check the inputs.
1235 if (truncation.IsUsedAsWord32()) {
1236 VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
1237 MachineRepresentation::kWord32);
1238 if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
1239 } else if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN())) {
1240 VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
1241 MachineRepresentation::kWord32, Type::Unsigned32());
1242 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
1243 } else {
1244 VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
1245 MachineRepresentation::kWord32, Type::Signed32());
1246 if (lower()) ChangeToInt32OverflowOp(node);
1247 }
1248 return;
1249 }
1250
1251 if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) &&
1252 TypeOf(node->InputAt(1))->Is(Type::Unsigned32()) &&
1253 (truncation.IsUsedAsWord32() ||
1254 NodeProperties::GetType(node)->Is(Type::Unsigned32()))) {
1255 // We can only promise Float64 truncation here, as the decision is
1256 // based on the feedback types of the inputs.
1257 VisitBinop(node,
1258 UseInfo(MachineRepresentation::kWord32, Truncation::Float64()),
1259 MachineRepresentation::kWord32);
1260 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
1261 return;
1262 }
1263 if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) &&
1264 TypeOf(node->InputAt(1))->Is(Type::Signed32()) &&
1265 (truncation.IsUsedAsWord32() ||
1266 NodeProperties::GetType(node)->Is(Type::Signed32()))) {
1267 // We can only promise Float64 truncation here, as the decision is
1268 // based on the feedback types of the inputs.
1269 VisitBinop(node,
1270 UseInfo(MachineRepresentation::kWord32, Truncation::Float64()),
1271 MachineRepresentation::kWord32);
1272 if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
1273 return;
1274 }
1275 // default case => Float64Mod
1276 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
1277 MachineRepresentation::kFloat64, Type::Number());
1278 if (lower()) ChangeToPureOp(node, Float64Op(node));
1279 return;
1280 }
1281
1178 // Dispatching routine for visiting the node {node} with the usage {use}. 1282 // Dispatching routine for visiting the node {node} with the usage {use}.
1179 // Depending on the operator, propagate new usage info to the inputs. 1283 // Depending on the operator, propagate new usage info to the inputs.
1180 void VisitNode(Node* node, Truncation truncation, 1284 void VisitNode(Node* node, Truncation truncation,
1181 SimplifiedLowering* lowering) { 1285 SimplifiedLowering* lowering) {
1182 // Unconditionally eliminate unused pure nodes (only relevant if there's 1286 // Unconditionally eliminate unused pure nodes (only relevant if there's
1183 // a pure operation in between two effectful ones, where the last one 1287 // a pure operation in between two effectful ones, where the last one
1184 // is unused). 1288 // is unused).
1185 // Note: We must not do this for constants, as they are cached and we 1289 // Note: We must not do this for constants, as they are cached and we
1186 // would thus kill the cached {node} during lowering (i.e. replace all 1290 // would thus kill the cached {node} during lowering (i.e. replace all
1187 // uses with Dead), but at that point some node lowering might have 1291 // uses with Dead), but at that point some node lowering might have
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
1585 if (lower()) ChangeToPureOp(node, Float64Op(node)); 1689 if (lower()) ChangeToPureOp(node, Float64Op(node));
1586 return; 1690 return;
1587 } 1691 }
1588 // Checked float64 x float64 => float64 1692 // Checked float64 x float64 => float64
1589 DCHECK_EQ(IrOpcode::kSpeculativeNumberDivide, node->opcode()); 1693 DCHECK_EQ(IrOpcode::kSpeculativeNumberDivide, node->opcode());
1590 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(), 1694 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
1591 MachineRepresentation::kFloat64, Type::Number()); 1695 MachineRepresentation::kFloat64, Type::Number());
1592 if (lower()) ChangeToPureOp(node, Float64Op(node)); 1696 if (lower()) ChangeToPureOp(node, Float64Op(node));
1593 return; 1697 return;
1594 } 1698 }
1595 case IrOpcode::kSpeculativeNumberModulus: { 1699 case IrOpcode::kSpeculativeNumberModulus:
1596 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we 1700 return VisitSpeculativeNumberModulus(node, truncation, lowering);
1597 // can only eliminate an unused speculative number operation if we know
1598 // that the inputs are PlainPrimitive, which excludes everything that's
1599 // might have side effects or throws during a ToNumber conversion.
1600 if (BothInputsAre(node, Type::PlainPrimitive())) {
1601 if (truncation.IsUnused()) return VisitUnused(node);
1602 }
1603 if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) &&
1604 (truncation.IsUsedAsWord32() ||
1605 NodeProperties::GetType(node)->Is(Type::Unsigned32()))) {
1606 // => unsigned Uint32Mod
1607 VisitWord32TruncatingBinop(node);
1608 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
1609 return;
1610 }
1611 if (BothInputsAre(node, Type::Signed32OrMinusZeroOrNaN()) &&
1612 (truncation.IsUsedAsWord32() ||
1613 NodeProperties::GetType(node)->Is(Type::Signed32()))) {
1614 // => signed Int32Mod
1615 VisitWord32TruncatingBinop(node);
1616 if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
1617 return;
1618 }
1619
1620 // Try to use type feedback.
1621 NumberOperationHint hint = NumberOperationHintOf(node->op());
1622
1623 // Handle the case when no uint32 checks on inputs are necessary
1624 // (but an overflow check is needed on the output).
1625 if (BothInputsAreUnsigned32(node)) {
1626 if (hint == NumberOperationHint::kSignedSmall ||
1627 hint == NumberOperationHint::kSigned32) {
1628 VisitBinop(node, UseInfo::TruncatingWord32(),
1629 MachineRepresentation::kWord32, Type::Unsigned32());
1630 if (lower()) ChangeToUint32OverflowOp(node);
1631 return;
1632 }
1633 }
1634
1635 // Handle the case when no int32 checks on inputs are necessary
1636 // (but an overflow check is needed on the output).
1637 if (BothInputsAre(node, Type::Signed32())) {
1638 // If both the inputs the feedback are int32, use the overflow op.
1639 if (hint == NumberOperationHint::kSignedSmall ||
1640 hint == NumberOperationHint::kSigned32) {
1641 VisitBinop(node, UseInfo::TruncatingWord32(),
1642 MachineRepresentation::kWord32, Type::Signed32());
1643 if (lower()) ChangeToInt32OverflowOp(node);
1644 return;
1645 }
1646 }
1647
1648 if (hint == NumberOperationHint::kSignedSmall ||
1649 hint == NumberOperationHint::kSigned32) {
1650 // If the result is truncated, we only need to check the inputs.
1651 if (truncation.IsUsedAsWord32()) {
1652 VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
1653 MachineRepresentation::kWord32);
1654 if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
1655 } else {
1656 VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
1657 MachineRepresentation::kWord32, Type::Signed32());
1658 if (lower()) ChangeToInt32OverflowOp(node);
1659 }
1660 return;
1661 }
1662
1663 if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) &&
1664 TypeOf(node->InputAt(1))->Is(Type::Unsigned32()) &&
1665 (truncation.IsUsedAsWord32() ||
1666 NodeProperties::GetType(node)->Is(Type::Unsigned32()))) {
1667 // We can only promise Float64 truncation here, as the decision is
1668 // based on the feedback types of the inputs.
1669 VisitBinop(node, UseInfo(MachineRepresentation::kWord32,
1670 Truncation::Float64()),
1671 MachineRepresentation::kWord32);
1672 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
1673 return;
1674 }
1675 if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) &&
1676 TypeOf(node->InputAt(1))->Is(Type::Signed32()) &&
1677 (truncation.IsUsedAsWord32() ||
1678 NodeProperties::GetType(node)->Is(Type::Signed32()))) {
1679 // We can only promise Float64 truncation here, as the decision is
1680 // based on the feedback types of the inputs.
1681 VisitBinop(node, UseInfo(MachineRepresentation::kWord32,
1682 Truncation::Float64()),
1683 MachineRepresentation::kWord32);
1684 if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
1685 return;
1686 }
1687 // default case => Float64Mod
1688 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
1689 MachineRepresentation::kFloat64, Type::Number());
1690 if (lower()) ChangeToPureOp(node, Float64Op(node));
1691 return;
1692 }
1693 case IrOpcode::kNumberModulus: { 1701 case IrOpcode::kNumberModulus: {
1694 if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) && 1702 if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) &&
1695 (truncation.IsUsedAsWord32() || 1703 (truncation.IsUsedAsWord32() ||
1696 NodeProperties::GetType(node)->Is(Type::Unsigned32()))) { 1704 NodeProperties::GetType(node)->Is(Type::Unsigned32()))) {
1697 // => unsigned Uint32Mod 1705 // => unsigned Uint32Mod
1698 VisitWord32TruncatingBinop(node); 1706 VisitWord32TruncatingBinop(node);
1699 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); 1707 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
1700 return; 1708 return;
1701 } 1709 }
1702 if (BothInputsAre(node, Type::Signed32OrMinusZeroOrNaN()) && 1710 if (BothInputsAre(node, Type::Signed32OrMinusZeroOrNaN()) &&
(...skipping 1626 matching lines...) Expand 10 before | Expand all | Expand 10 after
3329 isolate(), graph()->zone(), callable.descriptor(), 0, flags, 3337 isolate(), graph()->zone(), callable.descriptor(), 0, flags,
3330 Operator::kNoProperties); 3338 Operator::kNoProperties);
3331 to_number_operator_.set(common()->Call(desc)); 3339 to_number_operator_.set(common()->Call(desc));
3332 } 3340 }
3333 return to_number_operator_.get(); 3341 return to_number_operator_.get();
3334 } 3342 }
3335 3343
3336 } // namespace compiler 3344 } // namespace compiler
3337 } // namespace internal 3345 } // namespace internal
3338 } // namespace v8 3346 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698