diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 30 | ||||
-rw-r--r-- | gcc/varpool.c | 6 |
3 files changed, 37 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5d28f99..edaa4b7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2011-10-19 Jan Hubicka <jh@suse.cz> + + * cgraphunit.c (handle_alias_pairs): Also handle wekref with destination + declared. + (output_weakrefs): New function. + * varpool.c (varpool_create_variable_alias): Handle external aliases. + 2011-10-19 Jakub Jelinek <jakub@redhat.com> * dwarf2out.c (loc_descriptor): For SUBREG pass SUBREG_REG's mode as diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 96c910c..26c69ae 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1219,7 +1219,6 @@ handle_alias_pairs (void) for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p);) { if (TREE_CODE (p->decl) == FUNCTION_DECL - && !lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) && (target_node = cgraph_node_for_asm (p->target)) != NULL) { src_node = cgraph_get_node (p->decl); @@ -1231,12 +1230,12 @@ handle_alias_pairs (void) However for weakref we insist on EXTERNAL flag being set. See gcc.dg/attr-alias-5.c */ if (DECL_EXTERNAL (p->decl)) - DECL_EXTERNAL (p->decl) = 0; + DECL_EXTERNAL (p->decl) = lookup_attribute ("weakref", + DECL_ATTRIBUTES (p->decl)) != NULL; cgraph_create_function_alias (p->decl, target_node->decl); VEC_unordered_remove (alias_pair, alias_pairs, i); } else if (TREE_CODE (p->decl) == VAR_DECL - && !lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) && (target_vnode = varpool_node_for_asm (p->target)) != NULL) { /* Normally EXTERNAL flag is used to mark external inlines, @@ -1245,7 +1244,8 @@ handle_alias_pairs (void) However for weakref we insist on EXTERNAL flag being set. See gcc.dg/attr-alias-5.c */ if (DECL_EXTERNAL (p->decl)) - DECL_EXTERNAL (p->decl) = 0; + DECL_EXTERNAL (p->decl) = lookup_attribute ("weakref", + DECL_ATTRIBUTES (p->decl)) != NULL; varpool_create_variable_alias (p->decl, target_vnode->decl); VEC_unordered_remove (alias_pair, alias_pairs, i); } @@ -2064,6 +2064,26 @@ ipa_passes (void) bitmap_obstack_release (NULL); } +/* Weakrefs may be associated to external decls and thus not output + at expansion time. Emit all neccesary aliases. */ + +void +output_weakrefs (void) +{ + struct cgraph_node *node; + struct varpool_node *vnode; + for (node = cgraph_nodes; node; node = node->next) + if (node->alias && node->thunk.alias && DECL_EXTERNAL (node->decl) + && !TREE_ASM_WRITTEN (node->decl)) + assemble_alias (node->decl, + DECL_ASSEMBLER_NAME (node->thunk.alias)); + for (vnode = varpool_nodes; vnode; vnode = vnode->next) + if (vnode->alias && vnode->alias_of && DECL_EXTERNAL (vnode->decl) + && !TREE_ASM_WRITTEN (vnode->decl)) + assemble_alias (vnode->decl, + DECL_ASSEMBLER_NAME (vnode->alias_of)); +} + /* Perform simple optimizations based on callgraph. */ @@ -2150,6 +2170,8 @@ cgraph_optimize (void) varpool_assemble_pending_decls (); } + + output_weakrefs (); cgraph_process_new_functions (); cgraph_state = CGRAPH_STATE_FINISHED; diff --git a/gcc/varpool.c b/gcc/varpool.c index d223779..e342a91 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -703,9 +703,11 @@ varpool_create_variable_alias (tree alias, tree decl) gcc_assert (TREE_CODE (alias) == VAR_DECL); alias_node = varpool_node (alias); alias_node->alias = 1; - alias_node->finalized = 1; + if (!DECL_EXTERNAL (alias)) + alias_node->finalized = 1; alias_node->alias_of = decl; - if (decide_is_variable_needed (alias_node, alias) + if ((!DECL_EXTERNAL (alias) + && decide_is_variable_needed (alias_node, alias)) || alias_node->needed) varpool_mark_needed_node (alias_node); return alias_node; |