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

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

Issue 2181743004: [turbofan] Speculative optimize number operations with no feedback. Base URL: https://chromium.googlesource.com/v8/v8.git@631318
Patch Set: Created 4 years, 5 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 | « no previous file | src/compiler/redundancy-elimination.h » ('j') | src/compiler/redundancy-elimination.h » ('J')
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 a88658c408eed258899ff31448f2a6e9620a8f8c..8782e12375b3c5744a0c0a1e75ccf29b6c590f8c 100644
--- a/src/compiler/js-typed-lowering.cc
+++ b/src/compiler/js-typed-lowering.cc
@@ -27,35 +27,50 @@ 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_LE(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::kNone:
+ *hint = NumberOperationHint::kNone;
+ return true;
+ case BinaryOperationHints::kSignedSmall:
+ case BinaryOperationHints::kSigned32:
+ *hint = NumberOperationHint::kSigned32;
+ return true;
+ case BinaryOperationHints::kNumberOrOddball:
+ *hint = NumberOperationHint::kNumberOrOddball;
+ return true;
+ case BinaryOperationHints::kString:
+ case BinaryOperationHints::kAny:
+ return false;
}
}
- 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;
+ if (combined == CompareOperationHints::kNone) {
+ *hint = NumberOperationHint::kNone;
+ return true;
+ } else if (combined == CompareOperationHints::kSignedSmall) {
+ *hint = NumberOperationHint::kSigned32;
+ return true;
+ } else if (combined == CompareOperationHints::kNumberOrOddball) {
+ *hint = NumberOperationHint::kNumberOrOddball;
+ return true;
}
}
- return CompareOperationHints::kAny;
+ return false;
}
void ConvertInputsToNumber() {
@@ -138,7 +153,12 @@ class JSBinopReduction final {
return lowering_->Changed(node_);
}
- Reduction ChangeToSpeculativeOperator(const Operator* op, Type* upper_bound) {
+ Reduction ChangeToPureOperator(const Operator* op, Type* type) {
+ return ChangeToPureOperator(op, false, type);
+ }
+
+ Reduction ChangeToSpeculativeOperator(const Operator* op,
+ Type* type = Type::Any()) {
DCHECK_EQ(1, op->EffectInputCount());
DCHECK_EQ(1, op->EffectOutputCount());
DCHECK_EQ(false, OperatorProperties::HasContextInput(op));
@@ -181,16 +201,11 @@ class JSBinopReduction final {
// Update the type to number.
Type* node_type = NodeProperties::GetType(node_);
- NodeProperties::SetType(node_,
- Type::Intersect(node_type, upper_bound, zone()));
+ NodeProperties::SetType(node_, Type::Intersect(node_type, type, zone()));
return lowering_->Changed(node_);
}
- Reduction ChangeToPureOperator(const Operator* op, Type* type) {
- return ChangeToPureOperator(op, false, type);
- }
-
bool LeftInputIs(Type* t) { return left_type()->Is(t); }
bool RightInputIs(Type* t) { return right_type()->Is(t); }
@@ -429,31 +444,6 @@ 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.
- return r.ChangeToSpeculativeOperator(
- simplified()->SpeculativeNumberAdd(feedback), Type::Number());
- }
- if (r.BothInputsAre(Type::Number())) {
- // JSAdd(x:number, y:number) => NumberAdd(x, y)
- r.ConvertInputsToNumber();
- return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
- }
- if ((r.BothInputsAre(Type::PlainPrimitive()) ||
- !(flags() & kDeoptimizationEnabled)) &&
- r.NeitherInputCanBe(Type::StringOrReceiver())) {
- // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y))
- r.ConvertInputsToNumber();
- return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
- }
if (r.OneInputIs(Type::String())) {
StringAddFlags flags = STRING_ADD_CHECK_NONE;
if (!r.LeftInputIs(Type::String())) {
@@ -474,25 +464,50 @@ Reduction JSTypedLowering::ReduceJSAdd(Node* node) {
NodeProperties::ChangeOp(node, common()->Call(desc));
return Changed(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());
+ }
+ // Lower to the optimistic number binop.
+ return r.ChangeToSpeculativeOperator(
+ simplified()->SpeculativeNumberAdd(hint), Type::Number());
+ }
+ if (r.BothInputsAre(Type::Number())) {
+ // JSAdd(x:number, y:number) => NumberAdd(x, y)
+ r.ConvertInputsToNumber();
+ return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
+ }
+ if ((r.BothInputsAre(Type::PlainPrimitive()) ||
+ !(flags() & kDeoptimizationEnabled)) &&
+ r.NeitherInputCanBe(Type::StringOrReceiver())) {
+ // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y))
+ r.ConvertInputsToNumber();
+ return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
+ }
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) {
+ 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());
+ }
// Lower to the optimistic number binop.
return r.ChangeToSpeculativeOperator(
- simplified()->SpeculativeNumberSubtract(feedback), Type::Number());
+ simplified()->SpeculativeNumberSubtract(hint));
}
// If deoptimization is enabled we rely on type feedback.
@@ -508,18 +523,18 @@ Reduction JSTypedLowering::ReduceJSSubtract(Node* node) {
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));
}
// If deoptimization is enabled we rely on type feedback.
@@ -535,17 +550,18 @@ Reduction JSTypedLowering::ReduceJSMultiply(Node* node) {
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));
}
if (r.BothInputsAre(Type::PlainPrimitive())) {
// JSDivide(x:plain-primitive,
@@ -558,18 +574,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));
}
if (r.BothInputsAre(Type::PlainPrimitive())) {
// JSModulus(x:plain-primitive,
@@ -594,11 +610,12 @@ Reduction JSTypedLowering::ReduceShiftLeft(Node* node) {
if (flags() & kDisableIntegerBinaryOpReduction) return NoChange();
JSBinopReduction r(this, node);
- BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
- if (feedback == BinaryOperationHints::kSigned32 ||
- feedback == BinaryOperationHints::kSignedSmall) {
- return r.ChangeToSpeculativeOperator(
- simplified()->SpeculativeNumberShiftLeft(feedback), Type::Signed32());
+ NumberOperationHint hint;
+ if (r.GetBinaryNumberOperationHint(&hint)) {
+ if (hint == NumberOperationHint::kSigned32) {
+ return r.ChangeToSpeculativeOperator(
+ simplified()->SpeculativeNumberShiftLeft(hint));
+ }
}
// If deoptimization is enabled we rely on type feedback.
@@ -607,7 +624,7 @@ Reduction JSTypedLowering::ReduceShiftLeft(Node* node) {
r.ConvertInputsToNumber();
r.ConvertInputsToUI32(kSigned, kUnsigned);
return r.ChangeToPureOperator(simplified()->NumberShiftLeft(),
- Type::Number());
+ Type::Signed32());
}
return NoChange();
}
@@ -623,7 +640,6 @@ Reduction JSTypedLowering::ReduceUI32Shift(Node* node,
return r.ChangeToPureOperator(shift_op);
}
-
Reduction JSTypedLowering::ReduceJSComparison(Node* node) {
JSBinopReduction r(this, node);
if (r.BothInputsAre(Type::String())) {
@@ -651,49 +667,45 @@ 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 (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.GetCompareNumberOperationHint(&hint)) {
+ less_than = simplified()->SpeculativeNumberLessThan(hint);
+ less_than_or_equal = simplified()->SpeculativeNumberLessThanOrEqual(hint);
+ } else if (r.OneInputCannotBe(Type::StringOrReceiver()) &&
+ (!(flags() & kDeoptimizationEnabled) ||
+ r.BothInputsAre(Type::PlainPrimitive()))) {
+ 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);
+ } else {
+ return r.ChangeToPureOperator(comparison);
+ }
}
Reduction JSTypedLowering::ReduceJSEqualTypeOf(Node* node, bool invert) {
@@ -773,6 +785,7 @@ Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) {
}
return Changed(node);
}
+ // TODO(turbofan): Add support for comparison type feedback.
return NoChange();
}
« no previous file with comments | « no previous file | src/compiler/redundancy-elimination.h » ('j') | src/compiler/redundancy-elimination.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698