This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[ast-optimizer-branch] PATCH to simplify array base
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 08 Jun 2002 07:04:04 +0100
- Subject: [ast-optimizer-branch] PATCH to simplify array base
We haven't been simplifying array bases, but we should. Given an
expression like k.d[2][3] where k.d is of type int[3][4], this will now
simplify to
int (*t1)[3][4];
int t2;
t1 = &k.d;
t2 = (*t1)[2][3];
This is still an extension from the published SIMPLE grammar, but I believe
this was omitted there because the McCAT version of ARRAY_REF takes a
POINTER_TYPE argument, whereas the gcc version takes an ARRAY_TYPE. It
seems to me that it would make sense for gcc to support POINTER_TYPE
arguments as well, so that we can retain information about array indexing
off of pointers, but that can wait.
Booted and tested i686-pc-linux-gnu, applied ast-optimizer-branch.
2002-06-08 Jason Merrill <jason@redhat.com>
* tree-simple.c (is_simple_arraybase): New function.
(is_simple_arrayref): Use it to check the array base again.
* tree-simple.h: Add declaration.
* c-simplify.c (simplify_array_ref): Do simplify the base.
* expr.c (expand_expr): First make sure the type has a size.
*** c-simplify.c.~1~ Thu Jun 6 20:52:48 2002
--- c-simplify.c Sat Jun 8 06:49:37 2002
*************** simplify_expr (expr_p, pre_p, post_p, si
*** 1178,1184 ****
STMT is the statement tree that contains EXPR. It's used in cases
where simplifying an expression requires creating new statement
! trees. */
static void
simplify_array_ref (expr_p, pre_p, post_p, stmt)
--- 1178,1188 ----
STMT is the statement tree that contains EXPR. It's used in cases
where simplifying an expression requires creating new statement
! trees.
!
! FIXME: ARRAY_REF currently doesn't accept a pointer as the array
! argument, so this simplification uses an INDIRECT_REF of ARRAY_TYPE.
! ARRAY_REF should be extended. */
static void
simplify_array_ref (expr_p, pre_p, post_p, stmt)
*************** simplify_array_ref (expr_p, pre_p, post_
*** 1187,1193 ****
tree *post_p;
tree stmt;
{
! tree base;
varray_type dim_stack;
if (TREE_CODE (*expr_p) != ARRAY_REF)
--- 1191,1197 ----
tree *post_p;
tree stmt;
{
! tree base, array;
varray_type dim_stack;
if (TREE_CODE (*expr_p) != ARRAY_REF)
*************** simplify_array_ref (expr_p, pre_p, post_
*** 1209,1217 ****
and 'dim_stack' is a stack of pointers to all the dimensions in left
to right order (the leftmost dimension is at the top of the stack).
! Simplify each of the dimensions from left to right. Note that the
! base of the array is never simplified because that would break the
! semantics of C arrays. */
while (VARRAY_ACTIVE_SIZE (dim_stack) > 0)
{
tree *dim_p = (tree *)VARRAY_TOP_GENERIC_PTR (dim_stack);
--- 1213,1233 ----
and 'dim_stack' is a stack of pointers to all the dimensions in left
to right order (the leftmost dimension is at the top of the stack).
! Simplify the base, and then each of the dimensions from left to
! right. */
!
! array = TREE_OPERAND (base, 0);
! if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE)
! abort ();
! if (! is_simple_arraybase (array))
! {
! array = fold (build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (array)),
! array));
! simplify_expr (&array, pre_p, post_p, is_simple_id, stmt);
! array = build_indirect_ref (array, "");
! TREE_OPERAND (base, 0) = array;
! }
!
while (VARRAY_ACTIVE_SIZE (dim_stack) > 0)
{
tree *dim_p = (tree *)VARRAY_TOP_GENERIC_PTR (dim_stack);
*************** simplify_lvalue_expr (expr_p, pre_p, pos
*** 1774,1781 ****
}
else if (TREE_CODE (*expr_p) == ARRAY_REF)
{
- /* We do not simplify array basenames (yet). Simplifying the
- whole reference will just re-write the index, which is OK. */
simplify_expr (expr_p, pre_p, post_p, is_simple_varname, stmt);
}
else if (TREE_CODE (*expr_p) == COMPONENT_REF)
--- 1790,1795 ----
*** expr.c.~1~ Mon Jun 3 22:59:18 2002
--- expr.c Sat Jun 8 05:03:45 2002
*************** expand_expr (exp, target, tmode, modifie
*** 7148,7153 ****
--- 7148,7154 ----
size of the type isn't the same size as the bitfield,
we must use bitfield operations. */
|| (bitsize >= 0
+ && TYPE_SIZE (TREE_TYPE (exp))
&& (TREE_CODE (TYPE_SIZE (TREE_TYPE (exp)))
== INTEGER_CST)
&& 0 != compare_tree_int (TYPE_SIZE (TREE_TYPE (exp)),
*** tree-simple.c.~1~ Thu Jun 6 20:53:06 2002
--- tree-simple.c Sat Jun 8 03:05:16 2002
*************** Boston, MA 02111-1307, USA. */
*** 186,201 ****
| ID
arrayref
! : arraybase reflist => 'arraybase' is any valid C array
! name. Original grammar only
! allowed 'ID reflist'. This
! causes splits like k.d[2][3]
! into
!
! t1 = &(k.d[2])
! t2 = *(&t1[3])
!
! which is invalid.
reflist
: '[' val ']'
--- 186,194 ----
| ID
arrayref
! : ID reflist
! | '(' '*' ID ')' reflist => extension because ARRAY_REF
! requires an ARRAY_TYPE argument.
reflist
: '[' val ']'
*************** is_simple_val (t)
*** 789,806 ****
Return nonzero if T is an array reference of the form:
arrayref
! : arraybase reflist => 'arraybase' is any valid C array
! name. The original grammar
! allowed only ID here, but we
! cannot simplify array bases
! because we may get invalid
! code.
reflist
: '[' val ']'
| reflist '[' val ']' */
int
is_simple_arrayref (t)
tree t;
{
--- 782,808 ----
Return nonzero if T is an array reference of the form:
arrayref
! : ID reflist
! | '(' '*' ID ')' reflist => extension because ARRAY_REF
! requires an ARRAY_TYPE argument.
reflist
: '[' val ']'
| reflist '[' val ']' */
int
+ is_simple_arraybase (t)
+ tree t;
+ {
+ if (t == NULL_TREE)
+ return 1;
+
+ return (is_simple_id (t)
+ || (TREE_CODE (t) == INDIRECT_REF
+ && is_simple_id (TREE_OPERAND (t, 0))));
+ }
+
+ int
is_simple_arrayref (t)
tree t;
{
*************** is_simple_arrayref (t)
*** 813,818 ****
--- 815,822 ----
return is_simple_arrayref (TREE_OPERAND (t, 0));
return (TREE_CODE (t) == ARRAY_REF
+ && (is_simple_arraybase (TREE_OPERAND (t, 0))
+ || is_simple_arrayref (TREE_OPERAND (t, 0)))
&& is_simple_val (TREE_OPERAND (t, 1)));
}
*** tree-simple.h.~1~ Sat Apr 27 23:54:22 2002
--- tree-simple.h Sat Jun 8 06:49:37 2002
*************** int is_simple_const P
*** 49,54 ****
--- 49,55 ----
int is_simple_id PARAMS ((tree));
int is_simple_varname PARAMS ((tree));
int is_simple_val PARAMS ((tree));
+ int is_simple_arraybase PARAMS ((tree));
int is_simple_arrayref PARAMS ((tree));
int is_simple_compref PARAMS ((tree));
int is_simple_compref_lhs PARAMS ((tree));