B3 should reduce (integer) Sub(Neg(x), y) to Neg(Add(x, y))
https://bugs.webkit.org/show_bug.cgi?id=196371
Reviewed by Keith Miller.
JSTests:
* microbenchmarks/mul-immediate-sub.js: Added.
(doTest):
Source/JavaScriptCore:
Adding these strength reductions gives 2x a (x86) and 3x (arm64) performance improvement
on the microbenchmark.
* b3/B3ReduceStrength.cpp:
* b3/testb3.cpp:
(JSC::B3::testSubSub):
(JSC::B3::testSubSub2):
(JSC::B3::testSubAdd):
(JSC::B3::testSubFirstNeg):
(JSC::B3::run):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@247390 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog
index f73390e..1c97291 100644
--- a/JSTests/ChangeLog
+++ b/JSTests/ChangeLog
@@ -1,3 +1,13 @@
+2019-07-12 Justin Michaud <justin_michaud@apple.com>
+
+ B3 should reduce (integer) Sub(Neg(x), y) to Neg(Add(x, y))
+ https://bugs.webkit.org/show_bug.cgi?id=196371
+
+ Reviewed by Keith Miller.
+
+ * microbenchmarks/mul-immediate-sub.js: Added.
+ (doTest):
+
2019-07-12 Caio Lima <ticaiolima@gmail.com>
[BigInt] Add ValueBitLShift into DFG
diff --git a/JSTests/microbenchmarks/mul-immediate-sub.js b/JSTests/microbenchmarks/mul-immediate-sub.js
new file mode 100644
index 0000000..088ad76
--- /dev/null
+++ b/JSTests/microbenchmarks/mul-immediate-sub.js
@@ -0,0 +1,13 @@
+function doTest(max) {
+ let sum = 0
+ for (let i=0; i<max; ++i) {
+ sum = (((((((((((sum|0) + ((i*256)|0))|0) - ((i*9)|0))|0) - ((i*31)|0))|0) - ((i*67)|0))|0) - ((i*64)|0))|0)
+ }
+ return sum
+}
+noInline(doTest);
+
+for (let i=0; i<100000; ++i) doTest(10000)
+
+if (doTest(1000) != 42457500)
+ throw "Error: bad result: " + doTest(1000);
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 36fcdad..b281ca7 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,21 @@
+2019-07-12 Justin Michaud <justin_michaud@apple.com>
+
+ B3 should reduce (integer) Sub(Neg(x), y) to Neg(Add(x, y))
+ https://bugs.webkit.org/show_bug.cgi?id=196371
+
+ Reviewed by Keith Miller.
+
+ Adding these strength reductions gives 2x a (x86) and 3x (arm64) performance improvement
+ on the microbenchmark.
+
+ * b3/B3ReduceStrength.cpp:
+ * b3/testb3.cpp:
+ (JSC::B3::testSubSub):
+ (JSC::B3::testSubSub2):
+ (JSC::B3::testSubAdd):
+ (JSC::B3::testSubFirstNeg):
+ (JSC::B3::run):
+
2019-07-12 Caio Lima <ticaiolima@gmail.com>
[BigInt] Add ValueBitLShift into DFG
diff --git a/Source/JavaScriptCore/b3/B3ReduceStrength.cpp b/Source/JavaScriptCore/b3/B3ReduceStrength.cpp
index 102478f..9dc2633 100644
--- a/Source/JavaScriptCore/b3/B3ReduceStrength.cpp
+++ b/Source/JavaScriptCore/b3/B3ReduceStrength.cpp
@@ -651,6 +651,39 @@
break;
}
+ // Turn this: Sub(Neg(value), value2)
+ // Into this: Neg(Add(value, value2))
+ if (m_value->child(0)->opcode() == Neg) {
+ replaceWithNew<Value>(Neg, m_value->origin(),
+ m_insertionSet.insert<Value>(m_index, Add, m_value->origin(), m_value->child(0)->child(0), m_value->child(1)));
+ break;
+ }
+
+ // Turn this: Sub(Sub(a, b), c)
+ // Into this: Sub(a, Add(b, c))
+ if (m_value->child(0)->opcode() == Sub) {
+ replaceWithNew<Value>(Sub, m_value->origin(), m_value->child(0)->child(0),
+ m_insertionSet.insert<Value>(m_index, Add, m_value->origin(), m_value->child(0)->child(1), m_value->child(1)));
+ break;
+ }
+
+ // Turn this: Sub(a, Sub(b, c))
+ // Into this: Add(Sub(a, b), c)
+ if (m_value->child(1)->opcode() == Sub) {
+ replaceWithNew<Value>(Add, m_value->origin(),
+ m_insertionSet.insert<Value>(m_index, Sub, m_value->origin(), m_value->child(0), m_value->child(1)->child(0)),
+ m_value->child(1)->child(1));
+ break;
+ }
+
+ // Turn this: Sub(Add(a, b), c)
+ // Into this: Add(a, Sub(b, c))
+ if (m_value->child(0)->opcode() == Add) {
+ replaceWithNew<Value>(Add, m_value->origin(), m_value->child(0)->child(0),
+ m_insertionSet.insert<Value>(m_index, Sub, m_value->origin(), m_value->child(0)->child(1), m_value->child(1)));
+ break;
+ }
+
if (handleMulDistributivity())
break;
}
diff --git a/Source/JavaScriptCore/b3/testb3.cpp b/Source/JavaScriptCore/b3/testb3.cpp
index c9fd18e..e841bb8 100644
--- a/Source/JavaScriptCore/b3/testb3.cpp
+++ b/Source/JavaScriptCore/b3/testb3.cpp
@@ -2190,6 +2190,69 @@
CHECK(compileAndRun<int>(proc, a) == -a - 1);
}
+void testSubSub(int a, int b, int c)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ root->appendNewControlValue(
+ proc, Return, Origin(),
+ root->appendNew<Value>(
+ proc, Sub, Origin(),
+ root->appendNew<Value>(proc, Sub, Origin(),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)));
+
+ CHECK(compileAndRun<int>(proc, a, b, c) == (a-b)-c);
+}
+
+void testSubSub2(int a, int b, int c)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ root->appendNewControlValue(
+ proc, Return, Origin(),
+ root->appendNew<Value>(
+ proc, Sub, Origin(),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
+ root->appendNew<Value>(proc, Sub, Origin(),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2))));
+
+ CHECK(compileAndRun<int>(proc, a, b, c) == a-(b-c));
+}
+
+void testSubAdd(int a, int b, int c)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ root->appendNewControlValue(
+ proc, Return, Origin(),
+ root->appendNew<Value>(
+ proc, Sub, Origin(),
+ root->appendNew<Value>(proc, Add, Origin(),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)));
+
+ CHECK(compileAndRun<int>(proc, a, b, c) == (a+b)-c);
+}
+
+void testSubFirstNeg(int a, int b)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ root->appendNewControlValue(
+ proc, Return, Origin(),
+ root->appendNew<Value>(
+ proc, Sub, Origin(),
+ root->appendNew<Value>(proc, Neg, Origin(),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
+ root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
+
+ CHECK(compileAndRun<int>(proc, a, b) == (-a)-b);
+}
+
void testSubImmArg(int a, int b)
{
Procedure proc;
@@ -17457,6 +17520,11 @@
RUN_BINARY(testNegMulArgImm, int64Operands(), int64Operands());
RUN_TERNARY(testSubMulMulArgs, int64Operands(), int64Operands(), int64Operands());
+ RUN_TERNARY(testSubSub, int32Operands(), int32Operands(), int32Operands());
+ RUN_TERNARY(testSubSub2, int32Operands(), int32Operands(), int32Operands());
+ RUN_TERNARY(testSubAdd, int32Operands(), int32Operands(), int32Operands());
+ RUN_BINARY(testSubFirstNeg, int32Operands(), int32Operands());
+
RUN(testSubArgs32(1, 1));
RUN(testSubArgs32(1, 2));
RUN(testSubArgs32(13, -42));