OSDN Git Service

PR c++/16707
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-live.c
index 931ec78..45df501 100644 (file)
@@ -30,7 +30,7 @@ Boston, MA 02111-1307, USA.  */
 #include "diagnostic.h"
 #include "bitmap.h"
 #include "tree-flow.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-inline.h"
 #include "varray.h"
 #include "timevar.h"
@@ -102,7 +102,7 @@ delete_var_map (var_map map)
 
 /* This function will combine the partitions in MAP for VAR1 and VAR2.  It 
    Returns the partition which represents the new partition.  If the two 
-   partitions cannot be combined, NO_PARTITION is returned. */
+   partitions cannot be combined, NO_PARTITION is returned.  */
 
 int
 var_union (var_map map, tree var1, tree var2)
@@ -285,6 +285,34 @@ change_partition_var (var_map map, tree var, int part)
 }
 
 
+/* Helper function for mark_all_vars_used, called via walk_tree.  */
+
+static tree
+mark_all_vars_used_1 (tree *tp, int *walk_subtrees,
+                     void *data ATTRIBUTE_UNUSED)
+{
+  tree t = *tp;
+
+  /* Only need to mark VAR_DECLS; parameters and return results are not
+     eliminated as unused.  */
+  if (TREE_CODE (t) == VAR_DECL)
+    set_is_used (t);
+
+  if (DECL_P (t) || TYPE_P (t))
+    *walk_subtrees = 0;
+
+  return NULL;
+}
+
+/* Mark all VAR_DECLS under *EXPR_P as used, so that they won't be 
+   eliminated during the tree->rtl conversion process.  */
+
+static inline void
+mark_all_vars_used (tree *expr_p)
+{
+  walk_tree (expr_p, mark_all_vars_used_1, NULL, NULL);
+}
+
 /* This function looks through the program and uses FLAGS to determine what 
    SSA versioned variables are given entries in a new partition table.  This
    new partition map is returned.  */
@@ -294,23 +322,24 @@ create_ssa_var_map (int flags)
 {
   block_stmt_iterator bsi;
   basic_block bb;
-  tree *dest, *use;
+  tree dest, use;
   tree stmt;
   stmt_ann_t ann;
-  vuse_optype vuses;
-  vdef_optype vdefs;
   use_optype uses;
   def_optype defs;
   unsigned x;
   var_map map;
-#if defined ENABLE_CHECKING
+#ifdef ENABLE_CHECKING
   sbitmap used_in_real_ops;
   sbitmap used_in_virtual_ops;
+  vuse_optype vuses;
+  v_may_def_optype v_may_defs;
+  v_must_def_optype v_must_defs;
 #endif
 
-  map = init_var_map (highest_ssa_version + 1);
+  map = init_var_map (num_ssa_names + 1);
 
-#if defined ENABLE_CHECKING
+#ifdef ENABLE_CHECKING
   used_in_real_ops = sbitmap_alloc (num_referenced_vars);
   sbitmap_zero (used_in_real_ops);
 
@@ -321,14 +350,14 @@ create_ssa_var_map (int flags)
   if (flags & SSA_VAR_MAP_REF_COUNT)
     {
       map->ref_count
-       = (int *)xmalloc (((highest_ssa_version + 1) * sizeof (int)));
-      memset (map->ref_count, 0, (highest_ssa_version + 1) * sizeof (int));
+       = (int *)xmalloc (((num_ssa_names + 1) * sizeof (int)));
+      memset (map->ref_count, 0, (num_ssa_names + 1) * sizeof (int));
     }
 
   FOR_EACH_BB (bb)
     {
       tree phi, arg;
-      for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+      for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
        {
          int i;
          register_ssa_partition (map, PHI_RESULT (phi), false);
@@ -337,6 +366,8 @@ create_ssa_var_map (int flags)
              arg = PHI_ARG_DEF (phi, i);
              if (TREE_CODE (arg) == SSA_NAME)
                register_ssa_partition (map, arg, true);
+
+             mark_all_vars_used (&PHI_ARG_DEF_TREE (phi, i));
            }
        }
 
@@ -350,49 +381,50 @@ create_ssa_var_map (int flags)
          uses = USE_OPS (ann);
          for (x = 0; x < NUM_USES (uses); x++)
            {
-             use = USE_OP_PTR (uses, x);
-             register_ssa_partition (map, *use, true);
+             use = USE_OP (uses, x);
+             register_ssa_partition (map, use, true);
 
-#if defined ENABLE_CHECKING
-             SET_BIT (used_in_real_ops, var_ann (SSA_NAME_VAR (*use))->uid);
+#ifdef ENABLE_CHECKING
+             SET_BIT (used_in_real_ops, var_ann (SSA_NAME_VAR (use))->uid);
 #endif
            }
 
          defs = DEF_OPS (ann);
          for (x = 0; x < NUM_DEFS (defs); x++)
            {
-             dest = DEF_OP_PTR (defs, x);
-             register_ssa_partition (map, *dest, false);
+             dest = DEF_OP (defs, x);
+             register_ssa_partition (map, dest, false);
 
-#if defined ENABLE_CHECKING
-             SET_BIT (used_in_real_ops, var_ann (SSA_NAME_VAR (*dest))->uid);
+#ifdef ENABLE_CHECKING
+             SET_BIT (used_in_real_ops, var_ann (SSA_NAME_VAR (dest))->uid);
 #endif
            }
 
-         /* While we do not care about virtual operands for
-            out of SSA, we do need to look at them to make sure
-            we mark all the variables which are used.  */
+#ifdef ENABLE_CHECKING
+         /* Validate that virtual ops don't get used in funny ways.  */
          vuses = VUSE_OPS (ann);
          for (x = 0; x < NUM_VUSES (vuses); x++)
            {
              tree var = VUSE_OP (vuses, x);
-             set_is_used (var);
-
-#if defined ENABLE_CHECKING
              SET_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (var))->uid);
-#endif
            }
 
-         vdefs = VDEF_OPS (ann);
-         for (x = 0; x < NUM_VDEFS (vdefs); x++)
+         v_may_defs = V_MAY_DEF_OPS (ann);
+         for (x = 0; x < NUM_V_MAY_DEFS (v_may_defs); x++)
            {
-             tree var = VDEF_OP (vdefs, x);
-             set_is_used (var);
-
-#if defined ENABLE_CHECKING
+             tree var = V_MAY_DEF_OP (v_may_defs, x);
              SET_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (var))->uid);
-#endif
            }
+           
+         v_must_defs = V_MUST_DEF_OPS (ann);
+         for (x = 0; x < NUM_V_MUST_DEFS (v_must_defs); x++)
+           {
+             tree var = V_MUST_DEF_OP (v_must_defs, x);
+             SET_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (var))->uid);
+           }       
+#endif /* ENABLE_CHECKING */
+
+         mark_all_vars_used (bsi_stmt_ptr (bsi));
        }
     }
 
@@ -551,12 +583,10 @@ calculate_live_on_entry (var_map map)
   basic_block bb;
   bitmap saw_def;
   tree phi, var, stmt;
-  tree *vec;
+  tree op;
   edge e;
   varray_type stack;
   block_stmt_iterator bsi;
-  vuse_optype vuses;
-  vdef_optype vdefs;
   use_optype uses;
   def_optype defs;
   stmt_ann_t ann;
@@ -569,7 +599,7 @@ calculate_live_on_entry (var_map map)
     {
       bitmap_clear (saw_def);
 
-      for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+      for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
        {
          for (i = 0; i < PHI_NUM_ARGS (phi); i++)
            {
@@ -594,7 +624,7 @@ calculate_live_on_entry (var_map map)
         The a_3 referred to in b_3's PHI node is the one incoming on the
         edge, *not* the PHI node just seen.  */
 
-      for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+      for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
         {
          var = PHI_RESULT (phi);
          set_if_valid (map, saw_def, var);
@@ -610,39 +640,16 @@ calculate_live_on_entry (var_map map)
          num = NUM_USES (uses);
          for (i = 0; i < num; i++)
            {
-             vec = USE_OP_PTR (uses, i);
-             add_livein_if_notdef (live, saw_def, *vec, bb);
-           }
-
-         vuses = VUSE_OPS (ann);
-         num = NUM_VUSES (vuses);
-         for (i = 0; i < num; i++)
-           {
-             var = VUSE_OP (vuses, i);
-             add_livein_if_notdef (live, saw_def, var, bb);
-           }
-
-         vdefs = VDEF_OPS (ann);
-         num = NUM_VDEFS (vdefs);
-         for (i = 0; i < num; i++)
-           {
-             var = VDEF_OP (vdefs, i);
-             add_livein_if_notdef (live, saw_def, var, bb);
+             op = USE_OP (uses, i);
+             add_livein_if_notdef (live, saw_def, op, bb);
            }
 
          defs = DEF_OPS (ann);
          num = NUM_DEFS (defs);
          for (i = 0; i < num; i++)
            {
-             vec = DEF_OP_PTR (defs, i);
-             set_if_valid (map, saw_def, *vec);
-           }
-
-         num = NUM_VDEFS (vdefs);
-         for (i = 0; i < num; i++)
-           {
-             var = VDEF_RESULT (vdefs, i);
-             set_if_valid (map, saw_def, var);
+             op = DEF_OP (defs, i);
+             set_if_valid (map, saw_def, op);
            }
        }
     }
@@ -715,7 +722,7 @@ calculate_live_on_entry (var_map map)
                int z, ok = 0;
                for (phi = phi_nodes (e->dest); 
                     phi && !ok; 
-                    phi = TREE_CHAIN (phi))
+                    phi = PHI_CHAIN (phi))
                  {
                    for (z = 0; z < PHI_NUM_ARGS (phi); z++)
                      if (var == PHI_ARG_DEF (phi, z))
@@ -738,6 +745,8 @@ calculate_live_on_entry (var_map map)
     abort ();
 #endif
 
+  BITMAP_XFREE (saw_def);
+
   return live;
 }
 
@@ -763,7 +772,7 @@ calculate_live_on_exit (tree_live_info_p liveinfo)
   /* Set all the live-on-exit bits for uses in PHIs.  */
   FOR_EACH_BB (bb)
     {
-      for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+      for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
        for (i = 0; i < PHI_NUM_ARGS (phi); i++)
          { 
            t = PHI_ARG_DEF (phi, i);
@@ -861,7 +870,7 @@ tpa_delete (tpa_p tpa)
 }
 
 
-/* This function will remove any tree entires from TPA which have only a single
+/* This function will remove any tree entries from TPA which have only a single
    element.  This will help keep the size of the conflict graph down.  The 
    function returns the number of remaining tree lists.  */
 
@@ -1367,7 +1376,7 @@ build_tree_conflict_graph (tree_live_info_p liveinfo, tpa_p tpa,
             This is handled specially here since we may also be interested 
             in copies between real variables and SSA_NAME variables.  We may
             be interested in trying to coalesce SSA_NAME variables with
-            root variables in some cases.   */
+            root variables in some cases.  */
 
          if (TREE_CODE (stmt) == MODIFY_EXPR)
            {
@@ -1405,22 +1414,22 @@ build_tree_conflict_graph (tree_live_info_p liveinfo, tpa_p tpa,
 
          if (!is_a_copy)
            {
-             tree *var_p;
+             tree var;
 
              defs = DEF_OPS (ann);
              num = NUM_DEFS (defs);
              for (x = 0; x < num; x++)
                {
-                 var_p = DEF_OP_PTR (defs, x);
-                 add_conflicts_if_valid (tpa, graph, map, live, *var_p);
+                 var = DEF_OP (defs, x);
+                 add_conflicts_if_valid (tpa, graph, map, live, var);
                }
 
              uses = USE_OPS (ann);
              num = NUM_USES (uses);
              for (x = 0; x < num; x++)
                {
-                 var_p = USE_OP_PTR (uses, x);
-                 set_if_valid (map, live, *var_p);
+                 var = USE_OP (uses, x);
+                 set_if_valid (map, live, var);
                }
            }
        }
@@ -1430,7 +1439,7 @@ build_tree_conflict_graph (tree_live_info_p liveinfo, tpa_p tpa,
         going to be translated out of SSA form we must record a conflict
         between the result of the PHI and any variables with are live. 
         Otherwise the out-of-ssa translation may create incorrect code.  */
-      for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+      for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
        {
          tree result = PHI_RESULT (phi);
          int p = var_to_partition (map, result);
@@ -1442,7 +1451,7 @@ build_tree_conflict_graph (tree_live_info_p liveinfo, tpa_p tpa,
       /* Anything which is still live at this point interferes.  
         In order to implement this efficiently, only conflicts between
         partitions which have the same TPA root need be added.
-        TPA roots which have been seen are tracked in 'tpa_nodes'.  A non-zero
+        TPA roots which have been seen are tracked in 'tpa_nodes'.  A nonzero
         entry points to an index into 'partition_link', which then indexes 
         into itself forming a linked list of partitions sharing a tpa root 
         which have been seen as live up to this point.  Since partitions start
@@ -1755,7 +1764,7 @@ dump_var_map (FILE *f, var_map map)
         continue;
 
       t = 0;
-      for (y = 1; y < highest_ssa_version; y++)
+      for (y = 1; y < num_ssa_names; y++)
         {
          p = partition_find (map->var_partition, y);
          if (map->partition_to_compact)
@@ -1844,12 +1853,12 @@ register_ssa_partitions_for_vars (bitmap vars, var_map map)
 
             Note we delete PHI nodes in this loop if they are 
             associated with virtual vars which are going to be
-            renamed.   */
+            renamed.  */
          for (phi = phi_nodes (bb); phi; phi = next)
            {
              tree result = SSA_NAME_VAR (PHI_RESULT (phi));
 
-             next = TREE_CHAIN (phi);
+             next = PHI_CHAIN (phi);
              if (bitmap_bit_p (vars, var_ann (result)->uid))
                {
                  if (! is_gimple_reg (result))