FixupPhase should be more eager to demote bit math to untyped
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 May 2016 19:41:01 +0000 (19:41 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 May 2016 19:41:01 +0000 (19:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=157746

Reviewed by Mark Lam.
Source/JavaScriptCore:

This just makes the logic for how we fixup bit math match the way we do it in other places.
This doesn't affect performance on any major benchmark but it's a big win on new
microbenchmarks added in this change.

Details:

object-and                                     11.1610+-0.7602     ^      4.8105+-0.1690        ^ definitely 2.3201x faster
object-or                                      11.0845+-0.2487     ^      4.7146+-0.0374        ^ definitely 2.3511x faster
object-xor                                     10.2946+-0.9946     ^      4.7278+-0.0814        ^ definitely 2.1775x faster
object-lshift                                  10.4896+-1.0867     ^      4.7699+-0.0721        ^ definitely 2.1991x faster
object-rshift                                  11.1239+-0.5010     ^      4.7194+-0.0445        ^ definitely 2.3570x faster
object-urshift                                 10.9745+-0.1315     ^      4.7848+-0.0479        ^ definitely 2.2936x faster

* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):

LayoutTests:

* js/regress/object-and-expected.txt: Added.
* js/regress/object-and.html: Added.
* js/regress/object-int-and-array-expected.txt: Added.
* js/regress/object-int-and-array.html: Added.
* js/regress/object-lshift-expected.txt: Added.
* js/regress/object-lshift.html: Added.
* js/regress/object-or-expected.txt: Added.
* js/regress/object-or.html: Added.
* js/regress/object-rshift-expected.txt: Added.
* js/regress/object-rshift.html: Added.
* js/regress/object-urshift-expected.txt: Added.
* js/regress/object-urshift.html: Added.
* js/regress/object-xor-expected.txt: Added.
* js/regress/object-xor.html: Added.
* js/regress/script-tests/object-and.js: Added.
(o.valueOf):
* js/regress/script-tests/object-int-and-array.js: Added.
(i.o.valueOf):
* js/regress/script-tests/object-lshift.js: Added.
(o.valueOf):
* js/regress/script-tests/object-or.js: Added.
(o.valueOf):
* js/regress/script-tests/object-rshift.js: Added.
(o.valueOf):
* js/regress/script-tests/object-urshift.js: Added.
(o.valueOf):
* js/regress/script-tests/object-xor.js: Added.
(o.valueOf):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@200958 268f45cc-cd09-0410-ab3c-d52691b4dbfc

24 files changed:
LayoutTests/ChangeLog
LayoutTests/js/regress/object-and-expected.txt [new file with mode: 0644]
LayoutTests/js/regress/object-and.html [new file with mode: 0644]
LayoutTests/js/regress/object-int-and-array-expected.txt [new file with mode: 0644]
LayoutTests/js/regress/object-int-and-array.html [new file with mode: 0644]
LayoutTests/js/regress/object-lshift-expected.txt [new file with mode: 0644]
LayoutTests/js/regress/object-lshift.html [new file with mode: 0644]
LayoutTests/js/regress/object-or-expected.txt [new file with mode: 0644]
LayoutTests/js/regress/object-or.html [new file with mode: 0644]
LayoutTests/js/regress/object-rshift-expected.txt [new file with mode: 0644]
LayoutTests/js/regress/object-rshift.html [new file with mode: 0644]
LayoutTests/js/regress/object-urshift-expected.txt [new file with mode: 0644]
LayoutTests/js/regress/object-urshift.html [new file with mode: 0644]
LayoutTests/js/regress/object-xor-expected.txt [new file with mode: 0644]
LayoutTests/js/regress/object-xor.html [new file with mode: 0644]
LayoutTests/js/regress/script-tests/object-and.js [new file with mode: 0644]
LayoutTests/js/regress/script-tests/object-int-and-array.js [new file with mode: 0644]
LayoutTests/js/regress/script-tests/object-lshift.js [new file with mode: 0644]
LayoutTests/js/regress/script-tests/object-or.js [new file with mode: 0644]
LayoutTests/js/regress/script-tests/object-rshift.js [new file with mode: 0644]
LayoutTests/js/regress/script-tests/object-urshift.js [new file with mode: 0644]
LayoutTests/js/regress/script-tests/object-xor.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

index d0a5bee..e4ad27c 100644 (file)
@@ -1,3 +1,39 @@
+2016-05-16  Filip Pizlo  <fpizlo@apple.com>
+
+        FixupPhase should be more eager to demote bit math to untyped
+        https://bugs.webkit.org/show_bug.cgi?id=157746
+
+        Reviewed by Mark Lam.
+
+        * js/regress/object-and-expected.txt: Added.
+        * js/regress/object-and.html: Added.
+        * js/regress/object-int-and-array-expected.txt: Added.
+        * js/regress/object-int-and-array.html: Added.
+        * js/regress/object-lshift-expected.txt: Added.
+        * js/regress/object-lshift.html: Added.
+        * js/regress/object-or-expected.txt: Added.
+        * js/regress/object-or.html: Added.
+        * js/regress/object-rshift-expected.txt: Added.
+        * js/regress/object-rshift.html: Added.
+        * js/regress/object-urshift-expected.txt: Added.
+        * js/regress/object-urshift.html: Added.
+        * js/regress/object-xor-expected.txt: Added.
+        * js/regress/object-xor.html: Added.
+        * js/regress/script-tests/object-and.js: Added.
+        (o.valueOf):
+        * js/regress/script-tests/object-int-and-array.js: Added.
+        (i.o.valueOf):
+        * js/regress/script-tests/object-lshift.js: Added.
+        (o.valueOf):
+        * js/regress/script-tests/object-or.js: Added.
+        (o.valueOf):
+        * js/regress/script-tests/object-rshift.js: Added.
+        (o.valueOf):
+        * js/regress/script-tests/object-urshift.js: Added.
+        (o.valueOf):
+        * js/regress/script-tests/object-xor.js: Added.
+        (o.valueOf):
+
 2016-05-16  Michael Saboff  <msaboff@apple.com>
 
         RegExp /y flag incorrect handling of mixed-length alternation
diff --git a/LayoutTests/js/regress/object-and-expected.txt b/LayoutTests/js/regress/object-and-expected.txt
new file mode 100644 (file)
index 0000000..508b74c
--- /dev/null
@@ -0,0 +1,10 @@
+JSRegress/object-and
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/js/regress/object-and.html b/LayoutTests/js/regress/object-and.html
new file mode 100644 (file)
index 0000000..53ca842
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="../../resources/regress-pre.js"></script>
+<script src="script-tests/object-and.js"></script>
+<script src="../../resources/regress-post.js"></script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/js/regress/object-int-and-array-expected.txt b/LayoutTests/js/regress/object-int-and-array-expected.txt
new file mode 100644 (file)
index 0000000..083f3e6
--- /dev/null
@@ -0,0 +1,10 @@
+JSRegress/object-int-and-array
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/js/regress/object-int-and-array.html b/LayoutTests/js/regress/object-int-and-array.html
new file mode 100644 (file)
index 0000000..1491c41
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="../../resources/regress-pre.js"></script>
+<script src="script-tests/object-int-and-array.js"></script>
+<script src="../../resources/regress-post.js"></script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/js/regress/object-lshift-expected.txt b/LayoutTests/js/regress/object-lshift-expected.txt
new file mode 100644 (file)
index 0000000..eacf417
--- /dev/null
@@ -0,0 +1,10 @@
+JSRegress/object-lshift
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/js/regress/object-lshift.html b/LayoutTests/js/regress/object-lshift.html
new file mode 100644 (file)
index 0000000..10fbc88
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="../../resources/regress-pre.js"></script>
+<script src="script-tests/object-lshift.js"></script>
+<script src="../../resources/regress-post.js"></script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/js/regress/object-or-expected.txt b/LayoutTests/js/regress/object-or-expected.txt
new file mode 100644 (file)
index 0000000..9363a93
--- /dev/null
@@ -0,0 +1,10 @@
+JSRegress/object-or
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/js/regress/object-or.html b/LayoutTests/js/regress/object-or.html
new file mode 100644 (file)
index 0000000..4bf1354
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="../../resources/regress-pre.js"></script>
+<script src="script-tests/object-or.js"></script>
+<script src="../../resources/regress-post.js"></script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/js/regress/object-rshift-expected.txt b/LayoutTests/js/regress/object-rshift-expected.txt
new file mode 100644 (file)
index 0000000..82e9fc6
--- /dev/null
@@ -0,0 +1,10 @@
+JSRegress/object-rshift
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/js/regress/object-rshift.html b/LayoutTests/js/regress/object-rshift.html
new file mode 100644 (file)
index 0000000..ad0a30e
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="../../resources/regress-pre.js"></script>
+<script src="script-tests/object-rshift.js"></script>
+<script src="../../resources/regress-post.js"></script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/js/regress/object-urshift-expected.txt b/LayoutTests/js/regress/object-urshift-expected.txt
new file mode 100644 (file)
index 0000000..11f984d
--- /dev/null
@@ -0,0 +1,10 @@
+JSRegress/object-urshift
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/js/regress/object-urshift.html b/LayoutTests/js/regress/object-urshift.html
new file mode 100644 (file)
index 0000000..81741fe
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="../../resources/regress-pre.js"></script>
+<script src="script-tests/object-urshift.js"></script>
+<script src="../../resources/regress-post.js"></script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/js/regress/object-xor-expected.txt b/LayoutTests/js/regress/object-xor-expected.txt
new file mode 100644 (file)
index 0000000..3ebbd94
--- /dev/null
@@ -0,0 +1,10 @@
+JSRegress/object-xor
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/js/regress/object-xor.html b/LayoutTests/js/regress/object-xor.html
new file mode 100644 (file)
index 0000000..f5e4405
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script src="../../resources/regress-pre.js"></script>
+<script src="script-tests/object-xor.js"></script>
+<script src="../../resources/regress-post.js"></script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/js/regress/script-tests/object-and.js b/LayoutTests/js/regress/script-tests/object-and.js
new file mode 100644 (file)
index 0000000..3dd651e
--- /dev/null
@@ -0,0 +1,17 @@
+(function() {
+    var m = 1000;
+    var n = 1000;
+    var o = {valueOf: function() { return 42; }};
+    var result = 0;
+    for (var i = 0; i < m; ++i) {
+        result += o & 2;
+        for (var j = 0; j < n; ++j)
+            result *= 1.1;
+        for (var j = 0; j < n; ++j)
+            result /= 2;
+    }
+    
+    if (result != 4.610197065037039e-260)
+        throw "Error: bad result: " + result;
+})();
+
diff --git a/LayoutTests/js/regress/script-tests/object-int-and-array.js b/LayoutTests/js/regress/script-tests/object-int-and-array.js
new file mode 100644 (file)
index 0000000..3d3ab3e
--- /dev/null
@@ -0,0 +1,18 @@
+(function() {
+    var result = 0;
+    var m = 100;
+    var n = 100000;
+    var array = [];
+    for (var i = 0; i < 100; ++i)
+        array.push(12);
+    for (var i = 0; i < m; ++i) {
+        var value = 0;
+        var o = {valueOf: function() { return 42; }};
+        value += o;
+        var result = 0;
+        for (var j = 0; j < n; ++j)
+            result += array[value];
+    }
+    if (result != n * 12)
+        throw "Error: bad result: " + result;
+})();
diff --git a/LayoutTests/js/regress/script-tests/object-lshift.js b/LayoutTests/js/regress/script-tests/object-lshift.js
new file mode 100644 (file)
index 0000000..add30b9
--- /dev/null
@@ -0,0 +1,17 @@
+(function() {
+    var m = 1000;
+    var n = 1000;
+    var o = {valueOf: function() { return 1; }};
+    var result = 0;
+    for (var i = 0; i < m; ++i) {
+        result += 1 << o;
+        for (var j = 0; j < n; ++j)
+            result *= 1.1;
+        for (var j = 0; j < n; ++j)
+            result /= 2;
+    }
+    
+    if (result != 4.610197065037039e-260)
+        throw "Error: bad result: " + result;
+})();
+
diff --git a/LayoutTests/js/regress/script-tests/object-or.js b/LayoutTests/js/regress/script-tests/object-or.js
new file mode 100644 (file)
index 0000000..07704eb
--- /dev/null
@@ -0,0 +1,17 @@
+(function() {
+    var m = 1000;
+    var n = 1000;
+    var o = {valueOf: function() { return 42; }};
+    var result = 0;
+    for (var i = 0; i < m; ++i) {
+        result += o | 1;
+        for (var j = 0; j < n; ++j)
+            result *= 1.1;
+        for (var j = 0; j < n; ++j)
+            result /= 2;
+    }
+    
+    if (result != 9.911923689829635e-259)
+        throw "Error: bad result: " + result;
+})();
+
diff --git a/LayoutTests/js/regress/script-tests/object-rshift.js b/LayoutTests/js/regress/script-tests/object-rshift.js
new file mode 100644 (file)
index 0000000..e50a32b
--- /dev/null
@@ -0,0 +1,17 @@
+(function() {
+    var m = 1000;
+    var n = 1000;
+    var o = {valueOf: function() { return 1; }};
+    var result = 0;
+    for (var i = 0; i < m; ++i) {
+        result += 2 >> o;
+        for (var j = 0; j < n; ++j)
+            result *= 1.1;
+        for (var j = 0; j < n; ++j)
+            result /= 2;
+    }
+    
+    if (result != 2.3050985325185195e-260)
+        throw "Error: bad result: " + result;
+})();
+
diff --git a/LayoutTests/js/regress/script-tests/object-urshift.js b/LayoutTests/js/regress/script-tests/object-urshift.js
new file mode 100644 (file)
index 0000000..e0e342b
--- /dev/null
@@ -0,0 +1,17 @@
+(function() {
+    var m = 1000;
+    var n = 1000;
+    var o = {valueOf: function() { return 1; }};
+    var result = 0;
+    for (var i = 0; i < m; ++i) {
+        result += 2 >>> o;
+        for (var j = 0; j < n; ++j)
+            result *= 1.1;
+        for (var j = 0; j < n; ++j)
+            result /= 2;
+    }
+    
+    if (result != 2.3050985325185195e-260)
+        throw "Error: bad result: " + result;
+})();
+
diff --git a/LayoutTests/js/regress/script-tests/object-xor.js b/LayoutTests/js/regress/script-tests/object-xor.js
new file mode 100644 (file)
index 0000000..2e7f433
--- /dev/null
@@ -0,0 +1,17 @@
+(function() {
+    var m = 1000;
+    var n = 1000;
+    var o = {valueOf: function() { return 42; }};
+    var result = 0;
+    for (var i = 0; i < m; ++i) {
+        result += o ^ 2;
+        for (var j = 0; j < n; ++j)
+            result *= 1.1;
+        for (var j = 0; j < n; ++j)
+            result /= 2;
+    }
+    
+    if (result != 9.220394130074086e-259)
+        throw "Error: bad result: " + result;
+})();
+
index 6ed0fd7..84fc1a8 100644 (file)
@@ -1,3 +1,26 @@
+2016-05-16  Filip Pizlo  <fpizlo@apple.com>
+
+        FixupPhase should be more eager to demote bit math to untyped
+        https://bugs.webkit.org/show_bug.cgi?id=157746
+
+        Reviewed by Mark Lam.
+        
+        This just makes the logic for how we fixup bit math match the way we do it in other places.
+        This doesn't affect performance on any major benchmark but it's a big win on new
+        microbenchmarks added in this change.
+        
+        Details:
+
+        object-and                                     11.1610+-0.7602     ^      4.8105+-0.1690        ^ definitely 2.3201x faster
+        object-or                                      11.0845+-0.2487     ^      4.7146+-0.0374        ^ definitely 2.3511x faster
+        object-xor                                     10.2946+-0.9946     ^      4.7278+-0.0814        ^ definitely 2.1775x faster
+        object-lshift                                  10.4896+-1.0867     ^      4.7699+-0.0721        ^ definitely 2.1991x faster
+        object-rshift                                  11.1239+-0.5010     ^      4.7194+-0.0445        ^ definitely 2.3570x faster
+        object-urshift                                 10.9745+-0.1315     ^      4.7848+-0.0479        ^ definitely 2.2936x faster
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+
 2016-05-15  Michael Saboff  <msaboff@apple.com>
 
         RegExp /y flag incorrect handling of mixed-length alternation
index 1359e50..e09de55 100644 (file)
@@ -105,8 +105,7 @@ private:
         case BitRShift:
         case BitLShift:
         case BitURShift: {
-            if (Node::shouldSpeculateUntypedForBitOps(node->child1().node(), node->child2().node())
-                && m_graph.hasExitSite(node->origin.semantic, BadType)) {
+            if (Node::shouldSpeculateUntypedForBitOps(node->child1().node(), node->child2().node())) {
                 fixEdge<UntypedUse>(node->child1());
                 fixEdge<UntypedUse>(node->child2());
                 break;