This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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));

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]