loop invariant code motion and the jit
Peter Veentjer
alarmnummer at gmail.com
Wed Jan 18 07:25:49 UTC 2017
Hi,
I'm studying some JIT compiler optimizations to get a better understanding
of what happens on the lowest level.
I'm running into a problem with loop invariant code motion (or loop
hoisting) and my impression is that the JIT is not always doing hoisting.
For example:
E.g.
public class LoopInvariantCodeMotion {
public static void main(String[] args) {
long l =0;
for (int k = 0; k < 100000; k++) {
l+=doMath(k);
}
System.out.println(l);
}
public static int doMath(int a) {
int result = 0;
for (int k = 0; k < a; k++) {
int x = a +2;
result += x + k;
}
return result;
}
}
The 'int x = a+2' can be pulled out of the loop because it is an invariant
in the loop. However in the generated Assembly it is still in the loop.
However if I would change the code to 'int x = a * 2'' it is pulled out of
the loop (even though the *2 is implemented as a simple bitshift).
So can someone explain why the loop hoisting is so unpredictable?
These are my settings:
-XX:+UnlockDiagnosticVMOptions
-XX:PrintAssemblyOptions=intel
-XX:-BackgroundCompilation
-XX:-TieredCompilation
-XX:-Inline
-XX:CompileCommand=print,*LoopInvariantCodeMotion.doMath
-XX:LoopUnrollLimit=0
java version "1.8.0_101"
Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)
Linux silversurver 4.4.0-38-generic #57-Ubuntu SMP Tue Sep 6 15:42:33 UTC
2016 x86_64 x86_64 x86_64 GNU/Linux
-------------------------------------------------------------
Assembly with the +2
-------------------------------------------------------------
CompilerOracle: print *LoopInvariantCodeMotion.doMath
Compiled method (c2) 107 4
com.loop.LoopInvariantCodeMotion::doMath (27 bytes)
total in heap [0x00007f202906d550,0x00007f202906d7b0] = 608
relocation [0x00007f202906d678,0x00007f202906d680] = 8
main code [0x00007f202906d680,0x00007f202906d6e0] = 96
stub code [0x00007f202906d6e0,0x00007f202906d6f8] = 24
oops [0x00007f202906d6f8,0x00007f202906d700] = 8
metadata [0x00007f202906d700,0x00007f202906d708] = 8
scopes data [0x00007f202906d708,0x00007f202906d728] = 32
scopes pcs [0x00007f202906d728,0x00007f202906d7a8] = 128
dependencies [0x00007f202906d7a8,0x00007f202906d7b0] = 8
Loaded disassembler from /java/jdk/jdk1.8.0_101/jre/lib/amd64/hsdis-amd64.so
Decoding compiled method 0x00007f202906d550:
Code:
[Disassembling for mach='i386:x86-64']
[Entry Point]
[Verified Entry Point]
[Constants]
# {method} {0x00007f2031188488} 'doMath' '(I)I' in
'com/loop/LoopInvariantCodeMotion'
# parm0: rsi = int
# [sp+0x20] (sp of caller)
0x00007f202906d680: sub rsp,0x18
0x00007f202906d687: mov QWORD PTR [rsp+0x10],rbp ;*synchronization
entry
; -
com.loop.LoopInvariantCodeMotion::doMath at -1 (line 14)
0x00007f202906d68c: xor r11d,r11d
0x00007f202906d68f: test esi,esi
0x00007f202906d691: jle 0x00007f202906d6c0 ;*if_icmpge
; -
com.loop.LoopInvariantCodeMotion::doMath at 6 (line 15)
0x00007f202906d693: xor eax,eax
0x00007f202906d695: nop WORD PTR [rax+rax*1+0x0] ;*iload_0
; -
com.loop.LoopInvariantCodeMotion::doMath at 9 (line 16)
0x00007f202906d6a0: mov r10d,r11d
0x00007f202906d6a3: add r10d,esi
0x00007f202906d6a6: add eax,r10d
0x00007f202906d6a9: add eax,0x2 ;*iadd
; -
com.loop.LoopInvariantCodeMotion::doMath at 17 (line 17)
0x00007f202906d6ac: inc r11d ;*iinc
; -
com.loop.LoopInvariantCodeMotion::doMath at 19 (line 15)
0x00007f202906d6af: cmp r11d,esi
0x00007f202906d6b2: jl 0x00007f202906d6a0 ;*if_icmpge
; -
com.loop.LoopInvariantCodeMotion::doMath at 6 (line 15)
0x00007f202906d6b4: add rsp,0x10
0x00007f202906d6b8: pop rbp
0x00007f202906d6b9: test DWORD PTR [rip+0xca0c941],eax #
0x00007f2035a7a000
; {poll_return}
0x00007f202906d6bf: ret
0x00007f202906d6c0: xor eax,eax
0x00007f202906d6c2: jmp 0x00007f202906d6b4
0x00007f202906d6c4: hlt
0x00007f202906d6c5: hlt
0x00007f202906d6c6: hlt
0x00007f202906d6c7: hlt
0x00007f202906d6c8: hlt
0x00007f202906d6c9: hlt
0x00007f202906d6ca: hlt
0x00007f202906d6cb: hlt
0x00007f202906d6cc: hlt
0x00007f202906d6cd: hlt
0x00007f202906d6ce: hlt
0x00007f202906d6cf: hlt
0x00007f202906d6d0: hlt
0x00007f202906d6d1: hlt
0x00007f202906d6d2: hlt
0x00007f202906d6d3: hlt
0x00007f202906d6d4: hlt
0x00007f202906d6d5: hlt
0x00007f202906d6d6: hlt
0x00007f202906d6d7: hlt
0x00007f202906d6d8: hlt
0x00007f202906d6d9: hlt
0x00007f202906d6da: hlt
0x00007f202906d6db: hlt
0x00007f202906d6dc: hlt
0x00007f202906d6dd: hlt
0x00007f202906d6de: hlt
0x00007f202906d6df: hlt
[Exception Handler]
[Stub Code]
0x00007f202906d6e0: jmp 0x00007f202906c420 ; {no_reloc}
[Deopt Handler Code]
0x00007f202906d6e5: call 0x00007f202906d6ea
0x00007f202906d6ea: sub QWORD PTR [rsp],0x5
0x00007f202906d6ef: jmp 0x00007f2029046fc0 ; {runtime_call}
0x00007f202906d6f4: hlt
0x00007f202906d6f5: hlt
0x00007f202906d6f6: hlt
0x00007f202906d6f7: hlt
OopMapSet contains 0 OopMaps
-------------------------------------------------------------
Assembly with the * 2
-------------------------------------------------------------
CompilerOracle: print *LoopInvariantCodeMotion.doMath
Compiled method (c2) 108 4
com.loop.LoopInvariantCodeMotion::doMath (27 bytes)
total in heap [0x00007f6379078250,0x00007f63790784b0] = 608
relocation [0x00007f6379078378,0x00007f6379078380] = 8
main code [0x00007f6379078380,0x00007f63790783e0] = 96
stub code [0x00007f63790783e0,0x00007f63790783f8] = 24
oops [0x00007f63790783f8,0x00007f6379078400] = 8
metadata [0x00007f6379078400,0x00007f6379078408] = 8
scopes data [0x00007f6379078408,0x00007f6379078428] = 32
scopes pcs [0x00007f6379078428,0x00007f63790784a8] = 128
dependencies [0x00007f63790784a8,0x00007f63790784b0] = 8
Loaded disassembler from /java/jdk/jdk1.8.0_101/jre/lib/amd64/hsdis-amd64.so
Decoding compiled method 0x00007f6379078250:
Code:
[Disassembling for mach='i386:x86-64']
[Entry Point]
[Verified Entry Point]
[Constants]
# {method} {0x00007f6380ae0488} 'doMath' '(I)I' in
'com/loop/LoopInvariantCodeMotion'
# parm0: rsi = int
# [sp+0x20] (sp of caller)
0x00007f6379078380: sub rsp,0x18
0x00007f6379078387: mov QWORD PTR [rsp+0x10],rbp ;*synchronization
entry
; -
com.loop.LoopInvariantCodeMotion::doMath at -1 (line 14)
0x00007f637907838c: xor r11d,r11d
0x00007f637907838f: test esi,esi
0x00007f6379078391: jle 0x00007f63790783bd ;*if_icmpge
; -
com.loop.LoopInvariantCodeMotion::doMath at 6 (line 15)
0x00007f6379078393: mov r10d,esi
0x00007f6379078396: shl r10d,1
0x00007f6379078399: xor eax,eax
0x00007f637907839b: nop DWORD PTR [rax+rax*1+0x0]
;*iload_0
; -
com.loop.LoopInvariantCodeMotion::doMath at 9 (line 16)
0x00007f63790783a0: mov r8d,r10d
0x00007f63790783a3: add r8d,r11d
0x00007f63790783a6: add eax,r8d ;*iadd
; -
com.loop.LoopInvariantCodeMotion::doMath at 17 (line 17)
0x00007f63790783a9: inc r11d ;*iinc
; -
com.loop.LoopInvariantCodeMotion::doMath at 19 (line 15)
0x00007f63790783ac: cmp r11d,esi
0x00007f63790783af: jl 0x00007f63790783a0 ;*if_icmpge
; -
com.loop.LoopInvariantCodeMotion::doMath at 6 (line 15)
0x00007f63790783b1: add rsp,0x10
0x00007f63790783b5: pop rbp
0x00007f63790783b6: test DWORD PTR [rip+0xc359c44],eax #
0x00007f63853d2000
; {poll_return}
0x00007f63790783bc: ret
0x00007f63790783bd: xor eax,eax
0x00007f63790783bf: jmp 0x00007f63790783b1
0x00007f63790783c1: hlt
0x00007f63790783c2: hlt
0x00007f63790783c3: hlt
0x00007f63790783c4: hlt
0x00007f63790783c5: hlt
0x00007f63790783c6: hlt
0x00007f63790783c7: hlt
0x00007f63790783c8: hlt
0x00007f63790783c9: hlt
0x00007f63790783ca: hlt
0x00007f63790783cb: hlt
0x00007f63790783cc: hlt
0x00007f63790783cd: hlt
0x00007f63790783ce: hlt
0x00007f63790783cf: hlt
0x00007f63790783d0: hlt
0x00007f63790783d1: hlt
0x00007f63790783d2: hlt
0x00007f63790783d3: hlt
0x00007f63790783d4: hlt
0x00007f63790783d5: hlt
0x00007f63790783d6: hlt
0x00007f63790783d7: hlt
0x00007f63790783d8: hlt
0x00007f63790783d9: hlt
0x00007f63790783da: hlt
0x00007f63790783db: hlt
0x00007f63790783dc: hlt
0x00007f63790783dd: hlt
0x00007f63790783de: hlt
0x00007f63790783df: hlt
[Exception Handler]
[Stub Code]
0x00007f63790783e0: jmp 0x00007f6379075520 ; {no_reloc}
[Deopt Handler Code]
0x00007f63790783e5: call 0x00007f63790783ea
0x00007f63790783ea: sub QWORD PTR [rsp],0x5
0x00007f63790783ef: jmp 0x00007f6379046fc0 ; {runtime_call}
0x00007f63790783f4: hlt
0x00007f63790783f5: hlt
0x00007f63790783f6: hlt
0x00007f63790783f7: hlt
OopMapSet contains 0 OopMaps
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20170118/7030610d/attachment.html>
More information about the hotspot-compiler-dev
mailing list