| Index: src/compiler/js-typed-lowering.cc
|
| diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc
|
| index faf1251f7dea2052d8da71c96835e2cb22d6c2b3..04110774a6462cb1f9474485d6747406cb51ae39 100644
|
| --- a/src/compiler/js-typed-lowering.cc
|
| +++ b/src/compiler/js-typed-lowering.cc
|
| @@ -27,7 +27,7 @@ class JSBinopReduction final {
|
| JSBinopReduction(JSTypedLowering* lowering, Node* node)
|
| : lowering_(lowering), node_(node) {}
|
|
|
| - BinaryOperationHints::Hint GetUsableNumberFeedback() {
|
| + BinaryOperationHints::Hint GetNumberBinaryOperationFeedback() {
|
| if (!(lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) ||
|
| !(lowering_->flags() & JSTypedLowering::kTypeFeedbackEnabled)) {
|
| return BinaryOperationHints::kAny;
|
| @@ -45,6 +45,24 @@ class JSBinopReduction final {
|
| return BinaryOperationHints::kAny;
|
| }
|
|
|
| + CompareOperationHints::Hint GetNumberCompareOperationFeedback() {
|
| + if (!(lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) ||
|
| + !(lowering_->flags() & JSTypedLowering::kTypeFeedbackEnabled)) {
|
| + return CompareOperationHints::kAny;
|
| + }
|
| + DCHECK_NE(0, node_->op()->ControlOutputCount());
|
| + DCHECK_EQ(1, node_->op()->EffectOutputCount());
|
| + DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node_->op()));
|
| + CompareOperationHints hints = CompareOperationHintsOf(node_->op());
|
| + CompareOperationHints::Hint combined = hints.combined();
|
| + if (combined == CompareOperationHints::kSignedSmall ||
|
| + combined == CompareOperationHints::kSigned32 ||
|
| + combined == CompareOperationHints::kNumberOrUndefined) {
|
| + return combined;
|
| + }
|
| + return CompareOperationHints::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.
|
| @@ -125,7 +143,7 @@ class JSBinopReduction final {
|
| return lowering_->Changed(node_);
|
| }
|
|
|
| - Reduction ChangeToSpeculativeOperator(const Operator* op) {
|
| + Reduction ChangeToSpeculativeOperator(const Operator* op, Type* upper_bound) {
|
| DCHECK_EQ(1, op->EffectInputCount());
|
| DCHECK_EQ(1, op->EffectOutputCount());
|
| DCHECK_EQ(false, OperatorProperties::HasContextInput(op));
|
| @@ -167,7 +185,7 @@ class JSBinopReduction final {
|
| // Update the type to number.
|
| Type* node_type = NodeProperties::GetType(node_);
|
| NodeProperties::SetType(node_,
|
| - Type::Intersect(node_type, Type::Number(), zone()));
|
| + Type::Intersect(node_type, upper_bound, zone()));
|
|
|
| return lowering_->Changed(node_);
|
| }
|
| @@ -406,11 +424,11 @@ Reduction JSTypedLowering::ReduceJSAdd(Node* node) {
|
|
|
| JSBinopReduction r(this, node);
|
|
|
| - BinaryOperationHints::Hint feedback = r.GetUsableNumberFeedback();
|
| + BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
|
| if (feedback != BinaryOperationHints::kAny) {
|
| // Lower to the optimistic number binop.
|
| return r.ChangeToSpeculativeOperator(
|
| - simplified()->SpeculativeNumberAdd(feedback));
|
| + simplified()->SpeculativeNumberAdd(feedback), Type::Number());
|
| }
|
| if (r.BothInputsAre(Type::NumberOrUndefined())) {
|
| // JSAdd(x:number, y:number) => NumberAdd(x, y)
|
| @@ -464,11 +482,11 @@ Reduction JSTypedLowering::ReduceJSModulus(Node* node) {
|
| Reduction JSTypedLowering::ReduceJSSubtract(Node* node) {
|
| if (flags() & kDisableBinaryOpReduction) return NoChange();
|
| JSBinopReduction r(this, node);
|
| - BinaryOperationHints::Hint feedback = r.GetUsableNumberFeedback();
|
| + BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
|
| if (feedback != BinaryOperationHints::kAny) {
|
| // Lower to the optimistic number binop.
|
| return r.ChangeToSpeculativeOperator(
|
| - simplified()->SpeculativeNumberSubtract(feedback));
|
| + simplified()->SpeculativeNumberSubtract(feedback), Type::Number());
|
| }
|
| Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
|
| r.ConvertInputsToNumberOrUndefined(frame_state);
|
| @@ -544,7 +562,10 @@ Reduction JSTypedLowering::ReduceJSComparison(Node* node) {
|
| r.ChangeToPureOperator(stringOp);
|
| return Changed(node);
|
| }
|
| - if (r.OneInputCannotBe(Type::StringOrReceiver())) {
|
| +
|
| + 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::Unsigned32())) {
|
| @@ -553,6 +574,9 @@ Reduction JSTypedLowering::ReduceJSComparison(Node* node) {
|
| } else if (r.BothInputsAre(Type::Signed32())) {
|
| less_than = machine()->Int32LessThan();
|
| less_than_or_equal = machine()->Int32LessThanOrEqual();
|
| + } else if (hint != CompareOperationHints::kAny) {
|
| + less_than = simplified()->SpeculativeNumberLessThan(hint);
|
| + less_than_or_equal = simplified()->SpeculativeNumberLessThanOrEqual(hint);
|
| } else {
|
| // TODO(turbofan): mixed signed/unsigned int32 comparisons.
|
| Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
|
| @@ -579,7 +603,11 @@ Reduction JSTypedLowering::ReduceJSComparison(Node* node) {
|
| default:
|
| return NoChange();
|
| }
|
| - return r.ChangeToPureOperator(comparison);
|
| + 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.
|
|
|