Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Unified Diff: src/compiler/js-typed-lowering.cc

Issue 1921563002: [turbofan] Initial version of number type feedback. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/js-typed-lowering.h ('k') | src/compiler/opcodes.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/js-typed-lowering.cc
diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc
index 8375ece60cd1e2393b104d91182ff63adac67ae8..b5c8af66cf309afc491b01e09a9537ce88324c91 100644
--- a/src/compiler/js-typed-lowering.cc
+++ b/src/compiler/js-typed-lowering.cc
@@ -27,6 +27,24 @@ class JSBinopReduction final {
JSBinopReduction(JSTypedLowering* lowering, Node* node)
: lowering_(lowering), node_(node) {}
+ BinaryOperationHints::Hint GetUsableNumberFeedback() {
+ if (!(lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) ||
+ !(lowering_->flags() & JSTypedLowering::kTypeFeedbackEnabled)) {
+ return BinaryOperationHints::kAny;
+ }
+ DCHECK_NE(0, node_->op()->ControlOutputCount());
+ DCHECK_EQ(1, node_->op()->EffectOutputCount());
+ DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node_->op()));
+ BinaryOperationHints hints = BinaryOperationHintsOf(node_->op());
+ BinaryOperationHints::Hint combined = hints.combined();
+ if (combined == BinaryOperationHints::kSignedSmall ||
+ combined == BinaryOperationHints::kSigned32 ||
+ combined == BinaryOperationHints::kNumberOrUndefined) {
+ return combined;
+ }
+ return BinaryOperationHints::kAny;
+ }
+
void ConvertInputsToNumberOrUndefined(Node* frame_state) {
// To convert the inputs to numbers, we have to provide frame states
// for lazy bailouts in the ToNumber conversions.
@@ -107,6 +125,52 @@ class JSBinopReduction final {
return lowering_->Changed(node_);
}
+ Reduction ChangeToSpeculativeOperator(const Operator* op) {
+ DCHECK_EQ(1, op->EffectInputCount());
+ DCHECK_EQ(1, op->EffectOutputCount());
+ DCHECK_EQ(false, OperatorProperties::HasContextInput(op));
+ DCHECK_EQ(1, op->ControlInputCount());
+ DCHECK_EQ(1, op->ControlOutputCount());
+ DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(op));
+ DCHECK_EQ(2, op->ValueInputCount());
+
+ DCHECK_EQ(1, node_->op()->EffectInputCount());
+ DCHECK_EQ(1, node_->op()->EffectOutputCount());
+ DCHECK_EQ(1, node_->op()->ControlInputCount());
+ DCHECK_LT(1, node_->op()->ControlOutputCount());
+ DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node_->op()));
+ DCHECK_EQ(2, node_->op()->ValueInputCount());
+
+ // Reconnect the control output to bypass the IfSuccess node and
+ // possibly disconnect from the IfException node.
+ for (Edge edge : node_->use_edges()) {
+ Node* const user = edge.from();
+ DCHECK(!user->IsDead());
+ if (NodeProperties::IsControlEdge(edge)) {
+ if (user->opcode() == IrOpcode::kIfSuccess) {
+ user->ReplaceUses(node_);
+ user->Kill();
+ } else {
+ DCHECK_EQ(user->opcode(), IrOpcode::kIfException);
+ edge.UpdateTo(jsgraph()->Dead());
+ }
+ }
+ }
+
+ // Remove the lazy bailout frame state and the context.
+ node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_));
+ node_->RemoveInput(NodeProperties::FirstContextIndex(node_));
+
+ NodeProperties::ChangeOp(node_, op);
+
+ // Update the type to number.
+ Type* node_type = NodeProperties::GetType(node_);
+ NodeProperties::SetType(node_,
+ Type::Intersect(node_type, Type::Number(), zone()));
+
+ return lowering_->Changed(node_);
+ }
+
Reduction ChangeToPureOperator(const Operator* op, Type* type) {
return ChangeToPureOperator(op, false, type);
}
@@ -340,9 +404,18 @@ Reduction JSTypedLowering::ReduceJSAdd(Node* node) {
if (flags() & kDisableBinaryOpReduction) return NoChange();
JSBinopReduction r(this, node);
+
+ BinaryOperationHints::Hint feedback = r.GetUsableNumberFeedback();
+ if (feedback != BinaryOperationHints::kAny) {
+ // Lower to the optimistic number binop.
+ return r.ChangeToSpeculativeOperator(
+ simplified()->SpeculativeNumberAdd(feedback));
+ }
if (r.BothInputsAre(Type::NumberOrUndefined())) {
// JSAdd(x:number, y:number) => NumberAdd(x, y)
- return ReduceNumberBinop(node, simplified()->NumberAdd());
+ Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
+ r.ConvertInputsToNumberOrUndefined(frame_state);
+ return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
}
if (r.NeitherInputCanBe(Type::StringOrReceiver())) {
// JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y))
@@ -387,21 +460,34 @@ Reduction JSTypedLowering::ReduceJSModulus(Node* node) {
return NoChange();
}
+Reduction JSTypedLowering::ReduceJSSubtract(Node* node) {
+ if (flags() & kDisableBinaryOpReduction) return NoChange();
+ JSBinopReduction r(this, node);
+ BinaryOperationHints::Hint feedback = r.GetUsableNumberFeedback();
+ if (feedback != BinaryOperationHints::kAny) {
+ // Lower to the optimistic number binop.
+ return r.ChangeToSpeculativeOperator(
+ simplified()->SpeculativeNumberSubtract(feedback));
+ }
+ Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
+ r.ConvertInputsToNumberOrUndefined(frame_state);
+ return r.ChangeToPureOperator(simplified()->NumberSubtract(), Type::Number());
+}
-Reduction JSTypedLowering::ReduceNumberBinop(Node* node,
- const Operator* numberOp) {
+Reduction JSTypedLowering::ReduceJSMultiply(Node* node) {
if (flags() & kDisableBinaryOpReduction) return NoChange();
+ JSBinopReduction r(this, node);
+ Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
+ r.ConvertInputsToNumberOrUndefined(frame_state);
+ return r.ChangeToPureOperator(simplified()->NumberMultiply(), Type::Number());
+}
+Reduction JSTypedLowering::ReduceJSDivide(Node* node) {
+ if (flags() & kDisableBinaryOpReduction) return NoChange();
JSBinopReduction r(this, node);
- if (numberOp == simplified()->NumberModulus()) {
- if (r.BothInputsAre(Type::NumberOrUndefined())) {
- return r.ChangeToPureOperator(numberOp, Type::Number());
- }
- return NoChange();
- }
Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
r.ConvertInputsToNumberOrUndefined(frame_state);
- return r.ChangeToPureOperator(numberOp, Type::Number());
+ return r.ChangeToPureOperator(simplified()->NumberDivide(), Type::Number());
}
@@ -1785,11 +1871,11 @@ Reduction JSTypedLowering::Reduce(Node* node) {
case IrOpcode::kJSAdd:
return ReduceJSAdd(node);
case IrOpcode::kJSSubtract:
- return ReduceNumberBinop(node, simplified()->NumberSubtract());
+ return ReduceJSSubtract(node);
case IrOpcode::kJSMultiply:
- return ReduceNumberBinop(node, simplified()->NumberMultiply());
+ return ReduceJSMultiply(node);
case IrOpcode::kJSDivide:
- return ReduceNumberBinop(node, simplified()->NumberDivide());
+ return ReduceJSDivide(node);
case IrOpcode::kJSModulus:
return ReduceJSModulus(node);
case IrOpcode::kJSToBoolean:
« no previous file with comments | « src/compiler/js-typed-lowering.h ('k') | src/compiler/opcodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698