OSDN Git Service

2008-05-16 Tobias Burnus <burnus@net-b.de>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-live.c
index a78dd9c..ae4b909 100644 (file)
@@ -397,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));
@@ -420,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;
     }
@@ -430,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;
@@ -493,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;
@@ -516,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
       {
@@ -547,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);
 }
 
 
@@ -562,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.  */
@@ -576,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))
         {
@@ -588,18 +606,18 @@ 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.  */
-  for (cell = &cfun->unexpanded_var_list; *cell; )
+  /* Remove unmarked local vars from local_decls.  */
+  for (cell = &cfun->local_decls; *cell; )
     {
       tree var = TREE_VALUE (*cell);
 
@@ -607,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 local_decls.  */
+  if (global_unused_vars != NULL)
+    {
+      for (t = cfun->local_decls; 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->local_decls; *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