This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH Re: [ast-optimizer-branch] gcc.dg/struct-alias-1.cfailure
Here's the patch I'm applying.
2002-06-12 Jason Merrill <jason@redhat.com>
* tree-simple.c (is_simple_compound_lval): New fn.
(is_simple_varname): Call it instead of is_simple_arrayref and
is_simple_compref.
(is_simple_arrayref, is_simple_compref): Comment out.
* tree-simple.h: Declare it.
* c-simplify.c (simplify_expr_either): Comment out.
(simplify_compound_lval): New fn.
(simplify_array_ref, simplify_component_ref): Just call it.
*** c-simplify.c.~1~ Wed Jun 12 11:45:27 2002
--- c-simplify.c Wed Jun 12 16:08:27 2002
*************** static void simplify_expr_common PAR
*** 66,74 ****
int (*) PARAMS ((tree)), tree, int));
static void simplify_expr PARAMS ((tree *, tree *, tree *,
int (*) PARAMS ((tree)), tree));
- static void simplify_expr_either PARAMS ((tree *, tree *, tree *,
- int (*) PARAMS ((tree)), tree));
static void simplify_array_ref PARAMS ((tree *, tree *, tree *, tree));
static void simplify_self_mod_expr PARAMS ((tree *, tree *, tree *, tree));
static void simplify_component_ref PARAMS ((tree *, tree *, tree *, tree));
static void simplify_call_expr PARAMS ((tree *, tree *, tree *, tree));
--- 66,73 ----
int (*) PARAMS ((tree)), tree, int));
static void simplify_expr PARAMS ((tree *, tree *, tree *,
int (*) PARAMS ((tree)), tree));
static void simplify_array_ref PARAMS ((tree *, tree *, tree *, tree));
+ static void simplify_compound_lval PARAMS ((tree *, tree *, tree *, tree));
static void simplify_self_mod_expr PARAMS ((tree *, tree *, tree *, tree));
static void simplify_component_ref PARAMS ((tree *, tree *, tree *, tree));
static void simplify_call_expr PARAMS ((tree *, tree *, tree *, tree));
*************** simplify_lvalue_expr (expr_p, pre_p, pos
*** 1113,1118 ****
--- 1112,1120 ----
simplify_expr_common (expr_p, pre_p, post_p, simple_test_f, stmt, 2);
}
+ #if 0
+ static void simplify_expr_either PARAMS ((tree *, tree *, tree *,
+ int (*) PARAMS ((tree)), tree));
static void
simplify_expr_either (expr_p, pre_p, post_p, simple_test_f, stmt)
tree *expr_p;
*************** simplify_expr_either (expr_p, pre_p, pos
*** 1123,1128 ****
--- 1125,1131 ----
{
simplify_expr_common (expr_p, pre_p, post_p, simple_test_f, stmt, 1|2);
}
+ #endif
/** Build an expression for the address of T. Folds away INDIRECT_REF to
*************** simplify_array_ref (expr_p, pre_p, post_
*** 1169,1174 ****
--- 1172,1182 ----
tree *post_p;
tree stmt;
{
+ #if 1
+ /* Handle array and member refs together for now. When alias analysis
+ improves, we may want to go back to handling them separately. */
+ simplify_compound_lval (expr_p, pre_p, post_p, stmt);
+ #else
tree *p;
varray_type dim_stack;
*************** simplify_array_ref (expr_p, pre_p, post_
*** 1196,1203 ****
--- 1204,1269 ----
tree *dim_p = (tree *)VARRAY_TOP_GENERIC_PTR (dim_stack);
simplify_expr (dim_p, pre_p, post_p, is_simple_val, stmt);
}
+
+ VARRAY_FREE (dim_stack);
+ #endif
}
+ /* Simplify the COMPONENT_REF or ARRAY_REF node pointed by EXPR_P.
+
+ PRE_P points to the list where side effects that must happen before
+ *EXPR_P should be stored.
+
+ POST_P points to the list where side effects that must happen after
+ *EXPR_P should be stored.
+
+ 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_compound_lval (expr_p, pre_p, post_p, stmt)
+ tree *expr_p;
+ tree *pre_p;
+ tree *post_p;
+ tree stmt;
+ {
+ tree *p;
+ enum tree_code code;
+ varray_type dim_stack;
+
+ if (TREE_CODE (*expr_p) != ARRAY_REF && TREE_CODE (*expr_p) != COMPONENT_REF)
+ abort ();
+
+ /* Create a stack with all the array dimensions so that they can be
+ simplified from left to right (to match user expectations). */
+ VARRAY_GENERIC_PTR_INIT (dim_stack, 10, "dim_stack");
+
+ for (p = expr_p;
+ TREE_CODE (*p) == ARRAY_REF || TREE_CODE (*p) == COMPONENT_REF;
+ p = &TREE_OPERAND (*p, 0))
+ {
+ code = TREE_CODE (*p);
+ if (code == ARRAY_REF)
+ VARRAY_PUSH_GENERIC_PTR (dim_stack, (PTR) &TREE_OPERAND (*p, 1));
+ }
+
+ /* Now 'p' points to the first bit that isn't an ARRAY_REF or
+ COMPONENT_REF, 'code' is the TREE_CODE of the last bit that was, 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. */
+ simplify_expr_common (p, pre_p, post_p, is_simple_min_lval, stmt,
+ code == COMPONENT_REF ? 3 : 2);
+
+ for (; VARRAY_ACTIVE_SIZE (dim_stack) > 0; VARRAY_POP (dim_stack))
+ {
+ tree *dim_p = (tree *)VARRAY_TOP_GENERIC_PTR (dim_stack);
+ simplify_expr (dim_p, pre_p, post_p, is_simple_val, stmt);
+ }
+ }
/** Simplify the self modifying expression pointed by EXPR_P (++, --, +=, -=).
*************** simplify_component_ref (expr_p, pre_p, p
*** 1281,1286 ****
--- 1347,1357 ----
tree *post_p;
tree stmt;
{
+ #if 1
+ /* Handle array and member refs together for now. When alias analysis
+ improves, we may want to go back to handling them separately. */
+ simplify_compound_lval (expr_p, pre_p, post_p, stmt);
+ #else
tree *p;
if (TREE_CODE (*expr_p) != COMPONENT_REF)
*************** simplify_component_ref (expr_p, pre_p, p
*** 1293,1298 ****
--- 1364,1370 ----
/* 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);
+ #endif
}
*** tree-simple.c.~1~ Wed Jun 12 11:45:27 2002
--- tree-simple.c Wed Jun 12 13:14:07 2002
*************** Boston, MA 02111-1307, USA. */
*** 199,206 ****
---------------------------------------------------------------------- */
- static bool is_union_based_ref PARAMS ((tree));
-
/* Validation of SIMPLE statements. */
/** Return nonzero if T is a statement that complies with the SIMPLE
--- 199,204 ----
*************** is_simple_varname (t)
*** 661,669 ****
if (t == NULL_TREE)
return 1;
! return (is_simple_id (t) || is_simple_arrayref (t) || is_simple_compref (t));
}
/** Return nonzero if T is a constant. */
--- 659,710 ----
if (t == NULL_TREE)
return 1;
! return (is_simple_id (t)
! #if 0
! || is_simple_arrayref (t) || is_simple_compref (t)
! #else
! || is_simple_compound_lval (t)
! #endif
! );
}
+ /* Returns nonzero if T is an array or member reference of the form:
+
+ compound_lval
+ : min_lval '[' val ']'
+ | min_lval '.' ID
+ | compound_lval '[' val ']'
+ | compound_lval '.' ID
+
+ This is not part of the original SIMPLE definition, which separates
+ array and member references, but it seems reasonable to handle them
+ together. Also, this way we don't run into problems with union
+ aliasing; gcc requires that for accesses through a union to alias, the
+ union reference must be explicit, which was not always the case when we
+ were splitting up array and member refs. */
+
+ int
+ is_simple_compound_lval (t)
+ tree t;
+ {
+ /* 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 && TREE_CODE (t) != COMPONENT_REF)
+ return 0;
+
+ for (; TREE_CODE (t) == COMPONENT_REF || TREE_CODE (t) == ARRAY_REF;
+ t = TREE_OPERAND (t, 0))
+ {
+ if (TREE_CODE (t) == ARRAY_REF
+ && !is_simple_val (TREE_OPERAND (t, 1)))
+ return 0;
+ }
+
+ return is_simple_min_lval (t);
+ }
/** Return nonzero if T is a constant. */
*************** is_simple_min_lval (t)
*** 753,784 ****
return (is_simple_id (t)
|| (TREE_CODE (t) == INDIRECT_REF
! && is_simple_id (TREE_OPERAND (t, 0)))
! || is_union_based_ref (t));
! }
!
!
! /** 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;
}
!
/** Return nonzero if T is an array reference of the form:
arrayref
--- 794,803 ----
return (is_simple_id (t)
|| (TREE_CODE (t) == INDIRECT_REF
! && is_simple_id (TREE_OPERAND (t, 0))));
}
! #if 0
/** Return nonzero if T is an array reference of the form:
arrayref
*************** is_simple_compref (t)
*** 839,845 ****
return is_simple_min_lval (t);
}
!
/** Return nonzero if T is a typecast operation of the form
'(' cast ')' varname. */
--- 858,864 ----
return is_simple_min_lval (t);
}
! #endif
/** Return nonzero if T is a typecast operation of the form
'(' cast ')' varname. */
*** tree-simple.h.~1~ Wed Jun 12 11:45:27 2002
--- tree-simple.h Tue Jun 11 20:44:00 2002
*************** int is_simple_id P
*** 53,58 ****
--- 53,59 ----
int is_simple_varname PARAMS ((tree));
int is_simple_val PARAMS ((tree));
int is_simple_min_lval PARAMS ((tree));
+ int is_simple_compound_lval PARAMS ((tree));
int is_simple_arrayref PARAMS ((tree));
int is_simple_compref PARAMS ((tree));
int is_simple_cast PARAMS ((tree));