From: bmeurer@chromium.org Date: Wed, 4 Dec 2013 08:37:34 +0000 (+0000) Subject: Use constant types to represent the fixed right arg of a MOD. X-Git-Tag: upstream/4.7.83~11428 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1868ef5de966831d4fb7c8defa6b5fe41649a7b3;p=platform%2Fupstream%2Fv8.git Use constant types to represent the fixed right arg of a MOD. R=svenpanne@chromium.org Review URL: https://codereview.chromium.org/103933002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18246 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/ast.h b/src/ast.h index 0bbb90452..1fe593e93 100644 --- a/src/ast.h +++ b/src/ast.h @@ -1952,8 +1952,6 @@ class BinaryOperation V8_FINAL : public Expression { BailoutId RightId() const { return right_id_; } TypeFeedbackId BinaryOperationFeedbackId() const { return reuse(id()); } - Maybe fixed_right_arg() const { return fixed_right_arg_; } - void set_fixed_right_arg(Maybe arg) { fixed_right_arg_ = arg; } virtual void RecordToBooleanTypeFeedback( TypeFeedbackOracle* oracle) V8_OVERRIDE; @@ -1977,10 +1975,6 @@ class BinaryOperation V8_FINAL : public Expression { Expression* left_; Expression* right_; - // TODO(rossberg): the fixed arg should probably be represented as a Constant - // type for the RHS. - Maybe fixed_right_arg_; - // The short-circuit logical operations need an AST ID for their // right-hand subexpression. const BailoutId right_id_; diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc index 96cfc3784..e9876a4d2 100644 --- a/src/code-stubs-hydrogen.cc +++ b/src/code-stubs-hydrogen.cc @@ -923,14 +923,13 @@ HValue* CodeStubGraphBuilder::BuildCodeInitializedStub() { Push(BuildBinaryOperation( state.op(), left, right, handle(Type::String(), isolate()), right_type, - result_type, state.fixed_right_arg())); + result_type)); } if_leftisstring.Else(); { Push(BuildBinaryOperation( state.op(), left, right, - left_type, right_type, result_type, - state.fixed_right_arg())); + left_type, right_type, result_type)); } if_leftisstring.End(); result = Pop(); @@ -942,14 +941,13 @@ HValue* CodeStubGraphBuilder::BuildCodeInitializedStub() { Push(BuildBinaryOperation( state.op(), left, right, left_type, handle(Type::String(), isolate()), - result_type, state.fixed_right_arg())); + result_type)); } if_rightisstring.Else(); { Push(BuildBinaryOperation( state.op(), left, right, - left_type, right_type, result_type, - state.fixed_right_arg())); + left_type, right_type, result_type)); } if_rightisstring.End(); result = Pop(); @@ -957,8 +955,7 @@ HValue* CodeStubGraphBuilder::BuildCodeInitializedStub() { } else { result = BuildBinaryOperation( state.op(), left, right, - left_type, right_type, result_type, - state.fixed_right_arg()); + left_type, right_type, result_type); } // If we encounter a generic argument, the number conversion is diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 900e07ecd..534f6126b 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -8732,11 +8732,9 @@ HValue* HOptimizedGraphBuilder::BuildBinaryOperation( Handle left_type = expr->left()->bounds().lower; Handle right_type = expr->right()->bounds().lower; Handle result_type = expr->bounds().lower; - Maybe fixed_right_arg = expr->fixed_right_arg(); HValue* result = HGraphBuilder::BuildBinaryOperation( - expr->op(), left, right, left_type, right_type, - result_type, fixed_right_arg); + expr->op(), left, right, left_type, right_type, result_type); // Add a simulate after instructions with observable side effects, and // after phis, which are the result of BuildBinaryOperation when we // inlined some complex subgraph. @@ -8755,34 +8753,45 @@ HValue* HGraphBuilder::BuildBinaryOperation( HValue* right, Handle left_type, Handle right_type, - Handle result_type, - Maybe fixed_right_arg) { + Handle result_type) { Representation left_rep = Representation::FromType(left_type); Representation right_rep = Representation::FromType(right_type); - bool maybe_string_add = op == Token::ADD && - (left_type->Maybe(Type::String()) || - right_type->Maybe(Type::String())); - if (left_type->Is(Type::None())) { Add("Insufficient type feedback for LHS of binary operation", Deoptimizer::SOFT); // TODO(rossberg): we should be able to get rid of non-continuous // defaults. left_type = handle(Type::Any(), isolate()); - } else { - if (!maybe_string_add) left = TruncateToNumber(left, &left_type); - left_rep = Representation::FromType(left_type); + } else if (left_type->IsConstant()) { + HConstant* c_left = Add(left_type->AsConstant()); + IfBuilder if_same(this); + if (c_left->HasDoubleValue()) { + if_same.If(left, c_left, Token::EQ); + } else { + if_same.If(left, c_left); + } + if_same.Then(); + if_same.ElseDeopt("Unexpected LHS of binary operation"); + left = c_left; } if (right_type->Is(Type::None())) { Add("Insufficient type feedback for RHS of binary operation", Deoptimizer::SOFT); right_type = handle(Type::Any(), isolate()); - } else { - if (!maybe_string_add) right = TruncateToNumber(right, &right_type); - right_rep = Representation::FromType(right_type); + } else if (right_type->IsConstant()) { + HConstant* c_right = Add(right_type->AsConstant()); + IfBuilder if_same(this); + if (c_right->HasDoubleValue()) { + if_same.If(right, c_right, Token::EQ); + } else { + if_same.If(right, c_right); + } + if_same.Then(); + if_same.ElseDeopt("Unexpected RHS of binary operation"); + right = c_right; } // Special case for string addition here. @@ -8825,6 +8834,11 @@ HValue* HGraphBuilder::BuildBinaryOperation( return AddUncasted(left, right, STRING_ADD_CHECK_NONE); } + left = TruncateToNumber(left, &left_type); + left_rep = Representation::FromType(left_type); + right = TruncateToNumber(right, &right_type); + right_rep = Representation::FromType(right_type); + if (graph()->info()->IsStub()) { left = EnforceNumberType(left, left_type); right = EnforceNumberType(right, right_type); @@ -8856,22 +8870,6 @@ HValue* HGraphBuilder::BuildBinaryOperation( instr = AddUncasted(left, right); break; case Token::MOD: { - if (fixed_right_arg.has_value) { - if (right->IsConstant()) { - HConstant* c_right = HConstant::cast(right); - if (c_right->HasInteger32Value()) { - ASSERT_EQ(fixed_right_arg.value, c_right->Integer32Value()); - } - } else { - HConstant* fixed_right = Add( - static_cast(fixed_right_arg.value)); - IfBuilder if_same(this); - if_same.If(right, fixed_right, Token::EQ); - if_same.Then(); - if_same.ElseDeopt("Unexpected RHS of binary operation"); - right = fixed_right; - } - } instr = AddUncasted(left, right); break; } diff --git a/src/hydrogen.h b/src/hydrogen.h index 61e98b2b0..409935d38 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -1351,8 +1351,7 @@ class HGraphBuilder { HValue* right, Handle left_type, Handle right_type, - Handle result_type, - Maybe fixed_right_arg); + Handle result_type); HLoadNamedField* AddLoadFixedArrayLength(HValue *object); diff --git a/src/ic.cc b/src/ic.cc index 8a2550456..b548bc686 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -2329,7 +2329,10 @@ BinaryOpIC::State::State(ExtraICState extra_ic_state) { 1 << FixedRightArgValueField::decode(extra_ic_state)); left_kind_ = LeftKindField::decode(extra_ic_state); if (fixed_right_arg_.has_value) { - right_kind_ = Smi::IsValid(fixed_right_arg_.value) ? SMI : INT32; + // We have only 4 bits to encode the log2 of the fixed right arg, so the + // max value is 2^(2^4), which is always a SMI. + ASSERT(Smi::IsValid(fixed_right_arg_.value)); + right_kind_ = SMI; } else { right_kind_ = RightKindField::decode(extra_ic_state); } @@ -2582,6 +2585,17 @@ void BinaryOpIC::State::GenerateAheadOfTime( } +Handle BinaryOpIC::State::GetRightType(Isolate* isolate) const { + if (fixed_right_arg_.has_value) { + Handle value = handle(Smi::FromInt(fixed_right_arg_.value), isolate); + Handle type = handle(Type::Constant(value, isolate), isolate); + ASSERT(type->Is(KindToType(right_kind_, isolate))); + return type; + } + return KindToType(right_kind_, isolate); +} + + Handle BinaryOpIC::State::GetResultType(Isolate* isolate) const { Kind result_kind = result_kind_; if (HasSideEffects()) { diff --git a/src/ic.h b/src/ic.h index fa7ed6dbc..3d8b7fd33 100644 --- a/src/ic.h +++ b/src/ic.h @@ -866,14 +866,11 @@ class BinaryOpIC: public IC { Token::Value op() const { return op_; } OverwriteMode mode() const { return mode_; } - Maybe fixed_right_arg() const { return fixed_right_arg_; } Handle GetLeftType(Isolate* isolate) const { return KindToType(left_kind_, isolate); } - Handle GetRightType(Isolate* isolate) const { - return KindToType(right_kind_, isolate); - } + Handle GetRightType(Isolate* isolate) const; Handle GetResultType(Isolate* isolate) const; void Print(StringStream* stream) const; diff --git a/src/type-info.cc b/src/type-info.cc index 6e3a4f6b7..f445544a6 100644 --- a/src/type-info.cc +++ b/src/type-info.cc @@ -407,7 +407,6 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id, Handle* left, Handle* right, Handle* result, - Maybe* fixed_right_arg, Token::Value op) { Handle object = GetInfo(id); if (!object->IsCode()) { @@ -416,7 +415,6 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id, ASSERT(op < BinaryOpIC::State::FIRST_TOKEN || op > BinaryOpIC::State::LAST_TOKEN); *left = *right = *result = handle(Type::None(), isolate_); - *fixed_right_arg = Maybe(); return; } Handle code = Handle::cast(object); @@ -427,7 +425,6 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id, *left = state.GetLeftType(isolate()); *right = state.GetRightType(isolate()); *result = state.GetResultType(isolate()); - *fixed_right_arg = state.fixed_right_arg(); } diff --git a/src/type-info.h b/src/type-info.h index a0d321584..5a275b313 100644 --- a/src/type-info.h +++ b/src/type-info.h @@ -312,7 +312,6 @@ class TypeFeedbackOracle: public ZoneObject { Handle* left, Handle* right, Handle* result, - Maybe* fixed_right_arg, Token::Value operation); void CompareType(TypeFeedbackId id, diff --git a/src/typing.cc b/src/typing.cc index 8487c05eb..582b404a2 100644 --- a/src/typing.cc +++ b/src/typing.cc @@ -571,13 +571,11 @@ void AstTyper::VisitCountOperation(CountOperation* expr) { void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { // Collect type feedback. Handle type, left_type, right_type; - Maybe fixed_right_arg; oracle()->BinaryType(expr->BinaryOperationFeedbackId(), - &left_type, &right_type, &type, &fixed_right_arg, expr->op()); + &left_type, &right_type, &type, expr->op()); NarrowLowerType(expr, type); NarrowLowerType(expr->left(), left_type); NarrowLowerType(expr->right(), right_type); - expr->set_fixed_right_arg(fixed_right_arg); if (expr->op() == Token::OR || expr->op() == Token::AND) { expr->left()->RecordToBooleanTypeFeedback(oracle()); }