Title: [183495] trunk
Revision
183495
Author
[email protected]
Date
2015-04-28 11:54:12 -0700 (Tue, 28 Apr 2015)

Log Message

Source/_javascript_Core:
DFG+FTL should generate efficient code for branching on a string's boolean value.
<https://webkit.org/b/144317>

Reviewed by Geoff Garen & Filip Pizlo

Teach Branch nodes about StringUse and have them generate an efficient zero-length string check
instead of dropping out to C++ whenever we branch on a string.

The FTL JIT already handled Branch nodes with StringUse through its use of boolify(), so only
the DFG JIT gets some new codegen logic in this patch.

Test: js/regress/branch-on-string-as-boolean.js (~4.5x speedup)

* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::emitStringBranch):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::emitBranch):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::emitBranch):

LayoutTests:
DFG should generate efficient code for branching on a string's boolean value.
<https://webkit.org/b/144317>

Reviewed by Geoff Garen & Filip Pizlo.

* js/regress/branch-on-string-as-boolean-expected.txt: Added.
* js/regress/branch-on-string-as-boolean.html: Added.
* js/regress/script-tests/branch-on-string-as-boolean.js: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (183494 => 183495)


--- trunk/LayoutTests/ChangeLog	2015-04-28 18:36:59 UTC (rev 183494)
+++ trunk/LayoutTests/ChangeLog	2015-04-28 18:54:12 UTC (rev 183495)
@@ -1,3 +1,14 @@
+2015-04-28  Andreas Kling  <[email protected]>
+
+        DFG should generate efficient code for branching on a string's boolean value.
+        <https://webkit.org/b/144317>
+
+        Reviewed by Geoff Garen & Filip Pizlo.
+
+        * js/regress/branch-on-string-as-boolean-expected.txt: Added.
+        * js/regress/branch-on-string-as-boolean.html: Added.
+        * js/regress/script-tests/branch-on-string-as-boolean.js: Added.
+
 2015-04-27  Myles C. Maxfield  <[email protected]>
 
         Implement font-synthesis CSS property

Added: trunk/LayoutTests/js/regress/branch-on-string-as-boolean-expected.txt (0 => 183495)


--- trunk/LayoutTests/js/regress/branch-on-string-as-boolean-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/regress/branch-on-string-as-boolean-expected.txt	2015-04-28 18:54:12 UTC (rev 183495)
@@ -0,0 +1,10 @@
+JSRegress/branch-on-string-as-boolean
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/regress/branch-on-string-as-boolean.html (0 => 183495)


--- trunk/LayoutTests/js/regress/branch-on-string-as-boolean.html	                        (rev 0)
+++ trunk/LayoutTests/js/regress/branch-on-string-as-boolean.html	2015-04-28 18:54:12 UTC (rev 183495)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/js/regress/script-tests/branch-on-string-as-boolean.js (0 => 183495)


--- trunk/LayoutTests/js/regress/script-tests/branch-on-string-as-boolean.js	                        (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/branch-on-string-as-boolean.js	2015-04-28 18:54:12 UTC (rev 183495)
@@ -0,0 +1,12 @@
+// This test branches on the boolean value of a string, which should be fast in the DFG.
+
+function foo(string) {
+    var bar;
+    for (var i = 0; i < 10000000; ++i) {
+        if (string)
+            bar++;
+    }
+    return bar;
+}
+
+result = foo('hurr im a string');

Modified: trunk/Source/_javascript_Core/ChangeLog (183494 => 183495)


--- trunk/Source/_javascript_Core/ChangeLog	2015-04-28 18:36:59 UTC (rev 183494)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-04-28 18:54:12 UTC (rev 183495)
@@ -1,3 +1,28 @@
+2015-04-28  Andreas Kling  <[email protected]>
+
+        DFG+FTL should generate efficient code for branching on a string's boolean value.
+        <https://webkit.org/b/144317>
+
+        Reviewed by Geoff Garen & Filip Pizlo
+
+        Teach Branch nodes about StringUse and have them generate an efficient zero-length string check
+        instead of dropping out to C++ whenever we branch on a string.
+
+        The FTL JIT already handled Branch nodes with StringUse through its use of boolify(), so only
+        the DFG JIT gets some new codegen logic in this patch.
+
+        Test: js/regress/branch-on-string-as-boolean.js (~4.5x speedup)
+
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitStringBranch):
+        * dfg/DFGSpeculativeJIT.h:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitBranch):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitBranch):
+
 2015-04-28  Filip Pizlo  <[email protected]>
 
         VarargsForwardingPhase should only consider MovHints that have the candidate as a child

Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (183494 => 183495)


--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2015-04-28 18:36:59 UTC (rev 183494)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2015-04-28 18:54:12 UTC (rev 183495)
@@ -737,6 +737,8 @@
                 fixEdge<Int32Use>(node->child1());
             else if (node->child1()->shouldSpeculateNumber())
                 fixEdge<DoubleRepUse>(node->child1());
+            else if (node->child1()->shouldSpeculateString())
+                fixEdge<StringUse>(node->child1());
             break;
         }
             

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (183494 => 183495)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2015-04-28 18:36:59 UTC (rev 183494)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2015-04-28 18:54:12 UTC (rev 183495)
@@ -4040,6 +4040,15 @@
     unblessedBooleanResult(eqGPR, node);
 }
 
+void SpeculativeJIT::emitStringBranch(Edge nodeUse, BasicBlock* taken, BasicBlock* notTaken)
+{
+    SpeculateCellOperand str(this, nodeUse);
+    speculateString(nodeUse, str.gpr());
+    branchTest32(JITCompiler::NonZero, MacroAssembler::Address(str.gpr(), JSString::offsetOfLength()), taken);
+    jump(notTaken);
+    noResult(m_currentNode);
+}
+
 void SpeculativeJIT::compileConstantStoragePointer(Node* node)
 {
     GPRTemporary storage(this);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (183494 => 183495)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2015-04-28 18:36:59 UTC (rev 183494)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2015-04-28 18:54:12 UTC (rev 183495)
@@ -2103,6 +2103,7 @@
     void compileMiscStrictEq(Node*);
 
     void emitObjectOrOtherBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken);
+    void emitStringBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken);
     void emitBranch(Node*);
     
     struct StringSwitchCase {

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (183494 => 183495)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2015-04-28 18:36:59 UTC (rev 183494)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2015-04-28 18:54:12 UTC (rev 183495)
@@ -1573,7 +1573,12 @@
         emitObjectOrOtherBranch(node->child1(), taken, notTaken);
         return;
     }
-    
+
+    case StringUse: {
+        emitStringBranch(node->child1(), taken, notTaken);
+        return;
+    }
+
     case DoubleRepUse:
     case Int32Use: {
         if (node->child1().useKind() == Int32Use) {

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (183494 => 183495)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2015-04-28 18:36:59 UTC (rev 183494)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2015-04-28 18:54:12 UTC (rev 183495)
@@ -1742,6 +1742,11 @@
         return;
     }
 
+    case StringUse: {
+        emitStringBranch(node->child1(), taken, notTaken);
+        return;
+    }
+
     case UntypedUse:
     case BooleanUse: {
         JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to