diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-10-12 07:10:22 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-10-12 07:10:22 +0000 |
commit | a93b21ea450bb4af28f6d4f8b10956947ad3d51a (patch) | |
tree | 474026ffd420a838b23e399107df7fd8abcaea1a /gcc/tree-ssa-live.c | |
parent | 3dac447cd688525d64979440d1201913a75c2efa (diff) | |
download | gcc-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.c | 73 |
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 |