Bug 227203 - Add ARM64 SBFX and SBFIZ to instruction selector
Summary: Add ARM64 SBFX and SBFIZ to instruction selector
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Yijia Huang
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2021-06-20 21:53 PDT by Yijia Huang
Modified: 2021-06-29 11:41 PDT (History)
9 users (show)

See Also:


Attachments
Patch (23.99 KB, patch)
2021-06-28 23:02 PDT, Yijia Huang
no flags Details | Formatted Diff | Diff
Patch (30.93 KB, patch)
2021-06-29 09:24 PDT, Yijia Huang
no flags Details | Formatted Diff | Diff
Patch (30.92 KB, patch)
2021-06-29 10:48 PDT, Yijia Huang
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Yijia Huang 2021-06-20 21:53:28 PDT
...
Comment 1 Yijia Huang 2021-06-28 23:02:10 PDT
Created attachment 432454 [details]
Patch
Comment 2 Radar WebKit Bug Importer 2021-06-28 23:02:21 PDT
<rdar://problem/79899430>
Comment 3 Yijia Huang 2021-06-29 09:24:54 PDT
Created attachment 432485 [details]
Patch
Comment 4 Sam Weinig 2021-06-29 10:10:54 PDT
Comment on attachment 432485 [details]
Patch

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

> Source/JavaScriptCore/ChangeLog:11
> +            1. Itroduce a strength reduction rule for sign extending bitfield.
> +            2. Add Signed Bitfield Extract (SBFX) and Signed Bitfield Insert 
> +               in Zero (SBFIZ) to Air opcode to serve intruciton selector.

Two small typos here:

Itroduce -> Introduce
intruciton -> instruction

> Source/JavaScriptCore/ChangeLog:16
> +        According to Bit Twiddling Hacks, there are two ways to sign extends bitfield.

Typo: 

sign extends bitfield -> sign extend bitfields
Comment 5 Filip Pizlo 2021-06-29 10:20:19 PDT
Comment on attachment 432485 [details]
Patch

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

> Source/JavaScriptCore/ChangeLog:35
> +            Turn this: ((bf & mask1) ^ mask2) - mask2 
> +            Into this: (bf << amount) >> amount

Wow, this is super cool.

You should at some point also add a reduction for bitfield zero-extend  I mean, bitfield zero-extend is a funny way of saying "x & mask" where mask is !(mask & (mask + 1)).  You can also say it by doing "(x << amount) >> amount", but that's not the canonical form.  Totally separate from this patch though.

> Source/JavaScriptCore/b3/B3LowerToAir.cpp:3036
> +                if (left->opcode() != SShr || !canBeInternal(left))

A lot of the canBeInternal calls don't pass my sniff test.  It's not important for you to change this in this patch, but we should reconsider all of these eventually.

Let's just take this one as an example.

Say you have a program that does the following (capital letters are constants):

a = x << C
b = a >> C
c = b << D

print(a)
print(b)
print(c)

Clearly, the pattern won't match because of !canBeInternal for a and b.  So, this would emit three separate instructions.  But what if we removed canBeInternal?  It would still be just three separate instructions, and they wouldn't be any more expensive.  Now imagine if we remove the print(b), above.  Then, with the canBeInternal check, we're emitting three instructions.  Without the canBeInternal check, we'd emit only two (x << C and SBFIZ to compute c).  And that would be less expensive.

Basically, to decide if canBeInternal is profitable or not, you want to imagine a program where every internal value is actually used elsewhere, and then ask yourself: would the code I generate with my pattern be worse than without my pattern for that code if I never checked canBeInternal?  If the answer is that the pattern doesn't cause worst code generation in the all-internals-are-captured case, then you don't want canBeInternal checks.
Comment 6 Yijia Huang 2021-06-29 10:22:31 PDT
(In reply to Sam Weinig from comment #4)
> Comment on attachment 432485 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=432485&action=review
> 
> > Source/JavaScriptCore/ChangeLog:11
> > +            1. Itroduce a strength reduction rule for sign extending bitfield.
> > +            2. Add Signed Bitfield Extract (SBFX) and Signed Bitfield Insert 
> > +               in Zero (SBFIZ) to Air opcode to serve intruciton selector.
> 
> Two small typos here:
> 
> Itroduce -> Introduce
> intruciton -> instruction
> 
> > Source/JavaScriptCore/ChangeLog:16
> > +        According to Bit Twiddling Hacks, there are two ways to sign extends bitfield.
> 
> Typo: 
> 
> sign extends bitfield -> sign extend bitfields

Thanks for the review.
Comment 7 Yijia Huang 2021-06-29 10:22:51 PDT
(In reply to Filip Pizlo from comment #5)
> Comment on attachment 432485 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=432485&action=review
> 
> > Source/JavaScriptCore/ChangeLog:35
> > +            Turn this: ((bf & mask1) ^ mask2) - mask2 
> > +            Into this: (bf << amount) >> amount
> 
> Wow, this is super cool.
> 
> You should at some point also add a reduction for bitfield zero-extend  I
> mean, bitfield zero-extend is a funny way of saying "x & mask" where mask is
> !(mask & (mask + 1)).  You can also say it by doing "(x << amount) >>
> amount", but that's not the canonical form.  Totally separate from this
> patch though.
> 
> > Source/JavaScriptCore/b3/B3LowerToAir.cpp:3036
> > +                if (left->opcode() != SShr || !canBeInternal(left))
> 
> A lot of the canBeInternal calls don't pass my sniff test.  It's not
> important for you to change this in this patch, but we should reconsider all
> of these eventually.
> 
> Let's just take this one as an example.
> 
> Say you have a program that does the following (capital letters are
> constants):
> 
> a = x << C
> b = a >> C
> c = b << D
> 
> print(a)
> print(b)
> print(c)
> 
> Clearly, the pattern won't match because of !canBeInternal for a and b.  So,
> this would emit three separate instructions.  But what if we removed
> canBeInternal?  It would still be just three separate instructions, and they
> wouldn't be any more expensive.  Now imagine if we remove the print(b),
> above.  Then, with the canBeInternal check, we're emitting three
> instructions.  Without the canBeInternal check, we'd emit only two (x << C
> and SBFIZ to compute c).  And that would be less expensive.
> 
> Basically, to decide if canBeInternal is profitable or not, you want to
> imagine a program where every internal value is actually used elsewhere, and
> then ask yourself: would the code I generate with my pattern be worse than
> without my pattern for that code if I never checked canBeInternal?  If the
> answer is that the pattern doesn't cause worst code generation in the
> all-internals-are-captured case, then you don't want canBeInternal checks.

Thanks for the review.
Comment 8 Yijia Huang 2021-06-29 10:48:46 PDT
Created attachment 432500 [details]
Patch
Comment 9 EWS 2021-06-29 11:41:36 PDT
Committed r279378 (239243@main): <https://commits.webkit.org/239243@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 432500 [details].