Bug 172115 - [DFG] Constant Folding Phase should convert MakeRope("", String) => Identity(String)
Summary: [DFG] Constant Folding Phase should convert MakeRope("", String) => Identity(...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Yusuke Suzuki
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-05-15 05:36 PDT by Yusuke Suzuki
Modified: 2017-05-17 02:39 PDT (History)
8 users (show)

See Also:


Attachments
Patch (5.74 KB, patch)
2017-05-15 06:32 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (5.74 KB, patch)
2017-05-15 06:33 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (5.63 KB, patch)
2017-05-15 07:45 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (7.46 KB, patch)
2017-05-16 05:59 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (7.64 KB, patch)
2017-05-16 06:42 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Yusuke Suzuki 2017-05-15 05:36:15 PDT
This optimization is performed in Fixup phase. But in fixup phase, we may not figure out many constant values...
We should later perform this optimization in constant folding phase again.

I investigated ARES-6 Babylon and figured out that Babylon's Array#indexOf repeatedly find roped string.
This is because of readWord1 in Babylon, the implementation is like,

var word = "";
...
...
...
return word + data.slice(...);

Due to the above limitation, this now accidentally produces MakeRope!
Comment 1 Yusuke Suzuki 2017-05-15 05:41:29 PDT
Before:

firstIteration:     50.02 +- 14.56 ms
averageWorstCase:   26.52 +- 4.52 ms
steadyState:        8.15 +- 0.23 ms
summary:            22.03 +- 3.38 ms

After:

firstIteration:     49.08 +- 12.90 ms
averageWorstCase:   25.16 +- 3.82 ms
steadyState:        7.58 +- 0.21 ms
summary:            20.99 +- 2.73 ms
Comment 2 Yusuke Suzuki 2017-05-15 06:32:57 PDT
Created attachment 310129 [details]
Patch
Comment 3 Yusuke Suzuki 2017-05-15 06:33:36 PDT
Created attachment 310130 [details]
Patch
Comment 4 Yusuke Suzuki 2017-05-15 07:45:44 PDT
Created attachment 310136 [details]
Patch
Comment 5 Saam Barati 2017-05-15 12:34:31 PDT
Comment on attachment 310136 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=310136&action=review

Mostly LGTM, just a few comments

> Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp:643
> +            case MakeRope: {

I believe you need this code inside AbstractInterpreter as well to indicate we've found a constant. Perhaps all of it can just be moved there.

> Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp:653
> +                    const auto* string = asString(childConstant)->tryGetValueImpl();

Nit: Can we give this a type, since it's hard to see what's going on here without reading tryGetValueImpl()'s type?

> Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp:661
> +                    // Don't allow the MakeRope to have zero children.
> +                    if (!i && !node->child2())
> +                        break;

Why not just convert to lazy constant for "" here?
Comment 6 Yusuke Suzuki 2017-05-16 04:29:57 PDT
Comment on attachment 310136 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=310136&action=review

Thanks

>> Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp:643
>> +            case MakeRope: {
> 
> I believe you need this code inside AbstractInterpreter as well to indicate we've found a constant. Perhaps all of it can just be moved there.

Oops, right. I think we should have MakeRope here too since it can reduce the number of children (like, "" + a + b => a + b).

>> Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp:653
>> +                    const auto* string = asString(childConstant)->tryGetValueImpl();
> 
> Nit: Can we give this a type, since it's hard to see what's going on here without reading tryGetValueImpl()'s type?

OK, I've changed it to `StringImpl*`.

>> Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp:661
>> +                        break;
> 
> Why not just convert to lazy constant for "" here?

I think it is better to replace it to Identity(child1).
And current code covers all the cases in the following (L668) convertToIdentity simply.
Comment 7 Yusuke Suzuki 2017-05-16 05:59:59 PDT
Created attachment 310257 [details]
Patch
Comment 8 Yusuke Suzuki 2017-05-16 06:42:23 PDT
Created attachment 310259 [details]
Patch
Comment 9 Sam Weinig 2017-05-16 10:42:48 PDT
Comment on attachment 310259 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=310259&action=review

> Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:575
> +            if (!edge)
> +                break;

How can edge be null if it is a reference? I guess that works if Edge has a operator!, but its still a bit odd.
Comment 10 Saam Barati 2017-05-16 10:47:28 PDT
(In reply to Sam Weinig from comment #9)
> Comment on attachment 310259 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=310259&action=review
> 
> > Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:575
> > +            if (!edge)
> > +                break;
> 
> How can edge be null if it is a reference? I guess that works if Edge has a
> operator!, but its still a bit odd.

I agree it's a bit odd, but we do this all over the DFG. It does have an operator!
Comment 11 Saam Barati 2017-05-16 10:58:57 PDT
Comment on attachment 310259 [details]
Patch

r=me
Comment 12 Yusuke Suzuki 2017-05-16 14:25:57 PDT
Comment on attachment 310259 [details]
Patch

Thanks!
Comment 13 WebKit Commit Bot 2017-05-16 14:54:04 PDT
Comment on attachment 310259 [details]
Patch

Clearing flags on attachment: 310259

Committed r216948: <http://trac.webkit.org/changeset/216948>
Comment 14 WebKit Commit Bot 2017-05-16 14:54:06 PDT
All reviewed patches have been landed.  Closing bug.