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

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

Issue 2220573002: [turbofan] Add NumberOperationHint for speculative number operations. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Update comment. Created 4 years, 4 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/simplified-lowering.cc » ('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 1227e4f08cb6dd60654ac8dc2976ce8ceb25fb28..dc86dc3ad33586979794a54736483912a1ce557f 100644
--- a/src/compiler/js-typed-lowering.cc
+++ b/src/compiler/js-typed-lowering.cc
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "src/compiler/js-typed-lowering.h"
+
#include "src/code-factory.h"
#include "src/compilation-dependencies.h"
#include "src/compiler/access-builder.h"
#include "src/compiler/js-graph.h"
-#include "src/compiler/js-typed-lowering.h"
#include "src/compiler/linkage.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/node-properties.h"
@@ -27,35 +28,55 @@ class JSBinopReduction final {
JSBinopReduction(JSTypedLowering* lowering, Node* node)
: lowering_(lowering), node_(node) {}
- BinaryOperationHints::Hint GetNumberBinaryOperationFeedback() {
+ 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()));
BinaryOperationHints hints = BinaryOperationHintsOf(node_->op());
- BinaryOperationHints::Hint combined = hints.combined();
- if (combined == BinaryOperationHints::kSignedSmall ||
- combined == BinaryOperationHints::kSigned32 ||
- combined == BinaryOperationHints::kNumberOrOddball) {
- return combined;
+ switch (hints.combined()) {
+ case BinaryOperationHints::kSignedSmall:
+ *hint = NumberOperationHint::kSignedSmall;
+ return true;
+ case BinaryOperationHints::kSigned32:
+ *hint = NumberOperationHint::kSigned32;
+ return true;
+ case BinaryOperationHints::kNumberOrOddball:
+ *hint = NumberOperationHint::kNumberOrOddball;
+ return true;
+ case BinaryOperationHints::kAny:
+ case BinaryOperationHints::kNone:
+ case BinaryOperationHints::kString:
+ break;
}
}
- return BinaryOperationHints::kAny;
+ return false;
}
- CompareOperationHints::Hint GetNumberCompareOperationFeedback() {
+ bool GetCompareNumberOperationHint(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()));
CompareOperationHints hints = CompareOperationHintsOf(node_->op());
- CompareOperationHints::Hint combined = hints.combined();
- if (combined == CompareOperationHints::kSignedSmall ||
- combined == CompareOperationHints::kNumberOrOddball) {
- return combined;
+ switch (hints.combined()) {
+ case CompareOperationHints::kSignedSmall:
+ *hint = NumberOperationHint::kSignedSmall;
+ return true;
+ case CompareOperationHints::kNumberOrOddball:
+ *hint = NumberOperationHint::kNumberOrOddball;
+ return true;
+ case CompareOperationHints::kAny:
+ case CompareOperationHints::kNone:
+ case CompareOperationHints::kString:
+ case CompareOperationHints::kBoolean:
+ case CompareOperationHints::kUniqueName:
+ case CompareOperationHints::kInternalizedString:
+ case CompareOperationHints::kReceiver:
+ break;
}
}
- return CompareOperationHints::kAny;
+ return false;
}
void ConvertInputsToNumber() {
@@ -354,18 +375,17 @@ JSTypedLowering::JSTypedLowering(Editor* editor,
Reduction JSTypedLowering::ReduceJSAdd(Node* node) {
JSBinopReduction r(this, node);
- BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
- if (feedback == BinaryOperationHints::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());
- }
- if (feedback != BinaryOperationHints::kAny) {
- // Lower to the optimistic number binop.
+ 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(feedback), Type::Number());
+ simplified()->SpeculativeNumberAdd(hint), Type::Number());
}
if (r.BothInputsAre(Type::Number())) {
// JSAdd(x:number, y:number) => NumberAdd(x, y)
@@ -402,75 +422,69 @@ Reduction JSTypedLowering::ReduceJSAdd(Node* node) {
return NoChange();
}
-
Reduction JSTypedLowering::ReduceJSSubtract(Node* node) {
JSBinopReduction r(this, node);
- BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
- if (feedback == BinaryOperationHints::kNumberOrOddball &&
- r.BothInputsAre(Type::PlainPrimitive())) {
- // JSSubtract(x:plain-primitive, y:plain-primitive)
- // => NumberSubtract(ToNumber(x), ToNumber(y))
- r.ConvertInputsToNumber();
- return r.ChangeToPureOperator(simplified()->NumberSubtract(),
- Type::Number());
- }
- if (feedback != BinaryOperationHints::kAny) {
- // Lower to the optimistic number binop.
+ NumberOperationHint hint;
+ if (r.GetBinaryNumberOperationHint(&hint)) {
+ if (hint == NumberOperationHint::kNumberOrOddball &&
+ r.BothInputsAre(Type::PlainPrimitive())) {
+ // JSSubtract(x:plain-primitive, y:plain-primitive)
+ // => NumberSubtract(ToNumber(x), ToNumber(y))
+ r.ConvertInputsToNumber();
+ return r.ChangeToPureOperator(simplified()->NumberSubtract(),
+ Type::Number());
+ }
return r.ChangeToSpeculativeOperator(
- simplified()->SpeculativeNumberSubtract(feedback), Type::Number());
+ simplified()->SpeculativeNumberSubtract(hint), Type::Number());
}
-
- // If deoptimization is enabled we rely on type feedback.
if (r.BothInputsAre(Type::PlainPrimitive()) ||
!(flags() & kDeoptimizationEnabled)) {
r.ConvertInputsToNumber();
return r.ChangeToPureOperator(simplified()->NumberSubtract(),
Type::Number());
}
-
return NoChange();
}
Reduction JSTypedLowering::ReduceJSMultiply(Node* node) {
JSBinopReduction r(this, node);
- BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
- if (feedback == BinaryOperationHints::kNumberOrOddball &&
- r.BothInputsAre(Type::PlainPrimitive())) {
- // JSMultiply(x:plain-primitive,
- // y:plain-primitive) => NumberMultiply(ToNumber(x), ToNumber(y))
- r.ConvertInputsToNumber();
- return r.ChangeToPureOperator(simplified()->NumberMultiply(),
- Type::Number());
- }
- if (feedback != BinaryOperationHints::kAny) {
+ NumberOperationHint hint;
+ if (r.GetBinaryNumberOperationHint(&hint)) {
+ if (hint == NumberOperationHint::kNumberOrOddball &&
+ r.BothInputsAre(Type::PlainPrimitive())) {
+ // JSMultiply(x:plain-primitive,
+ // y:plain-primitive) => NumberMultiply(ToNumber(x),
+ // ToNumber(y))
+ r.ConvertInputsToNumber();
+ return r.ChangeToPureOperator(simplified()->NumberMultiply(),
+ Type::Number());
+ }
return r.ChangeToSpeculativeOperator(
- simplified()->SpeculativeNumberMultiply(feedback), Type::Number());
+ simplified()->SpeculativeNumberMultiply(hint), Type::Number());
}
-
- // If deoptimization is enabled we rely on type feedback.
if (r.BothInputsAre(Type::PlainPrimitive()) ||
!(flags() & kDeoptimizationEnabled)) {
r.ConvertInputsToNumber();
return r.ChangeToPureOperator(simplified()->NumberMultiply(),
Type::Number());
}
-
return NoChange();
}
Reduction JSTypedLowering::ReduceJSDivide(Node* node) {
JSBinopReduction r(this, node);
- BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
- if (feedback == BinaryOperationHints::kNumberOrOddball &&
- r.BothInputsAre(Type::PlainPrimitive())) {
- // JSDivide(x:plain-primitive,
- // y:plain-primitive) => NumberDivide(ToNumber(x), ToNumber(y))
- r.ConvertInputsToNumber();
- return r.ChangeToPureOperator(simplified()->NumberDivide(), Type::Number());
- }
- if (feedback != BinaryOperationHints::kAny) {
+ NumberOperationHint hint;
+ if (r.GetBinaryNumberOperationHint(&hint)) {
+ if (hint == NumberOperationHint::kNumberOrOddball &&
+ r.BothInputsAre(Type::PlainPrimitive())) {
+ // JSDivide(x:plain-primitive,
+ // y:plain-primitive) => NumberDivide(ToNumber(x), ToNumber(y))
+ r.ConvertInputsToNumber();
+ return r.ChangeToPureOperator(simplified()->NumberDivide(),
+ Type::Number());
+ }
return r.ChangeToSpeculativeOperator(
- simplified()->SpeculativeNumberDivide(feedback), Type::Number());
+ simplified()->SpeculativeNumberDivide(hint), Type::Number());
}
if (r.BothInputsAre(Type::PlainPrimitive())) {
// JSDivide(x:plain-primitive,
@@ -483,18 +497,18 @@ Reduction JSTypedLowering::ReduceJSDivide(Node* node) {
Reduction JSTypedLowering::ReduceJSModulus(Node* node) {
JSBinopReduction r(this, node);
- BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
- if (feedback == BinaryOperationHints::kNumberOrOddball &&
- r.BothInputsAre(Type::PlainPrimitive())) {
- // JSModulus(x:plain-primitive,
- // y:plain-primitive) => NumberModulus(ToNumber(x), ToNumber(y))
- r.ConvertInputsToNumber();
- return r.ChangeToPureOperator(simplified()->NumberModulus(),
- Type::Number());
- }
- if (feedback != BinaryOperationHints::kAny) {
+ NumberOperationHint hint;
+ if (r.GetBinaryNumberOperationHint(&hint)) {
+ if (hint == NumberOperationHint::kNumberOrOddball &&
+ r.BothInputsAre(Type::PlainPrimitive())) {
+ // JSModulus(x:plain-primitive,
+ // y:plain-primitive) => NumberModulus(ToNumber(x), ToNumber(y))
+ r.ConvertInputsToNumber();
+ return r.ChangeToPureOperator(simplified()->NumberModulus(),
+ Type::Number());
+ }
return r.ChangeToSpeculativeOperator(
- simplified()->SpeculativeNumberModulus(feedback), Type::Number());
+ simplified()->SpeculativeNumberModulus(hint), Type::Number());
}
if (r.BothInputsAre(Type::PlainPrimitive())) {
// JSModulus(x:plain-primitive,
@@ -509,21 +523,19 @@ Reduction JSTypedLowering::ReduceJSModulus(Node* node) {
Reduction JSTypedLowering::ReduceInt32Binop(Node* node,
const Operator* int_op) {
JSBinopReduction r(this, node);
- BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
- if (feedback != BinaryOperationHints::kAny) {
+ NumberOperationHint hint;
+ if (r.GetBinaryNumberOperationHint(&hint)) {
Operator const* speculative_op;
if (int_op->opcode() == IrOpcode::kNumberBitwiseAnd) {
- speculative_op = simplified()->SpeculativeNumberBitwiseAnd(feedback);
+ speculative_op = simplified()->SpeculativeNumberBitwiseAnd(hint);
} else if (int_op->opcode() == IrOpcode::kNumberBitwiseOr) {
- speculative_op = simplified()->SpeculativeNumberBitwiseOr(feedback);
+ speculative_op = simplified()->SpeculativeNumberBitwiseOr(hint);
} else {
DCHECK_EQ(IrOpcode::kNumberBitwiseXor, int_op->opcode());
- speculative_op = simplified()->SpeculativeNumberBitwiseXor(feedback);
+ speculative_op = simplified()->SpeculativeNumberBitwiseXor(hint);
}
return r.ChangeToSpeculativeOperator(speculative_op, Type::Signed32());
}
-
- // If deoptimization is enabled we rely on type feedback.
if (r.BothInputsAre(Type::PlainPrimitive()) ||
!(flags() & kDeoptimizationEnabled)) {
r.ConvertInputsToNumber();
@@ -533,33 +545,28 @@ Reduction JSTypedLowering::ReduceInt32Binop(Node* node,
return NoChange();
}
-Reduction JSTypedLowering::ReduceUI32Shift(Node* node,
- Signedness left_signedness,
+Reduction JSTypedLowering::ReduceUI32Shift(Node* node, Signedness signedness,
const Operator* shift_op) {
JSBinopReduction r(this, node);
- BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
- if (feedback != BinaryOperationHints::kAny) {
+ NumberOperationHint hint;
+ if (r.GetBinaryNumberOperationHint(&hint)) {
Operator const* speculative_op;
if (shift_op->opcode() == IrOpcode::kNumberShiftLeft) {
- speculative_op = simplified()->SpeculativeNumberShiftLeft(feedback);
+ speculative_op = simplified()->SpeculativeNumberShiftLeft(hint);
} else if (shift_op->opcode() == IrOpcode::kNumberShiftRightLogical) {
- speculative_op =
- simplified()->SpeculativeNumberShiftRightLogical(feedback);
+ speculative_op = simplified()->SpeculativeNumberShiftRightLogical(hint);
} else {
DCHECK_EQ(IrOpcode::kNumberShiftRight, shift_op->opcode());
- speculative_op = simplified()->SpeculativeNumberShiftRight(feedback);
+ speculative_op = simplified()->SpeculativeNumberShiftRight(hint);
}
return r.ChangeToSpeculativeOperator(
- speculative_op, shift_op->opcode() == IrOpcode::kNumberShiftRightLogical
- ? Type::Unsigned32()
- : Type::Signed32());
+ speculative_op,
+ signedness == kUnsigned ? Type::Unsigned32() : Type::Signed32());
}
-
- // If deoptimization is enabled we rely on type feedback.
if (r.BothInputsAre(Type::PlainPrimitive()) ||
!(flags() & kDeoptimizationEnabled)) {
r.ConvertInputsToNumber();
- r.ConvertInputsToUI32(left_signedness, kUnsigned);
+ r.ConvertInputsToUI32(signedness, kUnsigned);
return r.ChangeToPureOperator(shift_op);
}
return NoChange();
@@ -592,53 +599,49 @@ Reduction JSTypedLowering::ReduceJSComparison(Node* node) {
return Changed(node);
}
- CompareOperationHints::Hint hint = r.GetNumberCompareOperationFeedback();
- if (hint != CompareOperationHints::kAny ||
- r.OneInputCannotBe(Type::StringOrReceiver())) {
- const Operator* less_than;
- const Operator* less_than_or_equal;
- if (r.BothInputsAre(Type::Signed32()) ||
- r.BothInputsAre(Type::Unsigned32())) {
- less_than = simplified()->NumberLessThan();
- less_than_or_equal = simplified()->NumberLessThanOrEqual();
- } else if (hint != CompareOperationHints::kAny) {
- less_than = simplified()->SpeculativeNumberLessThan(hint);
- less_than_or_equal = simplified()->SpeculativeNumberLessThanOrEqual(hint);
- } else if (r.BothInputsAre(Type::PlainPrimitive()) ||
- !(flags() & kDeoptimizationEnabled)) {
- r.ConvertInputsToNumber();
- less_than = simplified()->NumberLessThan();
- less_than_or_equal = simplified()->NumberLessThanOrEqual();
- } else {
+ NumberOperationHint hint;
+ const Operator* less_than;
+ const Operator* less_than_or_equal;
+ if (r.BothInputsAre(Type::Signed32()) ||
+ r.BothInputsAre(Type::Unsigned32())) {
+ less_than = simplified()->NumberLessThan();
+ less_than_or_equal = simplified()->NumberLessThanOrEqual();
+ } else if (r.GetCompareNumberOperationHint(&hint)) {
+ less_than = simplified()->SpeculativeNumberLessThan(hint);
+ less_than_or_equal = simplified()->SpeculativeNumberLessThanOrEqual(hint);
+ } else if (r.OneInputCannotBe(Type::StringOrReceiver()) &&
+ (r.BothInputsAre(Type::PlainPrimitive()) ||
+ !(flags() & kDeoptimizationEnabled))) {
+ r.ConvertInputsToNumber();
+ less_than = simplified()->NumberLessThan();
+ less_than_or_equal = simplified()->NumberLessThanOrEqual();
+ } else {
+ return NoChange();
+ }
+ const Operator* comparison;
+ switch (node->opcode()) {
+ case IrOpcode::kJSLessThan:
+ comparison = less_than;
+ break;
+ case IrOpcode::kJSGreaterThan:
+ comparison = less_than;
+ r.SwapInputs(); // a > b => b < a
+ break;
+ case IrOpcode::kJSLessThanOrEqual:
+ comparison = less_than_or_equal;
+ break;
+ case IrOpcode::kJSGreaterThanOrEqual:
+ comparison = less_than_or_equal;
+ r.SwapInputs(); // a >= b => b <= a
+ break;
+ default:
return NoChange();
- }
- const Operator* comparison;
- switch (node->opcode()) {
- case IrOpcode::kJSLessThan:
- comparison = less_than;
- break;
- case IrOpcode::kJSGreaterThan:
- comparison = less_than;
- r.SwapInputs(); // a > b => b < a
- break;
- case IrOpcode::kJSLessThanOrEqual:
- comparison = less_than_or_equal;
- break;
- case IrOpcode::kJSGreaterThanOrEqual:
- comparison = less_than_or_equal;
- r.SwapInputs(); // a >= b => b <= a
- break;
- default:
- return NoChange();
- }
- if (comparison->EffectInputCount() > 0) {
- return r.ChangeToSpeculativeOperator(comparison, Type::Boolean());
- } else {
- return r.ChangeToPureOperator(comparison);
- }
}
- // TODO(turbofan): relax/remove effects of this operator in other cases.
- return NoChange(); // Keep a generic comparison.
+ if (comparison->EffectInputCount() > 0) {
+ return r.ChangeToSpeculativeOperator(comparison, Type::Boolean());
+ } else {
+ return r.ChangeToPureOperator(comparison);
+ }
}
Reduction JSTypedLowering::ReduceJSEqualTypeOf(Node* node, bool invert) {
« no previous file with comments | « src/compiler/js-typed-lowering.h ('k') | src/compiler/simplified-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698