[gij] Fix array accesses

Andrew Haley aph@redhat.com
Tue Jan 9 15:50:00 GMT 2007


This patch changes code generations fo arrays in libgcj; it generates

  *((elemtype)(&array->data) + index*size_exp)

instead of 

  (array->data)[n]

Now, you might say "That's the same thing."  Well, it is, kinda sorta,
but the array is defined as something like

typedef struct jcharArray
{
  short length;
  jchar data[];
} jcharArray;

where the data field has no declared size; and I think that SSA alias
analysis doesn't see array references into the jarray object as part
of that object.  At least, in my testing I'm discovering that
references to the data field get deleted.  This may be a bug.

Since our IL is not very well-specified, I don't know whether the
thing I used to do is correct.  However, this form is more canonical,
and it's what the C and C++ front ends generate, and it fixes the
problem.

Andrew.


2007-01-09  Andrew Haley  <aph@redhat.com>

	* expr.c (build_java_arrayaccess): Rewrite to generate array
	access in canonical form.
	(expand_java_arraystore): Use build_fold_addr_expr() on address of
	array access.

diff -u /tmp/notnfs/tromey/trunk/gcc/java/expr.c ./expr.c
--- /tmp/notnfs/tromey/trunk/gcc/java/expr.c	2007-01-04 16:43:15.000000000 +0000
+++ ./expr.c	2007-01-08 19:56:33.000000000 +0000
@@ -885,6 +885,7 @@
   tree data_field;
   tree ref;
   tree array_type = TREE_TYPE (TREE_TYPE (array));
+  tree size_exp = fold_convert (sizetype, size_in_bytes (type));
 
   if (!is_array_type_p (TREE_TYPE (array)))
     {
@@ -919,16 +920,34 @@
      to have the bounds check evaluated first. */
   if (throw != NULL_TREE)
     index = build2 (COMPOUND_EXPR, int_type_node, throw, index);
- 
+
   data_field = lookup_field (&array_type, get_identifier ("data"));
 
   ref = build3 (COMPONENT_REF, TREE_TYPE (data_field),    
 		build_java_indirect_ref (array_type, array, 
 					 flag_check_references),
 		data_field, NULL_TREE);
-  
-  node = build4 (ARRAY_REF, type, ref, index, NULL_TREE, NULL_TREE);
-  return node;
+
+  /* Take the address of the data field and convert it to a pointer to
+     the element type.  */
+  node = build1 (NOP_EXPR, build_pointer_type (type), build_address_of (ref));
+
+  /* Multiply the index by the size of an element to obtain a byte
+     offset.  Convert the result to a pointer to the element type.  */
+  index = fold_convert (TREE_TYPE (node),
+			build2 (MULT_EXPR, sizetype, 
+				fold_convert (sizetype, index), 
+				size_exp));
+
+  /* Sum the byte offset and the address of the data field.  */
+  node = fold_build2 (PLUS_EXPR, TREE_TYPE (node), node, index);
+
+  /* Finally, return
+
+    *((&array->data) + index*size_exp)
+
+  */
+  return build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (node)), node);
 }
 
 /* Generate code to throw an ArrayStoreException if OBJECT is not assignable
@@ -1163,7 +1182,7 @@
   java_add_local_var (temp);
   java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (temp),
 			 temp, 
-			 build_address_of (access)));
+			 build_fold_addr_expr (access)));
 
   if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
     {



More information about the Java-patches mailing list