re PR tree-optimization/16422 (gcc.c-torture/execute/980223.c fails)
authorRichard Henderson <rth@redhat.com>
Sun, 11 Jul 2004 17:33:02 +0000 (10:33 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Sun, 11 Jul 2004 17:33:02 +0000 (10:33 -0700)
        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.

From-SVN: r84523

gcc/ChangeLog
gcc/gimplify.c
gcc/tree-sra.c

index d52f351748702339eba72beba952355d40b218f4..3ab7cedeadb38b26d9c984a173e444cd89a5e8c3 100644 (file)
@@ -1,3 +1,12 @@
+2004-07-11  Richard Henderson  <rth@redhat.com>
+
+       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.
+
 2004-07-11  Roger Sayle  <roger@eyesopen.com>
 
        * rtlanal.c (insn_rtx_cost): New function, moved and renamed from
index f60ef89bc48f9b3e2b9d46d4e14d1a107b1ff539..5b8762067694fc3cf924caf14640dccbfb283399 100644 (file)
@@ -3816,6 +3816,11 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_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 6769407a71998f347e68529f59f07ff65a8420a0..1a4e5586c4f73ec9ada18af9ad4f3bac9bf03b42 100644 (file)
@@ -1513,6 +1513,55 @@ generate_element_zero (struct sra_elt *elt, tree *list_p)
     }
 }
 
+/* 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 +1585,7 @@ generate_element_init (struct sra_elt *elt, tree init, tree *list_p)
     {
       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 +1822,11 @@ scalarize_init (struct sra_elt *lhs_elt, tree rhs, block_stmt_iterator *bsi)
 
   /* 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.  */