OSDN Git Service

2009-04-03 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / tree-sra.c
index 8cada85..f0e4bd0 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.  */
@@ -1008,6 +1004,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 +1053,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 +1708,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 +1721,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 +2003,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 +2012,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.  */
@@ -2354,14 +2321,17 @@ sra_build_bf_assignment (tree dst, tree src)
       tmp = var;
       if (!is_gimple_variable (tmp))
        tmp = unshare_expr (var);
+      else
+       TREE_NO_WARNING (var) = true;
 
       tmp2 = make_rename_temp (utype, "SR");
 
       if (INTEGRAL_TYPE_P (TREE_TYPE (var)))
-       stmt = gimple_build_assign (tmp2, fold_convert (utype, tmp));
+       tmp = fold_convert (utype, tmp);
       else
-       stmt = gimple_build_assign (tmp2, fold_build1 (VIEW_CONVERT_EXPR,
-                                                      utype, tmp));
+       tmp = fold_build1 (VIEW_CONVERT_EXPR, utype, tmp);
+
+      stmt = gimple_build_assign (tmp2, tmp);
       gimple_seq_add_stmt (&seq, stmt);
     }
   else
@@ -2867,6 +2837,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));
@@ -3142,7 +3113,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);
     }
@@ -3223,12 +3194,20 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, gimple_stmt_iterator *gsi,
       if (!elt->use_block_copy)
        {
          tree type = TREE_TYPE (bfexpr);
-         tree var, vpos;
+         tree var = make_rename_temp (type, "SR"), tmp, vpos;
+         gimple st = NULL;
 
-         if (!TYPE_UNSIGNED (type))
-           type = unsigned_type_for (type);
+         gimple_assign_set_rhs1 (stmt, var);
+         update = true;
 
-         var = make_rename_temp (type, "SR");
+         if (!TYPE_UNSIGNED (type))
+           {
+             type = unsigned_type_for (type);
+             tmp = make_rename_temp (type, "SR");
+             st = gimple_build_assign (var,
+                                       fold_convert (TREE_TYPE (var), tmp));
+             var = tmp;
+           }
 
          gimple_seq_add_stmt (&seq,
                                gimple_build_assign
@@ -3245,8 +3224,8 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, gimple_stmt_iterator *gsi,
          sra_explode_bitfield_assignment
            (var, vpos, true, &seq, blen, bpos, elt);
 
-         gimple_assign_set_rhs1 (stmt, var);
-         update = true;
+         if (st)
+           gimple_seq_add_stmt (&seq, st);
        }
       else
        sra_sync_for_bitfield_assignment
@@ -3354,7 +3333,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);
@@ -3421,7 +3400,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);
     }
@@ -3472,7 +3451,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);
@@ -3633,7 +3612,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);
@@ -3646,8 +3624,6 @@ tree_sra (void)
       scan_function ();
       decide_instantiations ();
       scalarize_function ();
-      if (!bitmap_empty_p (sra_candidates))
-       todoflags |= TODO_rebuild_alias;
     }
 
   /* Free allocated memory.  */
@@ -3658,7 +3634,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
@@ -3670,7 +3646,7 @@ tree_sra_early (void)
   ret = tree_sra ();
   early_sra = false;
 
-  return ret & ~TODO_rebuild_alias;
+  return ret;
 }
 
 static bool
@@ -3715,7 +3691,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