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() {
PrepareEagerCheckpoint();
Node* index =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
index = NewNode(
simplified()->SpeculativeNumberAdd(NumberOperationHint::kSignedSmall),
index, jsgraph()->OneConstant());
index = NewNode(simplified()->SpeculativeSafeIntegerAdd(
NumberOperationHint::kSignedSmall),
index, jsgraph()->OneConstant());
environment()->BindAccumulator(index, Environment::kAttachFrameState);
}
......
......@@ -97,9 +97,19 @@ class JSSpeculativeBinopBuilder final {
const Operator* SpeculativeNumberOp(NumberOperationHint hint) {
switch (op_->opcode()) {
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:
return simplified()->SpeculativeNumberSubtract(hint);
if (hint == NumberOperationHint::kSignedSmall ||
hint == NumberOperationHint::kSigned32) {
return simplified()->SpeculativeSafeIntegerSubtract(hint);
} else {
return simplified()->SpeculativeNumberSubtract(hint);
}
case IrOpcode::kJSMultiply:
return simplified()->SpeculativeNumberMultiply(hint);
case IrOpcode::kJSDivide:
......
......@@ -306,7 +306,8 @@ InductionVariable* LoopVariableOptimizer::TryGetInductionVariable(Node* phi) {
Node* arith = phi->InputAt(1);
InductionVariable::ArithmeticType arithmeticType;
if (arith->opcode() == IrOpcode::kJSAdd ||
arith->opcode() == IrOpcode::kSpeculativeNumberAdd) {
arith->opcode() == IrOpcode::kSpeculativeNumberAdd ||
arith->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd) {
arithmeticType = InductionVariable::ArithmeticType::kAddition;
} else if (arith->opcode() == IrOpcode::kJSSubtract ||
arith->opcode() == IrOpcode::kSpeculativeNumberSubtract) {
......
......@@ -273,7 +273,9 @@
V(SpeculativeNumberBitwiseXor) \
V(SpeculativeNumberShiftLeft) \
V(SpeculativeNumberShiftRight) \
V(SpeculativeNumberShiftRightLogical)
V(SpeculativeNumberShiftRightLogical) \
V(SpeculativeSafeIntegerAdd) \
V(SpeculativeSafeIntegerSubtract)
#define SIMPLIFIED_NUMBER_UNOP_LIST(V) \
V(NumberAbs) \
......
......@@ -987,6 +987,18 @@ SPECULATIVE_NUMBER_BINOP(NumberShiftRight)
SPECULATIVE_NUMBER_BINOP(NumberShiftRightLogical)
#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) {
return ToNumber(Type::Intersect(type, Type::NumberOrOddball(), zone()));
}
......
......@@ -829,9 +829,11 @@ const Operator* RepresentationChanger::Int32OperatorFor(
IrOpcode::Value opcode) {
switch (opcode) {
case IrOpcode::kSpeculativeNumberAdd: // Fall through.
case IrOpcode::kSpeculativeSafeIntegerAdd:
case IrOpcode::kNumberAdd:
return machine()->Int32Add();
case IrOpcode::kSpeculativeNumberSubtract: // Fall through.
case IrOpcode::kSpeculativeSafeIntegerSubtract:
case IrOpcode::kNumberSubtract:
return machine()->Int32Sub();
case IrOpcode::kSpeculativeNumberMultiply:
......@@ -869,9 +871,9 @@ const Operator* RepresentationChanger::Int32OperatorFor(
const Operator* RepresentationChanger::Int32OverflowOperatorFor(
IrOpcode::Value opcode) {
switch (opcode) {
case IrOpcode::kSpeculativeNumberAdd:
case IrOpcode::kSpeculativeSafeIntegerAdd:
return simplified()->CheckedInt32Add();
case IrOpcode::kSpeculativeNumberSubtract:
case IrOpcode::kSpeculativeSafeIntegerSubtract:
return simplified()->CheckedInt32Sub();
case IrOpcode::kSpeculativeNumberDivide:
return simplified()->CheckedInt32Div();
......@@ -949,9 +951,11 @@ const Operator* RepresentationChanger::Float64OperatorFor(
IrOpcode::Value opcode) {
switch (opcode) {
case IrOpcode::kSpeculativeNumberAdd:
case IrOpcode::kSpeculativeSafeIntegerAdd:
case IrOpcode::kNumberAdd:
return machine()->Float64Add();
case IrOpcode::kSpeculativeNumberSubtract:
case IrOpcode::kSpeculativeSafeIntegerSubtract:
case IrOpcode::kNumberSubtract:
return machine()->Float64Sub();
case IrOpcode::kSpeculativeNumberMultiply:
......
......@@ -215,11 +215,11 @@ bool CanOverflowSigned32(const Operator* op, Type* left, Type* right,
right = Type::Intersect(right, Type::Signed32(), type_zone);
if (!left->IsInhabited() || !right->IsInhabited()) return false;
switch (op->opcode()) {
case IrOpcode::kSpeculativeNumberAdd:
case IrOpcode::kSpeculativeSafeIntegerAdd:
return (left->Max() + right->Max() > kMaxInt) ||
(left->Min() + right->Min() < kMinInt);
case IrOpcode::kSpeculativeNumberSubtract:
case IrOpcode::kSpeculativeSafeIntegerSubtract:
return (left->Max() - right->Min() > kMaxInt) ||
(left->Min() - right->Max() < kMinInt);
......@@ -1255,15 +1255,11 @@ class RepresentationSelector {
NodeProperties::ChangeOp(node, Uint32OverflowOp(node));
}
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.
void VisitSpeculativeIntegerAdditiveOp(Node* node, Truncation truncation,
SimplifiedLowering* lowering) {
// Only eliminate eliminate the node if the ToNumber conversion cannot
// cause any observable side-effect and if we know for sure that it
// is a number addition (we must exclude strings).
if (BothInputsAre(node, Type::NumberOrOddball())) {
if (truncation.IsUnused()) return VisitUnused(node);
}
......@@ -1300,7 +1296,7 @@ class RepresentationSelector {
// right-hand side is not minus zero, we do not have to distinguish
// between 0 and -0.
IdentifyZeros left_identify_zeros = truncation.identify_zeros();
if (node->opcode() == IrOpcode::kSpeculativeNumberAdd &&
if (node->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd &&
!right_feedback_type->Maybe(Type::MinusZero())) {
left_identify_zeros = kIdentifyZeros;
}
......@@ -1335,6 +1331,38 @@ class RepresentationSelector {
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,
SimplifiedLowering* lowering) {
// ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
......@@ -1615,6 +1643,10 @@ class RepresentationSelector {
return;
}
case IrOpcode::kSpeculativeSafeIntegerAdd:
case IrOpcode::kSpeculativeSafeIntegerSubtract:
return VisitSpeculativeIntegerAdditiveOp(node, truncation, lowering);
case IrOpcode::kSpeculativeNumberAdd:
case IrOpcode::kSpeculativeNumberSubtract:
return VisitSpeculativeAdditiveOp(node, truncation, lowering);
......
......@@ -382,7 +382,9 @@ NumberOperationHint NumberOperationHintOf(const Operator* op) {
op->opcode() == IrOpcode::kSpeculativeNumberBitwiseXor ||
op->opcode() == IrOpcode::kSpeculativeNumberEqual ||
op->opcode() == IrOpcode::kSpeculativeNumberLessThan ||
op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual);
op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual ||
op->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd ||
op->opcode() == IrOpcode::kSpeculativeSafeIntegerSubtract);
return OpParameter<NumberOperationHint>(op);
}
......
......@@ -340,6 +340,9 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
const Operator* NumberSilenceNaN();
const Operator* SpeculativeSafeIntegerAdd(NumberOperationHint hint);
const Operator* SpeculativeSafeIntegerSubtract(NumberOperationHint hint);
const Operator* SpeculativeNumberAdd(NumberOperationHint hint);
const Operator* SpeculativeNumberSubtract(NumberOperationHint hint);
const Operator* SpeculativeNumberMultiply(NumberOperationHint hint);
......
......@@ -797,6 +797,8 @@ void Verifier::Visitor::Check(Node* node) {
CheckValueInputIs(node, 1, Type::Number());
CheckTypeIs(node, Type::Boolean());
break;
case IrOpcode::kSpeculativeSafeIntegerAdd:
case IrOpcode::kSpeculativeSafeIntegerSubtract:
case IrOpcode::kSpeculativeNumberAdd:
case IrOpcode::kSpeculativeNumberSubtract:
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