OSDN Git Service

PR c++/27804
[pf3gnuchains/gcc-fork.git] / gcc / tree-outof-ssa.c
index 78ec5e7..0366614 100644 (file)
@@ -46,6 +46,7 @@ Boston, MA 02110-1301, USA.  */
 #include "tree-ssa-live.h"
 #include "tree-pass.h"
 #include "toplev.h"
+#include "vecprim.h"
 
 /* Flags to pass to remove_ssa_form.  */
 
@@ -53,9 +54,6 @@ Boston, MA 02110-1301, USA.  */
 #define SSANORM_COMBINE_TEMPS          0x2
 #define SSANORM_COALESCE_PARTITIONS    0x4
 
-DEF_VEC_I(int);
-DEF_VEC_ALLOC_I(int,heap);
-
 /* Used to hold all the components required to do SSA PHI elimination.
    The node and pred/succ list is a simple linear list of nodes and
    edges represented as pairs of nodes.
@@ -170,12 +168,12 @@ create_temp (tree t)
     }
   DECL_ARTIFICIAL (tmp) = DECL_ARTIFICIAL (t);
   DECL_IGNORED_P (tmp) = DECL_IGNORED_P (t);
-  add_referenced_tmp_var (tmp);
+  add_referenced_var (tmp);
 
-  /* add_referenced_tmp_var will create the annotation and set up some
+  /* add_referenced_var will create the annotation and set up some
      of the flags in the annotation.  However, some flags we need to
      inherit from our original variable.  */
-  var_ann (tmp)->type_mem_tag = var_ann (t)->type_mem_tag;
+  var_ann (tmp)->symbol_mem_tag = var_ann (t)->symbol_mem_tag;
   if (is_call_clobbered (t))
     mark_call_clobbered (tmp, var_ann (t)->escape_mask);
 
@@ -1299,7 +1297,8 @@ typedef struct value_expr_d
 typedef struct temp_expr_table_d 
 {
   var_map map;
-  void **version_info;         
+  void **version_info;
+  bitmap *expr_vars;
   value_expr_p *partition_dep_list;
   bitmap replaceable;
   bool saw_replaceable;
@@ -1322,7 +1321,7 @@ static inline void add_value_to_list (temp_expr_table_p, value_expr_p *, int);
 static inline void add_info_to_list (temp_expr_table_p, value_expr_p *, 
                                     value_expr_p);
 static value_expr_p remove_value_from_list (value_expr_p *, int);
-static void add_dependance (temp_expr_table_p, int, tree);
+static void add_dependence (temp_expr_table_p, int, tree);
 static bool check_replaceable (temp_expr_table_p, tree);
 static void finish_expr (temp_expr_table_p, int, bool);
 static void mark_replaceable (temp_expr_table_p, tree);
@@ -1344,6 +1343,7 @@ new_temp_expr_table (var_map map)
   t->map = map;
 
   t->version_info = XCNEWVEC (void *, num_ssa_names + 1);
+  t->expr_vars = XCNEWVEC (bitmap, num_ssa_names + 1);
   t->partition_dep_list = XCNEWVEC (value_expr_p,
                                     num_var_partitions (map) + 1);
 
@@ -1367,6 +1367,7 @@ free_temp_expr_table (temp_expr_table_p t)
 {
   value_expr_p p;
   tree *ret = NULL;
+  unsigned i;
 
 #ifdef ENABLE_CHECKING
   unsigned x;
@@ -1383,6 +1384,11 @@ free_temp_expr_table (temp_expr_table_p t)
   BITMAP_FREE (t->partition_in_use);
   BITMAP_FREE (t->replaceable);
 
+  for (i = 0; i <= num_ssa_names; i++)
+    if (t->expr_vars[i])
+      BITMAP_FREE (t->expr_vars[i]);
+  free (t->expr_vars);
+
   free (t->partition_dep_list);
   if (t->saw_replaceable)
     ret = (tree *)t->version_info;
@@ -1504,7 +1510,7 @@ remove_value_from_list (value_expr_p *list, int value)
    expression table.  */
 
 static void
-add_dependance (temp_expr_table_p tab, int version, tree var)
+add_dependence (temp_expr_table_p tab, int version, tree var)
 {
   int i, x;
   value_expr_p info;
@@ -1545,11 +1551,12 @@ add_dependance (temp_expr_table_p tab, int version, tree var)
 static bool
 check_replaceable (temp_expr_table_p tab, tree stmt)
 {
-  tree var, def;
+  tree var, def, basevar;
   int version;
   var_map map = tab->map;
   ssa_op_iter iter;
   tree call_expr;
+  bitmap def_vars = BITMAP_ALLOC (NULL), use_vars;
 
   if (TREE_CODE (stmt) != MODIFY_EXPR)
     return false;
@@ -1580,12 +1587,19 @@ check_replaceable (temp_expr_table_p tab, tree stmt)
     }
 
   version = SSA_NAME_VERSION (def);
+  basevar = SSA_NAME_VAR (def);
+  bitmap_set_bit (def_vars, DECL_UID (basevar));
 
   /* Add this expression to the dependency list for each use partition.  */
   FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
     {
-      add_dependance (tab, version, var);
+      add_dependence (tab, version, var);
+
+      use_vars = tab->expr_vars[SSA_NAME_VERSION (var)];
+      if (use_vars)
+       bitmap_ior_into (def_vars, use_vars);
     }
+  tab->expr_vars[version] = def_vars;
 
   /* If there are VUSES, add a dependence on virtual defs.  */
   if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE))
@@ -1704,7 +1718,7 @@ static void
 find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
 {
   block_stmt_iterator bsi;
-  tree stmt, def;
+  tree stmt, def, use;
   stmt_ann_t ann;
   int partition;
   var_map map = tab->map;
@@ -1717,30 +1731,34 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
       ann = stmt_ann (stmt);
 
       /* Determine if this stmt finishes an existing expression.  */
-      FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_USE)
+      FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
        {
-         if (tab->version_info[SSA_NAME_VERSION (def)])
+         unsigned ver = SSA_NAME_VERSION (use);
+
+         if (tab->version_info[ver])
            {
              bool same_root_var = false;
-             tree def2;
              ssa_op_iter iter2;
+             bitmap vars = tab->expr_vars[ver];
 
              /* See if the root variables are the same.  If they are, we
                 do not want to do the replacement to avoid problems with
                 code size, see PR tree-optimization/17549.  */
-             FOR_EACH_SSA_TREE_OPERAND (def2, stmt, iter2, SSA_OP_DEF)
-               if (SSA_NAME_VAR (def) == SSA_NAME_VAR (def2))
-                 {
-                   same_root_var = true;
-                   break;
-                 }
+             FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter2, SSA_OP_DEF)
+               {
+                 if (bitmap_bit_p (vars, DECL_UID (SSA_NAME_VAR (def))))
+                   {
+                     same_root_var = true;
+                     break;
+                   }
+               }
 
              /* Mark expression as replaceable unless stmt is volatile
                 or DEF sets the same root variable as STMT.  */
              if (!ann->has_volatile_ops && !same_root_var)
-               mark_replaceable (tab, def);
+               mark_replaceable (tab, use);
              else
-               finish_expr (tab, SSA_NAME_VERSION (def), false);
+               finish_expr (tab, ver, false);
            }
        }
       
@@ -2196,7 +2214,7 @@ analyze_edges_for_bb (basic_block bb)
        leader_match = leader;
 
        /* The tree_* cfg manipulation routines use the PENDING_EDGE field
-          for various PHI manipulations, so it gets cleared whhen calls are 
+          for various PHI manipulations, so it gets cleared when calls are 
           made to make_forwarder_block(). So make sure the edge is clear, 
           and use the saved stmt list.  */
        PENDING_STMT (leader) = NULL;
@@ -2485,7 +2503,7 @@ insert_backedge_copies (void)
    R. Morgan, ``Building an Optimizing Compiler'',
    Butterworth-Heinemann, Boston, MA, 1998. pp 176-186.  */
 
-static void
+static unsigned int
 rewrite_out_of_ssa (void)
 {
   var_map map;
@@ -2528,6 +2546,7 @@ rewrite_out_of_ssa (void)
   delete_var_map (map);
 
   in_ssa_p = false;
+  return 0;
 }