Reviewers: mads.ager,

Message:
We inline the fast-pass MUL binaryop when it is called in a loop to improve the
performanc while controling the code size. The MUL stub could be called by
different functions and we only inline MUL for some cases, so we must keep the
original MUL stub untouched. If we inline MUL everywhere, then some of the
instructions could be removed from the original MUL stub.

The perfomrance of v8-suite crypto benchmark is improved by 8.8% on Scorpion.
The v8-suite TotalCompiledCodeSize increase is less than 0.28%.




Please review this at http://codereview.chromium.org/2868018/show

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

Affected files:
  M     src/arm/assembler-arm.h
  M     src/arm/codegen-arm.cc


Index: src/arm/assembler-arm.h
===================================================================
--- src/arm/assembler-arm.h     (revision 4908)
+++ src/arm/assembler-arm.h     (working copy)
@@ -583,6 +583,10 @@
   // Assembler functions are invoked in between GetCode() calls.
   void GetCode(CodeDesc* desc);

+  byte* get_pc() { return pc_; }
+
+  void set_branch_target_at(Address pos, int branch_offset);
+
   // Label operations & relative jumps (PPUM Appendix D)
   //
   // Takes a branch opcode (cc) and a label (L) and generates
Index: src/arm/codegen-arm.cc
===================================================================
--- src/arm/codegen-arm.cc      (revision 4908)
+++ src/arm/codegen-arm.cc      (working copy)
@@ -878,7 +878,6 @@
       } else {
         // Fall through!
       }
-    case Token::MUL:
     case Token::DIV:
     case Token::MOD:
     case Token::SHL:
@@ -893,6 +892,58 @@
       break;
     }

+    case Token::MUL: {
+      Register result = r0;
+      Register rhs = frame_->PopToRegister();
+      Register lhs = frame_->PopToRegister(rhs);
+      GenericBinaryOpStub stub(op, overwrite_mode, lhs, rhs, constant_rhs);
+      if ((stub.runtime_operands_type() != BinaryOpIC::HEAP_NUMBERS) &&
+          (stub.runtime_operands_type() != BinaryOpIC::STRINGS) &&
+          (loop_nesting() != 0)) {
+        Address done_inline_mul;
+        JumpTarget done;
+        Register smi_test_reg = VirtualFrame::scratch0();
+        Register scratch = VirtualFrame::scratch1();
+        Register scratch2 = smi_test_reg;
+ // All ops need to know whether we are dealing with two Smis. Set up
+        // smi_test_reg to tell us that.
+        __ orr(smi_test_reg, lhs, Operand(rhs));
+        __ tst(smi_test_reg, Operand(kSmiTagMask));
+        smi_test_reg = no_reg;
+        done.Branch(ne);
+ // Remove tag from one operand (but keep sign), so that result is Smi.
+        __ mov(ip, Operand(rhs, ASR, kSmiTagSize));
+        // Do multiplication
+        // scratch = lower 32 bits of ip * lhs.
+        __ smull(scratch, scratch2, lhs, ip);
+        // Go slow on overflows (overflow bit is not set).
+        __ mov(ip, Operand(scratch, ASR, 31));
+        // No overflow if higher 33 bits are identical.
+        __ cmp(ip, Operand(scratch2));
+        done.Branch(ne);
+        // Go slow on zero result to handle -0.
+        __ tst(scratch, Operand(scratch));
+        __ mov(result, Operand(scratch), LeaveCC, ne);
+        done.Branch(ne);
+        done.Bind();
+        done_inline_mul = masm()->get_pc() - Assembler::kInstrSize;
+        frame_->SpillAll();
+        frame_->CallStub(&stub, 0);
+        Address done_inline_mul_target =
+            masm()->get_pc() - Assembler::kInstrSize;
+        int branch_offset = static_cast<int>(done_inline_mul_target -
+                                             done_inline_mul -
+                                             Assembler::kInstrSize);
+        __ set_branch_target_at(done_inline_mul,
+                                branch_offset);
+      } else {
+        frame_->SpillAll();
+        frame_->CallStub(&stub, 0);
+      }
+      frame_->EmitPush(r0);
+      break;
+    }
+
     case Token::COMMA: {
       Register scratch = frame_->PopToRegister();
       // Simply discard left value.


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to