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() || |