summaryrefslogtreecommitdiff
path: root/gcc/cgraph.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2013-08-19 10:14:06 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2013-08-19 10:14:06 +0000
commit5514adf9c7e76a087763a627c7b72d4e1da6b928 (patch)
tree6500dfce0eb1776cd3cf03771e785f6de3bc1607 /gcc/cgraph.c
parent837c3aa399e5ddbbb088600589977c6bc47344f8 (diff)
downloadgcc-5514adf9c7e76a087763a627c7b72d4e1da6b928.tar.gz
* Makeifle-in (ipa-devirt.o): New.
(GTFILES): Add ipa-utils.h and ipa-devirt.c * cgraphunit.c (decide_is_symbol_needed): Do not care about virtuals. (analyze_functions): Look into possible targets of polymorphic call. * dumpfile.c (dump_files): Add type-inheritance dump. * dumpfile.h (TDI_inheritance): New. * ipa-devirt.c: New file. * ipa-utils.h (odr_type_d): Forward declare. (odr_type): New type. (build_type_inheritance_graph): Declare. (possible_polymorphic_call_targets): Declare and introduce inline variant when only edge is pased. (dump_possible_polymorphic_call_targets): Likewise. * timevar.def (TV_IPA_INHERITANCE, TV_IPA_VIRTUAL_CALL): New. * tree.c (type_in_anonymous_namespace_p): Break out from ... (types_same_for_odr): ... here. * tree.h (type_in_anonymous_namespace_p): Declare. * g++.dg/ipa/type-inheritance-1.C: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@201836 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cgraph.c')
-rw-r--r--gcc/cgraph.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index e2f96d6436d..c6850c60c31 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1292,10 +1292,13 @@ cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
struct ipa_ref *ref;
cgraph_speculative_call_info (e, e, e2, ref);
- if (gimple_call_fndecl (e->call_stmt))
- e = cgraph_resolve_speculation (e, gimple_call_fndecl (e->call_stmt));
- if (!gimple_check_call_matching_types (e->call_stmt, e->callee->symbol.decl,
- true))
+ /* If there already is an direct call (i.e. as a result of inliner's substitution),
+ forget about speculating. */
+ if (decl)
+ e = cgraph_resolve_speculation (e, decl);
+ /* If types do not match, speculation was likely wrong. */
+ else if (!gimple_check_call_matching_types (e->call_stmt, e->callee->symbol.decl,
+ true))
{
e = cgraph_resolve_speculation (e, NULL);
if (dump_file)
@@ -1304,6 +1307,7 @@ cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
xstrdup (cgraph_node_name (e->caller)), e->caller->symbol.order,
xstrdup (cgraph_node_name (e->callee)), e->callee->symbol.order);
}
+ /* Expand speculation into GIMPLE code. */
else
{
if (dump_file)