OSDN Git Service

* auto-inc-dec.c: Fix pass description, remove apparent
[pf3gnuchains/gcc-fork.git] / gcc / tree-sra.c
index 01c0e12..626a253 100644 (file)
@@ -1,8 +1,8 @@
 /* Scalar Replacement of Aggregates (SRA) converts some structure
    references into scalar references, exposing them to the scalar
    optimizers.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
-     Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Free Software Foundation, Inc.
    Contributed by Diego Novillo <dnovillo@redhat.com>
 
 This file is part of GCC.
@@ -78,9 +78,6 @@ along with GCC; see the file COPYING3.  If not see
 /* True if this is the "early" pass, before inlining.  */
 static bool early_sra;
 
-/* The set of todo flags to return from tree_sra.  */
-static unsigned int todoflags;
-
 /* The set of aggregate variables that are candidates for scalarization.  */
 static bitmap sra_candidates;
 
@@ -210,7 +207,6 @@ extern void debug_sra_elt_name (struct sra_elt *);
 static tree generate_element_ref (struct sra_elt *);
 static gimple_seq sra_build_assignment (tree dst, tree src);
 static void mark_all_v_defs_seq (gimple_seq);
-static void mark_all_v_defs_stmt (gimple);
 
 \f
 /* Return true if DECL is an SRA candidate.  */
@@ -274,6 +270,10 @@ sra_type_can_be_decomposed_p (tree type)
                      != TYPE_PRECISION (TREE_TYPE (t))))
                goto fail;
 
+             /* And volatile fields.  */
+             if (TREE_THIS_VOLATILE (t))
+               goto fail;
+
              saw_one_field = true;
            }
 
@@ -1008,6 +1008,7 @@ sra_walk_gimple_assign (gimple stmt, gimple_stmt_iterator *gsi,
         we'd been passed the constructor directly.  Invoke INIT.  */
       else if (TREE_CODE (rhs) == VAR_DECL
               && TREE_STATIC (rhs)
+              && !DECL_EXTERNAL (rhs)
               && TREE_READONLY (rhs)
               && targetm.binds_local_p (rhs))
        fns->init (lhs_elt, DECL_INITIAL (rhs), gsi);
@@ -1056,11 +1057,10 @@ sra_walk_function (const struct sra_walk_fns *fns)
        ni = si;
        gsi_next (&ni);
 
-       /* If the statement has no virtual operands, then it doesn't
+       /* If the statement does not reference memory, then it doesn't
           make any structure references that we care about.  */
-       if (gimple_aliases_computed_p (cfun)
-           && ZERO_SSA_OPERANDS (stmt, (SSA_OP_VIRTUAL_DEFS | SSA_OP_VUSE)))
-             continue;
+       if (!gimple_references_memory_p (stmt))
+         continue;
 
        switch (gimple_code (stmt))
          {
@@ -1712,16 +1712,6 @@ try_instantiate_multiple_fields (struct sra_elt *elt, tree f)
   gcc_assert (block && block->is_scalar);
 
   var = block->replacement;
-
-  if ((bit & ~alchk)
-      || (HOST_WIDE_INT)size != tree_low_cst (DECL_SIZE (var), 1))
-    {
-      block->replacement = fold_build3 (BIT_FIELD_REF,
-                                       TREE_TYPE (block->element), var,
-                                       bitsize_int (size),
-                                       bitsize_int (bit & ~alchk));
-    }
-
   block->in_bitfld_block = 2;
 
   /* Add the member fields to the group, such that they access
@@ -1735,12 +1725,14 @@ try_instantiate_multiple_fields (struct sra_elt *elt, tree f)
       gcc_assert (fld && fld->is_scalar && !fld->replacement);
 
       fld->replacement = fold_build3 (BIT_FIELD_REF, field_type, var,
-                                     DECL_SIZE (f),
+                                     bitsize_int (TYPE_PRECISION (field_type)),
                                      bitsize_int
                                      ((TREE_INT_CST_LOW (DECL_FIELD_OFFSET (f))
                                        * BITS_PER_UNIT
                                        + (TREE_INT_CST_LOW
-                                          (DECL_FIELD_BIT_OFFSET (f))))
+                                          (DECL_FIELD_BIT_OFFSET (f)))
+                                       - (TREE_INT_CST_LOW
+                                          (TREE_OPERAND (block->element, 2))))
                                       & ~alchk));
       fld->in_bitfld_block = 1;
     }
@@ -2015,27 +2007,6 @@ decide_instantiations (void)
 \f
 /* Phase Four: Update the function to match the replacements created.  */
 
-/* Mark all the variables in VDEF/VUSE operators for STMT for
-   renaming. This becomes necessary when we modify all of a
-   non-scalar.  */
-
-static void
-mark_all_v_defs_stmt (gimple stmt)
-{
-  tree sym;
-  ssa_op_iter iter;
-
-  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);
-      mark_sym_for_renaming (sym);
-    }
-}
-
-
 /* Mark all the variables in virtual operands in all the statements in
    LIST for renaming.  */
 
@@ -2045,7 +2016,7 @@ mark_all_v_defs_seq (gimple_seq seq)
   gimple_stmt_iterator gsi;
 
   for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
-    mark_all_v_defs_stmt (gsi_stmt (gsi));
+    update_stmt_if_modified (gsi_stmt (gsi));
 }
 
 /* Mark every replacement under ELT with TREE_NO_WARNING.  */
@@ -2239,14 +2210,16 @@ sra_build_assignment (tree dst, tree src)
        var = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (dst), var);
 
       push_gimplify_context (&gctx);
-      gctx.into_ssa = true;
       gctx.allow_rhs_cond_expr = true;
 
       gimplify_assign (dst, var, &seq);
 
       if (gimple_referenced_vars (cfun))
        for (var = gctx.temps; var; var = TREE_CHAIN (var))
-         add_referenced_var (var);
+         {
+           add_referenced_var (var);
+           mark_sym_for_renaming (var);
+         }
       pop_gimplify_context (NULL);
 
       return seq;
@@ -2870,6 +2843,7 @@ static void
 sra_replace (gimple_stmt_iterator *gsi, gimple_seq seq)
 {
   sra_insert_before (gsi, seq);
+  unlink_stmt_vdef (gsi_stmt (*gsi));
   gsi_remove (gsi, false);
   if (gsi_end_p (*gsi))
     *gsi = gsi_last (gsi_seq (*gsi));
@@ -3145,7 +3119,7 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, gimple_stmt_iterator *gsi,
          replacement = tmp;
        }
       if (is_output)
-         mark_all_v_defs_stmt (stmt);
+         update_stmt_if_modified (stmt);
       *expr_p = REPLDUP (replacement);
       update_stmt (stmt);
     }
@@ -3365,7 +3339,7 @@ scalarize_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
         original block copy statement.  */
 
       stmt = gsi_stmt (*gsi);
-      mark_all_v_defs_stmt (stmt);
+      update_stmt_if_modified (stmt);
 
       seq = NULL;
       generate_element_copy (lhs_elt, rhs_elt, &seq);
@@ -3432,7 +3406,7 @@ scalarize_init (struct sra_elt *lhs_elt, tree rhs, gimple_stmt_iterator *gsi)
       /* The LHS is fully instantiated.  The list of initializations
         replaces the original structure assignment.  */
       gcc_assert (seq);
-      mark_all_v_defs_stmt (gsi_stmt (*gsi));
+      update_stmt_if_modified (gsi_stmt (*gsi));
       mark_all_v_defs_seq (seq);
       sra_replace (gsi, seq);
     }
@@ -3483,7 +3457,7 @@ scalarize_ldst (struct sra_elt *elt, tree other,
       gimple_seq seq = NULL;
       gimple stmt = gsi_stmt (*gsi);
 
-      mark_all_v_defs_stmt (stmt);
+      update_stmt_if_modified (stmt);
       generate_copy_inout (elt, is_output, other, &seq);
       gcc_assert (seq);
       mark_all_v_defs_seq (seq);
@@ -3644,7 +3618,6 @@ static unsigned int
 tree_sra (void)
 {
   /* Initialize local variables.  */
-  todoflags = 0;
   gcc_obstack_init (&sra_obstack);
   sra_candidates = BITMAP_ALLOC (NULL);
   needs_copy_in = BITMAP_ALLOC (NULL);
@@ -3657,8 +3630,6 @@ tree_sra (void)
       scan_function ();
       decide_instantiations ();
       scalarize_function ();
-      if (!bitmap_empty_p (sra_candidates))
-       todoflags |= TODO_rebuild_alias;
     }
 
   /* Free allocated memory.  */
@@ -3669,7 +3640,7 @@ tree_sra (void)
   BITMAP_FREE (sra_type_decomp_cache);
   BITMAP_FREE (sra_type_inst_cache);
   obstack_free (&sra_obstack, NULL);
-  return todoflags;
+  return 0;
 }
 
 static unsigned int
@@ -3681,7 +3652,7 @@ tree_sra_early (void)
   ret = tree_sra ();
   early_sra = false;
 
-  return ret & ~TODO_rebuild_alias;
+  return ret;
 }
 
 static bool
@@ -3726,7 +3697,7 @@ struct gimple_opt_pass pass_sra =
   PROP_cfg | PROP_ssa,                 /* properties_required */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
-  0,                                   /* todo_flags_start */
+  TODO_update_address_taken,           /* todo_flags_start */
   TODO_dump_func
   | TODO_update_ssa
   | TODO_ggc_collect