-
Enhancement
-
Resolution: Not an Issue
-
P3
-
6, 9, 10
-
sparc
-
generic
Name: ks84122 Date: 07/13/2004
public class loopissue
{
static volatile int[] v = null;
public static int checkme(int[] box)
{
int sum = 0;
int i;
for (i = 0; i < 225; i += 5)
{
sum += box[i];
sum ^= box[i + 1];
sum += box[i + 2];
sum ^= box[i + 3];
sum += box[i + 4];
}
return sum;
}
public static void main(String[] args)
{
int s = 0;
for (int i = 0; i < 10000; ++i)
{
v = new int[256];
s += checkme(v);
}
System.out.println(s);
}
}
/opt/jdk1.4.2/bin/java_g -server -XX:+PrintOptoAssembly -XX:+PrintCompilation loopissue
You see the integer divisions and multiplications being generated
in each trip!
094 SETX #1717986919,R_G5 ! long
09c + SRA R_L1,0,R_G1 ! int->long
0a0 + MULX R_G1,R_G5,R_G1 ! long
0a4 + SRA R_L1,#31,R_L0
0a8 SRAX R_G1,#33,R_L2
0ac + SUB R_L2,R_L0,R_L0
0b0 + SLL R_L0,#2,R_L2
0b4 + ADD R_L2,R_L0,R_L0
0b8 + SRA R_L0,0,R_G1 ! int->long
0bc + MULX R_G1,R_G5,R_G1 ! long
0c0 + SRA R_L0,#31,R_L1
0c4 SRAX R_G1,#33,R_L0
0c8 + SUB R_L0,R_L1,R_L1
0cc + AND R_L1,#-2,R_L0
0d0 + SLL R_L0,#2,R_L2
I comment on a bad interaction between range check elimination
and regular loop unrolling. In the case when the loop starting value
and the ending value are both constants, when the pre-loop is created
by range check elimination, the main loop initial value changes from
a constant to "phi + stride". Thus the loop trip count is no longer
a constant. When regular unrolling modifies the main loop ending
limit, the new limit is created:
new_limit = (((limit - init) / stride) & -2) * stride + init
(the purpose is to remove the last odd trip from happening)
This optimizes to constant if 'limit', 'init', and 'stride' are all
constant. But in this case 'init' is no longer constant. It ends up
doing a division and multiply every trip!
(Incident Review ID: 280099)
======================================================================
public class loopissue
{
static volatile int[] v = null;
public static int checkme(int[] box)
{
int sum = 0;
int i;
for (i = 0; i < 225; i += 5)
{
sum += box[i];
sum ^= box[i + 1];
sum += box[i + 2];
sum ^= box[i + 3];
sum += box[i + 4];
}
return sum;
}
public static void main(String[] args)
{
int s = 0;
for (int i = 0; i < 10000; ++i)
{
v = new int[256];
s += checkme(v);
}
System.out.println(s);
}
}
/opt/jdk1.4.2/bin/java_g -server -XX:+PrintOptoAssembly -XX:+PrintCompilation loopissue
You see the integer divisions and multiplications being generated
in each trip!
094 SETX #1717986919,R_G5 ! long
09c + SRA R_L1,0,R_G1 ! int->long
0a0 + MULX R_G1,R_G5,R_G1 ! long
0a4 + SRA R_L1,#31,R_L0
0a8 SRAX R_G1,#33,R_L2
0ac + SUB R_L2,R_L0,R_L0
0b0 + SLL R_L0,#2,R_L2
0b4 + ADD R_L2,R_L0,R_L0
0b8 + SRA R_L0,0,R_G1 ! int->long
0bc + MULX R_G1,R_G5,R_G1 ! long
0c0 + SRA R_L0,#31,R_L1
0c4 SRAX R_G1,#33,R_L0
0c8 + SUB R_L0,R_L1,R_L1
0cc + AND R_L1,#-2,R_L0
0d0 + SLL R_L0,#2,R_L2
I comment on a bad interaction between range check elimination
and regular loop unrolling. In the case when the loop starting value
and the ending value are both constants, when the pre-loop is created
by range check elimination, the main loop initial value changes from
a constant to "phi + stride". Thus the loop trip count is no longer
a constant. When regular unrolling modifies the main loop ending
limit, the new limit is created:
new_limit = (((limit - init) / stride) & -2) * stride + init
(the purpose is to remove the last odd trip from happening)
This optimizes to constant if 'limit', 'init', and 'stride' are all
constant. But in this case 'init' is no longer constant. It ends up
doing a division and multiply every trip!
(Incident Review ID: 280099)
======================================================================