Bug 171057 - [JSC] Use JSFixedArray directly when using call_varargs
Summary: [JSC] Use JSFixedArray directly when using call_varargs
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: 171262
  Show dependency treegraph
 
Reported: 2017-04-20 08:42 PDT by Yusuke Suzuki
Modified: 2017-04-25 00:24 PDT (History)
6 users (show)

See Also:


Attachments
Patch (5.70 KB, patch)
2017-04-20 08:48 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Patch (42.56 KB, patch)
2017-04-21 02:49 PDT, Yusuke Suzuki
no flags Details | Formatted Diff | Diff
Archive of layout-test-results from ews112 for mac-elcapitan (745.69 KB, application/zip)
2017-04-21 03:54 PDT, Build Bot
no flags Details
Patch (44.42 KB, patch)
2017-04-22 04:07 PDT, Yusuke Suzuki
saam: review+
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-04-20 08:42:27 PDT
Currently, when executing the following code,

var array = [0, 1, 2];
Math.max(...array);

The bytecode becomes like this.

[  49] spread            loc9, loc10
[  52] new_array_with_spread loc7, loc9, 1, BitVector:0:1
[  57] mov               loc9, loc8
[  60] call_varargs      loc5, loc5, loc8, loc7, -11, 0    predicting None

But (52)'s array is unnecessary if argument is only consisted by one spread.
Comment 1 Yusuke Suzuki 2017-04-20 08:48:51 PDT
Created attachment 307595 [details]
Patch

WIP
Comment 2 Saam Barati 2017-04-20 10:01:12 PDT
Comment on attachment 307595 [details]
Patch

I was thinking about doing something like this when I added JSFixedArray. I think this is probably best done as a transformation over DFG IR. If you can prove the array hasn't changed, you can pass the JSFixedArray directly in. That said, maybe it's worth setting up the infrastructure with array literals so it can be done in the bytecode generator. But I think the most success would be to do this over DFG IR
Comment 3 Yusuke Suzuki 2017-04-20 10:38:51 PDT
(In reply to Saam Barati from comment #2)
> Comment on attachment 307595 [details]
> Patch
> 
> I was thinking about doing something like this when I added JSFixedArray. I
> think this is probably best done as a transformation over DFG IR. If you can
> prove the array hasn't changed, you can pass the JSFixedArray directly in.
> That said, maybe it's worth setting up the infrastructure with array
> literals so it can be done in the bytecode generator. But I think the most
> success would be to do this over DFG IR

Yeah, that's nice insight! Thanks, eliminating NewArrayWithSpread in (maybe arguments elimination phase or object allocation sinking phase) seems clean.
(And the current patch is lacking this phase change right now b/c of WIP :P)

But I'm also exploring this approach because it is beneficial in all the tiers while arguments elimination phase is only done in FTL.
And I'm also considering about CallVararg(RuntimeFunc, Spread).

Now, it's still rough design, I need to look into this deeply.
Comment 4 Yusuke Suzuki 2017-04-20 11:29:11 PDT
(In reply to Yusuke Suzuki from comment #3)
> Yeah, that's nice insight! Thanks, eliminating NewArrayWithSpread in (maybe
> arguments elimination phase or object allocation sinking phase) seems clean.
> (And the current patch is lacking this phase change right now b/c of WIP :P)
> 
> But I'm also exploring this approach because it is beneficial in all the
> tiers while arguments elimination phase is only done in FTL.
> And I'm also considering about CallVararg(RuntimeFunc, Spread).
> 
> Now, it's still rough design, I need to look into this deeply.

OK, I would like to do the both. By only emitting op_spread, we can eliminate the new_array_with_spread for call_varargs in all the tiers. And we also would like to relax the current limiation for NewArrayWithSpread in arguments elimination phase to accept non-phantom spread & non-create-rest-related spread.
Comment 5 Yusuke Suzuki 2017-04-20 12:39:16 PDT
(In reply to Yusuke Suzuki from comment #4)
> OK, I would like to do the both. By only emitting op_spread, we can
> eliminate the new_array_with_spread for call_varargs in all the tiers. And
> we also would like to relax the current limiation for NewArrayWithSpread in
> arguments elimination phase to accept non-phantom spread &
> non-create-rest-related spread.

Simple bytecompiler level one will optimize the case like.

call(...array)

It's super easy to do that, and it is super beneficial because it is effective even in LLInt. And the above call form is quite common, so I think it's worth doing in bytecompiler. And the code itself should be quite simple, just adding small code to BytecodeGenerator. (And support spread form varargs.)

But we would like to analyze dfg and optimize,

var array = [...values];
call(...array);

thing too. Such thing can be effectively done in DFG arguments elimination phase.
Comment 6 Saam Barati 2017-04-20 13:17:30 PDT
(In reply to Yusuke Suzuki from comment #5)
> (In reply to Yusuke Suzuki from comment #4)
> > OK, I would like to do the both. By only emitting op_spread, we can
> > eliminate the new_array_with_spread for call_varargs in all the tiers. And
> > we also would like to relax the current limiation for NewArrayWithSpread in
> > arguments elimination phase to accept non-phantom spread &
> > non-create-rest-related spread.
> 
> Simple bytecompiler level one will optimize the case like.
> 
> call(...array)
> 
> It's super easy to do that, and it is super beneficial because it is
> effective even in LLInt. And the above call form is quite common, so I think
> it's worth doing in bytecompiler. And the code itself should be quite
> simple, just adding small code to BytecodeGenerator. (And support spread
> form varargs.)
> 
> But we would like to analyze dfg and optimize,
> 
> var array = [...values];
> call(...array);
> 
> thing too. Such thing can be effectively done in DFG arguments elimination
> phase.

Yeah I agree. I think it's worth having this peephole optimization in the byte compiler. We can develop a more sophisticated analysis in the DFG later.
Comment 7 Yusuke Suzuki 2017-04-21 02:49:25 PDT
Created attachment 307714 [details]
Patch

WIP
Comment 8 Build Bot 2017-04-21 03:54:04 PDT
Comment on attachment 307714 [details]
Patch

Attachment 307714 [details] did not pass mac-debug-ews (mac):
Output: http://webkit-queues.webkit.org/results/3575475

Number of test failures exceeded the failure limit.
Comment 9 Build Bot 2017-04-21 03:54:05 PDT
Created attachment 307717 [details]
Archive of layout-test-results from ews112 for mac-elcapitan

The attached test failures were seen while running run-webkit-tests on the mac-debug-ews.
Bot: ews112  Port: mac-elcapitan  Platform: Mac OS X 10.11.6
Comment 10 Yusuke Suzuki 2017-04-22 04:07:28 PDT
Created attachment 307908 [details]
Patch
Comment 11 Saam Barati 2017-04-24 12:33:29 PDT
Comment on attachment 307908 [details]
Patch

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

nice. r=me.
I think once we implement a more sophisticated analysis to transform code into this, it'll be nice to have this support in the FTL.

> Source/JavaScriptCore/ChangeLog:12
> +        to oit new_array_with_spread. This is very simple and effective because this

typo: oit => emit
Comment 12 Yusuke Suzuki 2017-04-24 21:39:54 PDT
Comment on attachment 307908 [details]
Patch

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

>> Source/JavaScriptCore/ChangeLog:12
>> +        to oit new_array_with_spread. This is very simple and effective because this
> 
> typo: oit => emit

Ah, this is typo, we should fix it oit => omit. Thanks!
Comment 13 Yusuke Suzuki 2017-04-24 22:09:18 PDT
Committed r215720: <http://trac.webkit.org/changeset/215720>