diff options
author | Jan Hubicka <jh@suse.cz> | 2010-09-19 01:13:17 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2010-09-18 23:13:17 +0000 |
commit | 9b389a5e64f957b30eb05315b7e15a649a8e1f66 (patch) | |
tree | 863c05e9f2399d3ae354b494076e8a668b4ee323 | |
parent | 1151446c17ede83ed30b2bfc68137e7573ed0d99 (diff) | |
download | gcc-9b389a5e64f957b30eb05315b7e15a649a8e1f66.zip gcc-9b389a5e64f957b30eb05315b7e15a649a8e1f66.tar.gz gcc-9b389a5e64f957b30eb05315b7e15a649a8e1f66.tar.bz2 |
re PR tree-optimization/45453 (ICE: verify_cgraph_node failed: inlined_to pointer set for noninline callers with -O2 -fno-early-inlining)
PR tree-optimization/45453
* cgraphunit.c (cgraph_finalize_function): Consider comdat & external
virtual functions are reachable.
* ipa-inline.c (cgraph_clone_inlined_nodes): Likewise.
* ipa.c (cgraph_remove_unreachable_nodes): Likewise.
* ipa-prop.c (ipa_modify_formal_parameters): Clear DECL_VIRTUAL_P
when modifying function.
* g++.dg/tree-ssa/pr45453.C: New testcase.
From-SVN: r164405
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 8 | ||||
-rw-r--r-- | gcc/ipa-inline.c | 6 | ||||
-rw-r--r-- | gcc/ipa-prop.c | 1 | ||||
-rw-r--r-- | gcc/ipa.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tree-ssa/pr45453.C | 19 |
7 files changed, 54 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f650899..1258409 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2010-09-18 Jan Hubicka <jh@suse.cz> + PR tree-optimization/45453 + * cgraphunit.c (cgraph_finalize_function): Consider comdat & external + virtual functions are reachable. + * ipa-inline.c (cgraph_clone_inlined_nodes): Likewise. + * ipa.c (cgraph_remove_unreachable_nodes): Likewise. + * ipa-prop.c (ipa_modify_formal_parameters): Clear DECL_VIRTUAL_P + when modifying function. + +2010-09-18 Jan Hubicka <jh@suse.cz> + PR tree-optimization/45605 * cgraphunit.c (cgraph_analyze_functions): Allocate bitmap obstack. * gimple-fold.c (static_object_in_other_unit_p): New function. diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index f296fe0..e390ec6 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -363,7 +363,13 @@ cgraph_finalize_function (tree decl, bool nested) there. */ if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)) || DECL_STATIC_CONSTRUCTOR (decl) - || DECL_STATIC_DESTRUCTOR (decl)) + || DECL_STATIC_DESTRUCTOR (decl) + /* COMDAT virtual functions may be referenced by vtable from + other compilatoin unit. Still we want to devirtualize calls + to those so we need to analyze them. + FIXME: We should introduce may edges for this purpose and update + their handling in unreachable function removal and inliner too. */ + || (DECL_VIRTUAL_P (decl) && (DECL_COMDAT (decl) || DECL_EXTERNAL (decl)))) cgraph_mark_reachable_node (node); /* If we've not yet emitted decl, tell the debug info about it. */ diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 964d03b..21e0b64 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -251,6 +251,12 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, In that case just go ahead and re-use it. */ if (!e->callee->callers->next_caller && cgraph_can_remove_if_no_direct_calls_p (e->callee) + /* Inlining might enable more devirtualizing, so we want to remove + those only after all devirtualizable virtual calls are processed. + Lacking may edges in callgraph we just preserve them post + inlining. */ + && (!DECL_VIRTUAL_P (e->callee->decl) + || (!DECL_COMDAT (e->callee->decl) && !DECL_EXTERNAL (e->callee->decl))) /* Don't reuse if more than one function shares a comdat group. If the other function(s) are needed, we need to emit even this function out of line. */ diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index ec45d7c..e1d821e 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -2120,6 +2120,7 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments, } TREE_TYPE (fndecl) = new_type; + DECL_VIRTUAL_P (fndecl) = 0; if (otypes) VEC_free (tree, heap, otypes); VEC_free (tree, heap, oparms); @@ -238,7 +238,12 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file) #endif varpool_reset_queue (); for (node = cgraph_nodes; node; node = node->next) - if (!cgraph_can_remove_if_no_direct_calls_and_refs_p (node) + if ((!cgraph_can_remove_if_no_direct_calls_and_refs_p (node) + /* Keep around virtual functions for possible devirtualization. */ + || (!before_inlining_p + && !node->global.inlined_to + && DECL_VIRTUAL_P (node->decl) + && (DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl)))) && ((!DECL_EXTERNAL (node->decl)) || before_inlining_p)) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 56d0fbd..805e4b8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-09-18 Jan Hubicka <jh@suse.cz> + + PR tree-optimization/45453 + * g++.dg/tree-ssa/pr45453.C: New testcase. + 2010-09-18 Jason Merrill <jason@redhat.com> * g++.dg/cpp0x/initlist44.C: New. diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr45453.C b/gcc/testsuite/g++.dg/tree-ssa/pr45453.C new file mode 100644 index 0000000..78c6460 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr45453.C @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +struct S +{ + S(); + virtual inline void foo () + { + foo(); + } +}; + +void +B () +{ + S().foo (); +} +/* We should inline foo and devirtualize call to foo in the inlined version. */ +// { dg-final { scan-tree-dump-times "OBJ_TYPE_REF" 1 "optimized" } } +// { dg-final { cleanup-tree-dump "optimized" } } |