OSDN Git Service

2005-11-03 Andrew Pinski <pinskia@physics.uc.edu>
[pf3gnuchains/gcc-fork.git] / gcc / tree-sra.c
index 973f84c..940f7a9 100644 (file)
@@ -18,8 +18,8 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -151,7 +151,7 @@ static tree generate_element_ref (struct sra_elt *);
 static bool
 is_sra_candidate_decl (tree decl)
 {
-  return DECL_P (decl) && bitmap_bit_p (sra_candidates, var_ann (decl)->uid);
+  return DECL_P (decl) && bitmap_bit_p (sra_candidates, DECL_UID (decl));
 }
 
 /* Return true if TYPE is a scalar type.  */
@@ -172,8 +172,8 @@ is_sra_scalar_type (tree type)
    instantiated, just that if we decide to break up the type into
    separate pieces that it can be done.  */
 
-static bool
-type_can_be_decomposed_p (tree type)
+bool
+sra_type_can_be_decomposed_p (tree type)
 {
   unsigned int cache = TYPE_UID (TYPE_MAIN_VARIANT (type)) * 2;
   tree t;
@@ -275,7 +275,7 @@ decl_can_be_decomposed_p (tree var)
     }
 
   /* We must be able to decompose the variable's type.  */
-  if (!type_can_be_decomposed_p (TREE_TYPE (var)))
+  if (!sra_type_can_be_decomposed_p (TREE_TYPE (var)))
     {
       if (dump_file && (dump_flags & TDF_DETAILS))
        {
@@ -296,7 +296,7 @@ type_can_instantiate_all_elements (tree type)
 {
   if (is_sra_scalar_type (type))
     return true;
-  if (!type_can_be_decomposed_p (type))
+  if (!sra_type_can_be_decomposed_p (type))
     return false;
 
   switch (TREE_CODE (type))
@@ -493,7 +493,7 @@ lookup_element (struct sra_elt *parent, tree child, tree type,
       if (TREE_CODE (child) == PARM_DECL)
        {
          elt->n_copies = 1;
-         bitmap_set_bit (needs_copy_in, var_ann (child)->uid);
+         bitmap_set_bit (needs_copy_in, DECL_UID (child));
        }
     }
 
@@ -724,7 +724,7 @@ sra_walk_expr (tree *expr_p, block_stmt_iterator *bsi, bool is_output,
        goto use_all;
 
       case ARRAY_RANGE_REF:
-       /* Similarly, an subrange reference is used to modify indexing.  Which
+       /* Similarly, a subrange reference is used to modify indexing.  Which
           means that the canonical element names that we have won't work.  */
        goto use_all;
 
@@ -940,15 +940,15 @@ sra_walk_function (const struct sra_walk_fns *fns)
 static bool
 find_candidates_for_sra (void)
 {
-  size_t i;
   bool any_set = false;
+  tree var;
+  referenced_var_iterator rvi;
 
-  for (i = 0; i < num_referenced_vars; i++)
+  FOR_EACH_REFERENCED_VAR (var, rvi)
     {
-      tree var = referenced_var (i);
       if (decl_can_be_decomposed_p (var))
         {
-          bitmap_set_bit (sra_candidates, var_ann (var)->uid);
+          bitmap_set_bit (sra_candidates, DECL_UID (var));
           any_set = true;
         }
     }
@@ -1094,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.  */
@@ -1325,7 +1325,7 @@ 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 max_size;
+         unsigned int max_size, max_count, inst_count, full_count;
 
          /* If the sra-max-structure-size parameter is 0, then the
             user has not overridden the parameter and we can choose a
@@ -1333,8 +1333,13 @@ decide_block_copy (struct sra_elt *elt)
          max_size = SRA_MAX_STRUCTURE_SIZE
            ? SRA_MAX_STRUCTURE_SIZE
            : MOVE_RATIO * UNITS_PER_WORD;
+         max_count = SRA_MAX_STRUCTURE_COUNT
+           ? SRA_MAX_STRUCTURE_COUNT
+           : MOVE_RATIO;
 
          full_size = tree_low_cst (size_tree, 1);
+         full_count = count_type_elements (elt->type, false);
+         inst_count = sum_instantiated_sizes (elt, &inst_size);
 
          /* ??? What to do here.  If there are two fields, and we've only
             instantiated one, then instantiating the other is clearly a win.
@@ -1344,15 +1349,12 @@ decide_block_copy (struct sra_elt *elt)
          /* If the structure is small, and we've made copies, go ahead
             and instantiate, hoping that the copies will go away.  */
          if (full_size <= max_size
+             && (full_count - inst_count) <= max_count
              && elt->n_copies > elt->n_uses)
            use_block_copy = false;
-         else
-           {
-             sum_instantiated_sizes (elt, &inst_size);
-
-             if (inst_size * 100 >= full_size * SRA_FIELD_STRUCTURE_RATIO)
-               use_block_copy = false;
-           }
+         else if (inst_count * 100 >= full_count * SRA_FIELD_STRUCTURE_RATIO
+                  && inst_size * 100 >= full_size * SRA_FIELD_STRUCTURE_RATIO)
+           use_block_copy = false;
 
          /* In order to avoid block copy, we have to be able to instantiate
             all elements of the type.  See if this is possible.  */
@@ -1526,7 +1528,22 @@ generate_copy_inout (struct sra_elt *elt, bool copy_out, tree expr,
   struct sra_elt *c;
   tree t;
 
-  if (elt->replacement)
+  if (!copy_out && TREE_CODE (expr) == SSA_NAME
+      && TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
+    {
+      tree r, i;
+
+      c = lookup_element (elt, integer_zero_node, NULL, NO_INSERT);
+      r = c->replacement;
+      c = lookup_element (elt, integer_one_node, NULL, NO_INSERT);
+      i = c->replacement;
+
+      t = build (COMPLEX_EXPR, elt->type, r, i);
+      t = build (MODIFY_EXPR, void_type_node, expr, t);
+      SSA_NAME_DEF_STMT (expr) = t;
+      append_to_statement_list (t, list_p);
+    }
+  else if (elt->replacement)
     {
       if (copy_out)
        t = build (MODIFY_EXPR, void_type_node, elt->replacement, expr);
@@ -1627,6 +1644,8 @@ generate_element_init_1 (struct sra_elt *elt, tree init, tree *list_p)
   enum tree_code init_code;
   struct sra_elt *sub;
   tree t;
+  unsigned HOST_WIDE_INT idx;
+  tree value, purpose;
 
   /* We can be passed DECL_INITIAL of a static variable.  It might have a
      conversion, which we strip off here.  */
@@ -1660,11 +1679,8 @@ generate_element_init_1 (struct sra_elt *elt, tree init, tree *list_p)
       break;
 
     case CONSTRUCTOR:
-      for (t = CONSTRUCTOR_ELTS (init); t ; t = TREE_CHAIN (t))
+      FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx, purpose, value)
        {
-         tree purpose = TREE_PURPOSE (t);
-         tree value = TREE_VALUE (t);
-
          if (TREE_CODE (purpose) == RANGE_EXPR)
            {
              tree lower = TREE_OPERAND (purpose, 0);
@@ -1714,16 +1730,9 @@ generate_element_init (struct sra_elt *elt, tree init, tree *list_p)
   if (ret && *list_p)
     {
       tree_stmt_iterator i;
-      size_t old, new, j;
-
-      old = num_referenced_vars;
 
       for (i = tsi_start (*list_p); !tsi_end_p (i); tsi_next (&i))
        find_new_referenced_vars (tsi_stmt_ptr (i));
-
-      new = num_referenced_vars;
-      for (j = old; j < new; ++j)
-       mark_sym_for_renaming (referenced_var (j));
     }
 
   return ret;
@@ -1761,7 +1770,7 @@ insert_edge_copies (tree stmt, basic_block bb)
 
 /* Helper function to insert LIST before BSI, and set up line number info.  */
 
-static void
+void
 sra_insert_before (block_stmt_iterator *bsi, tree list)
 {
   tree stmt = bsi_stmt (*bsi);
@@ -1773,7 +1782,7 @@ sra_insert_before (block_stmt_iterator *bsi, tree list)
 
 /* Similarly, but insert after BSI.  Handles insertion onto edges as well.  */
 
-static void
+void
 sra_insert_after (block_stmt_iterator *bsi, tree list)
 {
   tree stmt = bsi_stmt (*bsi);
@@ -2130,6 +2139,16 @@ debug_sra_elt_name (struct sra_elt *elt)
   fputc ('\n', stderr);
 }
 
+void 
+sra_init_cache (void)
+{
+  if (sra_type_decomp_cache) 
+    return;
+
+  sra_type_decomp_cache = BITMAP_ALLOC (NULL);
+  sra_type_inst_cache = BITMAP_ALLOC (NULL);
+}
+
 /* Main entry point.  */
 
 static void
@@ -2139,8 +2158,7 @@ tree_sra (void)
   gcc_obstack_init (&sra_obstack);
   sra_candidates = BITMAP_ALLOC (NULL);
   needs_copy_in = BITMAP_ALLOC (NULL);
-  sra_type_decomp_cache = BITMAP_ALLOC (NULL);
-  sra_type_inst_cache = BITMAP_ALLOC (NULL);
+  sra_init_cache ();
   sra_map = htab_create (101, sra_elt_hash, sra_elt_eq, NULL);
 
   /* Scan.  If we find anything, instantiate and scalarize.  */