OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-live.c
index 232df84..80ab425 100644 (file)
@@ -1,5 +1,5 @@
 /* Liveness for SSA trees.
-   Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010
+   Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Contributed by Andrew MacLeod <amacleod@redhat.com>
 
@@ -31,7 +31,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-dump.h"
 #include "tree-ssa-live.h"
 #include "diagnostic-core.h"
-#include "toplev.h"
 #include "debug.h"
 #include "flags.h"
 #include "gimple.h"
@@ -158,10 +157,8 @@ delete_var_map (var_map map)
 {
   var_map_base_fini (map);
   partition_delete (map->var_partition);
-  if (map->partition_to_view)
-    free (map->partition_to_view);
-  if (map->view_to_partition)
-    free (map->view_to_partition);
+  free (map->partition_to_view);
+  free (map->view_to_partition);
   free (map);
 }
 
@@ -377,7 +374,8 @@ mark_all_vars_used_1 (tree *tp, int *walk_subtrees, void *data)
      eliminated as unused.  */
   if (TREE_CODE (t) == VAR_DECL)
     {
-      if (data != NULL && bitmap_clear_bit ((bitmap) data, DECL_UID (t)))
+      if (data != NULL && bitmap_clear_bit ((bitmap) data, DECL_UID (t))
+         && DECL_CONTEXT (t) == current_function_decl)
        mark_all_vars_used (&DECL_INITIAL (t), data);
       set_is_used (t);
     }
@@ -428,7 +426,6 @@ remove_unused_scope_block_p (tree scope)
 {
   tree *t, *next;
   bool unused = !TREE_USED (scope);
-  var_ann_t ann;
   int nsubblocks = 0;
 
   for (t = &BLOCK_VARS (scope); *t; t = next)
@@ -465,8 +462,7 @@ remove_unused_scope_block_p (tree scope)
         info about optimized-out variables in the scope blocks.
         Exception are the scope blocks not containing any instructions
         at all so user can't get into the scopes at first place.  */
-      else if ((ann = var_ann (*t)) != NULL
-               && ann->used)
+      else if (var_ann (*t) != NULL && is_used_p (*t))
        unused = false;
       else if (TREE_CODE (*t) == LABEL_DECL && TREE_USED (*t))
        /* For labels that are still used in the IL, the decision to
@@ -491,11 +487,16 @@ remove_unused_scope_block_p (tree scope)
         can be considered dead.  We only want to keep around blocks user can
         breakpoint into and ask about value of optimized out variables.
 
-        Similarly we need to keep around types at least until all variables of
-        all nested blocks are gone.  We track no information on whether given
-        type is used or not.  */
+        Similarly we need to keep around types at least until all
+        variables of all nested blocks are gone.  We track no
+        information on whether given type is used or not, so we have
+        to keep them even when not emitting debug information,
+        otherwise we may end up remapping variables and their (local)
+        types in different orders depending on whether debug
+        information is being generated.  */
 
-      else if (debug_info_level == DINFO_LEVEL_NORMAL
+      else if (TREE_CODE (*t) == TYPE_DECL
+              || debug_info_level == DINFO_LEVEL_NORMAL
               || debug_info_level == DINFO_LEVEL_VERBOSE)
        ;
       else
@@ -626,13 +627,11 @@ dump_scope_block (FILE *file, int indent, tree scope, int flags)
   for (var = BLOCK_VARS (scope); var; var = DECL_CHAIN (var))
     {
       bool used = false;
-      var_ann_t ann;
 
-      if ((ann = var_ann (var))
-         && ann->used)
-       used = true;
+      if (var_ann (var))
+       used = is_used_p (var);
 
-      fprintf (file, "%*s",indent, "");
+      fprintf (file, "%*s", indent, "");
       print_generic_decl (file, var, flags);
       fprintf (file, "%s\n", used ? "" : " (unused)");
     }
@@ -685,9 +684,9 @@ remove_unused_locals (void)
   basic_block bb;
   tree var, t;
   referenced_var_iterator rvi;
-  var_ann_t ann;
   bitmap global_unused_vars = NULL;
   unsigned srcidx, dstidx, num;
+  bool have_local_clobbers = false;
 
   /* Removing declarations from lexical blocks when not optimizing is
      not only a waste of time, it actually causes differences in stack
@@ -695,11 +694,13 @@ remove_unused_locals (void)
   if (!optimize)
     return;
 
+  timevar_push (TV_REMOVE_UNUSED);
+
   mark_scope_block_unused (DECL_INITIAL (current_function_decl));
 
   /* Assume all locals are unused.  */
-  FOR_EACH_REFERENCED_VAR (t, rvi)
-    var_ann (t)->used = false;
+  FOR_EACH_REFERENCED_VAR (cfun, t, rvi)
+    clear_is_used (t);
 
   /* Walk the CFG marking all referenced symbols.  */
   FOR_EACH_BB (bb)
@@ -718,6 +719,12 @@ remove_unused_locals (void)
          if (is_gimple_debug (stmt))
            continue;
 
+         if (gimple_clobber_p (stmt))
+           {
+             have_local_clobbers = true;
+             continue;
+           }
+
          if (b)
            TREE_USED (b) = true;
 
@@ -751,6 +758,41 @@ remove_unused_locals (void)
          TREE_USED (e->goto_block) = true;
     }
 
+  /* We do a two-pass approach about the out-of-scope clobbers.  We want
+     to remove them if they are the only references to a local variable,
+     but we want to retain them when there's any other.  So the first pass
+     ignores them, and the second pass (if there were any) tries to remove
+     them.  */
+  if (have_local_clobbers)
+    FOR_EACH_BB (bb)
+      {
+       gimple_stmt_iterator gsi;
+
+       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
+         {
+           gimple stmt = gsi_stmt (gsi);
+           tree b = gimple_block (stmt);
+
+           if (gimple_clobber_p (stmt))
+             {
+               tree lhs = gimple_assign_lhs (stmt);
+               lhs = get_base_address (lhs);
+               if (TREE_CODE (lhs) == SSA_NAME)
+                 lhs = SSA_NAME_VAR (lhs);
+               if (DECL_P (lhs) && (!var_ann (lhs) || !is_used_p (lhs)))
+                 {
+                   unlink_stmt_vdef (stmt);
+                   gsi_remove (&gsi, true);
+                   release_defs (stmt);
+                   continue;
+                 }
+               if (b)
+                 TREE_USED (b) = true;
+             }
+           gsi_next (&gsi);
+         }
+      }
+
   cfun->has_local_explicit_reg_vars = false;
 
   /* Remove unmarked local vars from local_decls.  */
@@ -759,8 +801,8 @@ remove_unused_locals (void)
     {
       var = VEC_index (tree, cfun->local_decls, srcidx);
       if (TREE_CODE (var) != FUNCTION_DECL
-         && (!(ann = var_ann (var))
-             || !ann->used))
+         && (!var_ann (var)
+             || !is_used_p (var)))
        {
          if (is_global_var (var))
            {
@@ -791,8 +833,9 @@ remove_unused_locals (void)
       FOR_EACH_LOCAL_DECL (cfun, ix, var)
        if (TREE_CODE (var) == VAR_DECL
            && is_global_var (var)
-           && (ann = var_ann (var)) != NULL
-           && ann->used)
+           && var_ann (var) != NULL
+           && is_used_p (var)
+           && DECL_CONTEXT (var) == current_function_decl)
          mark_all_vars_used (&DECL_INITIAL (var), global_unused_vars);
 
       num = VEC_length (tree, cfun->local_decls);
@@ -814,12 +857,11 @@ remove_unused_locals (void)
     }
 
   /* Remove unused variables from REFERENCED_VARs.  */
-  FOR_EACH_REFERENCED_VAR (t, rvi)
+  FOR_EACH_REFERENCED_VAR (cfun, t, rvi)
     if (!is_global_var (t)
        && TREE_CODE (t) != PARM_DECL
        && TREE_CODE (t) != RESULT_DECL
-       && !(ann = var_ann (t))->used
-       && !ann->is_heapvar)
+       && !is_used_p (t))
       remove_referenced_var (t);
   remove_unused_scope_block_p (DECL_INITIAL (current_function_decl));
   if (dump_file && (dump_flags & TDF_DETAILS))
@@ -827,6 +869,8 @@ remove_unused_locals (void)
       fprintf (dump_file, "Scope blocks after cleanups:\n");
       dump_scope_blocks (dump_file, dump_flags);
     }
+
+  timevar_pop (TV_REMOVE_UNUSED);
 }