Revision: 13819
Author:   [email protected]
Date:     Tue Mar  5 00:47:59 2013
Log: Improve integer division on ARM in favor of power of 2 constant divisor
BUG=none
TEST=none

Review URL: https://chromiumcodereview.appspot.com/12052032
Patch from Rajeev R Krithivasan <[email protected]>.
http://code.google.com/p/v8/source/detail?r=13819

Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.cc
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/test/mjsunit/math-floor-of-div-nosudiv.js
 /branches/bleeding_edge/test/mjsunit/math-floor-of-div.js
 /branches/bleeding_edge/test/mjsunit/mjsunit.status

=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc      Fri Mar  1 08:06:34 2013
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc      Tue Mar  5 00:47:59 2013
@@ -1226,6 +1226,13 @@
   if (instr->representation().IsDouble()) {
     return DoArithmeticD(Token::DIV, instr);
   } else if (instr->representation().IsInteger32()) {
+    if (instr->HasPowerOf2Divisor()) {
+      ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero));
+      LOperand* value = UseRegisterAtStart(instr->left());
+      LDivI* div =
+          new(zone()) LDivI(value, UseOrConstant(instr->right()));
+      return AssignEnvironment(DefineSameAsFirst(div));
+    }
     // TODO(1042) The fixed register allocation
     // is needed because we call TypeRecordingBinaryOpStub from
     // the generated code, which requires registers r0
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri Mar 1 08:06:34 2013 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Mar 5 00:47:59 2013
@@ -1411,6 +1411,42 @@
     LDivI* instr_;
   };

+  if (instr->hydrogen()->HasPowerOf2Divisor()) {
+    Register dividend = ToRegister(instr->left());
+    int32_t divisor =
+        HConstant::cast(instr->hydrogen()->right())->Integer32Value();
+    int32_t test_value = 0;
+    int32_t power = 0;
+
+    if (divisor > 0) {
+      test_value = divisor - 1;
+      power = WhichPowerOf2(divisor);
+    } else {
+      // Check for (0 / -x) that will produce negative zero.
+      if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+        __ tst(dividend, Operand(dividend));
+        DeoptimizeIf(eq, instr->environment());
+      }
+      // Check for (kMinInt / -1).
+ if (divisor == -1 && instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+        __ cmp(dividend, Operand(kMinInt));
+        DeoptimizeIf(eq, instr->environment());
+      }
+      test_value = - divisor - 1;
+      power = WhichPowerOf2(-divisor);
+    }
+
+    if (test_value != 0) {
+      // Deoptimize if remainder is not 0.
+      __ tst(dividend, Operand(test_value));
+      DeoptimizeIf(ne, instr->environment());
+      __ mov(dividend, Operand(dividend, ASR, power));
+    }
+    if (divisor < 0) __ rsb(dividend, dividend, Operand(0));
+
+    return;
+  }
+
   const Register left = ToRegister(instr->left());
   const Register right = ToRegister(instr->right());
   const Register scratch = scratch0();
=======================================
--- /branches/bleeding_edge/test/mjsunit/math-floor-of-div-nosudiv.js Fri Dec 28 07:52:17 2012 +++ /branches/bleeding_edge/test/mjsunit/math-floor-of-div-nosudiv.js Tue Mar 5 00:47:59 2013
@@ -184,7 +184,7 @@
 %OptimizeFunctionOnNextCall(test_div);
 test_div();

-// Test for ia32/x64 flooring correctness.
+// Test for flooring correctness.
 var values2 = [1, 3, 10, 99, 100, 101, 0x7fffffff];
 function test_div2() {
   for (var i = 0; i < values2.length; i++) {
=======================================
--- /branches/bleeding_edge/test/mjsunit/math-floor-of-div.js Fri Dec 28 07:52:17 2012 +++ /branches/bleeding_edge/test/mjsunit/math-floor-of-div.js Tue Mar 5 00:47:59 2013
@@ -184,7 +184,7 @@
 %OptimizeFunctionOnNextCall(test_div);
 test_div();

-// Test for ia32/x64 flooring correctness.
+// Test for flooring correctness.
 var values2 = [1, 3, 10, 99, 100, 101, 0x7fffffff];
 function test_div2() {
   for (var i = 0; i < values2.length; i++) {
=======================================
--- /branches/bleeding_edge/test/mjsunit/mjsunit.status Wed Feb 27 04:14:21 2013 +++ /branches/bleeding_edge/test/mjsunit/mjsunit.status Tue Mar 5 00:47:59 2013
@@ -80,10 +80,6 @@
d8-os: PASS, SKIP if ($isolates || $arch == android_arm || $arch == android_ia32) tools/tickprocessor: PASS, SKIP if ($arch == android_arm || $arch == android_ia32)

-##############################################################################
-# This test is the same as math-floor-of-div for non ARM architectures.
-math-floor-of-div-nosudiv: PASS, SKIP if ($arch != arm && $arch != android_arm)
-
##############################################################################
 # Long running test that reproduces memory leak and should be run manually.
 regress/regress-2073: SKIP

--
--
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