Commit 0fd8c418 authored by Jaroslav Sevcik's avatar Jaroslav Sevcik Committed by Commit Bot

[turbofan] Introduce SpeculativeSafeInteger(Add|Subtract) operators.

This is just a refactoring in preparation for typing the speculative
integer operation as safe integers.

Bug: v8:5267
Change-Id: I56da91a72655a0733b2cf04afcf33cb1d2aa1415
Reviewed-on: https://chromium-review.googlesource.com/637830Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47640}
parent 3168a963
...@@ -2574,9 +2574,9 @@ void BytecodeGraphBuilder::VisitForInStep() { ...@@ -2574,9 +2574,9 @@ void BytecodeGraphBuilder::VisitForInStep() {
PrepareEagerCheckpoint(); PrepareEagerCheckpoint();
Node* index = Node* index =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
index = NewNode( index = NewNode(simplified()->SpeculativeSafeIntegerAdd(
simplified()->SpeculativeNumberAdd(NumberOperationHint::kSignedSmall), NumberOperationHint::kSignedSmall),
index, jsgraph()->OneConstant()); index, jsgraph()->OneConstant());
environment()->BindAccumulator(index, Environment::kAttachFrameState); environment()->BindAccumulator(index, Environment::kAttachFrameState);
} }
......
...@@ -97,9 +97,19 @@ class JSSpeculativeBinopBuilder final { ...@@ -97,9 +97,19 @@ class JSSpeculativeBinopBuilder final {
const Operator* SpeculativeNumberOp(NumberOperationHint hint) { const Operator* SpeculativeNumberOp(NumberOperationHint hint) {
switch (op_->opcode()) { switch (op_->opcode()) {
case IrOpcode::kJSAdd: case IrOpcode::kJSAdd:
return simplified()->SpeculativeNumberAdd(hint); if (hint == NumberOperationHint::kSignedSmall ||
hint == NumberOperationHint::kSigned32) {
return simplified()->SpeculativeSafeIntegerAdd(hint);
} else {
return simplified()->SpeculativeNumberAdd(hint);
}
case IrOpcode::kJSSubtract: case IrOpcode::kJSSubtract:
return simplified()->SpeculativeNumberSubtract(hint); if (hint == NumberOperationHint::kSignedSmall ||
hint == NumberOperationHint::kSigned32) {
return simplified()->SpeculativeSafeIntegerSubtract(hint);
} else {
return simplified()->SpeculativeNumberSubtract(hint);
}
case IrOpcode::kJSMultiply: case IrOpcode::kJSMultiply:
return simplified()->SpeculativeNumberMultiply(hint); return simplified()->SpeculativeNumberMultiply(hint);
case IrOpcode::kJSDivide: case IrOpcode::kJSDivide:
......
...@@ -306,7 +306,8 @@ InductionVariable* LoopVariableOptimizer::TryGetInductionVariable(Node* phi) { ...@@ -306,7 +306,8 @@ InductionVariable* LoopVariableOptimizer::TryGetInductionVariable(Node* phi) {
Node* arith = phi->InputAt(1); Node* arith = phi->InputAt(1);
InductionVariable::ArithmeticType arithmeticType; InductionVariable::ArithmeticType arithmeticType;
if (arith->opcode() == IrOpcode::kJSAdd || if (arith->opcode() == IrOpcode::kJSAdd ||
arith->opcode() == IrOpcode::kSpeculativeNumberAdd) { arith->opcode() == IrOpcode::kSpeculativeNumberAdd ||
arith->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd) {
arithmeticType = InductionVariable::ArithmeticType::kAddition; arithmeticType = InductionVariable::ArithmeticType::kAddition;
} else if (arith->opcode() == IrOpcode::kJSSubtract || } else if (arith->opcode() == IrOpcode::kJSSubtract ||
arith->opcode() == IrOpcode::kSpeculativeNumberSubtract) { arith->opcode() == IrOpcode::kSpeculativeNumberSubtract) {
......
...@@ -273,7 +273,9 @@ ...@@ -273,7 +273,9 @@
V(SpeculativeNumberBitwiseXor) \ V(SpeculativeNumberBitwiseXor) \
V(SpeculativeNumberShiftLeft) \ V(SpeculativeNumberShiftLeft) \
V(SpeculativeNumberShiftRight) \ V(SpeculativeNumberShiftRight) \
V(SpeculativeNumberShiftRightLogical) V(SpeculativeNumberShiftRightLogical) \
V(SpeculativeSafeIntegerAdd) \
V(SpeculativeSafeIntegerSubtract)
#define SIMPLIFIED_NUMBER_UNOP_LIST(V) \ #define SIMPLIFIED_NUMBER_UNOP_LIST(V) \
V(NumberAbs) \ V(NumberAbs) \
......
...@@ -987,6 +987,18 @@ SPECULATIVE_NUMBER_BINOP(NumberShiftRight) ...@@ -987,6 +987,18 @@ SPECULATIVE_NUMBER_BINOP(NumberShiftRight)
SPECULATIVE_NUMBER_BINOP(NumberShiftRightLogical) SPECULATIVE_NUMBER_BINOP(NumberShiftRightLogical)
#undef SPECULATIVE_NUMBER_BINOP #undef SPECULATIVE_NUMBER_BINOP
Type* OperationTyper::SpeculativeSafeIntegerAdd(Type* lhs, Type* rhs) {
lhs = SpeculativeToNumber(lhs);
rhs = SpeculativeToNumber(rhs);
return NumberAdd(lhs, rhs);
}
Type* OperationTyper::SpeculativeSafeIntegerSubtract(Type* lhs, Type* rhs) {
lhs = SpeculativeToNumber(lhs);
rhs = SpeculativeToNumber(rhs);
return NumberSubtract(lhs, rhs);
}
Type* OperationTyper::SpeculativeToNumber(Type* type) { Type* OperationTyper::SpeculativeToNumber(Type* type) {
return ToNumber(Type::Intersect(type, Type::NumberOrOddball(), zone())); return ToNumber(Type::Intersect(type, Type::NumberOrOddball(), zone()));
} }
......
...@@ -829,9 +829,11 @@ const Operator* RepresentationChanger::Int32OperatorFor( ...@@ -829,9 +829,11 @@ const Operator* RepresentationChanger::Int32OperatorFor(
IrOpcode::Value opcode) { IrOpcode::Value opcode) {
switch (opcode) { switch (opcode) {
case IrOpcode::kSpeculativeNumberAdd: // Fall through. case IrOpcode::kSpeculativeNumberAdd: // Fall through.
case IrOpcode::kSpeculativeSafeIntegerAdd:
case IrOpcode::kNumberAdd: case IrOpcode::kNumberAdd:
return machine()->Int32Add(); return machine()->Int32Add();
case IrOpcode::kSpeculativeNumberSubtract: // Fall through. case IrOpcode::kSpeculativeNumberSubtract: // Fall through.
case IrOpcode::kSpeculativeSafeIntegerSubtract:
case IrOpcode::kNumberSubtract: case IrOpcode::kNumberSubtract:
return machine()->Int32Sub(); return machine()->Int32Sub();
case IrOpcode::kSpeculativeNumberMultiply: case IrOpcode::kSpeculativeNumberMultiply:
...@@ -869,9 +871,9 @@ const Operator* RepresentationChanger::Int32OperatorFor( ...@@ -869,9 +871,9 @@ const Operator* RepresentationChanger::Int32OperatorFor(
const Operator* RepresentationChanger::Int32OverflowOperatorFor( const Operator* RepresentationChanger::Int32OverflowOperatorFor(
IrOpcode::Value opcode) { IrOpcode::Value opcode) {
switch (opcode) { switch (opcode) {
case IrOpcode::kSpeculativeNumberAdd: case IrOpcode::kSpeculativeSafeIntegerAdd:
return simplified()->CheckedInt32Add(); return simplified()->CheckedInt32Add();
case IrOpcode::kSpeculativeNumberSubtract: case IrOpcode::kSpeculativeSafeIntegerSubtract:
return simplified()->CheckedInt32Sub(); return simplified()->CheckedInt32Sub();
case IrOpcode::kSpeculativeNumberDivide: case IrOpcode::kSpeculativeNumberDivide:
return simplified()->CheckedInt32Div(); return simplified()->CheckedInt32Div();
...@@ -949,9 +951,11 @@ const Operator* RepresentationChanger::Float64OperatorFor( ...@@ -949,9 +951,11 @@ const Operator* RepresentationChanger::Float64OperatorFor(
IrOpcode::Value opcode) { IrOpcode::Value opcode) {
switch (opcode) { switch (opcode) {
case IrOpcode::kSpeculativeNumberAdd: case IrOpcode::kSpeculativeNumberAdd:
case IrOpcode::kSpeculativeSafeIntegerAdd:
case IrOpcode::kNumberAdd: case IrOpcode::kNumberAdd:
return machine()->Float64Add(); return machine()->Float64Add();
case IrOpcode::kSpeculativeNumberSubtract: case IrOpcode::kSpeculativeNumberSubtract:
case IrOpcode::kSpeculativeSafeIntegerSubtract:
case IrOpcode::kNumberSubtract: case IrOpcode::kNumberSubtract:
return machine()->Float64Sub(); return machine()->Float64Sub();
case IrOpcode::kSpeculativeNumberMultiply: case IrOpcode::kSpeculativeNumberMultiply:
......
...@@ -215,11 +215,11 @@ bool CanOverflowSigned32(const Operator* op, Type* left, Type* right, ...@@ -215,11 +215,11 @@ bool CanOverflowSigned32(const Operator* op, Type* left, Type* right,
right = Type::Intersect(right, Type::Signed32(), type_zone); right = Type::Intersect(right, Type::Signed32(), type_zone);
if (!left->IsInhabited() || !right->IsInhabited()) return false; if (!left->IsInhabited() || !right->IsInhabited()) return false;
switch (op->opcode()) { switch (op->opcode()) {
case IrOpcode::kSpeculativeNumberAdd: case IrOpcode::kSpeculativeSafeIntegerAdd:
return (left->Max() + right->Max() > kMaxInt) || return (left->Max() + right->Max() > kMaxInt) ||
(left->Min() + right->Min() < kMinInt); (left->Min() + right->Min() < kMinInt);
case IrOpcode::kSpeculativeNumberSubtract: case IrOpcode::kSpeculativeSafeIntegerSubtract:
return (left->Max() - right->Min() > kMaxInt) || return (left->Max() - right->Min() > kMaxInt) ||
(left->Min() - right->Max() < kMinInt); (left->Min() - right->Max() < kMinInt);
...@@ -1255,15 +1255,11 @@ class RepresentationSelector { ...@@ -1255,15 +1255,11 @@ class RepresentationSelector {
NodeProperties::ChangeOp(node, Uint32OverflowOp(node)); NodeProperties::ChangeOp(node, Uint32OverflowOp(node));
} }
void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation, void VisitSpeculativeIntegerAdditiveOp(Node* node, Truncation truncation,
SimplifiedLowering* lowering) { SimplifiedLowering* lowering) {
// ToNumber(x) can throw if x is either a Receiver or a Symbol, so we can // Only eliminate eliminate the node if the ToNumber conversion cannot
// only eliminate an unused speculative number operation if we know that // cause any observable side-effect and if we know for sure that it
// the inputs are PlainPrimitive, which excludes everything that's might // is a number addition (we must exclude strings).
// have side effects or throws during a ToNumber conversion. We are only
// allowed to perform a number addition if neither input is a String, even
// if the value is never used, so we further limit to NumberOrOddball in
// order to explicitly exclude String inputs.
if (BothInputsAre(node, Type::NumberOrOddball())) { if (BothInputsAre(node, Type::NumberOrOddball())) {
if (truncation.IsUnused()) return VisitUnused(node); if (truncation.IsUnused()) return VisitUnused(node);
} }
...@@ -1300,7 +1296,7 @@ class RepresentationSelector { ...@@ -1300,7 +1296,7 @@ class RepresentationSelector {
// right-hand side is not minus zero, we do not have to distinguish // right-hand side is not minus zero, we do not have to distinguish
// between 0 and -0. // between 0 and -0.
IdentifyZeros left_identify_zeros = truncation.identify_zeros(); IdentifyZeros left_identify_zeros = truncation.identify_zeros();
if (node->opcode() == IrOpcode::kSpeculativeNumberAdd && if (node->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd &&
!right_feedback_type->Maybe(Type::MinusZero())) { !right_feedback_type->Maybe(Type::MinusZero())) {
left_identify_zeros = kIdentifyZeros; left_identify_zeros = kIdentifyZeros;
} }
...@@ -1335,6 +1331,38 @@ class RepresentationSelector { ...@@ -1335,6 +1331,38 @@ class RepresentationSelector {
return; return;
} }
void VisitSpeculativeAdditiveOp(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. We are only
// allowed to perform a number addition if neither input is a String, even
// if the value is never used, so we further limit to NumberOrOddball in
// order to explicitly exclude String inputs.
if (BothInputsAre(node, Type::NumberOrOddball())) {
if (truncation.IsUnused()) return VisitUnused(node);
}
if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) &&
(GetUpperBound(node)->Is(Type::Signed32()) ||
GetUpperBound(node)->Is(Type::Unsigned32()) ||
truncation.IsUsedAsWord32())) {
// => Int32Add/Sub
VisitWord32TruncatingBinop(node);
if (lower()) ChangeToPureOp(node, Int32Op(node));
return;
}
// default case => Float64Add/Sub
VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
MachineRepresentation::kFloat64, Type::Number());
if (lower()) {
ChangeToPureOp(node, Float64Op(node));
}
return;
}
void VisitSpeculativeNumberModulus(Node* node, Truncation truncation, void VisitSpeculativeNumberModulus(Node* node, Truncation truncation,
SimplifiedLowering* lowering) { SimplifiedLowering* lowering) {
// ToNumber(x) can throw if x is either a Receiver or a Symbol, so we // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
...@@ -1615,6 +1643,10 @@ class RepresentationSelector { ...@@ -1615,6 +1643,10 @@ class RepresentationSelector {
return; return;
} }
case IrOpcode::kSpeculativeSafeIntegerAdd:
case IrOpcode::kSpeculativeSafeIntegerSubtract:
return VisitSpeculativeIntegerAdditiveOp(node, truncation, lowering);
case IrOpcode::kSpeculativeNumberAdd: case IrOpcode::kSpeculativeNumberAdd:
case IrOpcode::kSpeculativeNumberSubtract: case IrOpcode::kSpeculativeNumberSubtract:
return VisitSpeculativeAdditiveOp(node, truncation, lowering); return VisitSpeculativeAdditiveOp(node, truncation, lowering);
......
...@@ -382,7 +382,9 @@ NumberOperationHint NumberOperationHintOf(const Operator* op) { ...@@ -382,7 +382,9 @@ NumberOperationHint NumberOperationHintOf(const Operator* op) {
op->opcode() == IrOpcode::kSpeculativeNumberBitwiseXor || op->opcode() == IrOpcode::kSpeculativeNumberBitwiseXor ||
op->opcode() == IrOpcode::kSpeculativeNumberEqual || op->opcode() == IrOpcode::kSpeculativeNumberEqual ||
op->opcode() == IrOpcode::kSpeculativeNumberLessThan || op->opcode() == IrOpcode::kSpeculativeNumberLessThan ||
op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual); op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual ||
op->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd ||
op->opcode() == IrOpcode::kSpeculativeSafeIntegerSubtract);
return OpParameter<NumberOperationHint>(op); return OpParameter<NumberOperationHint>(op);
} }
......
...@@ -340,6 +340,9 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final ...@@ -340,6 +340,9 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
const Operator* NumberSilenceNaN(); const Operator* NumberSilenceNaN();
const Operator* SpeculativeSafeIntegerAdd(NumberOperationHint hint);
const Operator* SpeculativeSafeIntegerSubtract(NumberOperationHint hint);
const Operator* SpeculativeNumberAdd(NumberOperationHint hint); const Operator* SpeculativeNumberAdd(NumberOperationHint hint);
const Operator* SpeculativeNumberSubtract(NumberOperationHint hint); const Operator* SpeculativeNumberSubtract(NumberOperationHint hint);
const Operator* SpeculativeNumberMultiply(NumberOperationHint hint); const Operator* SpeculativeNumberMultiply(NumberOperationHint hint);
......
...@@ -797,6 +797,8 @@ void Verifier::Visitor::Check(Node* node) { ...@@ -797,6 +797,8 @@ void Verifier::Visitor::Check(Node* node) {
CheckValueInputIs(node, 1, Type::Number()); CheckValueInputIs(node, 1, Type::Number());
CheckTypeIs(node, Type::Boolean()); CheckTypeIs(node, Type::Boolean());
break; break;
case IrOpcode::kSpeculativeSafeIntegerAdd:
case IrOpcode::kSpeculativeSafeIntegerSubtract:
case IrOpcode::kSpeculativeNumberAdd: case IrOpcode::kSpeculativeNumberAdd:
case IrOpcode::kSpeculativeNumberSubtract: case IrOpcode::kSpeculativeNumberSubtract:
case IrOpcode::kSpeculativeNumberMultiply: case IrOpcode::kSpeculativeNumberMultiply:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment