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 fix union aliasing


My earlier patch to simplify array bases broke
gcc.c-torture/execute/990413-2.c; while gcc knows that

  __x.__i[0] = 0x0;

can alias __x.__d, it does not know that

  int (*t)[2] = &__x.__i;
  (*t)[0] = 0x0;

can alias it.  Until alias analysis is extended to handle this, we won't
simplify a sequence of array and member references if there's a union
involved.

Booted and tested i686-pc-linux-gnu.

Diego, you can go ahead with the merge now.  Thanks.

2002-06-10  Jason Merrill  <jason@redhat.com>

	* tree-simple.c (is_union_based_ref): New fn.
	(is_simple_min_lval): Use it.  Rename from is_simple_arraybase.
	(is_simple_arrayref): Adjust.  Use loop instead of recursion.
	(is_simple_compref): Likewise.
	(is_simple_compref_lhs): Remove.
	* tree-simple.h: Adjust.
	* c-simplify.c (simplify_array_ref): Adjust.
	(simplify_component_ref): Adjust.

*** c-simplify.c.~1~	Mon Jun 10 06:29:15 2002
--- c-simplify.c	Mon Jun 10 06:48:52 2002
*************** simplify_array_ref (expr_p, pre_p, post_
*** 1303,1309 ****
       Simplify the base, and then each of the dimensions from left to
       right.  */
  
!   simplify_lvalue_expr (p, pre_p, post_p, is_simple_arraybase, stmt);
  
    for (; VARRAY_ACTIVE_SIZE (dim_stack) > 0; VARRAY_POP (dim_stack))
      {
--- 1302,1308 ----
       Simplify the base, and then each of the dimensions from left to
       right.  */
  
!   simplify_lvalue_expr (p, pre_p, post_p, is_simple_min_lval, stmt);
  
    for (; VARRAY_ACTIVE_SIZE (dim_stack) > 0; VARRAY_POP (dim_stack))
      {
*************** simplify_component_ref (expr_p, pre_p, p
*** 1414,1420 ****
        abort ();
  
    /* Now we're down to the first bit that isn't a COMPONENT_REF.  */
!   simplify_expr_either (p, pre_p, post_p, is_simple_arraybase, stmt);
  }
  
  /* }}} */
--- 1413,1419 ----
        abort ();
  
    /* Now we're down to the first bit that isn't a COMPONENT_REF.  */
!   simplify_expr_either (p, pre_p, post_p, is_simple_min_lval, stmt);
  }
  
  /* }}} */
*** tree-simple.c.~1~	Sun Jun  9 00:50:33 2002
--- tree-simple.c	Mon Jun 10 08:09:08 2002
*************** Boston, MA 02111-1307, USA.  */
*** 199,204 ****
--- 199,206 ----
  
       ----------------------------------------------------------------------  */
  
+ static bool is_union_based_ref		PARAMS ((tree));
+ 
  /* Validation of SIMPLE statements.  */
  
  /** {{{ is_simple_stmt ()
*************** is_simple_val (t)
*** 783,803 ****
  
  /* }}} */
  
! /** {{{ is_simple_arrayref ()
  
!     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)
--- 785,801 ----
  
  /* }}} */
  
! /** {{{ is_simple_min_lvalue ()
  
!     Return true if T is a SIMPLE minimal lvalue, of the form
  
!     min_lval: ID | '(' '*' ID ')'
  
!     This never actually appears in the original SIMPLE grammar, but is
!     repeated in several places.  */
  
  int
! is_simple_min_lval (t)
       tree t;
  {
    if (t == NULL_TREE)
*************** is_simple_arraybase (t)
*** 805,813 ****
  
    return (is_simple_id (t)
  	  || (TREE_CODE (t) == INDIRECT_REF
! 	      && is_simple_id (TREE_OPERAND (t, 0))));
  }
  
  int
  is_simple_arrayref (t)
       tree t;
--- 803,851 ----
  
    return (is_simple_id (t)
  	  || (TREE_CODE (t) == INDIRECT_REF
! 	      && is_simple_id (TREE_OPERAND (t, 0)))
! 	  || is_union_based_ref (t));
  }
  
+ /* }}} */
+ 
+ /** {{{ is_union_based_ref ()
+ 
+     Returns true iff T is a compound lvalue expression involving a union.
+     We currently don't simplify such expressions because it confuses alias
+     analysis.  FIXME alias analysis should be smarter, and this should go
+     away.  gcc.c-torture/execute/990413-2.c breaks without this.  */
+ 
+ static bool
+ is_union_based_ref (t)
+      tree t;
+ {
+   for (; TREE_CODE (t) == COMPONENT_REF || TREE_CODE (t) == ARRAY_REF;
+        t = TREE_OPERAND (t, 0))
+     {
+       if (TREE_CODE (t) == COMPONENT_REF
+ 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == UNION_TYPE)
+ 	return 1;
+     }
+ 
+   return 0;
+ }
+ 
+ /* }}} */
+ 
+ /** {{{ is_simple_arrayref ()
+ 
+     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_arrayref (t)
       tree t;
*************** is_simple_arrayref (t)
*** 818,829 ****
    /* Allow arrays of complex types.  */
    if (TREE_CODE (t) == REALPART_EXPR
        || TREE_CODE (t) == IMAGPART_EXPR)
!     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)));
  }
  
  /* }}} */
--- 856,871 ----
    /* Allow arrays of complex types.  */
    if (TREE_CODE (t) == REALPART_EXPR
        || TREE_CODE (t) == IMAGPART_EXPR)
!     t = TREE_OPERAND (t, 0);
! 
!   if (TREE_CODE (t) != ARRAY_REF)
!     return 0;
! 
!   for (; TREE_CODE (t) == ARRAY_REF; t = TREE_OPERAND (t, 0))
!     if (! is_simple_val (TREE_OPERAND (t, 1)))
!       return 0;
  
!   return is_simple_min_lval (t);
  }
  
  /* }}} */
*************** is_simple_compref (t)
*** 847,876 ****
    if (t == NULL_TREE)
      return 1;
  
!   return (TREE_CODE (t) == COMPONENT_REF
! 	  && is_simple_compref_lhs (TREE_OPERAND (t, 0))
! 	  && is_simple_id (TREE_OPERAND (t, 1)));
! }
! 
! /* }}} */
! 
! /** {{{ is_simple_compref_lhs ()
! 
!     Return nonzero if T is allowed on the left side of a component
!     reference.  */
  
! int
! is_simple_compref_lhs (t)
!      tree t;
! {
!   if (t == NULL_TREE)
!     return 1;
  
!   /* Allow ID, *ID or a SIMPLE component reference on the LHS.  */
!   return (is_simple_id (t)
! 	  || (TREE_CODE (t) == INDIRECT_REF
! 	      && is_simple_id (TREE_OPERAND (t, 0)))
! 	  || is_simple_compref (t));
  }
  
  /* }}} */
--- 889,902 ----
    if (t == NULL_TREE)
      return 1;
  
!   if (TREE_CODE (t) != COMPONENT_REF)
!     return 0;
  
!   for (; TREE_CODE (t) == COMPONENT_REF; t = TREE_OPERAND (t, 0))
!     if (! is_simple_id (TREE_OPERAND (t, 1)))
!       abort ();
  
!   return is_simple_min_lval (t);
  }
  
  /* }}} */
*** tree-simple.h.~1~	Mon Jun 10 04:38:33 2002
--- tree-simple.h	Mon Jun 10 07:20:12 2002
*************** int is_simple_const                    P
*** 52,61 ****
  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));
  int is_simple_cast                     PARAMS ((tree));
  int is_simple_cast_op                  PARAMS ((tree));
  int is_simple_exprseq                  PARAMS ((tree));
--- 52,60 ----
  int is_simple_id                       PARAMS ((tree));
  int is_simple_varname                  PARAMS ((tree));
  int is_simple_val                      PARAMS ((tree));
! int is_simple_min_lval                 PARAMS ((tree));
  int is_simple_arrayref                 PARAMS ((tree));
  int is_simple_compref                  PARAMS ((tree));
  int is_simple_cast                     PARAMS ((tree));
  int is_simple_cast_op                  PARAMS ((tree));
  int is_simple_exprseq                  PARAMS ((tree));

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