aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2010-09-19 01:13:17 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2010-09-18 23:13:17 +0000
commit9b389a5e64f957b30eb05315b7e15a649a8e1f66 (patch)
tree863c05e9f2399d3ae354b494076e8a668b4ee323
parent1151446c17ede83ed30b2bfc68137e7573ed0d99 (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--gcc/cgraphunit.c8
-rw-r--r--gcc/ipa-inline.c6
-rw-r--r--gcc/ipa-prop.c1
-rw-r--r--gcc/ipa.c7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr45453.C19
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);
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 8c0ca86..e4835c1 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -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" } }