[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/443185 Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Commit-Queue: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#43235}
This commit is contained in:
parent
c0fe56e63d
commit
9d53d16bcf
@ -1942,8 +1942,9 @@ void BytecodeGraphBuilder::VisitForInStep() {
|
||||
PrepareEagerCheckpoint();
|
||||
Node* index =
|
||||
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
|
||||
index = NewNode(javascript()->Add(BinaryOperationHint::kSignedSmall), index,
|
||||
jsgraph()->OneConstant());
|
||||
index = NewNode(
|
||||
simplified()->SpeculativeNumberAdd(NumberOperationHint::kSignedSmall),
|
||||
index, jsgraph()->OneConstant());
|
||||
environment()->BindAccumulator(index, Environment::kAttachFrameState);
|
||||
}
|
||||
|
||||
|
@ -518,11 +518,7 @@ const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op) {
|
||||
}
|
||||
|
||||
BinaryOperationHint BinaryOperationHintOf(const Operator* op) {
|
||||
DCHECK(op->opcode() == IrOpcode::kJSAdd ||
|
||||
op->opcode() == IrOpcode::kJSSubtract ||
|
||||
op->opcode() == IrOpcode::kJSMultiply ||
|
||||
op->opcode() == IrOpcode::kJSDivide ||
|
||||
op->opcode() == IrOpcode::kJSModulus);
|
||||
DCHECK_EQ(IrOpcode::kJSAdd, op->opcode());
|
||||
return OpParameter<BinaryOperationHint>(op);
|
||||
}
|
||||
|
||||
|
@ -128,6 +128,7 @@ Reduction JSTypeHintLowering::ReduceBinaryOperation(const Operator* op,
|
||||
case IrOpcode::kJSShiftLeft:
|
||||
case IrOpcode::kJSShiftRight:
|
||||
case IrOpcode::kJSShiftRightLogical:
|
||||
case IrOpcode::kJSAdd:
|
||||
case IrOpcode::kJSSubtract:
|
||||
case IrOpcode::kJSMultiply:
|
||||
case IrOpcode::kJSDivide:
|
||||
@ -140,9 +141,6 @@ Reduction JSTypeHintLowering::ReduceBinaryOperation(const Operator* op,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IrOpcode::kJSAdd:
|
||||
// TODO(mstarzinger): Implement speculative lowering.
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
@ -30,30 +30,6 @@ class JSBinopReduction final {
|
||||
JSBinopReduction(JSTypedLowering* 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) {
|
||||
if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
|
||||
DCHECK_EQ(1, node_->op()->EffectOutputCount());
|
||||
@ -113,6 +89,7 @@ class JSBinopReduction final {
|
||||
// minimum length.
|
||||
bool ShouldCreateConsString() {
|
||||
DCHECK_EQ(IrOpcode::kJSAdd, node_->opcode());
|
||||
DCHECK(OneInputIs(Type::String()));
|
||||
if (BothInputsAre(Type::String()) ||
|
||||
((lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) &&
|
||||
BinaryOperationHintOf(node_->op()) == BinaryOperationHint::kString)) {
|
||||
@ -590,20 +567,22 @@ JSTypedLowering::JSTypedLowering(Editor* editor,
|
||||
}
|
||||
}
|
||||
|
||||
Reduction JSTypedLowering::ReduceSpeculativeNumberAdd(Node* node) {
|
||||
JSBinopReduction r(this, node);
|
||||
NumberOperationHint hint = NumberOperationHintOf(node->op());
|
||||
if (hint == NumberOperationHint::kNumberOrOddball &&
|
||||
r.BothInputsAre(Type::PlainPrimitive()) &&
|
||||
r.NeitherInputCanBe(Type::StringOrReceiver())) {
|
||||
// SpeculativeNumberAdd(x:-string, y:-string) =>
|
||||
// NumberAdd(ToNumber(x), ToNumber(y))
|
||||
r.ConvertInputsToNumber();
|
||||
return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
|
||||
}
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
Reduction JSTypedLowering::ReduceJSAdd(Node* node) {
|
||||
JSBinopReduction r(this, node);
|
||||
NumberOperationHint hint;
|
||||
if (r.GetBinaryNumberOperationHint(&hint)) {
|
||||
if (hint == NumberOperationHint::kNumberOrOddball &&
|
||||
r.BothInputsAre(Type::PlainPrimitive()) &&
|
||||
r.NeitherInputCanBe(Type::StringOrReceiver())) {
|
||||
// JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y))
|
||||
r.ConvertInputsToNumber();
|
||||
return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
|
||||
}
|
||||
return r.ChangeToSpeculativeOperator(
|
||||
simplified()->SpeculativeNumberAdd(hint), Type::Number());
|
||||
}
|
||||
if (r.BothInputsAre(Type::Number())) {
|
||||
// JSAdd(x:number, y:number) => NumberAdd(x, y)
|
||||
r.ConvertInputsToNumber();
|
||||
@ -2496,6 +2475,8 @@ Reduction JSTypedLowering::Reduce(Node* node) {
|
||||
return ReduceJSGeneratorRestoreRegister(node);
|
||||
// TODO(mstarzinger): Simplified operations hiding in JS-level reducer not
|
||||
// fooling anyone. Consider moving this into a separate reducer.
|
||||
case IrOpcode::kSpeculativeNumberAdd:
|
||||
return ReduceSpeculativeNumberAdd(node);
|
||||
case IrOpcode::kSpeculativeNumberSubtract:
|
||||
case IrOpcode::kSpeculativeNumberMultiply:
|
||||
case IrOpcode::kSpeculativeNumberDivide:
|
||||
|
@ -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 ReduceSpeculativeNumberAdd(Node* node);
|
||||
Reduction ReduceSpeculativeNumberBinop(Node* node);
|
||||
|
||||
Factory* factory() const;
|
||||
|
@ -1187,8 +1187,11 @@ class RepresentationSelector {
|
||||
// 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())) {
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -701,22 +701,6 @@ TEST_F(JSTypedLoweringTest, JSAddWithString) {
|
||||
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 internal
|
||||
} // namespace v8
|
||||
|
Loading…
Reference in New Issue
Block a user