summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-live.c
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2007-10-12 07:10:22 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2007-10-12 07:10:22 +0000
commita93b21ea450bb4af28f6d4f8b10956947ad3d51a (patch)
tree474026ffd420a838b23e399107df7fd8abcaea1a /gcc/tree-ssa-live.c
parent3dac447cd688525d64979440d1201913a75c2efa (diff)
downloadgcc-a93b21ea450bb4af28f6d4f8b10956947ad3d51a.tar.gz
PR tree-optimization/33645
* tree-ssa-live.c (mark_all_vars_used): Add data argument, pass it to walk_tree. (mark_all_vars_used_1): Pass data through to mark_all_vars_used. When calling set_is_used on a VAR_DECL, if data is not NULL and its DECL_UID is in the bitmap, call mark_all_vars_used on its DECL_INITIAL after clearing the bit in bitmap. (remove_unused_locals): Adjust mark_all_vars_used callers. Instead of removing unused global vars from unexpanded_var_list immediately record them in bitmap, call mark_all_vars_used on all used global vars from unexpanded_var_list and only purge global vars that weren't found used even during that step. * gcc.dg/pr33645-1.c: New test. * gcc.dg/pr33645-2.c: New test. * gcc.dg/pr33645-3.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129254 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-live.c')
-rw-r--r--gcc/tree-ssa-live.c73
1 files changed, 59 insertions, 14 deletions
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index a78dd9c19eb..f12de815a39 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -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;
@@ -547,9 +554,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 +569,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 +584,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,17 +596,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);
@@ -607,12 +615,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