Message ID | 20100706115549.GA12425@kam.mff.cuni.cz |
---|---|
State | New |
Headers | show |
On Tue, Jul 6, 2010 at 1:55 PM, Jan Hubicka <hubicka@ucw.cz> wrote: >> Changelog is incomplete (missing cgraph.h change). >> >> Otherwise it makes sense. >> >> Thanks, >> Richard. > > Must've got incomplette file somehow. This is full version I am re-testing now. > OK if it passes? Yes. Thanks, Richard. > * lto-symtab.c (lto_cgraph_replace_node): Handle aliases. > (lto_symtab_resolve_can_prevail_p): Also alias of cgraph node > with body can prevail. > (lto_symtab_resolve_symbols): Use cgraph_get_node_or_alias. > (lto_symtab_merge_cgraph_nodes_1): Do not remove nodes from aliases. > * cgraph.c (cgraph_get_node_or_alias): New function. > * cgraph.h (cgraph_get_node_or_alias): Declare. > Index: lto-symtab.c > =================================================================== > --- lto-symtab.c (revision 161847) > +++ lto-symtab.c (working copy) > @@ -206,6 +206,24 @@ lto_cgraph_replace_node (struct cgraph_n > struct cgraph_node *prevailing_node) > { > struct cgraph_edge *e, *next; > + bool no_aliases_please = false; > + > + if (cgraph_dump_file) > + { > + fprintf (cgraph_dump_file, "Replacing cgraph node %s/%i by %s/%i" > + " for symbol %s\n", > + cgraph_node_name (node), node->uid, > + cgraph_node_name (prevailing_node), > + prevailing_node->uid, > + IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl))); > + } > + > + if (prevailing_node->same_body_alias) > + { > + if (prevailing_node->thunk.thunk_p) > + no_aliases_please = true; > + prevailing_node = prevailing_node->same_body; > + } > > /* Merge node flags. */ > if (node->needed) > @@ -227,27 +244,37 @@ lto_cgraph_replace_node (struct cgraph_n > /* Redirect incomming references. */ > ipa_clone_refering (prevailing_node, NULL, &node->ref_list); > > - if (node->same_body) > + /* If we have aliases, redirect them to the prevailing node. */ > + if (!node->same_body_alias && node->same_body) > { > - struct cgraph_node *alias; > + struct cgraph_node *alias, *last; > + /* We prevail aliases/tunks by a thunk. This is doable but > + would need thunk combination. Hopefully no ABI changes will > + every be crazy enough. */ > + gcc_assert (!no_aliases_please); > > for (alias = node->same_body; alias; alias = alias->next) > - if (DECL_ASSEMBLER_NAME_SET_P (alias->decl)) > - { > - lto_symtab_entry_t se > - = lto_symtab_get (DECL_ASSEMBLER_NAME (alias->decl)); > - > - for (; se; se = se->next) > - if (se->node == node) > - { > - se->node = NULL; > - break; > - } > - } > + { > + last = alias; > + gcc_assert (alias->same_body_alias); > + alias->same_body = prevailing_node; > + alias->thunk.alias = prevailing_node->decl; > + } > + last->next = prevailing_node->same_body; > + /* Node with aliases is prevailed by alias. > + We could handle this, but combining thunks together will be tricky. > + Hopefully this does not happen. */ > + if (prevailing_node->same_body) > + prevailing_node->same_body->previous = last; > + prevailing_node->same_body = node->same_body; > + node->same_body = NULL; > } > > /* Finally remove the replaced node. */ > - cgraph_remove_node (node); > + if (node->same_body_alias) > + cgraph_remove_same_body_alias (node); > + else > + cgraph_remove_node (node); > } > > /* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging > @@ -433,7 +460,9 @@ lto_symtab_resolve_can_prevail_p (lto_sy > > /* For functions we need a non-discarded body. */ > if (TREE_CODE (e->decl) == FUNCTION_DECL) > - return (e->node && e->node->analyzed); > + return (e->node > + && (e->node->analyzed > + || (e->node->same_body_alias && e->node->same_body->analyzed))); > > /* A variable should have a size. */ > else if (TREE_CODE (e->decl) == VAR_DECL) > @@ -461,7 +490,7 @@ lto_symtab_resolve_symbols (void **slot) > for (e = (lto_symtab_entry_t) *slot; e; e = e->next) > { > if (TREE_CODE (e->decl) == FUNCTION_DECL) > - e->node = cgraph_get_node (e->decl); > + e->node = cgraph_get_node_or_alias (e->decl); > else if (TREE_CODE (e->decl) == VAR_DECL) > { > e->vnode = varpool_get_node (e->decl); > @@ -751,22 +780,7 @@ lto_symtab_merge_cgraph_nodes_1 (void ** > for (e = prevailing->next; e; e = e->next) > { > if (e->node != NULL) > - { > - if (e->node->decl != e->decl && e->node->same_body) > - { > - struct cgraph_node *alias; > - > - for (alias = e->node->same_body; alias; alias = alias->next) > - if (alias->decl == e->decl) > - break; > - if (alias) > - { > - cgraph_remove_same_body_alias (alias); > - continue; > - } > - } > - lto_cgraph_replace_node (e->node, prevailing->node); > - } > + lto_cgraph_replace_node (e->node, prevailing->node); > if (e->vnode != NULL) > lto_varpool_replace_node (e->vnode, prevailing->vnode); > } > Index: cgraph.c > =================================================================== > --- cgraph.c (revision 161847) > +++ cgraph.c (working copy) > @@ -604,6 +604,29 @@ cgraph_add_thunk (tree alias, tree decl, > is assigned. */ > > +/* Returns the cgraph or alias node assigned to DECL or NULL if no cgraph node > + is assigned. */ > + > struct cgraph_node * > +cgraph_get_node_or_alias (tree decl) > +{ > + struct cgraph_node key, *node = NULL, **slot; > + > + gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); > + > + if (!cgraph_hash) > + return NULL; > + > + key.decl = decl; > + > + slot = (struct cgraph_node **) htab_find_slot (cgraph_hash, &key, > + NO_INSERT); > + > + if (slot && *slot) > + node = *slot; > + return node; > +} > + > +/* Returns the cgraph node assigned to DECL or NULL if no cgraph node > + is assigned. */ > + > +struct cgraph_node * > cgraph_get_node (tree decl) > { > struct cgraph_node key, *node = NULL, **slot; > Index: cgraph.h > =================================================================== > --- cgraph.h (revision 161866) > +++ cgraph.h (working copy) > @@ -556,6 +560,7 @@ struct cgraph_edge *cgraph_create_edge ( > struct cgraph_edge *cgraph_create_indirect_edge (struct cgraph_node *, gimple, int, > gcov_type, int, int); > struct cgraph_node * cgraph_get_node (tree); > +struct cgraph_node * cgraph_get_node_or_alias (tree); > struct cgraph_node *cgraph_node (tree); > bool cgraph_same_body_alias (tree, tree); > void cgraph_add_thunk (tree, tree, bool, HOST_WIDE_INT, HOST_WIDE_INT, tree, tree); >
Index: lto-symtab.c =================================================================== --- lto-symtab.c (revision 161847) +++ lto-symtab.c (working copy) @@ -206,6 +206,24 @@ lto_cgraph_replace_node (struct cgraph_n struct cgraph_node *prevailing_node) { struct cgraph_edge *e, *next; + bool no_aliases_please = false; + + if (cgraph_dump_file) + { + fprintf (cgraph_dump_file, "Replacing cgraph node %s/%i by %s/%i" + " for symbol %s\n", + cgraph_node_name (node), node->uid, + cgraph_node_name (prevailing_node), + prevailing_node->uid, + IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl))); + } + + if (prevailing_node->same_body_alias) + { + if (prevailing_node->thunk.thunk_p) + no_aliases_please = true; + prevailing_node = prevailing_node->same_body; + } /* Merge node flags. */ if (node->needed) @@ -227,27 +244,37 @@ lto_cgraph_replace_node (struct cgraph_n /* Redirect incomming references. */ ipa_clone_refering (prevailing_node, NULL, &node->ref_list); - if (node->same_body) + /* If we have aliases, redirect them to the prevailing node. */ + if (!node->same_body_alias && node->same_body) { - struct cgraph_node *alias; + struct cgraph_node *alias, *last; + /* We prevail aliases/tunks by a thunk. This is doable but + would need thunk combination. Hopefully no ABI changes will + every be crazy enough. */ + gcc_assert (!no_aliases_please); for (alias = node->same_body; alias; alias = alias->next) - if (DECL_ASSEMBLER_NAME_SET_P (alias->decl)) - { - lto_symtab_entry_t se - = lto_symtab_get (DECL_ASSEMBLER_NAME (alias->decl)); - - for (; se; se = se->next) - if (se->node == node) - { - se->node = NULL; - break; - } - } + { + last = alias; + gcc_assert (alias->same_body_alias); + alias->same_body = prevailing_node; + alias->thunk.alias = prevailing_node->decl; + } + last->next = prevailing_node->same_body; + /* Node with aliases is prevailed by alias. + We could handle this, but combining thunks together will be tricky. + Hopefully this does not happen. */ + if (prevailing_node->same_body) + prevailing_node->same_body->previous = last; + prevailing_node->same_body = node->same_body; + node->same_body = NULL; } /* Finally remove the replaced node. */ - cgraph_remove_node (node); + if (node->same_body_alias) + cgraph_remove_same_body_alias (node); + else + cgraph_remove_node (node); } /* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging @@ -433,7 +460,9 @@ lto_symtab_resolve_can_prevail_p (lto_sy /* For functions we need a non-discarded body. */ if (TREE_CODE (e->decl) == FUNCTION_DECL) - return (e->node && e->node->analyzed); + return (e->node + && (e->node->analyzed + || (e->node->same_body_alias && e->node->same_body->analyzed))); /* A variable should have a size. */ else if (TREE_CODE (e->decl) == VAR_DECL) @@ -461,7 +490,7 @@ lto_symtab_resolve_symbols (void **slot) for (e = (lto_symtab_entry_t) *slot; e; e = e->next) { if (TREE_CODE (e->decl) == FUNCTION_DECL) - e->node = cgraph_get_node (e->decl); + e->node = cgraph_get_node_or_alias (e->decl); else if (TREE_CODE (e->decl) == VAR_DECL) { e->vnode = varpool_get_node (e->decl); @@ -751,22 +780,7 @@ lto_symtab_merge_cgraph_nodes_1 (void ** for (e = prevailing->next; e; e = e->next) { if (e->node != NULL) - { - if (e->node->decl != e->decl && e->node->same_body) - { - struct cgraph_node *alias; - - for (alias = e->node->same_body; alias; alias = alias->next) - if (alias->decl == e->decl) - break; - if (alias) - { - cgraph_remove_same_body_alias (alias); - continue; - } - } - lto_cgraph_replace_node (e->node, prevailing->node); - } + lto_cgraph_replace_node (e->node, prevailing->node); if (e->vnode != NULL) lto_varpool_replace_node (e->vnode, prevailing->vnode); } Index: cgraph.c =================================================================== --- cgraph.c (revision 161847) +++ cgraph.c (working copy) @@ -604,6 +604,29 @@ cgraph_add_thunk (tree alias, tree decl, is assigned. */ +/* Returns the cgraph or alias node assigned to DECL or NULL if no cgraph node + is assigned. */ + struct cgraph_node * +cgraph_get_node_or_alias (tree decl) +{ + struct cgraph_node key, *node = NULL, **slot; + + gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); + + if (!cgraph_hash) + return NULL; + + key.decl = decl; + + slot = (struct cgraph_node **) htab_find_slot (cgraph_hash, &key, + NO_INSERT); + + if (slot && *slot) + node = *slot; + return node; +} + +/* Returns the cgraph node assigned to DECL or NULL if no cgraph node + is assigned. */ + +struct cgraph_node * cgraph_get_node (tree decl) { struct cgraph_node key, *node = NULL, **slot; Index: cgraph.h =================================================================== --- cgraph.h (revision 161866) +++ cgraph.h (working copy) @@ -556,6 +560,7 @@ struct cgraph_edge *cgraph_create_edge ( struct cgraph_edge *cgraph_create_indirect_edge (struct cgraph_node *, gimple, int, gcov_type, int, int); struct cgraph_node * cgraph_get_node (tree); +struct cgraph_node * cgraph_get_node_or_alias (tree); struct cgraph_node *cgraph_node (tree); bool cgraph_same_body_alias (tree, tree); void cgraph_add_thunk (tree, tree, bool, HOST_WIDE_INT, HOST_WIDE_INT, tree, tree);