Bug 18190

Summary: [5/6 regression] primitive array optimization is gone
Product: gcc Reporter: Tom Tromey <tromey>
Component: javaAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED WONTFIX    
Severity: minor CC: gcc-bugs, java-prs, pinskia
Priority: P5 Keywords: missed-optimization
Version: 4.0.0   
Target Milestone: 5.5   
Host: Target:
Build: Known to work:
Known to fail: 4.0.4, 4.9.4 Last reconfirmed: 2009-03-20 22:56:21
Bug Depends on:    
Bug Blocks: 17574    
Attachments: front-end part
A new patch which completes porting the expand part to the gimplifier

Description Tom Tromey 2004-10-28 01:15:46 UTC
Sample source:

public class t
{
  public static final int[] x = { 5, 7, 9, 11 };
}

In gcc 3.3 (and 3.4 and earlier than 3.3), this code compiled
to something like:

.LJv0.0:
	.long	_Jv_intVTable
	.long	4
	.long	5
	.long	7
	.long	9
	.long	11

Now we actually emit code for this.

The culprits are a combination of this patch to gcj:

2004-07-08  Richard Henderson  <rth@redhat.com>

	* expr.c (case_identity, get_primitive_array_vtable,
	java_expand_expr, emit_init_test_initialization): Remove.
	* java-tree.h (java_expand_expr): Remove.
	* lang.c (LANG_HOOKS_EXPAND_EXPR): Remove.

and this patch to libgcj (which removed the primitive vtables):

2004-07-23  Bryce McKinlay  <mckinlay@redhat.com>

	* prims.cc (_Jv_InitPrimClass): Don't create an array class.
	(_Jv_CreateJavaVM): Don't pass array vtable parameter to
	_Jv_InitPrimClass.
	(DECLARE_PRIM_TYPE): Don't declare array vtables.
	* include/jvm.h (struct _Jv_ArrayVTable): Removed.
	* java/lang/Class.h (_Jv_InitPrimClass): Update friend declaration.
Comment 1 Andrew Pinski 2004-10-28 01:39:41 UTC
Confirmed.
Comment 2 Andrew Pinski 2004-11-04 04:53:33 UTC
Some of the code from java_expand_expr should be moved into java_gimplify_new_array_init.
And maybe fix up libjava code or maybe just storing the array's vtable by using a store.  I might look 
into doing this tomorrow.
Comment 3 Bryce McKinlay 2004-11-04 18:46:05 UTC
Here's my thoughts about this:

- This optimization only ever worked for source compilation. Bytecode compilers
always emit array initializers as code, so for byte compilation it makes no
difference.

- I don't see a strong reason not to reference the vtable symbols, but if we
decide to remove my patch then we need to be careful that the original bug
remains fixed - see: http://gcc.gnu.org/ml/java-patches/2004-q3/msg00343.html

- Is this optimization really worth worrying about? I'm pretty sure that
performance-wise, the difference is insignificant - binary size is what we
should be concerned about here. Is a binary that initializes arrays in code
significantly larger?

Comment 4 Andrew Pinski 2004-11-04 21:18:53 UTC
Created attachment 7473 [details]
front-end part

Here is the front-end part which is just a port of the expand stuff to the
gimplifier (it works in the sense I can see that we get the same assembly code
as before the merge of the tree-ssa and now).
ChangeLog:
* java-gimplify.c: Include parse.h.
(get_primitive_array_vtable): New function.
(java_gimplify_new_array_init): Add staticly allocated arrays.
Comment 5 Andrew Pinski 2004-11-04 21:19:45 UTC
Note I attached the front-end part so the only thing left is to fix up libjava to emit the vtables again.
Comment 6 Andrew Pinski 2004-11-04 23:05:02 UTC
Created attachment 7474 [details]
A new patch which completes porting the expand part to the gimplifier

This new patch which adds the other part of what the expand code did for
NEW_ARRAY_INIT for arrays greater than 10 and constants (with primitive types)
to be copied from a static variable:
ChangeLog:
* java-gimplify.c: Include parse.h.
(get_primitive_array_vtable): New function.
(java_gimplify_new_array_init): Add staticly allocated primitive arrays
and copy arrays which have more than 10 elements and is
constant primitives.
Comment 7 Andrew Pinski 2004-11-04 23:06:02 UTC
I finished up porting the other part of the expand part.
Comment 8 Mark Mitchell 2005-01-19 18:52:23 UTC
Ada and Java bugs are not release-critical; therefore, I've removed the target
milsetone.
Comment 9 Mark Mitchell 2005-08-22 01:47:21 UTC
Removing target milestone per last comment.
Comment 10 Mark Mitchell 2006-05-25 02:35:30 UTC
Will not be fixed in 4.1.1; adjust target milestone to 4.1.2.
Comment 11 Joseph S. Myers 2008-07-04 16:34:30 UTC
Closing 4.1 branch.
Comment 12 Steven Bosscher 2009-03-20 18:30:28 UTC
Tom, this hasn't been reconfirmed in a while.  Does this bug still exist in gcj?
Comment 13 Richard Biener 2009-03-20 22:44:14 UTC
It at least still happens with 4.3 and I have no belief that it is fixed with
4.4 if comment #3 applies.  Code generated is also absymal (-O2):

_ZN1t18__U3c_clinit__U3e_EJvv:
.LFB2:
        pushl   %ebp
.LCFI0:
        movl    %esp, %ebp
.LCFI1:
        subl    $8, %esp
.LCFI2:
        movl    $4, 4(%esp)
        movl    $_Jv_intClass, (%esp)
        call    _Jv_NewPrimArray
        movl    4(%eax), %edx
        testl   %edx, %edx
        je      .L8
        cmpl    $1, %edx
        movl    $5, 8(%eax)
        jbe     .L9
        cmpl    $2, %edx
        movl    $7, 12(%eax)
        jbe     .L10
        cmpl    $3, %edx
        movl    $9, 16(%eax)
        jbe     .L11
        movl    $11, 20(%eax)
        movl    %eax, _ZN1t1xE
        leave
        ret
.L8:
        movl    $0, (%esp)
        call    _Jv_ThrowBadArrayIndex
.L9:
        movl    $1, (%esp)
        call    _Jv_ThrowBadArrayIndex
.L10:
        movl    $2, (%esp)
        call    _Jv_ThrowBadArrayIndex
.L11:
        movl    $3, (%esp)
        call    _Jv_ThrowBadArrayIndex

(4.3 again), we do not seem to be able to CSE the load of the array length
on the tree level and we have no way (still) of commoning the calls to
_Jv_ThrowBadArrayIndex either:

<bb 2>:
  D.241 = _Jv_NewPrimArray (&_Jv_intClass, 4);
  D.249 = D.241->length;
  if (D.249 != 0)
    goto <bb 4>;
  else
    goto <bb 3>;

<bb 3>:
  _Jv_ThrowBadArrayIndex (0);

<bb 4>:
  D.241->data[0] = 5;
  D.263 = D.241->length;
  if ((unsigned int) D.263 > 1)
    goto <bb 6>;
  else
    goto <bb 5>;

<bb 5>:
  _Jv_ThrowBadArrayIndex (1);

<bb 6>:
  D.241->data[1] = 7;
  D.277 = D.241->length;
  if ((unsigned int) D.277 > 2)
    goto <bb 8>;
  else
    goto <bb 7>;

<bb 7>:
  _Jv_ThrowBadArrayIndex (2);

<bb 8>:
  D.241->data[2] = 9;
  D.291 = D.241->length;
  if ((unsigned int) D.291 > 3)
    goto <bb 10>;
  else
    goto <bb 9>;

<bb 9>:
  _Jv_ThrowBadArrayIndex (3);

<bb 10>:
  D.241->data[3] = 11;
  x = D.241;
  return;
Comment 14 Joseph S. Myers 2009-03-31 16:20:53 UTC
Closing 4.2 branch.
Comment 15 Richard Biener 2009-08-04 12:26:06 UTC
GCC 4.3.4 is being released, adjusting target milestone.
Comment 16 Richard Biener 2010-05-22 18:10:04 UTC
GCC 4.3.5 is being released, adjusting target milestone.
Comment 17 Richard Biener 2011-06-27 12:12:55 UTC
4.3 branch is being closed, moving to 4.4.7 target.
Comment 18 Jakub Jelinek 2012-03-13 12:45:37 UTC
4.4 branch is being closed, moving to 4.5.4 target.
Comment 19 Jakub Jelinek 2013-04-12 15:16:05 UTC
GCC 4.6.4 has been released and the branch has been closed.
Comment 20 Richard Biener 2014-06-12 13:42:42 UTC
The 4.7 branch is being closed, moving target milestone to 4.8.4.
Comment 21 Jakub Jelinek 2014-12-19 13:32:35 UTC
GCC 4.8.4 has been released.
Comment 22 Richard Biener 2015-06-23 08:14:57 UTC
The gcc-4_8-branch is being closed, re-targeting regressions to 4.9.3.
Comment 23 Jakub Jelinek 2015-06-26 19:57:01 UTC
GCC 4.9.3 has been released.
Comment 24 Richard Biener 2016-08-03 10:36:08 UTC
GCC 4.9 branch is being closed
Comment 25 Andrew Pinski 2016-10-03 05:42:30 UTC
This won't be fixed for 5.x or 6.x so closing as won't fix.