This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[ast-optimizer-branch] PATCH to fix union aliasing
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 10 Jun 2002 08:17:01 +0100
- Subject: [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));