[13] RFR (S): 8075052: Autobox elimination hinders loop unrolling

Vladimir Kozlov vladimir.kozlov at oracle.com
Mon Feb 4 19:39:12 UTC 2019


Got it. So it is cached array checks. Okay.

Thanks,
Vladimir

On 2/4/19 10:56 AM, Vladimir Ivanov wrote:
>> So loop is not unrolled because of IntegerCache checks in valueOf()?
>> I assume valueOf() is inlined and the check is the only difference from new Integer(). Right?
>> And the check should be collapsing too if result is not used. So why loop is not counted?
> 
> Sorry, the title is very misleading. I don't remember all the details, but it seems I confused 2 loops - main and post 
> loops - when filed the bug.
> 
> Main loop is counted and unrolled, but full of the following code pattern:
> 
>    0x00000001174210c0: mov    0x10(%rdi,%r10,4),%r9d
>    0x00000001174210c5: mov    %r9d,%r11d
>    0x00000001174210c8: add    $0x80,%r11d
>    0x00000001174210cf: cmp    $0x100,%r11d
>    0x00000001174210d6: jae    0x000000011742120b
> ...
>    0x00000001174211b8: add    $0x8,%r10d
>    0x00000001174211bc: cmp    %ebx,%r10d
>    0x00000001174211bf: jl     0x00000001174210c0 ; loop back edge
> 
> 
> ...
>    0x000000011742120b: mov    %r9d,%r8d
>    0x000000011742120e: mov    %eax,%ebp
>    0x0000000117421210: jmp    0x000000011742123c
> ...
>    0x000000011742123c: mov    $0xffffff45,%esi
>    0x0000000117421241: mov    %r10d,(%rsp)
>    0x0000000117421245: mov    %r8d,0x8(%rsp)
>    0x000000011742124a: mov    %rcx,0x10(%rsp)
>    0x000000011742124f: callq  0x00000001173b23a0    ;   {runtime_call UncommonTrapBlob}
> 
> 
> It's a left-over from IntegerCache checks in Integer.valueOf() which C2 can't fully eliminate.
> 
> After the fix the main loop looks as follows:
> 
>    0x0000000111b54830: add    0x10(%r11,%r8,4),%eax
> ...
>    0x0000000111b54853: add    0x2c(%r11,%r8,4),%eax
>    0x0000000111b54858: add    $0x8,%r8d
>    0x0000000111b5485c: cmp    %ecx,%r8d
>    0x0000000111b5485f: jl     0x0000000111b54830
> 
>> The only issue I have with it is if you have exception path in code and you have to throw an exception (OOM, for 
>> example) even when result is not used. But on other hand it is similar for normal scalar replaced allocation since 
>> exception can come only from allocation in valueOf().
> 
> Yes, by calling it "pure" I meant all side effects occur only as part of result computation. If result value isn't 
> needed, it's safe to get rid of all the side effects as part of computation elimination.
> 
>> Code change is fine to me. I just want more information about the cause.
> 
> Thanks for review! I'll experiment with annotation John & Remi suggested.
> 
> Best regards,
> Vladimir Ivanov
> 
>> On 2/1/19 7:19 PM, Vladimir Ivanov wrote:
>>> http://cr.openjdk.java.net/~vlivanov/8075052/webrev.00/
>>> https://bugs.openjdk.java.net/browse/JDK-8075052
>>>
>>> C2 doesn't optimize Integer.valueOf() as good as new Integer().
>>> (There's a benchmark in the bug which demonstrates the difference.)
>>>
>>> It is caused by the fact that though Integer.intValue() can see through the call, the call itself isn't optimized 
>>> away if the result (box) is not used. It is unconditionally inlined and hinders consequent optimizations.
>>>
>>> Proposed fix is to treat Integer.valueOf() as if it were a pure method and remove the call if its result (boxed 
>>> value) isn't used.
>>>
>>> Testing: hs-precheckin-comp, tier1-7 (in progress)
>>>
>>> Best regards,
>>> Vladimir Ivanov


More information about the hotspot-compiler-dev mailing list