counting down loop and unwanted test?

Peter Veentjer alarmnummer at gmail.com
Tue Jan 31 09:30:08 UTC 2017


I'm looking at some assembly generated for a very simple for loop:

public class LoopCountDown {

    public static void main(String[] args) {
        int result = 0;
        for (int k = 0; k < 100_000; k++) {
            result += doMath(100);
        }
        System.out.println(result);
    }

    public static int doMath(int n) {
        int result = n;
        for (int k = n; k > 0; k--) {
            result += 2 * result;
        }
        return result;
    }
}

I'm not interested in the results of this program. I'm just curious about
how the JIT optimized the actual loop-logic.

When I output the assembler (full listing at the end), I get the following
relevant part:

 0x000000011049868c: test   esi,esi
  0x000000011049868e: jle    0x00000001104986ad  ;*ifle
                                                ; -
com.loop.LoopCountDown::doMath at 5 (line 15)

  0x0000000110498690: mov    eax,esi            ;*iload_1
                                                ; -
com.loop.LoopCountDown::doMath at 8 (line 16)

  0x0000000110498692: mov    r10d,eax
  0x0000000110498695: shl    r10d,1
  0x0000000110498698: add    eax,r10d           ;*iadd
                                                ; -
com.loop.LoopCountDown::doMath at 12 (line 16)

  *0x000000011049869b: dec    esi                ;*iinc*
*                                                ; -
com.loop.LoopCountDown::doMath at 14 (line 15)*

*  0x000000011049869d: test   esi,esi*
*  0x000000011049869f: jg     0x0000000110498692  ;*ifle*


My question is about the test at 0x000000011049869d. Why is it needed?
Perhaps it is too much of an edge case to optimize?

The dec instruction will set the NZ flag:

http://x86.renejeschke.de/html/file_module_x86_id_71.html

So if the jg at the end would be changed to a jnz, the jnz can make use of
this NZ flag; no need for a test.

For more information see page 90 of
http://www.agner.org/optimize/optimizing_assembly.pdf

My JVM arguments:

-XX:+UnlockDiagnosticVMOptions -XX:PrintAssemblyOptions=intel
-XX:-TieredCompilation -XX:-Inline -XX:-BackgroundCompilation
-XX:CompileCommand=print,*LoopCountDown.doMath -XX:LoopUnrollLimit=0

JVM version:

java version "1.8.0_91"

Java(TM) SE Runtime Environment (build 1.8.0_91-b14)

Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)


CompilerOracle: print *LoopCountDown.doMath
Compiled method (c2)     174    8
com.loop.LoopCountDown::doMath (22 bytes)
 total in heap  [0x0000000110498550,0x0000000110498790] = 576
 relocation     [0x0000000110498670,0x0000000110498678] = 8
 main code      [0x0000000110498680,0x00000001104986c0] = 64
 stub code      [0x00000001104986c0,0x00000001104986d8] = 24
 oops           [0x00000001104986d8,0x00000001104986e0] = 8
 metadata       [0x00000001104986e0,0x00000001104986e8] = 8
 scopes data    [0x00000001104986e8,0x0000000110498708] = 32
 scopes pcs     [0x0000000110498708,0x0000000110498788] = 128
 dependencies   [0x0000000110498788,0x0000000110498790] = 8
Loaded disassembler from
/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/hsdis-amd64.dylib
Decoding compiled method 0x0000000110498550:
Code:
[Disassembling for mach='i386:x86-64']
[Entry Point]
[Verified Entry Point]
[Constants]
  # {method} {0x00000001d89df478} 'doMath' '(I)I' in
'com/loop/LoopCountDown'
  # parm0:    rsi       = int
  #           [sp+0x20]  (sp of caller)
  0x0000000110498680: sub    rsp,0x18
  0x0000000110498687: mov    QWORD PTR [rsp+0x10],rbp  ;*synchronization
entry
                                                ; -
com.loop.LoopCountDown::doMath at -1 (line 14)

  0x000000011049868c: test   esi,esi
  0x000000011049868e: jle    0x00000001104986ad  ;*ifle
                                                ; -
com.loop.LoopCountDown::doMath at 5 (line 15)

  0x0000000110498690: mov    eax,esi            ;*iload_1
                                                ; -
com.loop.LoopCountDown::doMath at 8 (line 16)

  0x0000000110498692: mov    r10d,eax
  0x0000000110498695: shl    r10d,1
  0x0000000110498698: add    eax,r10d           ;*iadd
                                                ; -
com.loop.LoopCountDown::doMath at 12 (line 16)

  0x000000011049869b: dec    esi                ;*iinc
                                                ; -
com.loop.LoopCountDown::doMath at 14 (line 15)

  0x000000011049869d: test   esi,esi
  0x000000011049869f: jg     0x0000000110498692  ;*ifle
                                                ; -
com.loop.LoopCountDown::doMath at 5 (line 15)

  0x00000001104986a1: add    rsp,0x10
  0x00000001104986a5: pop    rbp
  0x00000001104986a6: test   DWORD PTR [rip+0xfffffffffff71954],eax
 # 0x000000011040a000
                                                ;   {poll_return}
  0x00000001104986ac: ret
  0x00000001104986ad: mov    eax,esi
  0x00000001104986af: jmp    0x00000001104986a1
  0x00000001104986b1: hlt
  0x00000001104986b2: hlt
  0x00000001104986b3: hlt
  0x00000001104986b4: hlt
  0x00000001104986b5: hlt
  0x00000001104986b6: hlt
  0x00000001104986b7: hlt
  0x00000001104986b8: hlt
  0x00000001104986b9: hlt
  0x00000001104986ba: hlt
  0x00000001104986bb: hlt
  0x00000001104986bc: hlt
  0x00000001104986bd: hlt
  0x00000001104986be: hlt
  0x00000001104986bf: hlt
[Exception Handler]
[Stub Code]
  0x00000001104986c0: jmp    0x0000000110488f60  ;   {no_reloc}
[Deopt Handler Code]
  0x00000001104986c5: call   0x00000001104986ca
  0x00000001104986ca: sub    QWORD PTR [rsp],0x5
  0x00000001104986cf: jmp    0x0000000110463d00  ;   {runtime_call}
  0x00000001104986d4: hlt
  0x00000001104986d5: hlt
  0x00000001104986d6: hlt
  0x00000001104986d7: hlt
OopMapSet contains 0 OopMaps
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20170131/99d8661a/attachment.html>


More information about the hotspot-compiler-dev mailing list