Bug 180471 - [compiler] Unoptimal code generation for for-loops when no continuation point
Summary: [compiler] Unoptimal code generation for for-loops when no continuation point
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.3   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.3 M7   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-04-02 07:50 EDT by Philipe Mulet CLA
Modified: 2007-04-27 09:51 EDT (History)
0 users

See Also:


Attachments
Proposed patch (60.47 KB, patch)
2007-04-02 11:23 EDT, Philipe Mulet CLA
no flags Details | Diff
Better patch (70.15 KB, patch)
2007-04-02 15:58 EDT, Philipe Mulet CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Philipe Mulet CLA 2007-04-02 07:50:01 EDT
Build 3.3M6

Following code could be slightly better generated:

public class X {
	public static void main(String[] args) {
		while (args.length > 0) {
			System.out.println();
			break;
		}
		for (int i = 0; i < args.length; i++) {
			System.out.println(i);
			break;
		}
		for (String s : args) {
			System.out.println(s);
			break;
		}
		do {
			System.out.println();
			break;
		} while (args.length > 0);
	}
}

The 2 for-loops are not reversed, like the while does (due to no continuation point).
Comment 1 Philipe Mulet CLA 2007-04-02 07:51:23 EDT
  // Method descriptor #15 ([Ljava/lang/String;)V
  // Stack: 2, Locals: 5
  public static void main(String[] args);
     0  aload_0 [args]
     1  arraylength
     2  ifle 11
     5  getstatic System.out : PrintStream [16]
     8  invokevirtual PrintStream.println() : void [22]
    11  iconst_0
    12  istore_1 [i]
    13  goto 26
    16  getstatic System.out : PrintStream [16]
    19  iload_1 [i]
    20  invokevirtual PrintStream.println(int) : void [27]
    23  goto 32
    26  iload_1 [i]
    27  aload_0 [args]
    28  arraylength
    29  if_icmplt 16
    32  aload_0 [args]
    33  astore 4
    35  iconst_0
    36  istore_2
    37  aload 4
    39  arraylength
    40  istore_3
    41  goto 59
    44  aload 4
    46  iload_2
    47  aaload
    48  astore_1 [s]
    49  getstatic System.out : PrintStream [16]
    52  aload_1 [s]
    53  invokevirtual PrintStream.println(String) : void [30]
    56  goto 64
    59  iload_2
    60  iload_3
    61  if_icmplt 44
    64  getstatic System.out : PrintStream [16]
    67  invokevirtual PrintStream.println() : void [22]
    70  return
Comment 2 Philipe Mulet CLA 2007-04-02 07:53:14 EDT
The do statement looks suspicious too.
Comment 3 Philipe Mulet CLA 2007-04-02 07:59:04 EDT
Actually do loops are fine.

public class X {
	void foo1(int[] array) {
		while (array.length > 0) {
			System.out.println();
			break;
		}
	}
	void foo2(int[] array) {
		for (int i = 0; i < array.length; i++) {
			System.out.println(i);
			break;
		}
	}
	void foo3(int[] array) {
		for (int i : array) {
			System.out.println(i);
			break;
		}
	}
	void foo4(int[] array) {
		do {
			System.out.println();
			break;
		} while (array.length > 0);
	}
}

produces:
  // Method descriptor #15 ([I)V
  // Stack: 1, Locals: 2
  void foo1(int[] array);
     0  aload_1 [array]
     1  arraylength
     2  ifle 11
     5  getstatic System.out : PrintStream [16]
     8  invokevirtual PrintStream.println() : void [22]
    11  return
      Line numbers:
        [pc: 0, line: 3]
        [pc: 5, line: 4]
        [pc: 11, line: 7]
      Local variable table:
        [pc: 0, pc: 12] local: this index: 0 type: X
        [pc: 0, pc: 12] local: array index: 1 type: int[]
  
  // Method descriptor #15 ([I)V
  // Stack: 2, Locals: 3
  void foo2(int[] array);
     0  iconst_0
     1  istore_2 [i]
     2  goto 15
     5  getstatic System.out : PrintStream [16]
     8  iload_2 [i]
     9  invokevirtual PrintStream.println(int) : void [30]
    12  goto 21
    15  iload_2 [i]
    16  aload_1 [array]
    17  arraylength
    18  if_icmplt 5
    21  return
      Line numbers:
        [pc: 0, line: 9]
        [pc: 5, line: 10]
        [pc: 12, line: 11]
        [pc: 15, line: 9]
        [pc: 21, line: 13]
      Local variable table:
        [pc: 0, pc: 22] local: this index: 0 type: X
        [pc: 0, pc: 22] local: array index: 1 type: int[]
        [pc: 2, pc: 21] local: i index: 2 type: int
  
  // Method descriptor #15 ([I)V
  // Stack: 2, Locals: 6
  void foo3(int[] array);
     0  aload_1 [array]
     1  astore 5
     3  iconst_0
     4  istore_3
     5  aload 5
     7  arraylength
     8  istore 4
    10  goto 28
    13  aload 5
    15  iload_3
    16  iaload
    17  istore_2 [i]
    18  getstatic System.out : PrintStream [16]
    21  iload_2 [i]
    22  invokevirtual PrintStream.println(int) : void [30]
    25  goto 34
    28  iload_3
    29  iload 4
    31  if_icmplt 13
    34  return
      Line numbers:
        [pc: 0, line: 15]
        [pc: 18, line: 16]
        [pc: 25, line: 17]
        [pc: 28, line: 15]
        [pc: 34, line: 19]
      Local variable table:
        [pc: 0, pc: 35] local: this index: 0 type: X
        [pc: 0, pc: 35] local: array index: 1 type: int[]
        [pc: 18, pc: 28] local: i index: 2 type: int
  
  // Method descriptor #15 ([I)V
  // Stack: 1, Locals: 2
  void foo4(int[] array);
    0  getstatic System.out : PrintStream [16]
    3  invokevirtual PrintStream.println() : void [22]
    6  return
      Line numbers:
        [pc: 0, line: 22]
        [pc: 6, line: 25]
      Local variable table:
        [pc: 0, pc: 7] local: this index: 0 type: X
        [pc: 0, pc: 7] local: array index: 1 type: int[]
Comment 4 Philipe Mulet CLA 2007-04-02 11:20:02 EDT
Added ForeachStatementTests#test047 + updated other existing ones.
Added ForStatementTest#test002-test004.
Updated TryStementTest.
Comment 5 Philipe Mulet CLA 2007-04-02 11:22:07 EDT
With changes, we now generate:

  // Method descriptor #6 ()V
  // Stack: 1, Locals: 1
  public X();
    0  aload_0 [this]
    1  invokespecial Object() [8]
    4  return
      Line numbers:
        [pc: 0, line: 1]
      Local variable table:
        [pc: 0, pc: 5] local: this index: 0 type: X
  
  // Method descriptor #15 ([I)V
  // Stack: 1, Locals: 2
  void foo1(int[] array);
     0  aload_1 [array]
     1  arraylength
     2  ifle 11
     5  getstatic System.out : PrintStream [16]
     8  invokevirtual PrintStream.println() : void [22]
    11  return
      Line numbers:
        [pc: 0, line: 3]
        [pc: 5, line: 4]
        [pc: 11, line: 7]
      Local variable table:
        [pc: 0, pc: 12] local: this index: 0 type: X
        [pc: 0, pc: 12] local: array index: 1 type: int[]
  
  // Method descriptor #15 ([I)V
  // Stack: 2, Locals: 3
  void foo2(int[] array);
     0  iconst_0
     1  istore_2 [i]
     2  iload_2 [i]
     3  aload_1 [array]
     4  arraylength
     5  if_icmpge 15
     8  getstatic System.out : PrintStream [16]
    11  iload_2 [i]
    12  invokevirtual PrintStream.println(int) : void [30]
    15  return
      Line numbers:
        [pc: 0, line: 9]
        [pc: 8, line: 10]
        [pc: 15, line: 13]
      Local variable table:
        [pc: 0, pc: 16] local: this index: 0 type: X
        [pc: 0, pc: 16] local: array index: 1 type: int[]
        [pc: 2, pc: 15] local: i index: 2 type: int
  
  // Method descriptor #15 ([I)V
  // Stack: 2, Locals: 4
  void foo3(int[] array);
     0  aload_1 [array]
     1  dup
     2  astore_3
     3  arraylength
     4  ifeq 18
     7  aload_3
     8  iconst_0
     9  iaload
    10  istore_2 [i]
    11  getstatic System.out : PrintStream [16]
    14  iload_2 [i]
    15  invokevirtual PrintStream.println(int) : void [30]
    18  return
      Line numbers:
        [pc: 0, line: 15]
        [pc: 11, line: 16]
        [pc: 18, line: 19]
      Local variable table:
        [pc: 0, pc: 19] local: this index: 0 type: X
        [pc: 0, pc: 19] local: array index: 1 type: int[]
        [pc: 11, pc: 18] local: i index: 2 type: int
  
  // Method descriptor #15 ([I)V
  // Stack: 1, Locals: 2
  void foo4(int[] array);
    0  getstatic System.out : PrintStream [16]
    3  invokevirtual PrintStream.println() : void [22]
    6  return
      Line numbers:
        [pc: 0, line: 22]
        [pc: 6, line: 25]
      Local variable table:
        [pc: 0, pc: 7] local: this index: 0 type: X
        [pc: 0, pc: 7] local: array index: 1 type: int[]
Comment 6 Philipe Mulet CLA 2007-04-02 11:23:56 EDT
Created attachment 62672 [details]
Proposed patch
Comment 7 Philipe Mulet CLA 2007-04-02 15:58:56 EDT
Created attachment 62706 [details]
Better patch
Comment 8 Philipe Mulet CLA 2007-04-02 16:00:16 EDT
Released for 3.3M7
Fixed
Comment 9 Philipe Mulet CLA 2007-04-03 05:44:47 EDT
fyi - javac generates 31 bytecodes for #foo3, where we only issue 18.

  // Method descriptor #12 ([I)V
  // Stack: 2, Locals: 6
  void foo3(int[] arg0);
     0  aload_1
     1  astore_2
     2  aload_2
     3  arraylength
     4  istore_3
     5  iconst_0
     6  istore 4
     8  iload 4
    10  iload_3
    11  if_icmpge 31
    14  aload_2
    15  iload 4
    17  iaload
    18  istore 5
    20  getstatic System.out : PrintStream [2]
    23  iload 5
    25  invokevirtual PrintStream.println(int) : void [4]
    28  goto 31
    31  return
      Line numbers:
        [pc: 0, line: 15]
        [pc: 20, line: 16]
        [pc: 28, line: 17]
        [pc: 31, line: 19]
      Stack map table: number of frames 2
        [pc: 8, append: {int[], int, int}]
        [pc: 31, chop 3 local(s)]
Comment 10 Jerome Lanneluc CLA 2007-04-27 09:51:20 EDT
Verified for 3.3M7 with I20070427-0010