-
Enhancement
-
Resolution: Unresolved
-
P4
-
25
-
generic
Please consider following test
import jdk.internal.vm.annotation.Stable;
import java.util.stream.IntStream;
public class constant_value {
@Stable
public static int [] arr;
public static int micro(int val) {
return arr[0] + arr[1] + arr[2] + arr[8] + arr[16] + val;
}
public static void main(String [] args) {
int res = 0;
arr = IntStream.range(0, 32).map(i -> 0).toArray();
for (int i = 0; i < 10000; i++) {
res += micro(i);
}
System.out.println("[res] " + res);
}
}
Here, all the elements of the stable array are set to zero.
java -Xbootclasspath/a:. -XX:CompileCommand=PrintIdealPhase,constant_value::micro,AFTER_PARSING -XX:CompileOnly=constant_value::micro --add-exports=java.base/jdk.internal.vm.annotation=ALL-UNNAMED -Xbatch -XX:-TieredCompilation -cp . constant_value
We can see multiple LoadI Nodes in post-parsing IR
AFTER: AFTER_PARSING
0 Root === 0 49 [[ 0 1 3 44 23 39 25 34 29 ]]
3 Start === 3 0 [[ 3 5 6 7 8 9 10 ]] #{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address, 5:int}
5 Parm === 3 [[ 49 ]] Control !jvms: constant_value::micro @ bci:-1 (line 10)
6 Parm === 3 [[ 49 ]] I_O !jvms: constant_value::micro @ bci:-1 (line 10)
7 Parm === 3 [[ 49 46 41 36 27 31 ]] Memory Memory: @BotPTR *+bot, idx=Bot; !jvms: constant_value::micro @ bci:-1 (line 10)
8 Parm === 3 [[ 49 ]] FramePtr !jvms: constant_value::micro @ bci:-1 (line 10)
9 Parm === 3 [[ 49 ]] ReturnAdr !jvms: constant_value::micro @ bci:-1 (line 10)
10 Parm === 3 [[ 48 ]] Parm0: int !jvms: constant_value::micro @ bci:-1 (line 10)
23 ConP === 0 [[ 26 26 30 30 35 35 40 40 45 45 ]] #stable:int[int:32] (java/lang/Cloneable,java/io/Serializable)<ciTypeArray length=32 type=<ciTypeArrayKlass name=[I loaded=true ident=1353 address=0x00007f729c01a0e0> ident=1367 address=0x00007f73502f96e0> *
25 ConL === 0 [[ 26 ]] #long:16
26 AddP === _ 23 23 25 [[ 27 ]] !jvms: constant_value::micro @ bci:4 (line 10)
27 LoadI === _ 7 26 [[ 32 ]] @int[int:>=0] (java/lang/Cloneable,java/io/Serializable):exact+any *, idx=4; #int !jvms: constant_value::micro @ bci:4 (line 10)
29 ConL === 0 [[ 30 ]] #long:20
30 AddP === _ 23 23 29 [[ 31 ]] !jvms: constant_value::micro @ bci:9 (line 10)
31 LoadI === _ 7 30 [[ 32 ]] @int[int:>=0] (java/lang/Cloneable,java/io/Serializable):exact+any *, idx=4; #int !jvms: constant_value::micro @ bci:9 (line 10)
32 AddI === _ 27 31 [[ 37 ]] !jvms: constant_value::micro @ bci:10 (line 10)
34 ConL === 0 [[ 35 ]] #long:24
35 AddP === _ 23 23 34 [[ 36 ]] !jvms: constant_value::micro @ bci:15 (line 10)
36 LoadI === _ 7 35 [[ 37 ]] @int[int:>=0] (java/lang/Cloneable,java/io/Serializable):exact+any *, idx=4; #int !jvms: constant_value::micro @ bci:15 (line 10)
37 AddI === _ 32 36 [[ 42 ]] !jvms: constant_value::micro @ bci:16 (line 10)
39 ConL === 0 [[ 40 ]] #long:48
40 AddP === _ 23 23 39 [[ 41 ]] !jvms: constant_value::micro @ bci:22 (line 10)
41 LoadI === _ 7 40 [[ 42 ]] @int[int:>=0] (java/lang/Cloneable,java/io/Serializable):exact+any *, idx=4; #int !jvms: constant_value::micro @ bci:22 (line 10)
42 AddI === _ 37 41 [[ 47 ]] !jvms: constant_value::micro @ bci:23 (line 10)
44 ConL === 0 [[ 45 ]] #long:80
45 AddP === _ 23 23 44 [[ 46 ]] !jvms: constant_value::micro @ bci:29 (line 10)
46 LoadI === _ 7 45 [[ 47 ]] @int[int:>=0] (java/lang/Cloneable,java/io/Serializable):exact+any *, idx=4; #int !jvms: constant_value::micro @ bci:29 (line 10)
47 AddI === _ 42 46 [[ 48 ]] !jvms: constant_value::micro @ bci:30 (line 10)
48 AddI === _ 10 47 [[ 49 ]] !jvms: constant_value::micro @ bci:32 (line 10)
If we initialize the stable array with a non-zero value, e.g., 1, all the array index expressions are folded.
import jdk.internal.vm.annotation.Stable;
import java.util.stream.IntStream;
public class constant_value {
@Stable
public static int [] arr;
public static int micro(int val) {
return arr[0] + arr[1] + arr[2] + arr[8] + arr[16] + val;
}
public static void main(String [] args) {
int res = 0;
arr = IntStream.range(0, 32).map(i -> 1).toArray();
for (int i = 0; i < 10000; i++) {
res += micro(i);
}
System.out.println("[res] " + res);
}
}
CPROMPT>java -Xbootclasspath/a:. -XX:CompileCommand=PrintIdealPhase,constant_value::micro,AFTER_PARSING -XX:CompileOnly=constant_value::micro --add-exports=java.base/jdk.internal.vm.annotation=ALL-UNNAMED -Xbatch -XX:-TieredCompilation -cp . constant_value
CompileCommand: PrintIdealPhase constant_value.micro const char* PrintIdealPhase = 'AFTER_PARSING'
CompileCommand: compileonly constant_value.micro bool compileonly = true
AFTER: AFTER_PARSING
0 Root === 0 52 [[ 0 1 3 50 ]]
3 Start === 3 0 [[ 3 5 6 7 8 9 10 ]] #{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address, 5:int}
5 Parm === 3 [[ 52 ]] Control !jvms: constant_value::micro @ bci:-1 (line 10)
6 Parm === 3 [[ 52 ]] I_O !jvms: constant_value::micro @ bci:-1 (line 10)
7 Parm === 3 [[ 52 ]] Memory Memory: @BotPTR *+bot, idx=Bot; !jvms: constant_value::micro @ bci:-1 (line 10)
8 Parm === 3 [[ 52 ]] FramePtr !jvms: constant_value::micro @ bci:-1 (line 10)
9 Parm === 3 [[ 52 ]] ReturnAdr !jvms: constant_value::micro @ bci:-1 (line 10)
10 Parm === 3 [[ 51 ]] Parm0: int !jvms: constant_value::micro @ bci:-1 (line 10)
50 ConI === 0 [[ 51 ]] #int:5
51 AddI === _ 10 50 [[ 52 ]] !jvms: constant_value::micro @ bci:32 (line 10)
52 Return === 5 6 7 8 9 returns 51 [[ 0 ]]
[res] 50045000
CPROMPT>
import jdk.internal.vm.annotation.Stable;
import java.util.stream.IntStream;
public class constant_value {
@Stable
public static int [] arr;
public static int micro(int val) {
return arr[0] + arr[1] + arr[2] + arr[8] + arr[16] + val;
}
public static void main(String [] args) {
int res = 0;
arr = IntStream.range(0, 32).map(i -> 0).toArray();
for (int i = 0; i < 10000; i++) {
res += micro(i);
}
System.out.println("[res] " + res);
}
}
Here, all the elements of the stable array are set to zero.
java -Xbootclasspath/a:. -XX:CompileCommand=PrintIdealPhase,constant_value::micro,AFTER_PARSING -XX:CompileOnly=constant_value::micro --add-exports=java.base/jdk.internal.vm.annotation=ALL-UNNAMED -Xbatch -XX:-TieredCompilation -cp . constant_value
We can see multiple LoadI Nodes in post-parsing IR
AFTER: AFTER_PARSING
0 Root === 0 49 [[ 0 1 3 44 23 39 25 34 29 ]]
3 Start === 3 0 [[ 3 5 6 7 8 9 10 ]] #{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address, 5:int}
5 Parm === 3 [[ 49 ]] Control !jvms: constant_value::micro @ bci:-1 (line 10)
6 Parm === 3 [[ 49 ]] I_O !jvms: constant_value::micro @ bci:-1 (line 10)
7 Parm === 3 [[ 49 46 41 36 27 31 ]] Memory Memory: @BotPTR *+bot, idx=Bot; !jvms: constant_value::micro @ bci:-1 (line 10)
8 Parm === 3 [[ 49 ]] FramePtr !jvms: constant_value::micro @ bci:-1 (line 10)
9 Parm === 3 [[ 49 ]] ReturnAdr !jvms: constant_value::micro @ bci:-1 (line 10)
10 Parm === 3 [[ 48 ]] Parm0: int !jvms: constant_value::micro @ bci:-1 (line 10)
23 ConP === 0 [[ 26 26 30 30 35 35 40 40 45 45 ]] #stable:int[int:32] (java/lang/Cloneable,java/io/Serializable)<ciTypeArray length=32 type=<ciTypeArrayKlass name=[I loaded=true ident=1353 address=0x00007f729c01a0e0> ident=1367 address=0x00007f73502f96e0> *
25 ConL === 0 [[ 26 ]] #long:16
26 AddP === _ 23 23 25 [[ 27 ]] !jvms: constant_value::micro @ bci:4 (line 10)
27 LoadI === _ 7 26 [[ 32 ]] @int[int:>=0] (java/lang/Cloneable,java/io/Serializable):exact+any *, idx=4; #int !jvms: constant_value::micro @ bci:4 (line 10)
29 ConL === 0 [[ 30 ]] #long:20
30 AddP === _ 23 23 29 [[ 31 ]] !jvms: constant_value::micro @ bci:9 (line 10)
31 LoadI === _ 7 30 [[ 32 ]] @int[int:>=0] (java/lang/Cloneable,java/io/Serializable):exact+any *, idx=4; #int !jvms: constant_value::micro @ bci:9 (line 10)
32 AddI === _ 27 31 [[ 37 ]] !jvms: constant_value::micro @ bci:10 (line 10)
34 ConL === 0 [[ 35 ]] #long:24
35 AddP === _ 23 23 34 [[ 36 ]] !jvms: constant_value::micro @ bci:15 (line 10)
36 LoadI === _ 7 35 [[ 37 ]] @int[int:>=0] (java/lang/Cloneable,java/io/Serializable):exact+any *, idx=4; #int !jvms: constant_value::micro @ bci:15 (line 10)
37 AddI === _ 32 36 [[ 42 ]] !jvms: constant_value::micro @ bci:16 (line 10)
39 ConL === 0 [[ 40 ]] #long:48
40 AddP === _ 23 23 39 [[ 41 ]] !jvms: constant_value::micro @ bci:22 (line 10)
41 LoadI === _ 7 40 [[ 42 ]] @int[int:>=0] (java/lang/Cloneable,java/io/Serializable):exact+any *, idx=4; #int !jvms: constant_value::micro @ bci:22 (line 10)
42 AddI === _ 37 41 [[ 47 ]] !jvms: constant_value::micro @ bci:23 (line 10)
44 ConL === 0 [[ 45 ]] #long:80
45 AddP === _ 23 23 44 [[ 46 ]] !jvms: constant_value::micro @ bci:29 (line 10)
46 LoadI === _ 7 45 [[ 47 ]] @int[int:>=0] (java/lang/Cloneable,java/io/Serializable):exact+any *, idx=4; #int !jvms: constant_value::micro @ bci:29 (line 10)
47 AddI === _ 42 46 [[ 48 ]] !jvms: constant_value::micro @ bci:30 (line 10)
48 AddI === _ 10 47 [[ 49 ]] !jvms: constant_value::micro @ bci:32 (line 10)
If we initialize the stable array with a non-zero value, e.g., 1, all the array index expressions are folded.
import jdk.internal.vm.annotation.Stable;
import java.util.stream.IntStream;
public class constant_value {
@Stable
public static int [] arr;
public static int micro(int val) {
return arr[0] + arr[1] + arr[2] + arr[8] + arr[16] + val;
}
public static void main(String [] args) {
int res = 0;
arr = IntStream.range(0, 32).map(i -> 1).toArray();
for (int i = 0; i < 10000; i++) {
res += micro(i);
}
System.out.println("[res] " + res);
}
}
CPROMPT>java -Xbootclasspath/a:. -XX:CompileCommand=PrintIdealPhase,constant_value::micro,AFTER_PARSING -XX:CompileOnly=constant_value::micro --add-exports=java.base/jdk.internal.vm.annotation=ALL-UNNAMED -Xbatch -XX:-TieredCompilation -cp . constant_value
CompileCommand: PrintIdealPhase constant_value.micro const char* PrintIdealPhase = 'AFTER_PARSING'
CompileCommand: compileonly constant_value.micro bool compileonly = true
AFTER: AFTER_PARSING
0 Root === 0 52 [[ 0 1 3 50 ]]
3 Start === 3 0 [[ 3 5 6 7 8 9 10 ]] #{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address, 5:int}
5 Parm === 3 [[ 52 ]] Control !jvms: constant_value::micro @ bci:-1 (line 10)
6 Parm === 3 [[ 52 ]] I_O !jvms: constant_value::micro @ bci:-1 (line 10)
7 Parm === 3 [[ 52 ]] Memory Memory: @BotPTR *+bot, idx=Bot; !jvms: constant_value::micro @ bci:-1 (line 10)
8 Parm === 3 [[ 52 ]] FramePtr !jvms: constant_value::micro @ bci:-1 (line 10)
9 Parm === 3 [[ 52 ]] ReturnAdr !jvms: constant_value::micro @ bci:-1 (line 10)
10 Parm === 3 [[ 51 ]] Parm0: int !jvms: constant_value::micro @ bci:-1 (line 10)
50 ConI === 0 [[ 51 ]] #int:5
51 AddI === _ 10 50 [[ 52 ]] !jvms: constant_value::micro @ bci:32 (line 10)
52 Return === 5 6 7 8 9 returns 51 [[ 0 ]]
[res] 50045000
CPROMPT>