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.