<div dir="ltr">Thanks for the response Vladimir.  In this case though, can the JIT not see that the cmp bytecodes of non-taken branches have no side effects and remove them altogether? Is that just deemed not worth the cost or is there something fundamental I'm missing here?</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jun 4, 2015 at 7:36 PM, Vladimir Kozlov <span dir="ltr"><<a href="mailto:vladimir.kozlov@oracle.com" target="_blank">vladimir.kozlov@oracle.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">VM does not profiling values. We profiling branches.<br>
When C2 construct control flow graph it follows bytecode. And it can't eliminate cmp code based only on branch profiling. Profiling still shows that all cmp bytecodes are always executed - only branches are not taken. We would eliminate tests if they were on non taken branch.<br>
We generate uncommon traps for branches which were not taken based on profiling.<span class="HOEnZb"><font color="#888888"><br>
<br>
Vladimir</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
On 6/4/15 4:20 PM, Vitaly Davidovich wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi,<br>
<br>
Suppose you have a method like this:<br>
<br>
private static int f(final int x) {<br>
         if (x == 0)<br>
             return 1;<br>
         else if (x == 1)<br>
             return 2;<br>
         else if (x == 2)<br>
             return 3;<br>
         return 4;<br>
<br>
     }<br>
<br>
If I then call it with x=2 always, the generated asm is not what I<br>
expect (8u40 with C2 compiler)<br>
<br>
   # parm0:    rsi       = int<br>
   #           [sp+0x30]  (sp of caller)<br>
   0x00007fcc5970c520: mov    %eax,-0x14000(%rsp)<br>
   0x00007fcc5970c527: push   %rbp<br>
   0x00007fcc5970c528: sub    $0x20,%rsp         ;*synchronization entry<br>
<br>
   0x00007fcc5970c52c: test   %esi,%esi<br>
   0x00007fcc5970c52e: je     0x00007fcc5970c55d  ;*ifne<br>
<br>
   0x00007fcc5970c530: cmp    $0x1,%esi<br>
   0x00007fcc5970c533: je     0x00007fcc5970c571  ;*if_icmpne<br>
<br>
   0x00007fcc5970c535: cmp    $0x2,%esi<br>
   0x00007fcc5970c538: jne    0x00007fcc5970c54b  ;*if_icmpne<br>
<br>
   0x00007fcc5970c53a: mov    $0x3,%eax<br>
   0x00007fcc5970c53f: add    $0x20,%rsp<br>
   0x00007fcc5970c543: pop    %rbp<br>
   0x00007fcc5970c544: test   %eax,0x5e0dab6(%rip)300000        #<br>
0x00007fcc5f51a000<br>
                                                 ;   {poll_return}<br>
   0x00007fcc5970c54a: retq<br>
<snip><br>
<br>
It's checking the if conditions in order, and then jumps to some runtime<br>
calls (I'm assuming that's for deopt to restore pruned branches? Cause I<br>
don't see anything that returns 1 or 2 otherwise).  Why is this code not<br>
favoring x=2? I'd have thought this code would be something like (after<br>
epilogue):<br>
<br>
cmp $0x2, %esi<br>
jne <deopt_or_other_cases><br>
mov $0x3, %eax<br>
retq<br>
<br>
Thanks<br>
<br>
</blockquote>
</div></div></blockquote></div><br></div>