diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-09 10:36:24 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-09 10:36:24 +0000 |
commit | 8838b9d46cc7e0820f0bd390886b5b8bae38d51b (patch) | |
tree | 35a95043c534b6a727a3d427c998055634f68924 /gcc/varasm.c | |
parent | bfce477d4ecb1a383a83766247a45119be38b99d (diff) | |
download | gcc-8838b9d46cc7e0820f0bd390886b5b8bae38d51b.tar.gz |
2010-11-09 Richard Guenther <rguenther@suse.de>
PR middle-end/46221
* varasm.c (compute_visible_aliases): New function.
(remove_unreachable_alias_pairs): Aliases make a target available
even though we reclaimed the cgraph node.
(finish_aliases_1): Likewise.
* Makefile.in (varasm.o): Add pointer-set.h dependency.
* gcc.target/i386/alias-1.c: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@166479 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r-- | gcc/varasm.c | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c index fe60bb2397d..0c80c931fff 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see #include "cfglayout.h" #include "basic-block.h" #include "tree-iterator.h" +#include "pointer-set.h" #ifdef XCOFF_DEBUGGING_INFO #include "xcoffout.h" /* Needed for external data @@ -5415,18 +5416,58 @@ do_assemble_alias (tree decl, tree target) } +/* Compute the set of indentifier nodes that is generated by aliases + whose targets are reachable. */ + +static struct pointer_set_t * +compute_visible_aliases (void) +{ + struct pointer_set_t *visible; + unsigned i; + alias_pair *p; + bool changed; + + /* We have to compute the set of visible nodes including aliases + themselves. */ + visible = pointer_set_create (); + do + { + changed = false; + for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); ++i) + { + struct cgraph_node *fnode = NULL; + struct varpool_node *vnode = NULL; + fnode = cgraph_node_for_asm (p->target); + vnode = (fnode == NULL) ? varpool_node_for_asm (p->target) : NULL; + if ((fnode + || vnode + || pointer_set_contains (visible, p->target)) + && !pointer_set_insert (visible, DECL_ASSEMBLER_NAME (p->decl))) + changed = true; + } + } + while (changed); + + return visible; +} + /* Remove the alias pairing for functions that are no longer in the call graph. */ void remove_unreachable_alias_pairs (void) { + struct pointer_set_t *visible; unsigned i; alias_pair *p; if (alias_pairs == NULL) return; + /* We have to compute the set of visible nodes including aliases + themselves. */ + visible = compute_visible_aliases (); + for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); ) { if (!DECL_EXTERNAL (p->decl)) @@ -5435,7 +5476,9 @@ remove_unreachable_alias_pairs (void) struct varpool_node *vnode = NULL; fnode = cgraph_node_for_asm (p->target); vnode = (fnode == NULL) ? varpool_node_for_asm (p->target) : NULL; - if (fnode == NULL && vnode == NULL) + if (!fnode + && !vnode + && !pointer_set_contains (visible, p->target)) { VEC_unordered_remove (alias_pair, alias_pairs, i); continue; @@ -5444,6 +5487,8 @@ remove_unreachable_alias_pairs (void) i++; } + + pointer_set_destroy (visible); } @@ -5453,9 +5498,17 @@ remove_unreachable_alias_pairs (void) void finish_aliases_1 (void) { + struct pointer_set_t *visible; unsigned i; alias_pair *p; + if (alias_pairs == NULL) + return; + + /* We have to compute the set of visible nodes including aliases + themselves. */ + visible = compute_visible_aliases (); + FOR_EACH_VEC_ELT (alias_pair, alias_pairs, i, p) { tree target_decl; @@ -5463,6 +5516,9 @@ finish_aliases_1 (void) target_decl = find_decl_and_mark_needed (p->decl, p->target); if (target_decl == NULL) { + if (pointer_set_contains (visible, p->target)) + continue; + if (! (p->emitted_diags & ALIAS_DIAG_TO_UNDEF) && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl))) { @@ -5485,6 +5541,8 @@ finish_aliases_1 (void) p->emitted_diags |= ALIAS_DIAG_TO_EXTERN; } } + + pointer_set_destroy (visible); } /* Second pass of completing pending aliases. Emit the actual assembly. |