From 8f69fd823ceae7b237d79b69e79ea794aa9b8622 Mon Sep 17 00:00:00 2001 From: rguenth Date: Fri, 4 Sep 2009 18:54:01 +0000 Subject: [PATCH] 2009-09-04 Richard Guenther PR middle-end/41257 * (cgraph_finalize_compilation_unit): Move finalizing aliases after emitting tunks. Move emitting thunks and ctors from ... (cgraph_optimize): ... here. Remove redundant cgraph_analyze_functions. * varasm.c (find_decl_and_mark_needed): Remove no longer necessary check. (finish_aliases_1): Adjust check for thunk aliases. * g++.dg/torture/pr41257.C: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151431 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 11 +++++ gcc/cgraphunit.c | 74 +++++++++++++++++----------------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/torture/pr41257.C | 20 +++++++++ gcc/varasm.c | 10 +---- 5 files changed, 75 insertions(+), 45 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr41257.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 34bc5c208af..6af6c2b1ab0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2009-09-04 Richard Guenther + + PR middle-end/41257 + * (cgraph_finalize_compilation_unit): Move finalizing aliases + after emitting tunks. Move emitting thunks and ctors from ... + (cgraph_optimize): ... here. Remove redundant + cgraph_analyze_functions. + * varasm.c (find_decl_and_mark_needed): Remove no longer + necessary check. + (finish_aliases_1): Adjust check for thunk aliases. + 2009-09-04 Daniel Gutson * config/arm/arm.md (ctzsi2): Added braces diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 1505b56c141..0acc4723f07 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1018,6 +1018,30 @@ cgraph_analyze_functions (void) ggc_collect (); } + +/* Emit thunks for every node in the cgraph. + FIXME: We really ought to emit thunks only for functions that are needed. */ + +static void +cgraph_emit_thunks (void) +{ + struct cgraph_node *n; + + for (n = cgraph_nodes; n; n = n->next) + { + /* Only emit thunks on functions defined in this TU. + Note that this may emit more thunks than strictly necessary. + During optimization some nodes may disappear. It would be + nice to only emit thunks only for the functions that will be + emitted, but we cannot know that until the inliner and other + IPA passes have run (see the sequencing of the call to + cgraph_mark_functions_to_output in cgraph_optimize). */ + if (!DECL_EXTERNAL (n->decl)) + lang_hooks.callgraph.emit_associated_thunks (n->decl); + } +} + + /* Analyze the whole compilation unit once it is parsed completely. */ void @@ -1026,8 +1050,16 @@ cgraph_finalize_compilation_unit (void) /* Do not skip analyzing the functions if there were errors, we miss diagnostics for following functions otherwise. */ + /* Emit size functions we didn't inline. */ finalize_size_functions (); - finish_aliases_1 (); + + /* Emit thunks, if needed. */ + if (lang_hooks.callgraph.emit_associated_thunks) + cgraph_emit_thunks (); + + /* Call functions declared with the "constructor" or "destructor" + attribute. */ + cgraph_build_cdtor_fns (); if (!quiet_flag) { @@ -1035,6 +1067,10 @@ cgraph_finalize_compilation_unit (void) fflush (stderr); } + /* Mark alias targets necessary and emit diagnostics. */ + finish_aliases_1 (); + + /* Gimplify and lower all functions. */ timevar_push (TV_CGRAPH); cgraph_analyze_functions (); timevar_pop (TV_CGRAPH); @@ -1322,29 +1358,6 @@ ipa_passes (void) } -/* Emit thunks for every node in the cgraph. - FIXME: We really ought to emit thunks only for functions that are needed. */ - -static void -cgraph_emit_thunks (void) -{ - struct cgraph_node *n; - - for (n = cgraph_nodes; n; n = n->next) - { - /* Only emit thunks on functions defined in this TU. - Note that this may emit more thunks than strictly necessary. - During optimization some nodes may disappear. It would be - nice to only emit thunks only for the functions that will be - emitted, but we cannot know that until the inliner and other - IPA passes have run (see the sequencing of the call to - cgraph_mark_functions_to_output in cgraph_optimize). */ - if (!DECL_EXTERNAL (n->decl)) - lang_hooks.callgraph.emit_associated_thunks (n->decl); - } -} - - /* Perform simple optimizations based on callgraph. */ static void @@ -1357,22 +1370,9 @@ cgraph_optimize (void) verify_cgraph (); #endif - /* Emit thunks, if needed. */ - if (lang_hooks.callgraph.emit_associated_thunks) - { - cgraph_emit_thunks (); - if (errorcount || sorrycount) - return; - } - - /* Call functions declared with the "constructor" or "destructor" - attribute. */ - cgraph_build_cdtor_fns (); - /* Frontend may output common variables after the unit has been finalized. It is safe to deal with them here as they are always zero initialized. */ varpool_analyze_pending_decls (); - cgraph_analyze_functions (); timevar_push (TV_CGRAPHOPT); if (pre_ipa_mem_report) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d51cc0215f4..b9c772b5ac9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-09-04 Richard Guenther + + PR middle-end/41257 + * g++.dg/torture/pr41257.C: New testcase. + 2009-09-04 Martin Jambor PR tree-optimization/41112 diff --git a/gcc/testsuite/g++.dg/torture/pr41257.C b/gcc/testsuite/g++.dg/torture/pr41257.C new file mode 100644 index 00000000000..60cfc533979 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr41257.C @@ -0,0 +1,20 @@ +/* { dg-do compile } */ + +struct A +{ + virtual void foo(); + virtual ~A(); + int i; +}; + +struct B : virtual A {}; + +struct C : B +{ + virtual void foo(); +}; + +void bar() +{ + C().foo(); +} diff --git a/gcc/varasm.c b/gcc/varasm.c index d7f861195ff..864ab16671f 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -5395,13 +5395,7 @@ find_decl_and_mark_needed (tree decl, tree target) if (fnode) { - /* We can't mark function nodes as used after cgraph global info - is finished. This wouldn't generally be necessary, but C++ - virtual table thunks are introduced late in the game and - might seem like they need marking, although in fact they - don't. */ - if (! cgraph_global_info_ready) - cgraph_mark_needed_node (fnode); + cgraph_mark_needed_node (fnode); return fnode->decl; } else if (vnode) @@ -5571,7 +5565,7 @@ finish_aliases_1 (void) to bind locally. Of course this is a hack - to keep it working do the following (which is not strictly correct). */ && (! TREE_CODE (target_decl) == FUNCTION_DECL - || ! TREE_STATIC (target_decl)) + || ! DECL_VIRTUAL_P (target_decl)) && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl))) error ("%q+D aliased to external symbol %qE", p->decl, p->target); -- 2.11.0