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

Unified Diff: src/compiler/simplified-lowering.cc

Issue 2287303002: [turbofan] More efficient code generation for unsigned modulus. (Closed)
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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/simplified-lowering.cc
diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc
index d886cf02a702a9b69e4c2c573e6b08be62f6e597..f5a541d1443b031b2d23123f7d994c98382869f0 100644
--- a/src/compiler/simplified-lowering.cc
+++ b/src/compiler/simplified-lowering.cc
@@ -1175,6 +1175,110 @@ class RepresentationSelector {
return;
}
+ void VisitSpeculativeNumberModulus(Node* node, Truncation truncation,
+ SimplifiedLowering* lowering) {
+ // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
+ // can only eliminate an unused speculative number operation if we know
+ // that the inputs are PlainPrimitive, which excludes everything that's
+ // might have side effects or throws during a ToNumber conversion.
+ if (BothInputsAre(node, Type::PlainPrimitive())) {
+ if (truncation.IsUnused()) return VisitUnused(node);
+ }
+ if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) &&
+ (truncation.IsUsedAsWord32() ||
+ NodeProperties::GetType(node)->Is(Type::Unsigned32()))) {
+ // => unsigned Uint32Mod
+ VisitWord32TruncatingBinop(node);
+ if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
+ return;
+ }
+ if (BothInputsAre(node, Type::Signed32OrMinusZeroOrNaN()) &&
+ (truncation.IsUsedAsWord32() ||
+ NodeProperties::GetType(node)->Is(Type::Signed32()))) {
+ // => signed Int32Mod
+ VisitWord32TruncatingBinop(node);
+ if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
+ return;
+ }
+
+ // Try to use type feedback.
+ NumberOperationHint hint = NumberOperationHintOf(node->op());
+
+ // Handle the case when no uint32 checks on inputs are necessary
+ // (but an overflow check is needed on the output).
+ if (BothInputsAreUnsigned32(node)) {
+ if (hint == NumberOperationHint::kSignedSmall ||
+ hint == NumberOperationHint::kSigned32) {
+ VisitBinop(node, UseInfo::TruncatingWord32(),
+ MachineRepresentation::kWord32, Type::Unsigned32());
+ if (lower()) ChangeToUint32OverflowOp(node);
+ return;
+ }
+ }
+
+ // Handle the case when no int32 checks on inputs are necessary
+ // (but an overflow check is needed on the output).
+ if (BothInputsAre(node, Type::Signed32())) {
+ // If both the inputs the feedback are int32, use the overflow op.
+ if (hint == NumberOperationHint::kSignedSmall ||
+ hint == NumberOperationHint::kSigned32) {
+ VisitBinop(node, UseInfo::TruncatingWord32(),
+ MachineRepresentation::kWord32, Type::Signed32());
+ if (lower()) ChangeToInt32OverflowOp(node);
+ return;
+ }
+ }
+
+ if (hint == NumberOperationHint::kSignedSmall ||
+ hint == NumberOperationHint::kSigned32) {
+ // If the result is truncated, we only need to check the inputs.
+ if (truncation.IsUsedAsWord32()) {
+ VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
+ MachineRepresentation::kWord32);
+ if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
+ } else if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN())) {
+ VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
+ MachineRepresentation::kWord32, Type::Unsigned32());
+ if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
+ } else {
+ VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
+ MachineRepresentation::kWord32, Type::Signed32());
+ if (lower()) ChangeToInt32OverflowOp(node);
+ }
+ return;
+ }
+
+ if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) &&
+ TypeOf(node->InputAt(1))->Is(Type::Unsigned32()) &&
+ (truncation.IsUsedAsWord32() ||
+ NodeProperties::GetType(node)->Is(Type::Unsigned32()))) {
+ // We can only promise Float64 truncation here, as the decision is
+ // based on the feedback types of the inputs.
+ VisitBinop(node,
+ UseInfo(MachineRepresentation::kWord32, Truncation::Float64()),
+ MachineRepresentation::kWord32);
+ if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
+ return;
+ }
+ if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) &&
+ TypeOf(node->InputAt(1))->Is(Type::Signed32()) &&
+ (truncation.IsUsedAsWord32() ||
+ NodeProperties::GetType(node)->Is(Type::Signed32()))) {
+ // We can only promise Float64 truncation here, as the decision is
+ // based on the feedback types of the inputs.
+ VisitBinop(node,
+ UseInfo(MachineRepresentation::kWord32, Truncation::Float64()),
+ MachineRepresentation::kWord32);
+ if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
+ return;
+ }
+ // default case => Float64Mod
+ VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
+ MachineRepresentation::kFloat64, Type::Number());
+ if (lower()) ChangeToPureOp(node, Float64Op(node));
+ return;
+ }
+
// Dispatching routine for visiting the node {node} with the usage {use}.
// Depending on the operator, propagate new usage info to the inputs.
void VisitNode(Node* node, Truncation truncation,
@@ -1592,104 +1696,8 @@ class RepresentationSelector {
if (lower()) ChangeToPureOp(node, Float64Op(node));
return;
}
- case IrOpcode::kSpeculativeNumberModulus: {
- // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
- // can only eliminate an unused speculative number operation if we know
- // that the inputs are PlainPrimitive, which excludes everything that's
- // might have side effects or throws during a ToNumber conversion.
- if (BothInputsAre(node, Type::PlainPrimitive())) {
- if (truncation.IsUnused()) return VisitUnused(node);
- }
- if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) &&
- (truncation.IsUsedAsWord32() ||
- NodeProperties::GetType(node)->Is(Type::Unsigned32()))) {
- // => unsigned Uint32Mod
- VisitWord32TruncatingBinop(node);
- if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
- return;
- }
- if (BothInputsAre(node, Type::Signed32OrMinusZeroOrNaN()) &&
- (truncation.IsUsedAsWord32() ||
- NodeProperties::GetType(node)->Is(Type::Signed32()))) {
- // => signed Int32Mod
- VisitWord32TruncatingBinop(node);
- if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
- return;
- }
-
- // Try to use type feedback.
- NumberOperationHint hint = NumberOperationHintOf(node->op());
-
- // Handle the case when no uint32 checks on inputs are necessary
- // (but an overflow check is needed on the output).
- if (BothInputsAreUnsigned32(node)) {
- if (hint == NumberOperationHint::kSignedSmall ||
- hint == NumberOperationHint::kSigned32) {
- VisitBinop(node, UseInfo::TruncatingWord32(),
- MachineRepresentation::kWord32, Type::Unsigned32());
- if (lower()) ChangeToUint32OverflowOp(node);
- return;
- }
- }
-
- // Handle the case when no int32 checks on inputs are necessary
- // (but an overflow check is needed on the output).
- if (BothInputsAre(node, Type::Signed32())) {
- // If both the inputs the feedback are int32, use the overflow op.
- if (hint == NumberOperationHint::kSignedSmall ||
- hint == NumberOperationHint::kSigned32) {
- VisitBinop(node, UseInfo::TruncatingWord32(),
- MachineRepresentation::kWord32, Type::Signed32());
- if (lower()) ChangeToInt32OverflowOp(node);
- return;
- }
- }
-
- if (hint == NumberOperationHint::kSignedSmall ||
- hint == NumberOperationHint::kSigned32) {
- // If the result is truncated, we only need to check the inputs.
- if (truncation.IsUsedAsWord32()) {
- VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
- MachineRepresentation::kWord32);
- if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
- } else {
- VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
- MachineRepresentation::kWord32, Type::Signed32());
- if (lower()) ChangeToInt32OverflowOp(node);
- }
- return;
- }
-
- if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) &&
- TypeOf(node->InputAt(1))->Is(Type::Unsigned32()) &&
- (truncation.IsUsedAsWord32() ||
- NodeProperties::GetType(node)->Is(Type::Unsigned32()))) {
- // We can only promise Float64 truncation here, as the decision is
- // based on the feedback types of the inputs.
- VisitBinop(node, UseInfo(MachineRepresentation::kWord32,
- Truncation::Float64()),
- MachineRepresentation::kWord32);
- if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
- return;
- }
- if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) &&
- TypeOf(node->InputAt(1))->Is(Type::Signed32()) &&
- (truncation.IsUsedAsWord32() ||
- NodeProperties::GetType(node)->Is(Type::Signed32()))) {
- // We can only promise Float64 truncation here, as the decision is
- // based on the feedback types of the inputs.
- VisitBinop(node, UseInfo(MachineRepresentation::kWord32,
- Truncation::Float64()),
- MachineRepresentation::kWord32);
- if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
- return;
- }
- // default case => Float64Mod
- VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
- MachineRepresentation::kFloat64, Type::Number());
- if (lower()) ChangeToPureOp(node, Float64Op(node));
- return;
- }
+ case IrOpcode::kSpeculativeNumberModulus:
+ return VisitSpeculativeNumberModulus(node, truncation, lowering);
case IrOpcode::kNumberModulus: {
if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) &&
(truncation.IsUsedAsWord32() ||
« 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