OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-live.c
index e8194aa..80ab425 100644 (file)
@@ -1,5 +1,5 @@
 /* Liveness for SSA trees.
 /* 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>
 
    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 "tree-dump.h"
 #include "tree-ssa-live.h"
 #include "diagnostic-core.h"
-#include "toplev.h"
 #include "debug.h"
 #include "flags.h"
 #include "gimple.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);
 {
   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);
 }
 
   free (map);
 }
 
@@ -362,13 +359,13 @@ mark_all_vars_used_1 (tree *tp, int *walk_subtrees, void *data)
       && (b = TREE_BLOCK (t)) != NULL)
     TREE_USED (b) = true;
 
       && (b = TREE_BLOCK (t)) != NULL)
     TREE_USED (b) = true;
 
-  /* Ignore TREE_ORIGINAL for TARGET_MEM_REFS, as well as other
-     fields that do not contain vars.  */
+  /* Ignore TMR_OFFSET and TMR_STEP for TARGET_MEM_REFS, as those
+     fields do not contain vars.  */
   if (TREE_CODE (t) == TARGET_MEM_REF)
     {
   if (TREE_CODE (t) == TARGET_MEM_REF)
     {
-      mark_all_vars_used (&TMR_SYMBOL (t), data);
       mark_all_vars_used (&TMR_BASE (t), data);
       mark_all_vars_used (&TMR_INDEX (t), data);
       mark_all_vars_used (&TMR_BASE (t), data);
       mark_all_vars_used (&TMR_INDEX (t), data);
+      mark_all_vars_used (&TMR_INDEX2 (t), data);
       *walk_subtrees = 0;
       return NULL;
     }
       *walk_subtrees = 0;
       return NULL;
     }
@@ -377,11 +374,9 @@ mark_all_vars_used_1 (tree *tp, int *walk_subtrees, void *data)
      eliminated as unused.  */
   if (TREE_CODE (t) == VAR_DECL)
     {
      eliminated as unused.  */
   if (TREE_CODE (t) == VAR_DECL)
     {
-      if (data != NULL && bitmap_bit_p ((bitmap) data, DECL_UID (t)))
-       {
-         bitmap_clear_bit ((bitmap) data, DECL_UID (t));
-         mark_all_vars_used (&DECL_INITIAL (t), data);
-       }
+      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);
     }
   /* remove_unused_scope_block_p requires information about labels
       set_is_used (t);
     }
   /* remove_unused_scope_block_p requires information about labels
@@ -431,7 +426,6 @@ remove_unused_scope_block_p (tree scope)
 {
   tree *t, *next;
   bool unused = !TREE_USED (scope);
 {
   tree *t, *next;
   bool unused = !TREE_USED (scope);
-  var_ann_t ann;
   int nsubblocks = 0;
 
   for (t = &BLOCK_VARS (scope); *t; t = next)
   int nsubblocks = 0;
 
   for (t = &BLOCK_VARS (scope); *t; t = next)
@@ -468,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.  */
         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
        unused = false;
       else if (TREE_CODE (*t) == LABEL_DECL && TREE_USED (*t))
        /* For labels that are still used in the IL, the decision to
@@ -494,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.
 
         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
               || debug_info_level == DINFO_LEVEL_VERBOSE)
        ;
       else
@@ -629,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;
   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)");
     }
       print_generic_decl (file, var, flags);
       fprintf (file, "%s\n", used ? "" : " (unused)");
     }
@@ -688,9 +684,9 @@ remove_unused_locals (void)
   basic_block bb;
   tree var, t;
   referenced_var_iterator rvi;
   basic_block bb;
   tree var, t;
   referenced_var_iterator rvi;
-  var_ann_t ann;
   bitmap global_unused_vars = NULL;
   unsigned srcidx, dstidx, num;
   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
 
   /* Removing declarations from lexical blocks when not optimizing is
      not only a waste of time, it actually causes differences in stack
@@ -698,11 +694,13 @@ remove_unused_locals (void)
   if (!optimize)
     return;
 
   if (!optimize)
     return;
 
+  timevar_push (TV_REMOVE_UNUSED);
+
   mark_scope_block_unused (DECL_INITIAL (current_function_decl));
 
   /* Assume all locals are 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)
 
   /* Walk the CFG marking all referenced symbols.  */
   FOR_EACH_BB (bb)
@@ -721,6 +719,12 @@ remove_unused_locals (void)
          if (is_gimple_debug (stmt))
            continue;
 
          if (is_gimple_debug (stmt))
            continue;
 
+         if (gimple_clobber_p (stmt))
+           {
+             have_local_clobbers = true;
+             continue;
+           }
+
          if (b)
            TREE_USED (b) = true;
 
          if (b)
            TREE_USED (b) = true;
 
@@ -754,6 +758,41 @@ remove_unused_locals (void)
          TREE_USED (e->goto_block) = true;
     }
 
          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.  */
   cfun->has_local_explicit_reg_vars = false;
 
   /* Remove unmarked local vars from local_decls.  */
@@ -762,8 +801,8 @@ remove_unused_locals (void)
     {
       var = VEC_index (tree, cfun->local_decls, srcidx);
       if (TREE_CODE (var) != FUNCTION_DECL
     {
       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))
            {
        {
          if (is_global_var (var))
            {
@@ -794,8 +833,9 @@ remove_unused_locals (void)
       FOR_EACH_LOCAL_DECL (cfun, ix, var)
        if (TREE_CODE (var) == VAR_DECL
            && is_global_var (var)
       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);
          mark_all_vars_used (&DECL_INITIAL (var), global_unused_vars);
 
       num = VEC_length (tree, cfun->local_decls);
@@ -816,18 +856,12 @@ remove_unused_locals (void)
       BITMAP_FREE (global_unused_vars);
     }
 
       BITMAP_FREE (global_unused_vars);
     }
 
-  /* Remove unused variables from REFERENCED_VARs.  As a special
-     exception keep the variables that are believed to be aliased.
-     Those can't be easily removed from the alias sets and operand
-     caches.  They will be removed shortly after the next may_alias
-     pass is performed.  */
-  FOR_EACH_REFERENCED_VAR (t, rvi)
+  /* Remove unused variables from REFERENCED_VARs.  */
+  FOR_EACH_REFERENCED_VAR (cfun, t, rvi)
     if (!is_global_var (t)
        && TREE_CODE (t) != PARM_DECL
        && TREE_CODE (t) != RESULT_DECL
     if (!is_global_var (t)
        && TREE_CODE (t) != PARM_DECL
        && TREE_CODE (t) != RESULT_DECL
-       && !(ann = var_ann (t))->used
-       && !ann->is_heapvar
-       && !TREE_ADDRESSABLE (t))
+       && !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))
       remove_referenced_var (t);
   remove_unused_scope_block_p (DECL_INITIAL (current_function_decl));
   if (dump_file && (dump_flags & TDF_DETAILS))
@@ -835,6 +869,8 @@ remove_unused_locals (void)
       fprintf (dump_file, "Scope blocks after cleanups:\n");
       dump_scope_blocks (dump_file, dump_flags);
     }
       fprintf (dump_file, "Scope blocks after cleanups:\n");
       dump_scope_blocks (dump_file, dump_flags);
     }
+
+  timevar_pop (TV_REMOVE_UNUSED);
 }
 
 
 }
 
 
@@ -1253,8 +1289,8 @@ dump_enumerated_decls (FILE *file, int flags)
   struct walk_stmt_info wi;
   VEC (numbered_tree, heap) *decl_list = VEC_alloc (numbered_tree, heap, 40);
 
   struct walk_stmt_info wi;
   VEC (numbered_tree, heap) *decl_list = VEC_alloc (numbered_tree, heap, 40);
 
+  memset (&wi, '\0', sizeof (wi));
   wi.info = (void*) decl_list;
   wi.info = (void*) decl_list;
-  wi.pset = NULL;
   FOR_EACH_BB (bb)
     {
       gimple_stmt_iterator gsi;
   FOR_EACH_BB (bb)
     {
       gimple_stmt_iterator gsi;
@@ -1264,9 +1300,7 @@ dump_enumerated_decls (FILE *file, int flags)
          walk_gimple_stmt (&gsi, NULL, dump_enumerated_decls_push, &wi);
     }
   decl_list = (VEC (numbered_tree, heap) *) wi.info;
          walk_gimple_stmt (&gsi, NULL, dump_enumerated_decls_push, &wi);
     }
   decl_list = (VEC (numbered_tree, heap) *) wi.info;
-  qsort (VEC_address (numbered_tree, decl_list),
-        VEC_length (numbered_tree, decl_list),
-        sizeof (numbered_tree), compare_decls_by_uid);
+  VEC_qsort (numbered_tree, decl_list, compare_decls_by_uid);
   if (VEC_length (numbered_tree, decl_list))
     {
       unsigned ix;
   if (VEC_length (numbered_tree, decl_list))
     {
       unsigned ix;
@@ -1275,7 +1309,7 @@ dump_enumerated_decls (FILE *file, int flags)
 
       fprintf (file, "Declarations used by %s, sorted by DECL_UID:\n",
               current_function_name ());
 
       fprintf (file, "Declarations used by %s, sorted by DECL_UID:\n",
               current_function_name ());
-      for (ix = 0; VEC_iterate (numbered_tree, decl_list, ix, ntp); ix++)
+      FOR_EACH_VEC_ELT (numbered_tree, decl_list, ix, ntp)
        {
          if (ntp->t == last)
            continue;
        {
          if (ntp->t == last)
            continue;