OSDN Git Service

* tree-ssa-live.c (remove_unused_scope_block_p): Drop
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-live.c
index 2c8491c..51d682c 100644 (file)
@@ -1,12 +1,12 @@
 /* Liveness for SSA trees.
-   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
    Contributed by Andrew MacLeod <amacleod@redhat.com>
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -15,9 +15,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License 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, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
@@ -398,13 +397,13 @@ change_partition_var (var_map map, tree var, int part)
 }
 
 
-static inline void mark_all_vars_used (tree *);
+static inline void mark_all_vars_used (tree *, void *data);
 
 /* 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)
+                     void *data)
 {
   tree t = *tp;
   enum tree_code_class c = TREE_CODE_CLASS (TREE_CODE (t));
@@ -421,9 +420,9 @@ mark_all_vars_used_1 (tree *tp, int *walk_subtrees,
      fields that do not contain vars.  */
   if (TREE_CODE (t) == TARGET_MEM_REF)
     {
-      mark_all_vars_used (&TMR_SYMBOL (t));
-      mark_all_vars_used (&TMR_BASE (t));
-      mark_all_vars_used (&TMR_INDEX (t));
+      mark_all_vars_used (&TMR_SYMBOL (t), data);
+      mark_all_vars_used (&TMR_BASE (t), data);
+      mark_all_vars_used (&TMR_INDEX (t), data);
       *walk_subtrees = 0;
       return NULL;
     }
@@ -431,7 +430,14 @@ mark_all_vars_used_1 (tree *tp, int *walk_subtrees,
   /* 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 (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);
+       }
+      set_is_used (t);
+    }
 
   if (IS_TYPE_OR_DECL_P (t))
     *walk_subtrees = 0;
@@ -462,7 +468,7 @@ mark_scope_block_unused (tree scope)
        or there is precisely one subblocks and the block
        has same abstract origin as outer block and declares
        no variables, so it is pure wrapper.
-   When we are not outputting full debug info, we also elliminate dead variables
+   When we are not outputting full debug info, we also eliminate dead variables
    out of scope blocks to let them to be recycled by GGC and to save copying work
    done by the inliner.  */
 
@@ -478,7 +484,7 @@ remove_unused_scope_block_p (tree scope)
     {
       next = &TREE_CHAIN (*t);
 
-      /* Debug info of nested function reffers to the block of the
+      /* Debug info of nested function refers to the block of the
         function.  */
       if (TREE_CODE (*t) == FUNCTION_DECL)
        unused = false;
@@ -494,8 +500,15 @@ remove_unused_scope_block_p (tree scope)
       /* When we are not doing full debug info, we however can keep around
         only the used variables for cfgexpand's memory packing saving quite
         a lot of memory.  */
-      else if (debug_info_level != DINFO_LEVEL_NORMAL
-              && debug_info_level != DINFO_LEVEL_VERBOSE)
+      else if (debug_info_level == DINFO_LEVEL_NORMAL
+              || debug_info_level == DINFO_LEVEL_VERBOSE
+              /* Removing declarations before inlining is going to affect
+                 DECL_UID that in turn is going to affect hashtables and
+                 code generation.  */
+              || !cfun->after_inlining)
+       unused = false;
+
+      else
        {
          *t = TREE_CHAIN (*t);
          next = t;
@@ -517,7 +530,10 @@ remove_unused_scope_block_p (tree scope)
            nsubblocks ++;
          }
        else
-          *t = BLOCK_CHAIN (*t);
+         {
+           gcc_assert (!BLOCK_VARS (*t));
+           *t = BLOCK_CHAIN (*t);
+         }
       }
     else
       {
@@ -548,9 +564,9 @@ remove_unused_scope_block_p (tree scope)
    eliminated during the tree->rtl conversion process.  */
 
 static inline void
-mark_all_vars_used (tree *expr_p)
+mark_all_vars_used (tree *expr_p, void *data)
 {
-  walk_tree (expr_p, mark_all_vars_used_1, NULL, NULL);
+  walk_tree (expr_p, mark_all_vars_used_1, data, NULL);
 }
 
 
@@ -563,6 +579,7 @@ remove_unused_locals (void)
   tree t, *cell;
   referenced_var_iterator rvi;
   var_ann_t ann;
+  bitmap global_unused_vars = NULL;
 
   mark_scope_block_unused (DECL_INITIAL (current_function_decl));
   /* Assume all locals are unused.  */
@@ -577,7 +594,7 @@ remove_unused_locals (void)
 
       /* Walk the statements.  */
       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
-       mark_all_vars_used (bsi_stmt_ptr (bsi));
+       mark_all_vars_used (bsi_stmt_ptr (bsi), NULL);
 
       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
         {
@@ -589,17 +606,17 @@ remove_unused_locals (void)
            continue;
 
           def = PHI_RESULT (phi);
-          mark_all_vars_used (&def);
+         mark_all_vars_used (&def, NULL);
 
           FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES)
             {
              tree arg = USE_FROM_PTR (arg_p);
-             mark_all_vars_used (&arg);
+             mark_all_vars_used (&arg, NULL);
             }
         }
     }
 
-  /* Remove unmarked vars and clear used flag.  */
+  /* Remove unmarked local vars from unexpanded_var_list.  */
   for (cell = &cfun->unexpanded_var_list; *cell; )
     {
       tree var = TREE_VALUE (*cell);
@@ -608,12 +625,49 @@ remove_unused_locals (void)
          && (!(ann = var_ann (var))
              || !ann->used))
        {
-         *cell = TREE_CHAIN (*cell);
-         continue;
+         if (is_global_var (var))
+           {
+             if (global_unused_vars == NULL)
+               global_unused_vars = BITMAP_ALLOC (NULL);
+             bitmap_set_bit (global_unused_vars, DECL_UID (var));
+           }
+         else
+           {
+             *cell = TREE_CHAIN (*cell);
+             continue;
+           }
        }
       cell = &TREE_CHAIN (*cell);
     }
 
+  /* Remove unmarked global vars from unexpanded_var_list.  */
+  if (global_unused_vars != NULL)
+    {
+      for (t = cfun->unexpanded_var_list; t; t = TREE_CHAIN (t))
+       {
+         tree var = TREE_VALUE (t);
+
+         if (TREE_CODE (var) == VAR_DECL
+             && is_global_var (var)
+             && (ann = var_ann (var)) != NULL
+             && ann->used)
+           mark_all_vars_used (&DECL_INITIAL (var), global_unused_vars);
+       }
+
+      for (cell = &cfun->unexpanded_var_list; *cell; )
+       {
+         tree var = TREE_VALUE (*cell);
+
+         if (TREE_CODE (var) == VAR_DECL
+             && is_global_var (var)
+             && bitmap_bit_p (global_unused_vars, DECL_UID (var)))
+           *cell = TREE_CHAIN (*cell);
+         else
+           cell = &TREE_CHAIN (*cell);
+       }
+      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