Use constant types to represent the fixed right arg of a MOD.
authorbmeurer@chromium.org <bmeurer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 4 Dec 2013 08:37:34 +0000 (08:37 +0000)
committerbmeurer@chromium.org <bmeurer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 4 Dec 2013 08:37:34 +0000 (08:37 +0000)
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

src/ast.h
src/code-stubs-hydrogen.cc
src/hydrogen.cc
src/hydrogen.h
src/ic.cc
src/ic.h
src/type-info.cc
src/type-info.h
src/typing.cc

index 0bbb90452a674c21619b8abc167594a1fc63f4b8..1fe593e9359754d3b4ad3290fe13348a6ed47ae6 100644 (file)
--- 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<int> fixed_right_arg() const { return fixed_right_arg_; }
-  void set_fixed_right_arg(Maybe<int> 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<int> fixed_right_arg_;
-
   // The short-circuit logical operations need an AST ID for their
   // right-hand subexpression.
   const BailoutId right_id_;
index 96cfc378476943483ab2f6dc862f3cf3389848f9..e9876a4d2d3bcc5039eae9b0ec657853955ee9a1 100644 (file)
@@ -923,14 +923,13 @@ HValue* CodeStubGraphBuilder<BinaryOpICStub>::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<BinaryOpICStub>::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<BinaryOpICStub>::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
index 900e07ecdf9fa68a32540fc76be401d0b064a343..534f6126b67ba9a415d7c8afc583dee25a114a46 100644 (file)
@@ -8732,11 +8732,9 @@ HValue* HOptimizedGraphBuilder::BuildBinaryOperation(
   Handle<Type> left_type = expr->left()->bounds().lower;
   Handle<Type> right_type = expr->right()->bounds().lower;
   Handle<Type> result_type = expr->bounds().lower;
-  Maybe<int> 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<Type> left_type,
     Handle<Type> right_type,
-    Handle<Type> result_type,
-    Maybe<int> fixed_right_arg) {
+    Handle<Type> 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<HDeoptimize>("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<HConstant>(left_type->AsConstant());
+    IfBuilder if_same(this);
+    if (c_left->HasDoubleValue()) {
+      if_same.If<HCompareNumericAndBranch>(left, c_left, Token::EQ);
+    } else {
+      if_same.If<HCompareObjectEqAndBranch>(left, c_left);
+    }
+    if_same.Then();
+    if_same.ElseDeopt("Unexpected LHS of binary operation");
+    left = c_left;
   }
 
   if (right_type->Is(Type::None())) {
     Add<HDeoptimize>("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<HConstant>(right_type->AsConstant());
+    IfBuilder if_same(this);
+    if (c_right->HasDoubleValue()) {
+      if_same.If<HCompareNumericAndBranch>(right, c_right, Token::EQ);
+    } else {
+      if_same.If<HCompareObjectEqAndBranch>(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<HStringAdd>(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<HMul>(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<HConstant>(
-                static_cast<int>(fixed_right_arg.value));
-            IfBuilder if_same(this);
-            if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ);
-            if_same.Then();
-            if_same.ElseDeopt("Unexpected RHS of binary operation");
-            right = fixed_right;
-          }
-        }
         instr = AddUncasted<HMod>(left, right);
         break;
       }
index 61e98b2b0ce9c0053c131098bd74d30a4cc15c2f..409935d38b34fd1e5e4ed9679d37a46a79c38fa8 100644 (file)
@@ -1351,8 +1351,7 @@ class HGraphBuilder {
                                HValue* right,
                                Handle<Type> left_type,
                                Handle<Type> right_type,
-                               Handle<Type> result_type,
-                               Maybe<int> fixed_right_arg);
+                               Handle<Type> result_type);
 
   HLoadNamedField* AddLoadFixedArrayLength(HValue *object);
 
index 8a25504564640c17e7a8f5f067889a2b6aececa8..b548bc68609675d7fa100e1c32c78fe6bdb4f93c 100644 (file)
--- 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<Type> BinaryOpIC::State::GetRightType(Isolate* isolate) const {
+  if (fixed_right_arg_.has_value) {
+    Handle<Smi> value = handle(Smi::FromInt(fixed_right_arg_.value), isolate);
+    Handle<Type> type = handle(Type::Constant(value, isolate), isolate);
+    ASSERT(type->Is(KindToType(right_kind_, isolate)));
+    return type;
+  }
+  return KindToType(right_kind_, isolate);
+}
+
+
 Handle<Type> BinaryOpIC::State::GetResultType(Isolate* isolate) const {
   Kind result_kind = result_kind_;
   if (HasSideEffects()) {
index fa7ed6dbc1381f60aee70703a65d34566179dfba..3d8b7fd33eb2883c844d045d58e8af6c35e2c31e 100644 (file)
--- 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<int> fixed_right_arg() const { return fixed_right_arg_; }
 
     Handle<Type> GetLeftType(Isolate* isolate) const {
       return KindToType(left_kind_, isolate);
     }
-    Handle<Type> GetRightType(Isolate* isolate) const {
-      return KindToType(right_kind_, isolate);
-    }
+    Handle<Type> GetRightType(Isolate* isolate) const;
     Handle<Type> GetResultType(Isolate* isolate) const;
 
     void Print(StringStream* stream) const;
index 6e3a4f6b7a483bda6ebb38f08a62e59703060592..f445544a6d23190ed951d194bf9b039fa9d90c32 100644 (file)
@@ -407,7 +407,6 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id,
                                     Handle<Type>* left,
                                     Handle<Type>* right,
                                     Handle<Type>* result,
-                                    Maybe<int>* fixed_right_arg,
                                     Token::Value op) {
   Handle<Object> 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<int>();
     return;
   }
   Handle<Code> code = Handle<Code>::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();
 }
 
 
index a0d32158445934a12d99b5d73603c79f8686bf11..5a275b313fc7e335c404579ccda6433cd595d85c 100644 (file)
@@ -312,7 +312,6 @@ class TypeFeedbackOracle: public ZoneObject {
                   Handle<Type>* left,
                   Handle<Type>* right,
                   Handle<Type>* result,
-                  Maybe<int>* fixed_right_arg,
                   Token::Value operation);
 
   void CompareType(TypeFeedbackId id,
index 8487c05eb4af9fe472509c5afc34ae0eb1916053..582b404a29457345b49ec2bb68e2622f96dc8566 100644 (file)
@@ -571,13 +571,11 @@ void AstTyper::VisitCountOperation(CountOperation* expr) {
 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
   // Collect type feedback.
   Handle<Type> type, left_type, right_type;
-  Maybe<int> 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());
   }