Changeset 215472 in webkit


Ignore:
Timestamp:
Apr 18, 2017 11:06:37 AM (7 years ago)
Author:
Yusuke Suzuki
Message:

[DFG] Convert ValueAdd(Int32, String) => MakeRope(ToString(Int32), String)
https://bugs.webkit.org/show_bug.cgi?id=170943

Reviewed by Geoffrey Garen.

JSTests:

  • microbenchmarks/number-to-string-with-add-empty.js: Added.

(toStringLeft):
(toStringRight):

  • microbenchmarks/number-to-string-with-add-in-loop.js: Added.

(toStringLeft):
(toStringRight):

  • microbenchmarks/number-to-string-with-add.js: Added.

(toStringLeft):
(toStringRight):

  • stress/number-to-string-with-add.js: Added.

(shouldBe):
(toStringRight):
(toStringLeftEmpty):
(toStringRightEmpty):

Source/JavaScriptCore:

This patch converts ValueAdd(Int32, String) to MakeRope(ToString(Int32), String).
This has 2 great features.

  1. MakeRope(ToString(Int32), String) is less clobbering.

While ValueAdd ends up calling functions, VM knows much about MakeRope(ToString(Int32), String)
and VM knows it is less clobbering. It encourages LICM and other operations that is conservatively
executed because of ValueAdd's clobbering.

  1. Simply, MakeRope(ToString(Int32), String) is faster than ValueAdd.

While ValueAdd ends up calling a generic function, our ToString(Int32) calls well-optimized toString
operation. And later, MakeRope can fall into the fast path that just takes a string from a free list.
It is simply faster than ValueAdd.

We ensure that this patch shows performance improvement in attached benchmarks.

baseline patched

number-to-string-with-add-empty 16.2763+-3.3930 10.3142+-1.0967 definitely 1.5780x faster
number-to-string-with-add-in-loop 168.7621+-10.9738 15.5307+-3.3179 definitely 10.8664x faster
number-to-string-with-add 18.8557+-4.8292 11.6901+-2.5650 might be 1.6130x faster

In SixSpeed,

baseline patched

template_string_tag.es5 200.1027+-20.6871 25.7925+-11.4052 definitely 7.7582x faster
template_string_tag.es6 331.3913+-12.1750 286.6958+-26.0441 definitely 1.1559x faster
for-of-array.es5 412.4344+-23.2517 272.8707+-47.2118 definitely 1.5115x faster
for-of-array.es6 504.0082+-65.5045 300.3277+-12.8193 definitely 1.6782x faster

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::createToString):

  • dfg/DFGPredictionPropagationPhase.cpp:
Location:
trunk
Files:
4 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r215459 r215472  
     12017-04-18  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [DFG] Convert ValueAdd(Int32, String) => MakeRope(ToString(Int32), String)
     4        https://bugs.webkit.org/show_bug.cgi?id=170943
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        * microbenchmarks/number-to-string-with-add-empty.js: Added.
     9        (toStringLeft):
     10        (toStringRight):
     11        * microbenchmarks/number-to-string-with-add-in-loop.js: Added.
     12        (toStringLeft):
     13        (toStringRight):
     14        * microbenchmarks/number-to-string-with-add.js: Added.
     15        (toStringLeft):
     16        (toStringRight):
     17        * stress/number-to-string-with-add.js: Added.
     18        (shouldBe):
     19        (toStringRight):
     20        (toStringLeftEmpty):
     21        (toStringRightEmpty):
     22
    1232017-04-18  Yusuke Suzuki  <utatane.tea@gmail.com>
    224
  • trunk/Source/JavaScriptCore/ChangeLog

    r215471 r215472  
     12017-04-18  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [DFG] Convert ValueAdd(Int32, String) => MakeRope(ToString(Int32), String)
     4        https://bugs.webkit.org/show_bug.cgi?id=170943
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        This patch converts ValueAdd(Int32, String) to MakeRope(ToString(Int32), String).
     9        This has 2 great features.
     10
     11        1. MakeRope(ToString(Int32), String) is less clobbering.
     12
     13        While ValueAdd ends up calling functions, VM knows much about MakeRope(ToString(Int32), String)
     14        and VM knows it is less clobbering. It encourages LICM and other operations that is conservatively
     15        executed because of ValueAdd's clobbering.
     16
     17        2. Simply, MakeRope(ToString(Int32), String) is faster than ValueAdd.
     18
     19        While ValueAdd ends up calling a generic function, our ToString(Int32) calls well-optimized toString
     20        operation. And later, MakeRope can fall into the fast path that just takes a string from a free list.
     21        It is simply faster than ValueAdd.
     22
     23        We ensure that this patch shows performance improvement in attached benchmarks.
     24
     25                                                        baseline                  patched
     26
     27            number-to-string-with-add-empty         16.2763+-3.3930     ^     10.3142+-1.0967        ^ definitely 1.5780x faster
     28            number-to-string-with-add-in-loop      168.7621+-10.9738    ^     15.5307+-3.3179        ^ definitely 10.8664x faster
     29            number-to-string-with-add               18.8557+-4.8292           11.6901+-2.5650          might be 1.6130x faster
     30
     31        In SixSpeed,
     32
     33                                               baseline                  patched
     34
     35            template_string_tag.es5       200.1027+-20.6871    ^     25.7925+-11.4052       ^ definitely 7.7582x faster
     36            template_string_tag.es6       331.3913+-12.1750    ^    286.6958+-26.0441       ^ definitely 1.1559x faster
     37            for-of-array.es5              412.4344+-23.2517    ^    272.8707+-47.2118       ^ definitely 1.5115x faster
     38            for-of-array.es6              504.0082+-65.5045    ^    300.3277+-12.8193       ^ definitely 1.6782x faster
     39
     40        * dfg/DFGFixupPhase.cpp:
     41        (JSC::DFG::FixupPhase::fixupNode):
     42        (JSC::DFG::FixupPhase::createToString):
     43        * dfg/DFGPredictionPropagationPhase.cpp:
     44
    1452017-04-18  Michael Saboff  <msaboff@apple.com>
    246
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r215038 r215472  
    165165                break;
    166166
    167             fixEdge<UntypedUse>(node->child1());
    168             fixEdge<UntypedUse>(node->child2());
     167            Edge& child1 = node->child1();
     168            Edge& child2 = node->child2();
     169            if (child1->shouldSpeculateString() || child2->shouldSpeculateString()) {
     170                if (child1->shouldSpeculateInt32() || child2->shouldSpeculateInt32()) {
     171                    auto convertString = [&](Node* node, Edge& edge) {
     172                        if (edge->shouldSpeculateInt32())
     173                            convertStringAddUse<Int32Use>(node, edge);
     174                        else {
     175                            ASSERT(edge->shouldSpeculateString());
     176                            convertStringAddUse<StringUse>(node, edge);
     177                        }
     178                    };
     179                    convertString(node, child1);
     180                    convertString(node, child2);
     181                    convertToMakeRope(node);
     182                    break;
     183                }
     184            }
     185
     186            fixEdge<UntypedUse>(child1);
     187            fixEdge<UntypedUse>(child2);
    169188            node->setResult(NodeResultJS);
    170189            break;
     
    19281947    void createToString(Node* node, Edge& edge)
    19291948    {
    1930         edge.setNode(m_insertionSet.insertNode(
     1949        Node* toString = m_insertionSet.insertNode(
    19311950            m_indexInBlock, SpecString, ToString, node->origin,
    1932             Edge(edge.node(), useKind)));
     1951            Edge(edge.node(), useKind));
     1952        switch (useKind) {
     1953        case Int32Use:
     1954        case Int52RepUse:
     1955        case DoubleRepUse:
     1956        case NotCellUse:
     1957            toString->clearFlags(NodeMustGenerate);
     1958            break;
     1959        default:
     1960            break;
     1961        }
     1962        edge.setNode(toString);
    19331963    }
    19341964   
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r214296 r215472  
    192192                    else
    193193                        changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
    194                 } else if (isStringOrStringObjectSpeculation(left) && isStringOrStringObjectSpeculation(right)) {
     194                } else if (isStringOrStringObjectSpeculation(left) || isStringOrStringObjectSpeculation(right)) {
    195195                    // left or right is definitely something other than a number.
    196196                    changed |= mergePrediction(SpecString);
Note: See TracChangeset for help on using the changeset viewer.