diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc index b8967864d3..d488efef24 100644 --- a/src/compiler/ast-graph-builder.cc +++ b/src/compiler/ast-graph-builder.cc @@ -2769,16 +2769,16 @@ Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op, js_op = javascript()->Add(hint); break; case Token::SUB: - js_op = javascript()->Subtract(hint); + js_op = javascript()->Subtract(); break; case Token::MUL: - js_op = javascript()->Multiply(hint); + js_op = javascript()->Multiply(); break; case Token::DIV: - js_op = javascript()->Divide(hint); + js_op = javascript()->Divide(); break; case Token::MOD: - js_op = javascript()->Modulus(hint); + js_op = javascript()->Modulus(); break; default: UNREACHABLE(); diff --git a/src/compiler/bytecode-graph-builder.cc b/src/compiler/bytecode-graph-builder.cc index 1474f2d4a7..62f72fb29a 100644 --- a/src/compiler/bytecode-graph-builder.cc +++ b/src/compiler/bytecode-graph-builder.cc @@ -1557,23 +1557,17 @@ void BytecodeGraphBuilder::VisitAdd() { } void BytecodeGraphBuilder::VisitSub() { - BuildBinaryOp(javascript()->Subtract( - GetBinaryOperationHint(kBinaryOperationHintIndex))); + BuildBinaryOp(javascript()->Subtract()); } void BytecodeGraphBuilder::VisitMul() { - BuildBinaryOp(javascript()->Multiply( - GetBinaryOperationHint(kBinaryOperationHintIndex))); + BuildBinaryOp(javascript()->Multiply()); } -void BytecodeGraphBuilder::VisitDiv() { - BuildBinaryOp( - javascript()->Divide(GetBinaryOperationHint(kBinaryOperationHintIndex))); -} +void BytecodeGraphBuilder::VisitDiv() { BuildBinaryOp(javascript()->Divide()); } void BytecodeGraphBuilder::VisitMod() { - BuildBinaryOp( - javascript()->Modulus(GetBinaryOperationHint(kBinaryOperationHintIndex))); + BuildBinaryOp(javascript()->Modulus()); } void BytecodeGraphBuilder::VisitBitwiseOr() { @@ -1605,10 +1599,10 @@ void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* op) { Node* left = environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); Node* right = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0)); - FeedbackSlot slot = feedback_vector()->ToSlot( - bytecode_iterator().GetIndexOperand(kBinaryOperationSmiHintIndex)); Node* node = nullptr; + FeedbackSlot slot = feedback_vector()->ToSlot( + bytecode_iterator().GetIndexOperand(kBinaryOperationSmiHintIndex)); if (Node* simplified = TryBuildSimplifiedBinaryOp(op, left, right, slot)) { node = simplified; } else { @@ -1624,8 +1618,7 @@ void BytecodeGraphBuilder::VisitAddSmi() { } void BytecodeGraphBuilder::VisitSubSmi() { - BuildBinaryOpWithImmediate(javascript()->Subtract( - GetBinaryOperationHint(kBinaryOperationSmiHintIndex))); + BuildBinaryOpWithImmediate(javascript()->Subtract()); } void BytecodeGraphBuilder::VisitBitwiseOrSmi() { @@ -1648,19 +1641,37 @@ void BytecodeGraphBuilder::VisitInc() { PrepareEagerCheckpoint(); // Note: Use subtract -1 here instead of add 1 to ensure we always convert to // a number, not a string. - const Operator* js_op = - javascript()->Subtract(GetBinaryOperationHint(kCountOperationHintIndex)); - Node* node = NewNode(js_op, environment()->LookupAccumulator(), - jsgraph()->Constant(-1)); + Node* left = environment()->LookupAccumulator(); + Node* right = jsgraph()->Constant(-1); + const Operator* op = javascript()->Subtract(); + + Node* node = nullptr; + FeedbackSlot slot = feedback_vector()->ToSlot( + bytecode_iterator().GetIndexOperand(kCountOperationHintIndex)); + if (Node* simplified = TryBuildSimplifiedBinaryOp(op, left, right, slot)) { + node = simplified; + } else { + node = NewNode(op, left, right); + } + environment()->BindAccumulator(node, Environment::kAttachFrameState); } void BytecodeGraphBuilder::VisitDec() { PrepareEagerCheckpoint(); - const Operator* js_op = - javascript()->Subtract(GetBinaryOperationHint(kCountOperationHintIndex)); - Node* node = NewNode(js_op, environment()->LookupAccumulator(), - jsgraph()->OneConstant()); + Node* left = environment()->LookupAccumulator(); + Node* right = jsgraph()->OneConstant(); + const Operator* op = javascript()->Subtract(); + + Node* node = nullptr; + FeedbackSlot slot = feedback_vector()->ToSlot( + bytecode_iterator().GetIndexOperand(kCountOperationHintIndex)); + if (Node* simplified = TryBuildSimplifiedBinaryOp(op, left, right, slot)) { + node = simplified; + } else { + node = NewNode(op, left, right); + } + environment()->BindAccumulator(node, Environment::kAttachFrameState); } diff --git a/src/compiler/js-operator.cc b/src/compiler/js-operator.cc index 2a97a20b92..e0bd847707 100644 --- a/src/compiler/js-operator.cc +++ b/src/compiler/js-operator.cc @@ -545,6 +545,10 @@ CompareOperationHint CompareOperationHintOf(const Operator* op) { V(ShiftLeft, Operator::kNoProperties, 2, 1) \ V(ShiftRight, Operator::kNoProperties, 2, 1) \ V(ShiftRightLogical, Operator::kNoProperties, 2, 1) \ + V(Subtract, Operator::kNoProperties, 2, 1) \ + V(Multiply, Operator::kNoProperties, 2, 1) \ + V(Divide, Operator::kNoProperties, 2, 1) \ + V(Modulus, Operator::kNoProperties, 2, 1) \ V(ToInteger, Operator::kNoProperties, 1, 1) \ V(ToLength, Operator::kNoProperties, 1, 1) \ V(ToName, Operator::kNoProperties, 1, 1) \ @@ -568,12 +572,7 @@ CompareOperationHint CompareOperationHintOf(const Operator* op) { V(Debugger, Operator::kNoProperties, 0, 0) \ V(GetSuperConstructor, Operator::kNoWrite, 1, 1) -#define BINARY_OP_LIST(V) \ - V(Add) \ - V(Subtract) \ - V(Multiply) \ - V(Divide) \ - V(Modulus) +#define BINARY_OP_LIST(V) V(Add) #define COMPARE_OP_LIST(V) \ V(Equal, Operator::kNoProperties) \ diff --git a/src/compiler/js-operator.h b/src/compiler/js-operator.h index 74bcb00e88..e3f98edbba 100644 --- a/src/compiler/js-operator.h +++ b/src/compiler/js-operator.h @@ -579,10 +579,10 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final const Operator* ShiftRight(); const Operator* ShiftRightLogical(); const Operator* Add(BinaryOperationHint hint); - const Operator* Subtract(BinaryOperationHint hint); - const Operator* Multiply(BinaryOperationHint hint); - const Operator* Divide(BinaryOperationHint hint); - const Operator* Modulus(BinaryOperationHint hint); + const Operator* Subtract(); + const Operator* Multiply(); + const Operator* Divide(); + const Operator* Modulus(); const Operator* ToBoolean(ToBooleanHints hints); const Operator* ToInteger(); diff --git a/src/compiler/js-type-hint-lowering.cc b/src/compiler/js-type-hint-lowering.cc index 3c440fb201..8045be72eb 100644 --- a/src/compiler/js-type-hint-lowering.cc +++ b/src/compiler/js-type-hint-lowering.cc @@ -127,7 +127,11 @@ Reduction JSTypeHintLowering::ReduceBinaryOperation(const Operator* op, case IrOpcode::kJSBitwiseAnd: case IrOpcode::kJSShiftLeft: case IrOpcode::kJSShiftRight: - case IrOpcode::kJSShiftRightLogical: { + case IrOpcode::kJSShiftRightLogical: + case IrOpcode::kJSSubtract: + case IrOpcode::kJSMultiply: + case IrOpcode::kJSDivide: + case IrOpcode::kJSModulus: { JSSpeculativeBinopBuilder b(this, op, left, right, effect, control, slot); NumberOperationHint hint; if (b.GetBinaryNumberOperationHint(&hint)) { @@ -137,10 +141,6 @@ Reduction JSTypeHintLowering::ReduceBinaryOperation(const Operator* op, break; } case IrOpcode::kJSAdd: - case IrOpcode::kJSSubtract: - case IrOpcode::kJSMultiply: - case IrOpcode::kJSDivide: - case IrOpcode::kJSModulus: // TODO(mstarzinger): Implement speculative lowering. break; default: diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc index 5652c47d97..c4c80bd671 100644 --- a/src/compiler/js-typed-lowering.cc +++ b/src/compiler/js-typed-lowering.cc @@ -370,6 +370,25 @@ class JSBinopReduction final { return nullptr; } + const Operator* NumberOpFromSpeculativeNumberOp() { + switch (node_->opcode()) { + case IrOpcode::kSpeculativeNumberAdd: + return simplified()->NumberAdd(); + case IrOpcode::kSpeculativeNumberSubtract: + return simplified()->NumberSubtract(); + case IrOpcode::kSpeculativeNumberMultiply: + return simplified()->NumberMultiply(); + case IrOpcode::kSpeculativeNumberDivide: + return simplified()->NumberDivide(); + case IrOpcode::kSpeculativeNumberModulus: + return simplified()->NumberModulus(); + default: + break; + } + UNREACHABLE(); + return nullptr; + } + const Operator* SpeculativeNumberOp(NumberOperationHint hint) { switch (node_->opcode()) { case IrOpcode::kJSAdd: @@ -632,16 +651,6 @@ Reduction JSTypedLowering::ReduceJSAdd(Node* node) { Reduction JSTypedLowering::ReduceNumberBinop(Node* node) { JSBinopReduction r(this, node); - NumberOperationHint hint; - if (r.GetBinaryNumberOperationHint(&hint)) { - if (hint == NumberOperationHint::kNumberOrOddball && - r.BothInputsAre(Type::NumberOrOddball())) { - r.ConvertInputsToNumber(); - return r.ChangeToPureOperator(r.NumberOp(), Type::Number()); - } - return r.ChangeToSpeculativeOperator(r.SpeculativeNumberOp(hint), - Type::Number()); - } if (r.BothInputsAre(Type::PlainPrimitive()) || !(flags() & kDeoptimizationEnabled)) { r.ConvertInputsToNumber(); @@ -650,6 +659,18 @@ Reduction JSTypedLowering::ReduceNumberBinop(Node* node) { return NoChange(); } +Reduction JSTypedLowering::ReduceSpeculativeNumberBinop(Node* node) { + JSBinopReduction r(this, node); + NumberOperationHint hint = NumberOperationHintOf(node->op()); + if (hint == NumberOperationHint::kNumberOrOddball && + r.BothInputsAre(Type::NumberOrOddball())) { + r.ConvertInputsToNumber(); + return r.ChangeToPureOperator(r.NumberOpFromSpeculativeNumberOp(), + Type::Number()); + } + return NoChange(); +} + Reduction JSTypedLowering::ReduceInt32Binop(Node* node) { JSBinopReduction r(this, node); if (r.BothInputsAre(Type::PlainPrimitive()) || @@ -2473,6 +2494,13 @@ Reduction JSTypedLowering::Reduce(Node* node) { return ReduceJSGeneratorRestoreContinuation(node); case IrOpcode::kJSGeneratorRestoreRegister: return ReduceJSGeneratorRestoreRegister(node); + // TODO(mstarzinger): Simplified operations hiding in JS-level reducer not + // fooling anyone. Consider moving this into a separate reducer. + case IrOpcode::kSpeculativeNumberSubtract: + case IrOpcode::kSpeculativeNumberMultiply: + case IrOpcode::kSpeculativeNumberDivide: + case IrOpcode::kSpeculativeNumberModulus: + return ReduceSpeculativeNumberBinop(node); default: break; } diff --git a/src/compiler/js-typed-lowering.h b/src/compiler/js-typed-lowering.h index 0abbcf2b66..bd2147e02d 100644 --- a/src/compiler/js-typed-lowering.h +++ b/src/compiler/js-typed-lowering.h @@ -84,6 +84,7 @@ class V8_EXPORT_PRIVATE JSTypedLowering final Reduction ReduceInt32Binop(Node* node); Reduction ReduceUI32Shift(Node* node, Signedness signedness); Reduction ReduceCreateConsString(Node* node); + Reduction ReduceSpeculativeNumberBinop(Node* node); Factory* factory() const; Graph* graph() const; diff --git a/test/cctest/compiler/test-js-typed-lowering.cc b/test/cctest/compiler/test-js-typed-lowering.cc index b656d4d2b1..360672c41a 100644 --- a/test/cctest/compiler/test-js-typed-lowering.cc +++ b/test/cctest/compiler/test-js-typed-lowering.cc @@ -264,11 +264,11 @@ TEST(AddNumber1) { TEST(NumberBinops) { JSTypedLoweringTester R; const Operator* ops[] = { - R.javascript.Add(R.binop_hints), R.simplified.NumberAdd(), - R.javascript.Subtract(R.binop_hints), R.simplified.NumberSubtract(), - R.javascript.Multiply(R.binop_hints), R.simplified.NumberMultiply(), - R.javascript.Divide(R.binop_hints), R.simplified.NumberDivide(), - R.javascript.Modulus(R.binop_hints), R.simplified.NumberModulus(), + R.javascript.Add(R.binop_hints), R.simplified.NumberAdd(), + R.javascript.Subtract(), R.simplified.NumberSubtract(), + R.javascript.Multiply(), R.simplified.NumberMultiply(), + R.javascript.Divide(), R.simplified.NumberDivide(), + R.javascript.Modulus(), R.simplified.NumberModulus(), }; for (size_t i = 0; i < arraysize(kNumberTypes); ++i) { @@ -899,13 +899,13 @@ TEST(RemovePureNumberBinopEffects) { R.simplified.NumberEqual(), R.javascript.Add(R.binop_hints), R.simplified.NumberAdd(), - R.javascript.Subtract(R.binop_hints), + R.javascript.Subtract(), R.simplified.NumberSubtract(), - R.javascript.Multiply(R.binop_hints), + R.javascript.Multiply(), R.simplified.NumberMultiply(), - R.javascript.Divide(R.binop_hints), + R.javascript.Divide(), R.simplified.NumberDivide(), - R.javascript.Modulus(R.binop_hints), + R.javascript.Modulus(), R.simplified.NumberModulus(), R.javascript.LessThan(R.compare_hints), R.simplified.NumberLessThan(), @@ -931,8 +931,8 @@ TEST(OrderNumberBinopEffects1) { JSTypedLoweringTester R; const Operator* ops[] = { - R.javascript.Subtract(R.binop_hints), R.simplified.NumberSubtract(), - R.javascript.Multiply(R.binop_hints), R.simplified.NumberMultiply(), + R.javascript.Subtract(), R.simplified.NumberSubtract(), + R.javascript.Multiply(), R.simplified.NumberMultiply(), }; for (size_t j = 0; j < arraysize(ops); j += 2) { @@ -956,9 +956,9 @@ TEST(OrderNumberBinopEffects2) { JSTypedLoweringTester R; const Operator* ops[] = { - R.javascript.Add(R.binop_hints), R.simplified.NumberAdd(), - R.javascript.Subtract(R.binop_hints), R.simplified.NumberSubtract(), - R.javascript.Multiply(R.binop_hints), R.simplified.NumberMultiply(), + R.javascript.Add(R.binop_hints), R.simplified.NumberAdd(), + R.javascript.Subtract(), R.simplified.NumberSubtract(), + R.javascript.Multiply(), R.simplified.NumberMultiply(), }; for (size_t j = 0; j < arraysize(ops); j += 2) { diff --git a/test/unittests/compiler/js-typed-lowering-unittest.cc b/test/unittests/compiler/js-typed-lowering-unittest.cc index e8a6fd09ce..53bacaac3d 100644 --- a/test/unittests/compiler/js-typed-lowering-unittest.cc +++ b/test/unittests/compiler/js-typed-lowering-unittest.cc @@ -717,25 +717,6 @@ TEST_F(JSTypedLoweringTest, JSAddSmis) { rhs, effect, control)); } -// ----------------------------------------------------------------------------- -// JSSubtract - -TEST_F(JSTypedLoweringTest, JSSubtractSmis) { - 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()->Subtract(hint), lhs, rhs, - context, frame_state, effect, control)); - ASSERT_TRUE(r.Changed()); - EXPECT_THAT(r.replacement(), - IsSpeculativeNumberSubtract(NumberOperationHint::kSignedSmall, - lhs, rhs, effect, control)); -} - } // namespace compiler } // namespace internal } // namespace v8 diff --git a/test/unittests/compiler/typer-unittest.cc b/test/unittests/compiler/typer-unittest.cc index 8684523522..13c190d363 100644 --- a/test/unittests/compiler/typer-unittest.cc +++ b/test/unittests/compiler/typer-unittest.cc @@ -245,22 +245,22 @@ TEST_F(TyperTest, TypeJSAdd) { TEST_F(TyperTest, TypeJSSubtract) { - TestBinaryArithOp(javascript_.Subtract(hints_), std::minus()); + TestBinaryArithOp(javascript_.Subtract(), std::minus()); } TEST_F(TyperTest, TypeJSMultiply) { - TestBinaryArithOp(javascript_.Multiply(hints_), std::multiplies()); + TestBinaryArithOp(javascript_.Multiply(), std::multiplies()); } TEST_F(TyperTest, TypeJSDivide) { - TestBinaryArithOp(javascript_.Divide(hints_), std::divides()); + TestBinaryArithOp(javascript_.Divide(), std::divides()); } TEST_F(TyperTest, TypeJSModulus) { - TestBinaryArithOp(javascript_.Modulus(hints_), modulo); + TestBinaryArithOp(javascript_.Modulus(), modulo); } @@ -366,6 +366,10 @@ TEST_BINARY_MONOTONICITY(BitwiseAnd) TEST_BINARY_MONOTONICITY(ShiftLeft) TEST_BINARY_MONOTONICITY(ShiftRight) TEST_BINARY_MONOTONICITY(ShiftRightLogical) +TEST_BINARY_MONOTONICITY(Subtract) +TEST_BINARY_MONOTONICITY(Multiply) +TEST_BINARY_MONOTONICITY(Divide) +TEST_BINARY_MONOTONICITY(Modulus) #undef TEST_BINARY_MONOTONICITY #define TEST_BINARY_MONOTONICITY(name) \ @@ -373,10 +377,6 @@ TEST_BINARY_MONOTONICITY(ShiftRightLogical) TestBinaryMonotonicity(javascript_.name(BinaryOperationHint::kAny)); \ } TEST_BINARY_MONOTONICITY(Add) -TEST_BINARY_MONOTONICITY(Subtract) -TEST_BINARY_MONOTONICITY(Multiply) -TEST_BINARY_MONOTONICITY(Divide) -TEST_BINARY_MONOTONICITY(Modulus) #undef TEST_BINARY_MONOTONICITY } // namespace compiler