Suboptimal C2 code generation

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Fri Nov 20 15:44:02 UTC 2015


Me too. I'd expect that IfNode::search_identical() handles that, but 
evidently it doesn't. Filed JDK-8143542 [1] to track the problem.

Thanks for the report!

Best regards,
Vladimir Ivanov

[1] https://bugs.openjdk.java.net/browse/JDK-8143542

On 11/20/15 4:19 PM, Vitaly Davidovich wrote:
> Hi Vladimir,
>
> Yes, this is exactly it -- "halfway to desired shape" is a great
> description.
>
> The motivating example, from which I extracted this small illustrative
> one, is wrapping an instance of some interface and providing a
> different/narrowed view on top of it; the wrapped interface object has
> strong profile towards one type, with a very small occurrence of it
> being null.  After wrapping it, the wrapper is then used to invoke
> another method in the following manner:
>
> Wrapper w = ...;
> callAnotherMethod(w.value(), w.value2(), w.value3(), w.value4()...);
>
> Each of these valueX() methods internally does that null check.  I
> wanted to see if the JIT would effectively transform that chain into:
>
> if (w.i != null) {
>      callAnotherMethod(<no repeated null checks, just call into the
> interface methods>);
> } else {
>     callAnotherMethod(<use the null value branches from all those
> accessors>);
> }
>
> After the above transformation and knowing that there's a single
> receiver type (when it's not null) with very simple code backing the
> interface methods, I was checking if the interface calls were
> devirtualized.  What I found was a bit surprising, which warranted this
> email :).
>
> Would it be difficult to enhance this?
>
> Thanks
>
>
> On Fri, Nov 20, 2015 at 7:54 AM, Vladimir Ivanov
> <vladimir.x.ivanov at oracle.com <mailto:vladimir.x.ivanov at oracle.com>> wrote:
>
>     It looks like C2 stops halfway to desired shape.
>     The load is commoned, but repeated null check is not eliminated.
>
>     Final IR shape looks like:
>        w = Load this._w
>
>        If (w == NULL) deopt
>
>        i = Load w._i
>
>        If (i != NULL) {
>          If (!i instanceof C) deopt
>        } v1 = Phi(T:1,F:-1);
>
>        If (i != NULL) {
>          If (!i instanceof C) deopt
>        } v2 = Phi(T:2,F:-1)
>
>        return v1+v2
>
>     The next transformation would be:
>        w = Load this._w
>        If (w == NULL) deopt
>        i = Load w._i
>        If (i != NULL) {
>          If (!i instanceof C) deopt
>          If (!i instanceof C) deopt
>        } v1 = Phi(T:1,F:-1)
>          v2 = Phi(T:2,F:-1)
>        return v1+v2
>
>     And finally:
>        w = Load this._w
>        If (w == NULL) deopt
>        i = Load w._i
>        If (i != NULL) {
>          If (!i instanceof C) deopt
>        } v1 = Phi(T:1,F:-1)
>          v2 = Phi(T:2,F:-1)
>        return i1+i2;
>
>     Best regards,
>     Vladimir Ivanov
>
>     On 11/20/15 5:29 AM, John Rose wrote:
>
>         On Nov 19, 2015, at 2:58 PM, Vitaly Davidovich
>         <vitalyd at gmail.com <mailto:vitalyd at gmail.com>
>         <mailto:vitalyd at gmail.com <mailto:vitalyd at gmail.com>>> wrote:
>
>
>                      return _w.value() + _w.value2();
>
>
>         Which is (ignoring non-taken null branches):
>
>                   return _w._i.value() + _w._i.value2();
>
>         There are two independent fetches of _w._i in the bytecode.
>         The machine code is treating them as independent, where
>         we would want the optimizer to use a common value.
>
>         The machine code is optimistic that _w._i is always a C,
>         but it appears to be leaving open the possibility that some
>         activity not tracked by the JIT could store some other C2 <: I.
>
>         What happens at 0x00007ff5f82e00f9?  Does it de-opt,
>         or does it merge back into 0x00007ff5f82e00b2?  In the
>         latter case, the JIT cannot assume that _w._i is a C.
>
>         So, it could be a failure to de-opt, or it could be some
>         fluff in the IR which is preventing the two _w._i from
>         commoning.  Or something else.
>
>         — John
>
>


More information about the hotspot-compiler-dev mailing list