Revision: 24554
Author: [email protected]
Date: Mon Oct 13 11:09:32 2014 UTC
Log: [turbofan] Optimize Int32Mod by power-of-two.
TEST=mjsunit/asm/int32-tmod,unittests
[email protected]
Review URL: https://codereview.chromium.org/649083005
https://code.google.com/p/v8/source/detail?r=24554
Modified:
/branches/bleeding_edge/src/compiler/machine-operator-reducer.cc
/branches/bleeding_edge/src/compiler/machine-operator-reducer.h
/branches/bleeding_edge/test/mjsunit/asm/int32-tmod.js
/branches/bleeding_edge/test/unittests/compiler/graph-unittest.cc
/branches/bleeding_edge/test/unittests/compiler/graph-unittest.h
/branches/bleeding_edge/test/unittests/compiler/machine-operator-reducer-unittest.cc
=======================================
--- /branches/bleeding_edge/src/compiler/machine-operator-reducer.cc Fri
Oct 10 10:23:04 2014 UTC
+++ /branches/bleeding_edge/src/compiler/machine-operator-reducer.cc Mon
Oct 13 11:09:32 2014 UTC
@@ -262,19 +262,8 @@
}
break;
}
- case IrOpcode::kInt32Mod: {
- Int32BinopMatcher m(node);
- if (m.right().Is(1)) return ReplaceInt32(0); // x % 1 => 0
- if (m.right().Is(-1)) return ReplaceInt32(0); // x % -1 => 0
- // TODO(turbofan): if (m.left().Is(0))
- // TODO(turbofan): if (m.right().IsPowerOf2())
- // TODO(turbofan): if (m.right().Is(0))
- // TODO(turbofan): if (m.LeftEqualsRight())
- if (m.IsFoldable() && !m.right().Is(0)) { // K % K => K
- return ReplaceInt32(m.left().Value() % m.right().Value());
- }
- break;
- }
+ case IrOpcode::kInt32Mod:
+ return ReduceInt32Mod(node);
case IrOpcode::kUint32Mod: {
Uint32BinopMatcher m(node);
if (m.right().Is(1)) return ReplaceInt32(0); // x % 1 => 0
@@ -508,6 +497,44 @@
}
return NoChange();
}
+
+
+Reduction MachineOperatorReducer::ReduceInt32Mod(Node* const node) {
+ Int32BinopMatcher m(node);
+ if (m.right().Is(1)) return ReplaceInt32(0); // x % 1 => 0
+ if (m.right().Is(-1)) return ReplaceInt32(0); // x % -1 => 0
+ // TODO(turbofan): if (m.left().Is(0))
+ // TODO(turbofan): if (m.right().Is(0))
+ // TODO(turbofan): if (m.LeftEqualsRight())
+ if (m.IsFoldable() && !m.right().Is(0)) { // K % K => K
+ return ReplaceInt32(m.left().Value() % m.right().Value());
+ }
+ if (m.right().IsPowerOf2()) {
+ int32_t const divisor = m.right().Value();
+ Node* zero = Int32Constant(0);
+ Node* mask = Int32Constant(divisor - 1);
+ Node* dividend = m.left().node();
+
+ Node* check = graph()->NewNode(machine()->Int32LessThan(), dividend,
zero);
+ Node* branch =
+ graph()->NewNode(common()->Branch(), check, graph()->start());
+
+ Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* neg = graph()->NewNode(
+ machine()->Int32Sub(), zero,
+ graph()->NewNode(
+ machine()->Word32And(),
+ graph()->NewNode(machine()->Int32Sub(), zero, dividend),
mask));
+
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+ Node* pos = graph()->NewNode(machine()->Word32And(), dividend, mask);
+
+ Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+ Node* phi = graph()->NewNode(common()->Phi(kMachInt32, 2), neg, pos,
merge);
+ return Replace(phi);
+ }
+ return NoChange();
+}
Reduction MachineOperatorReducer::ReduceProjection(size_t index, Node*
node) {
=======================================
--- /branches/bleeding_edge/src/compiler/machine-operator-reducer.h Fri Sep
26 07:35:59 2014 UTC
+++ /branches/bleeding_edge/src/compiler/machine-operator-reducer.h Mon Oct
13 11:09:32 2014 UTC
@@ -49,6 +49,7 @@
return Replace(Int64Constant(value));
}
+ Reduction ReduceInt32Mod(Node* node);
Reduction ReduceProjection(size_t index, Node* node);
Graph* graph() const;
=======================================
--- /branches/bleeding_edge/test/mjsunit/asm/int32-tmod.js Wed Oct 8
10:53:46 2014 UTC
+++ /branches/bleeding_edge/test/mjsunit/asm/int32-tmod.js Mon Oct 13
11:09:32 2014 UTC
@@ -4,6 +4,10 @@
function Module(stdlib, foreign, heap) {
"use asm";
+ function f0(i) {
+ i = i|0;
+ return i % 2 | 0;
+ }
function f1(i) {
i = i|0;
return i % 3 | 0;
@@ -20,12 +24,13 @@
i = i|0;
return i % 3333339 | 0;
}
- return { f1: f1, f2: f2, f3: f3, f4: f4 };
+ return { f0: f0, f1: f1, f2: f2, f3: f3, f4: f4 };
}
var m = Module(this, {}, new ArrayBuffer(1024));
for (var i = -2147483648; i < 2147483648; i += 3999773) {
+ assertEquals(i % 2 | 0, m.f0(i));
assertEquals(i % 3 | 0, m.f1(i));
assertEquals(i % 9 | 0, m.f2(i));
assertEquals(i % 1024 | 0, m.f3(i));
=======================================
--- /branches/bleeding_edge/test/unittests/compiler/graph-unittest.cc Fri
Oct 10 10:23:04 2014 UTC
+++ /branches/bleeding_edge/test/unittests/compiler/graph-unittest.cc Mon
Oct 13 11:09:32 2014 UTC
@@ -948,7 +948,9 @@
IS_BINOP_MATCHER(Word64Shl)
IS_BINOP_MATCHER(Word64Equal)
IS_BINOP_MATCHER(Int32AddWithOverflow)
+IS_BINOP_MATCHER(Int32Sub)
IS_BINOP_MATCHER(Int32Mul)
+IS_BINOP_MATCHER(Int32LessThan)
IS_BINOP_MATCHER(Uint32LessThan)
IS_BINOP_MATCHER(Uint32LessThanOrEqual)
#undef IS_BINOP_MATCHER
=======================================
--- /branches/bleeding_edge/test/unittests/compiler/graph-unittest.h Fri
Oct 10 10:23:04 2014 UTC
+++ /branches/bleeding_edge/test/unittests/compiler/graph-unittest.h Mon
Oct 13 11:09:32 2014 UTC
@@ -148,8 +148,12 @@
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsInt32AddWithOverflow(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsInt32Sub(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsInt32Mul(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsInt32LessThan(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsUint32LessThan(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsUint32LessThanOrEqual(const Matcher<Node*>& lhs_matcher,
=======================================
---
/branches/bleeding_edge/test/unittests/compiler/machine-operator-reducer-unittest.cc
Fri Oct 10 10:23:04 2014 UTC
+++
/branches/bleeding_edge/test/unittests/compiler/machine-operator-reducer-unittest.cc
Mon Oct 13 11:09:32 2014 UTC
@@ -7,6 +7,11 @@
#include "src/compiler/machine-operator-reducer.h"
#include "src/compiler/typer.h"
#include "test/unittests/compiler/graph-unittest.h"
+#include "testing/gmock-support.h"
+
+using testing::AllOf;
+using testing::Capture;
+using testing::CaptureEq;
namespace v8 {
namespace internal {
@@ -561,6 +566,37 @@
EXPECT_THAT(r.replacement(), IsWord32And(p0, IsInt32Constant(m)));
}
}
+
+
+//
-----------------------------------------------------------------------------
+// Int32Mod
+
+
+TEST_F(MachineOperatorReducerTest, Int32ModWithPowerOfTwo) {
+ Node* p0 = Parameter(0);
+ TRACED_FORRANGE(int32_t, x, 1, 30) {
+ int32_t const divisor = 1 << x;
+ Node* node =
+ graph()->NewNode(machine()->Int32Mod(), p0,
Int32Constant(divisor));
+ Reduction r = Reduce(node);
+ ASSERT_TRUE(r.Changed());
+
+ Capture<Node*> branch;
+ Node* phi = r.replacement();
+ int32_t const mask = divisor - 1;
+ EXPECT_THAT(
+ phi, IsPhi(kMachInt32,
+ IsInt32Sub(IsInt32Constant(0),
+ IsWord32And(IsInt32Sub(IsInt32Constant(0),
p0),
+ IsInt32Constant(mask))),
+ IsWord32And(p0, IsInt32Constant(mask)),
+ IsMerge(IsIfTrue(CaptureEq(&branch)),
+ IsIfFalse(AllOf(
+ CaptureEq(&branch),
+ IsBranch(IsInt32LessThan(p0,
IsInt32Constant(0)),
+ graph()->start()))))));
+ }
+}
//
-----------------------------------------------------------------------------
--
--
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/d/optout.