From b25833451bbe9b8a2194598b026cea071f4e9e65 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 18 Nov 2009 10:53:52 +0100 Subject: re PR c++/3187 (gcc lays down two copies of constructors) PR c++/3187 * cgraph.h (struct cgraph_node): Add same_body and same_body_alias fields. (cgraph_same_body_alias, cgraph_remove_same_body_alias): New prototypes. * cgraphunit.c (cgraph_expand_function, cgraph_emit_thunks, cgraph_materialize_all_clones): Handle same_body aliases. * cgraph.c (cgraph_allocate_node): New function. (cgraph_create_node): Use it. (cgraph_node_for_decl, cgraph_node, cgraph_get_node, cgraph_node_for_asm, cgraph_remove_node): Handle same_body aliases. (cgraph_same_body_alias, cgraph_remove_same_body_alias): New functions. * lto-cgraph.c (lto_output_node): Stream out same_body aliases. (input_node): Stream in same_body aliases. * lto-symtab.c (lto_cgraph_replace_node): Clear node pointers for same_body aliases. (lto_symtab_merge_cgraph_nodes_1): Handle same_body aliases. * cp-tree.h (expand_or_defer_fn_1): New prototype. * decl2.c (cp_write_global_declarations): Mark as !DECL_EXTERNAL also all same_body aliases. * semantics.c (expand_or_defer_fn): Move most of the function except registering with cgraph to ... (expand_or_defer_fn_1): ... here. New function. * optimize.c: Include cgraph.h. (maybe_clone_body): If in charge parm is not used and both base and complete clones are created and are not comdat, tell cgraph they have the same body. * Make-lang.in (cp/optimize.o): Depend on $(CGRAPH_H). * g++.dg/abi/mangle26.C: Also match *C2* definition. * g++.dg/abi/mangle27.C: Likewise. * g++.dg/abi/mangle28.C: Likewise. * g++.dg/abi/mangle29.C: Likewise. From-SVN: r154284 --- gcc/cgraphunit.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'gcc/cgraphunit.c') diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 2c232a5..e934b3d 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1040,7 +1040,7 @@ cgraph_analyze_functions (void) static void cgraph_emit_thunks (void) { - struct cgraph_node *n; + struct cgraph_node *n, *alias; for (n = cgraph_nodes; n; n = n->next) { @@ -1053,7 +1053,12 @@ cgraph_emit_thunks (void) cgraph_mark_functions_to_output in cgraph_optimize). */ if (n->reachable && !DECL_EXTERNAL (n->decl)) - lang_hooks.callgraph.emit_associated_thunks (n->decl); + { + lang_hooks.callgraph.emit_associated_thunks (n->decl); + for (alias = n->same_body; alias; alias = alias->next) + if (!DECL_EXTERNAL (alias->decl)) + lang_hooks.callgraph.emit_associated_thunks (alias->decl); + } } } @@ -1175,6 +1180,14 @@ cgraph_expand_function (struct cgraph_node *node) /* Make sure that BE didn't give up on compiling. */ gcc_assert (TREE_ASM_WRITTEN (decl)); current_function_decl = NULL; + if (node->same_body) + { + struct cgraph_node *alias; + bool saved_alias = node->alias; + for (alias = node->same_body; alias; alias = alias->next) + assemble_alias (alias->decl, DECL_ASSEMBLER_NAME (decl)); + node->alias = saved_alias; + } gcc_assert (!cgraph_preserve_function_body_p (decl)); cgraph_release_function_body (node); /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer @@ -1924,7 +1937,22 @@ cgraph_materialize_all_clones (void) { gimple new_stmt; gimple_stmt_iterator gsi; - + + if (e->callee->same_body) + { + struct cgraph_node *alias; + + for (alias = e->callee->same_body; + alias; + alias = alias->next) + if (decl == alias->decl) + break; + /* Don't update call from same body alias to the real + function. */ + if (alias) + continue; + } + if (cgraph_dump_file) { fprintf (cgraph_dump_file, "updating call of %s in %s:", -- cgit v1.1