This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
fix pr16422
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 11 Jul 2004 10:35:56 -0700
- Subject: fix pr16422
PR tree-opt/16422
* tree-sra.c (generate_one_element_init): New.
(generate_element_init): Use it.
(scalarize_init): Push/pop gimplify context around it.
(find_new_referenced_vars_1, find_new_referenced_vars): New.
* gimplify.c (gimplify_expr): Allow SSA_NAME.
Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v
retrieving revision 2.43
diff -u -p -r2.43 gimplify.c
--- gimplify.c 8 Jul 2004 07:45:43 -0000 2.43
+++ gimplify.c 11 Jul 2004 17:24:42 -0000
@@ -3816,6 +3816,11 @@ gimplify_expr (tree *expr_p, tree *pre_p
ret = GS_ALL_DONE;
break;
+ case SSA_NAME:
+ /* Allow callbacks into the gimplifier during optimization. */
+ ret = GS_ALL_DONE;
+ break;
+
default:
/* If this is a comparison of objects of aggregate type, handle
it specially (by converting to a call to memcmp). It would be
Index: tree-sra.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-sra.c,v
retrieving revision 2.18
diff -u -p -r2.18 tree-sra.c
--- tree-sra.c 8 Jul 2004 16:16:41 -0000 2.18
+++ tree-sra.c 11 Jul 2004 17:24:42 -0000
@@ -1513,6 +1556,55 @@ generate_element_zero (struct sra_elt *e
}
}
+/* Find all variables within the gimplified statement that were not previously
+ visible to the function and add them to the referenced variables list. */
+
+static tree
+find_new_referenced_vars_1 (tree *tp, int *walk_subtrees,
+ void *data ATTRIBUTE_UNUSED)
+{
+ tree t = *tp;
+
+ if (TREE_CODE (t) == VAR_DECL && !var_ann (t))
+ add_referenced_tmp_var (t);
+
+ if (DECL_P (t) || TYPE_P (t))
+ *walk_subtrees = 0;
+
+ return NULL;
+}
+
+static inline void
+find_new_referenced_vars (tree *stmt_p)
+{
+ walk_tree (stmt_p, find_new_referenced_vars_1, NULL, NULL);
+}
+
+/* Generate an assignment VAR = INIT, where INIT may need gimplification.
+ Add the result to *LIST_P. */
+
+static void
+generate_one_element_init (tree var, tree init, tree *list_p)
+{
+ tree stmt;
+
+ /* The replacement can be almost arbitrarily complex. Gimplify. */
+ stmt = build (MODIFY_EXPR, void_type_node, var, init);
+ gimplify_stmt (&stmt);
+
+ /* The replacement can expose previously unreferenced variables. */
+ if (TREE_CODE (stmt) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator i;
+ for (i = tsi_start (stmt); !tsi_end_p (i); tsi_next (&i))
+ find_new_referenced_vars (tsi_stmt_ptr (i));
+ }
+ else
+ find_new_referenced_vars (&stmt);
+
+ append_to_statement_list (stmt, list_p);
+}
+
/* Generate a set of assignment statements in *LIST_P to set all instantiated
elements under ELT with the contents of the initializer INIT. In addition,
mark all assigned elements VISITED; this allows easy coordination with
@@ -1536,8 +1628,7 @@ generate_element_init (struct sra_elt *e
{
if (elt->replacement)
{
- t = build (MODIFY_EXPR, void_type_node, elt->replacement, init);
- append_to_statement_list (t, list_p);
+ generate_one_element_init (elt->replacement, init, list_p);
elt->visited = true;
}
return result;
@@ -1774,7 +1865,11 @@ scalarize_init (struct sra_elt *lhs_elt,
/* Generate initialization statements for all members extant in the RHS. */
if (rhs)
- result = generate_element_init (lhs_elt, rhs, &list);
+ {
+ push_gimplify_context ();
+ result = generate_element_init (lhs_elt, rhs, &list);
+ pop_gimplify_context (NULL);
+ }
/* CONSTRUCTOR is defined such that any member not mentioned is assigned
a zero value. Initialize the rest of the instantiated elements. */