Reviewers: Jakob,

Message:
Still incomplete (collecting the right thing on ia32 only), just to see if
things are going into the right direction...

Description:
Improve integer div/mod with constant right operands.

Please review this at https://chromiumcodereview.appspot.com/15735005/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/code-stubs.h
  M src/ia32/code-stubs-ia32.cc
  M src/ic.cc


Index: src/code-stubs.h
diff --git a/src/code-stubs.h b/src/code-stubs.h
index aa6a4101951f3d762df2659d2ae870a677a91cc7..2d59c9eba4cf5d61d41a69e2f825cf2cd8ac3ef7 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -870,7 +870,9 @@ class BinaryOpStub: public PlatformCodeStub {
         platform_specific_bit_(false),
         left_type_(BinaryOpIC::UNINITIALIZED),
         right_type_(BinaryOpIC::UNINITIALIZED),
-        result_type_(BinaryOpIC::UNINITIALIZED) {
+        result_type_(BinaryOpIC::UNINITIALIZED),
+        has_fixed_right_arg_(false),
+        encoded_right_arg_(encode_arg_value(1)) {
     Initialize();
     ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
   }
@@ -879,13 +881,17 @@ class BinaryOpStub: public PlatformCodeStub {
       int key,
       BinaryOpIC::TypeInfo left_type,
       BinaryOpIC::TypeInfo right_type,
-      BinaryOpIC::TypeInfo result_type = BinaryOpIC::UNINITIALIZED)
+      BinaryOpIC::TypeInfo result_type,
+      bool has_fixed_right_arg,
+      int fixed_right_arg_value)
       : op_(OpBits::decode(key)),
         mode_(ModeBits::decode(key)),
         platform_specific_bit_(PlatformSpecificBits::decode(key)),
         left_type_(left_type),
         right_type_(right_type),
-        result_type_(result_type) { }
+        result_type_(result_type),
+        has_fixed_right_arg_(has_fixed_right_arg),
+        encoded_right_arg_(encode_arg_value(fixed_right_arg_value)) { }

   static void decode_types_from_minor_key(int minor_key,
                                           BinaryOpIC::TypeInfo* left_type,
@@ -903,6 +909,24 @@ class BinaryOpStub: public PlatformCodeStub {
     return static_cast<Token::Value>(OpBits::decode(minor_key));
   }

+  static bool decode_has_fixed_right_arg_from_minor_key(int minor_key) {
+    return HasFixedRightArgBits::decode(minor_key);
+  }
+
+  static int decode_fixed_right_arg_value_from_minor_key(int minor_key) {
+    return decode_arg_value(FixedRightArgValueBits::decode(minor_key));
+  }
+
+  int fixed_right_arg_value() const {
+    return decode_arg_value(encoded_right_arg_);
+  }
+
+  static bool can_encode_arg_value(int value) {
+    return value > 0 &&
+        IsPowerOf2(value) &&
+ WhichPowerOf2(value) < static_cast<int>(FixedRightArgValueBits::kSize);
+  }
+
   enum SmiCodeGenerateHeapNumberResults {
     ALLOW_HEAPNUMBER_RESULTS,
     NO_HEAPNUMBER_RESULTS
@@ -918,6 +942,18 @@ class BinaryOpStub: public PlatformCodeStub {
   BinaryOpIC::TypeInfo right_type_;
   BinaryOpIC::TypeInfo result_type_;

+  bool has_fixed_right_arg_;
+  int encoded_right_arg_;
+
+  static int encode_arg_value(int value) {
+    ASSERT(can_encode_arg_value(value));
+    return WhichPowerOf2(value);
+  }
+
+  static int decode_arg_value(int value) {
+    return 1 << value;
+  }
+
   virtual void PrintName(StringStream* stream);

   // Minor key encoding in 19 bits TTTRRRLLLSOOOOOOOMM.
@@ -927,6 +963,8 @@ class BinaryOpStub: public PlatformCodeStub {
   class LeftTypeBits: public BitField<BinaryOpIC::TypeInfo, 10, 3> {};
   class RightTypeBits: public BitField<BinaryOpIC::TypeInfo, 13, 3> {};
   class ResultTypeBits: public BitField<BinaryOpIC::TypeInfo, 16, 3> {};
+  class HasFixedRightArgBits: public BitField<bool, 19, 1> {};
+  class FixedRightArgValueBits: public BitField<int, 20, 5> {};

   Major MajorKey() { return BinaryOp; }
   int MinorKey() {
@@ -935,7 +973,9 @@ class BinaryOpStub: public PlatformCodeStub {
            | PlatformSpecificBits::encode(platform_specific_bit_)
            | LeftTypeBits::encode(left_type_)
            | RightTypeBits::encode(right_type_)
-           | ResultTypeBits::encode(result_type_);
+           | ResultTypeBits::encode(result_type_)
+           | HasFixedRightArgBits::encode(has_fixed_right_arg_)
+           | FixedRightArgValueBits::encode(encoded_right_arg_);
   }


Index: src/ia32/code-stubs-ia32.cc
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 507aeb6772a1c1919c04ad0e39b36a13af5716c9..c0297e9f5793bbb6854b08b40ecf22ea19c03f0a 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -1611,7 +1611,7 @@ static void BinaryOpStub_GenerateSmiCode(


 void BinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
-  Label call_runtime;
+  Label right_arg_changed, call_runtime;

   switch (op_) {
     case Token::ADD:
@@ -1632,6 +1632,11 @@ void BinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
       UNREACHABLE();
   }

+  if (op_ == Token::MOD && has_fixed_right_arg_) {
+    __ cmp(eax, Immediate(Smi::FromInt(fixed_right_arg_value())));
+    __ j(not_equal, &right_arg_changed);
+  }
+
   if (result_type_ == BinaryOpIC::UNINITIALIZED ||
       result_type_ == BinaryOpIC::SMI) {
     BinaryOpStub_GenerateSmiCode(
@@ -1643,6 +1648,7 @@ void BinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {

// Code falls through if the result is not returned as either a smi or heap
   // number.
+  __ bind(&right_arg_changed);
   switch (op_) {
     case Token::ADD:
     case Token::SUB:
@@ -1745,8 +1751,7 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
     case Token::MUL:
     case Token::DIV:
     case Token::MOD: {
-      Label not_floats;
-      Label not_int32;
+      Label not_floats, not_int32, right_arg_changed;
       if (CpuFeatures::IsSupported(SSE2)) {
         CpuFeatureScope use_sse2(masm, SSE2);
         // It could be that only SMIs have been seen at either the left
@@ -1764,6 +1769,10 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
         FloatingPointHelper::LoadSSE2Operands(masm, &not_floats);
FloatingPointHelper::CheckSSE2OperandsAreInt32(masm, &not_int32, ecx);
         if (op_ == Token::MOD) {
+          if (has_fixed_right_arg_) {
+            __ cmp(eax, Immediate(Smi::FromInt(fixed_right_arg_value())));
+            __ j(not_equal, &right_arg_changed);
+          }
           GenerateRegisterArgsPush(masm);
           __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION);
         } else {
@@ -1816,6 +1825,7 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {

       __ bind(&not_floats);
       __ bind(&not_int32);
+      __ bind(&right_arg_changed);
       GenerateTypeTransition(masm);
       break;
     }
Index: src/ic.cc
diff --git a/src/ic.cc b/src/ic.cc
index ea0c1fbbe1d70438ee2983ee0d682ef5d3700f24..655f5f5ab3ca6fa05aefa746c25c598132e65bde 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -2619,18 +2619,45 @@ RUNTIME_FUNCTION(MaybeObject*, BinaryOp_Patch) {
     }
   }

-  BinaryOpStub stub(key, new_left, new_right, result_type);
+  bool previous_has_fixed_right_arg =
+      BinaryOpStub::decode_has_fixed_right_arg_from_minor_key(key);
+  int previous_fixed_right_arg_value =
+      BinaryOpStub::decode_fixed_right_arg_value_from_minor_key(key);
+
+  bool new_has_fixed_right_arg = false;
+  int new_fixed_right_arg_value = 1;
+
+  if (op == Token::MOD && right->IsSmi()) {
+    int value = Smi::cast(*right)->value();
+    if (BinaryOpStub::can_encode_arg_value(value) &&
+        (!previous_has_fixed_right_arg ||
+         previous_fixed_right_arg_value == value)) {
+      new_has_fixed_right_arg = true;
+      new_fixed_right_arg_value = value;
+    }
+  }
+
+  BinaryOpStub stub(key, new_left, new_right, result_type,
+                    new_has_fixed_right_arg, new_fixed_right_arg_value);
   Handle<Code> code = stub.GetCode(isolate);
   if (!code.is_null()) {
 #ifdef DEBUG
     if (FLAG_trace_ic) {
       PrintF("[BinaryOpIC in ");
       JavaScriptFrame::PrintTop(isolate, stdout, false, true);
-      PrintF(" ((%s+%s)->((%s+%s)->%s))#%s @ %p]\n",
+      PrintF(" ((%s+%s",
              BinaryOpIC::GetName(previous_left),
-             BinaryOpIC::GetName(previous_right),
+             BinaryOpIC::GetName(previous_right));
+      if (previous_has_fixed_right_arg) {
+        PrintF("{%d}", previous_fixed_right_arg_value);
+      }
+      PrintF(")->((%s+%s",
              BinaryOpIC::GetName(new_left),
-             BinaryOpIC::GetName(new_right),
+             BinaryOpIC::GetName(new_right));
+      if (new_has_fixed_right_arg) {
+        PrintF("{%d}", new_fixed_right_arg_value);
+      }
+      PrintF(")->%s))#%s @ %p]\n",
              BinaryOpIC::GetName(result_type),
              Token::Name(op),
              static_cast<void*>(*code));


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to