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 | |
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')
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr33645-1.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr33645-2.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr33645-3.c | 20 | ||||
-rw-r--r-- | gcc/tree-ssa-live.c | 73 |
6 files changed, 137 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a5272799e0d..c1f44631d68 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2007-10-12 Jakub Jelinek <jakub@redhat.com> + + 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. + 2007-10-11 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> * gthr-posix.h (__gthread_active_init): Create detached instead of diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7434c1e36c9..79626fc1172 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2007-10-12 Jakub Jelinek <jakub@redhat.com> + PR tree-optimization/33645 + * gcc.dg/pr33645-1.c: New test. + * gcc.dg/pr33645-2.c: New test. + * gcc.dg/pr33645-3.c: New test. + PR c++/32121 * g++.dg/ext/label4.C: Adjust error regexp. * g++.dg/ext/label6.C: Adjust error regexp. diff --git a/gcc/testsuite/gcc.dg/pr33645-1.c b/gcc/testsuite/gcc.dg/pr33645-1.c new file mode 100644 index 00000000000..1ec8a2ff872 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr33645-1.c @@ -0,0 +1,18 @@ +/* PR tree-optimization/33645 */ +/* { dg-do link } */ +/* { dg-options "-O2 -fno-unit-at-a-time" } */ + +__attribute__((noinline)) int +bar (int *x) +{ + return *x++; +} + +int +main () +{ + static int var1_s; + static int *var1_t = &var1_s; + + return bar (var1_t) != 0; +} diff --git a/gcc/testsuite/gcc.dg/pr33645-2.c b/gcc/testsuite/gcc.dg/pr33645-2.c new file mode 100644 index 00000000000..3c4bcb060e5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr33645-2.c @@ -0,0 +1,20 @@ +/* PR tree-optimization/33645 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -funit-at-a-time" } */ + +__attribute__((noinline)) int +bar (int *x) +{ + return *x++; +} + +int +main () +{ + static int var1_s; + static int *var1_t = &var1_s; + + return bar (var1_t) != 0; +} + +/* { dg-final { scan-assembler-not "var1_t" } } */ diff --git a/gcc/testsuite/gcc.dg/pr33645-3.c b/gcc/testsuite/gcc.dg/pr33645-3.c new file mode 100644 index 00000000000..28b933c412c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr33645-3.c @@ -0,0 +1,20 @@ +/* PR tree-optimization/33645 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-unit-at-a-time" } */ + +__attribute__((noinline)) int +bar (int *x) +{ + return *x++; +} + +int +main () +{ + static int var1_s; + static int *const var1_t = &var1_s; + + return bar (var1_t) != 0; +} + +/* { dg-final { scan-assembler-not "var1_t" } } */ 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 |