Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-5073662

Range check elimination interferes with regular loop unrolling

XMLWordPrintable

    • 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)
      ======================================================================

            Unassigned Unassigned
            ksoshals Kirill Soshalskiy (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: