}
-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));
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;
}
/* 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;
/* 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;
nsubblocks ++;
}
else
- *t = BLOCK_CHAIN (*t);
+ {
+ gcc_assert (!BLOCK_VARS (*t));
+ *t = BLOCK_CHAIN (*t);
+ }
}
else
{
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);
}
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. */
/* 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))
{
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);
&& (!(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