Commit 9d53d16b authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[turbofan] Handle arithmetic addition in early lowering.

This handles arithmetic addition operations during the early type-hint
lowering (i.e. during graph construction). The string addition case is
still handled by {JSTypedLowering} as it needs static type information.

R=bmeurer@chromium.org

Change-Id: I9df47dfc5bf7613c51f6d803ab43d5d3f6c21be8
Reviewed-on: https://chromium-review.googlesource.com/443185Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#43235}
parent c0fe56e6
...@@ -1942,8 +1942,9 @@ void BytecodeGraphBuilder::VisitForInStep() { ...@@ -1942,8 +1942,9 @@ void BytecodeGraphBuilder::VisitForInStep() {
PrepareEagerCheckpoint(); PrepareEagerCheckpoint();
Node* index = Node* index =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
index = NewNode(javascript()->Add(BinaryOperationHint::kSignedSmall), index, index = NewNode(
jsgraph()->OneConstant()); simplified()->SpeculativeNumberAdd(NumberOperationHint::kSignedSmall),
index, jsgraph()->OneConstant());
environment()->BindAccumulator(index, Environment::kAttachFrameState); environment()->BindAccumulator(index, Environment::kAttachFrameState);
} }
......
...@@ -518,11 +518,7 @@ const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op) { ...@@ -518,11 +518,7 @@ const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op) {
} }
BinaryOperationHint BinaryOperationHintOf(const Operator* op) { BinaryOperationHint BinaryOperationHintOf(const Operator* op) {
DCHECK(op->opcode() == IrOpcode::kJSAdd || DCHECK_EQ(IrOpcode::kJSAdd, op->opcode());
op->opcode() == IrOpcode::kJSSubtract ||
op->opcode() == IrOpcode::kJSMultiply ||
op->opcode() == IrOpcode::kJSDivide ||
op->opcode() == IrOpcode::kJSModulus);
return OpParameter<BinaryOperationHint>(op); return OpParameter<BinaryOperationHint>(op);
} }
......
...@@ -128,6 +128,7 @@ Reduction JSTypeHintLowering::ReduceBinaryOperation(const Operator* op, ...@@ -128,6 +128,7 @@ Reduction JSTypeHintLowering::ReduceBinaryOperation(const Operator* op,
case IrOpcode::kJSShiftLeft: case IrOpcode::kJSShiftLeft:
case IrOpcode::kJSShiftRight: case IrOpcode::kJSShiftRight:
case IrOpcode::kJSShiftRightLogical: case IrOpcode::kJSShiftRightLogical:
case IrOpcode::kJSAdd:
case IrOpcode::kJSSubtract: case IrOpcode::kJSSubtract:
case IrOpcode::kJSMultiply: case IrOpcode::kJSMultiply:
case IrOpcode::kJSDivide: case IrOpcode::kJSDivide:
...@@ -140,9 +141,6 @@ Reduction JSTypeHintLowering::ReduceBinaryOperation(const Operator* op, ...@@ -140,9 +141,6 @@ Reduction JSTypeHintLowering::ReduceBinaryOperation(const Operator* op,
} }
break; break;
} }
case IrOpcode::kJSAdd:
// TODO(mstarzinger): Implement speculative lowering.
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
......
...@@ -30,30 +30,6 @@ class JSBinopReduction final { ...@@ -30,30 +30,6 @@ class JSBinopReduction final {
JSBinopReduction(JSTypedLowering* lowering, Node* node) JSBinopReduction(JSTypedLowering* lowering, Node* node)
: lowering_(lowering), node_(node) {} : lowering_(lowering), node_(node) {}
bool GetBinaryNumberOperationHint(NumberOperationHint* hint) {
if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
DCHECK_NE(0, node_->op()->ControlOutputCount());
DCHECK_EQ(1, node_->op()->EffectOutputCount());
DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node_->op()));
switch (BinaryOperationHintOf(node_->op())) {
case BinaryOperationHint::kSignedSmall:
*hint = NumberOperationHint::kSignedSmall;
return true;
case BinaryOperationHint::kSigned32:
*hint = NumberOperationHint::kSigned32;
return true;
case BinaryOperationHint::kNumberOrOddball:
*hint = NumberOperationHint::kNumberOrOddball;
return true;
case BinaryOperationHint::kAny:
case BinaryOperationHint::kNone:
case BinaryOperationHint::kString:
break;
}
}
return false;
}
bool GetCompareNumberOperationHint(NumberOperationHint* hint) { bool GetCompareNumberOperationHint(NumberOperationHint* hint) {
if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) { if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
DCHECK_EQ(1, node_->op()->EffectOutputCount()); DCHECK_EQ(1, node_->op()->EffectOutputCount());
...@@ -113,6 +89,7 @@ class JSBinopReduction final { ...@@ -113,6 +89,7 @@ class JSBinopReduction final {
// minimum length. // minimum length.
bool ShouldCreateConsString() { bool ShouldCreateConsString() {
DCHECK_EQ(IrOpcode::kJSAdd, node_->opcode()); DCHECK_EQ(IrOpcode::kJSAdd, node_->opcode());
DCHECK(OneInputIs(Type::String()));
if (BothInputsAre(Type::String()) || if (BothInputsAre(Type::String()) ||
((lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) && ((lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) &&
BinaryOperationHintOf(node_->op()) == BinaryOperationHint::kString)) { BinaryOperationHintOf(node_->op()) == BinaryOperationHint::kString)) {
...@@ -590,20 +567,22 @@ JSTypedLowering::JSTypedLowering(Editor* editor, ...@@ -590,20 +567,22 @@ JSTypedLowering::JSTypedLowering(Editor* editor,
} }
} }
Reduction JSTypedLowering::ReduceJSAdd(Node* node) { Reduction JSTypedLowering::ReduceSpeculativeNumberAdd(Node* node) {
JSBinopReduction r(this, node); JSBinopReduction r(this, node);
NumberOperationHint hint; NumberOperationHint hint = NumberOperationHintOf(node->op());
if (r.GetBinaryNumberOperationHint(&hint)) { if (hint == NumberOperationHint::kNumberOrOddball &&
if (hint == NumberOperationHint::kNumberOrOddball && r.BothInputsAre(Type::PlainPrimitive()) &&
r.BothInputsAre(Type::PlainPrimitive()) && r.NeitherInputCanBe(Type::StringOrReceiver())) {
r.NeitherInputCanBe(Type::StringOrReceiver())) { // SpeculativeNumberAdd(x:-string, y:-string) =>
// JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y)) // NumberAdd(ToNumber(x), ToNumber(y))
r.ConvertInputsToNumber(); r.ConvertInputsToNumber();
return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
}
return r.ChangeToSpeculativeOperator(
simplified()->SpeculativeNumberAdd(hint), Type::Number());
} }
return NoChange();
}
Reduction JSTypedLowering::ReduceJSAdd(Node* node) {
JSBinopReduction r(this, node);
if (r.BothInputsAre(Type::Number())) { if (r.BothInputsAre(Type::Number())) {
// JSAdd(x:number, y:number) => NumberAdd(x, y) // JSAdd(x:number, y:number) => NumberAdd(x, y)
r.ConvertInputsToNumber(); r.ConvertInputsToNumber();
...@@ -2496,6 +2475,8 @@ Reduction JSTypedLowering::Reduce(Node* node) { ...@@ -2496,6 +2475,8 @@ Reduction JSTypedLowering::Reduce(Node* node) {
return ReduceJSGeneratorRestoreRegister(node); return ReduceJSGeneratorRestoreRegister(node);
// TODO(mstarzinger): Simplified operations hiding in JS-level reducer not // TODO(mstarzinger): Simplified operations hiding in JS-level reducer not
// fooling anyone. Consider moving this into a separate reducer. // fooling anyone. Consider moving this into a separate reducer.
case IrOpcode::kSpeculativeNumberAdd:
return ReduceSpeculativeNumberAdd(node);
case IrOpcode::kSpeculativeNumberSubtract: case IrOpcode::kSpeculativeNumberSubtract:
case IrOpcode::kSpeculativeNumberMultiply: case IrOpcode::kSpeculativeNumberMultiply:
case IrOpcode::kSpeculativeNumberDivide: case IrOpcode::kSpeculativeNumberDivide:
......
...@@ -84,6 +84,7 @@ class V8_EXPORT_PRIVATE JSTypedLowering final ...@@ -84,6 +84,7 @@ class V8_EXPORT_PRIVATE JSTypedLowering final
Reduction ReduceInt32Binop(Node* node); Reduction ReduceInt32Binop(Node* node);
Reduction ReduceUI32Shift(Node* node, Signedness signedness); Reduction ReduceUI32Shift(Node* node, Signedness signedness);
Reduction ReduceCreateConsString(Node* node); Reduction ReduceCreateConsString(Node* node);
Reduction ReduceSpeculativeNumberAdd(Node* node);
Reduction ReduceSpeculativeNumberBinop(Node* node); Reduction ReduceSpeculativeNumberBinop(Node* node);
Factory* factory() const; Factory* factory() const;
......
...@@ -1187,8 +1187,11 @@ class RepresentationSelector { ...@@ -1187,8 +1187,11 @@ class RepresentationSelector {
// ToNumber(x) can throw if x is either a Receiver or a Symbol, so we can // 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 // only eliminate an unused speculative number operation if we know that
// the inputs are PlainPrimitive, which excludes everything that's might // the inputs are PlainPrimitive, which excludes everything that's might
// have side effects or throws during a ToNumber conversion. // have side effects or throws during a ToNumber conversion. We are only
if (BothInputsAre(node, Type::PlainPrimitive())) { // 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 (truncation.IsUnused()) return VisitUnused(node);
} }
......
...@@ -701,22 +701,6 @@ TEST_F(JSTypedLoweringTest, JSAddWithString) { ...@@ -701,22 +701,6 @@ TEST_F(JSTypedLoweringTest, JSAddWithString) {
lhs, rhs, context, frame_state, effect, control)); lhs, rhs, context, frame_state, effect, control));
} }
TEST_F(JSTypedLoweringTest, JSAddSmis) {
BinaryOperationHint const hint = BinaryOperationHint::kSignedSmall;
Node* lhs = Parameter(Type::Number(), 0);
Node* rhs = Parameter(Type::Number(), 1);
Node* context = Parameter(Type::Any(), 2);
Node* frame_state = EmptyFrameState();
Node* effect = graph()->start();
Node* control = graph()->start();
Reduction r = Reduce(graph()->NewNode(javascript()->Add(hint), lhs, rhs,
context, frame_state, effect, control));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(),
IsSpeculativeNumberAdd(NumberOperationHint::kSignedSmall, lhs,
rhs, effect, control));
}
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
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