OSDN Git Service

resync
[pf3gnuchains/gcc-fork.git] / gcc / tree-sra.c
index 1510904..7abdd3d 100644 (file)
@@ -25,7 +25,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
-#include "errors.h"
 #include "ggc.h"
 #include "tree.h"
 
@@ -897,9 +896,7 @@ sra_walk_function (const struct sra_walk_fns *fns)
 
        /* If the statement has no virtual operands, then it doesn't
           make any structure references that we care about.  */
-       if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) == 0
-           && NUM_VUSES (VUSE_OPS (ann)) == 0
-           && NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) == 0)
+       if (ZERO_SSA_OPERANDS (stmt, (SSA_OP_VIRTUAL_DEFS | SSA_OP_VUSE)))
          continue;
 
        switch (TREE_CODE (stmt))
@@ -1097,7 +1094,7 @@ build_element_name (struct sra_elt *elt)
 {
   build_element_name_1 (elt);
   obstack_1grow (&sra_obstack, '\0');
-  return obstack_finish (&sra_obstack);
+  return XOBFINISH (&sra_obstack, char *);
 }
 
 /* Instantiate an element as an independent variable.  */
@@ -1116,15 +1113,21 @@ instantiate_element (struct sra_elt *elt)
   DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (base);
   DECL_ARTIFICIAL (var) = 1;
 
+  if (TREE_THIS_VOLATILE (elt->type))
+    {
+      TREE_THIS_VOLATILE (var) = 1;
+      TREE_SIDE_EFFECTS (var) = 1;
+    }
+
   if (DECL_NAME (base) && !DECL_IGNORED_P (base))
     {
       char *pretty_name = build_element_name (elt);
       DECL_NAME (var) = get_identifier (pretty_name);
       obstack_free (&sra_obstack, pretty_name);
 
-      DECL_DEBUG_EXPR (var) = generate_element_ref (elt);
+      SET_DECL_DEBUG_EXPR (var, generate_element_ref (elt));
       DECL_DEBUG_EXPR_IS_FROM (var) = 1;
-
+      
       DECL_IGNORED_P (var) = 0;
       TREE_NO_WARNING (var) = TREE_NO_WARNING (base);
     }
@@ -1293,6 +1296,12 @@ decide_block_copy (struct sra_elt *elt)
          fputc ('\n', dump_file);
        }
 
+      /* Disable scalarization of sub-elements */
+      for (c = elt->children; c; c = c->sibling)
+       {
+         c->cannot_scalarize = 1;
+         decide_block_copy (c);
+       }
       return false;
     }
 
@@ -1316,7 +1325,6 @@ decide_block_copy (struct sra_elt *elt)
       else if (host_integerp (size_tree, 1))
        {
          unsigned HOST_WIDE_INT full_size, inst_size = 0;
-         unsigned int inst_count;
          unsigned int max_size;
 
          /* If the sra-max-structure-size parameter is 0, then the
@@ -1340,7 +1348,7 @@ decide_block_copy (struct sra_elt *elt)
            use_block_copy = false;
          else
            {
-             inst_count = sum_instantiated_sizes (elt, &inst_size);
+             sum_instantiated_sizes (elt, &inst_size);
 
              if (inst_size * 100 >= full_size * SRA_FIELD_STRUCTURE_RATIO)
                use_block_copy = false;
@@ -1417,6 +1425,8 @@ decide_instantiations (void)
     }
   bitmap_clear (&done_head);
 
+  mark_set_for_renaming (sra_candidates);
+
   if (dump_file)
     fputc ('\n', dump_file);
 }
@@ -1428,21 +1438,39 @@ decide_instantiations (void)
    renaming. This becomes necessary when we modify all of a non-scalar.  */
 
 static void
-mark_all_v_defs (tree stmt)
+mark_all_v_defs_1 (tree stmt)
 {
   tree sym;
   ssa_op_iter iter;
 
-  get_stmt_operands (stmt);
+  update_stmt_if_modified (stmt);
 
   FOR_EACH_SSA_TREE_OPERAND (sym, stmt, iter, SSA_OP_ALL_VIRTUALS)
     {
       if (TREE_CODE (sym) == SSA_NAME)
        sym = SSA_NAME_VAR (sym);
-      bitmap_set_bit (vars_to_rename, var_ann (sym)->uid);
+      mark_sym_for_renaming (sym);
+    }
+}
+
+
+/* Mark all the variables in virtual operands in all the statements in
+   LIST for renaming.  */
+
+static void
+mark_all_v_defs (tree list)
+{
+  if (TREE_CODE (list) != STATEMENT_LIST)
+    mark_all_v_defs_1 (list);
+  else
+    {
+      tree_stmt_iterator i;
+      for (i = tsi_start (list); !tsi_end_p (i); tsi_next (&i))
+       mark_all_v_defs_1 (tsi_stmt (i));
     }
 }
 
+
 /* Build a single level component reference to ELT rooted at BASE.  */
 
 static tree
@@ -1634,10 +1662,31 @@ generate_element_init_1 (struct sra_elt *elt, tree init, tree *list_p)
     case CONSTRUCTOR:
       for (t = CONSTRUCTOR_ELTS (init); t ; t = TREE_CHAIN (t))
        {
-         sub = lookup_element (elt, TREE_PURPOSE (t), NULL, NO_INSERT);
-         if (sub == NULL)
-           continue;
-         result &= generate_element_init_1 (sub, TREE_VALUE (t), list_p);
+         tree purpose = TREE_PURPOSE (t);
+         tree value = TREE_VALUE (t);
+
+         if (TREE_CODE (purpose) == RANGE_EXPR)
+           {
+             tree lower = TREE_OPERAND (purpose, 0);
+             tree upper = TREE_OPERAND (purpose, 1);
+
+             while (1)
+               {
+                 sub = lookup_element (elt, lower, NULL, NO_INSERT);
+                 if (sub != NULL)
+                   result &= generate_element_init_1 (sub, value, list_p);
+                 if (tree_int_cst_equal (lower, upper))
+                   break;
+                 lower = int_const_binop (PLUS_EXPR, lower,
+                                          integer_one_node, true);
+               }
+           }
+         else
+           {
+             sub = lookup_element (elt, purpose, NULL, NO_INSERT);
+             if (sub != NULL)
+               result &= generate_element_init_1 (sub, value, list_p);
+           }
        }
       break;
 
@@ -1674,7 +1723,7 @@ generate_element_init (struct sra_elt *elt, tree init, tree *list_p)
 
       new = num_referenced_vars;
       for (j = old; j < new; ++j)
-       bitmap_set_bit (vars_to_rename, j);
+       mark_sym_for_renaming (referenced_var (j));
     }
 
   return ret;
@@ -1768,7 +1817,7 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi,
       if (is_output)
        mark_all_v_defs (stmt);
       *expr_p = elt->replacement;
-      modify_stmt (stmt);
+      update_stmt (stmt);
     }
   else
     {
@@ -1788,7 +1837,7 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi,
       generate_copy_inout (elt, is_output, generate_element_ref (elt), &list);
       if (list == NULL)
        return;
-      mark_all_v_defs (expr_first (list));
+      mark_all_v_defs (list);
       if (is_output)
        sra_insert_after (bsi, list);
       else
@@ -1816,7 +1865,7 @@ scalarize_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
 
       TREE_OPERAND (stmt, 0) = lhs_elt->replacement;
       TREE_OPERAND (stmt, 1) = rhs_elt->replacement;
-      modify_stmt (stmt);
+      update_stmt (stmt);
     }
   else if (lhs_elt->use_block_copy || rhs_elt->use_block_copy)
     {
@@ -1833,7 +1882,7 @@ scalarize_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
                           generate_element_ref (rhs_elt), &list);
       if (list)
        {
-         mark_all_v_defs (expr_first (list));
+         mark_all_v_defs (list);
          sra_insert_before (bsi, list);
        }
 
@@ -1841,7 +1890,10 @@ scalarize_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
       generate_copy_inout (lhs_elt, true,
                           generate_element_ref (lhs_elt), &list);
       if (list)
-       sra_insert_after (bsi, list);
+       {
+         mark_all_v_defs (list);
+         sra_insert_after (bsi, list);
+       }
     }
   else
     {
@@ -1855,6 +1907,7 @@ scalarize_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
       list = NULL;
       generate_element_copy (lhs_elt, rhs_elt, &list);
       gcc_assert (list);
+      mark_all_v_defs (list);
       sra_replace (bsi, list);
     }
 }
@@ -1904,7 +1957,7 @@ scalarize_init (struct sra_elt *lhs_elt, tree rhs, block_stmt_iterator *bsi)
         exposes constants to later optimizations.  */
       if (list)
        {
-         mark_all_v_defs (expr_first (list));
+         mark_all_v_defs (list);
          sra_insert_after (bsi, list);
        }
     }
@@ -1914,6 +1967,7 @@ scalarize_init (struct sra_elt *lhs_elt, tree rhs, block_stmt_iterator *bsi)
         replaces the original structure assignment.  */
       gcc_assert (list);
       mark_all_v_defs (bsi_stmt (*bsi));
+      mark_all_v_defs (list);
       sra_replace (bsi, list);
     }
 }
@@ -1964,6 +2018,7 @@ scalarize_ldst (struct sra_elt *elt, tree other,
 
       mark_all_v_defs (stmt);
       generate_copy_inout (elt, is_output, other, &list);
+      mark_all_v_defs (list);
       gcc_assert (list);
 
       /* Preserve EH semantics.  */
@@ -2019,7 +2074,10 @@ scalarize_parms (void)
     }
 
   if (list)
-    insert_edge_copies (list, ENTRY_BLOCK_PTR);
+    {
+      insert_edge_copies (list, ENTRY_BLOCK_PTR);
+      mark_all_v_defs (list);
+    }
 }
 
 /* Entry point to phase 4.  Update the function to match replacements.  */
@@ -2122,7 +2180,7 @@ struct tree_opt_pass pass_sra =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func | TODO_rename_vars
+  TODO_dump_func | TODO_update_ssa
     | TODO_ggc_collect | TODO_verify_ssa,  /* todo_flags_finish */
   0                                    /* letter */
 };