<div dir="ltr">By the way, the context for this example is the following.  Suppose you have a class with such a method.  This class is then used in different java processes such that in each instance only one of those branches is ever taken and the other compares have no side effects.  Ideally, the compiled code would favor that fast path, which may not be the first arm of the if/else chain.</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jun 4, 2015 at 7:42 PM, Vitaly Davidovich <span dir="ltr"><<a href="mailto:vitalyd@gmail.com" target="_blank">vitalyd@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><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="HOEnZb"><div class="h5"><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><font color="#888888"><br>
<br>
Vladimir</font></span><div><div><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>
</div></div></blockquote></div><br></div>