cgraph.c (cgraph_create_indirect_edge): Discover polymorphic calls and record basic info into indirect_info.

* cgraph.c (cgraph_create_indirect_edge): Discover
	polymorphic calls and record basic info into indirect_info.
	* gimple-fold.c (gimple_fold_call): When doing BINFO based
	devirtualization, ignore objc function calls.
	* ipa-cp.c (initialize_node_lattices): Be ready for polymorphic
	call with no parm index info.
	* ipa-prop.c (ipa_analyze_call_uses): Likewise.
	* tree.c (virtual_method_call_p): New function.
	* tree.h (virtual_method_call_p): Declare.

From-SVN: r201824
This commit is contained in:
Jan Hubicka 2013-08-18 11:22:42 +02:00 committed by Jan Hubicka
parent 34fdd6b31e
commit 1d5755efee
7 changed files with 56 additions and 3 deletions

View File

@ -1,3 +1,15 @@
2013-08-18 Jan Hubicka <jh@suse.cz>
* cgraph.c (cgraph_create_indirect_edge): Discover
polymorphic calls and record basic info into indirect_info.
* gimple-fold.c (gimple_fold_call): When doing BINFO based
devirtualization, ignore objc function calls.
* ipa-cp.c (initialize_node_lattices): Be ready for polymorphic
call with no parm index info.
* ipa-prop.c (ipa_analyze_call_uses): Likewise.
* tree.c (virtual_method_call_p): New function.
* tree.h (virtual_method_call_p): Declare.
2013-08-16 Jan Hubicka <jh@suse.cz>
PR middle-end/58179

View File

@ -925,6 +925,7 @@ cgraph_create_indirect_edge (struct cgraph_node *caller, gimple call_stmt,
{
struct cgraph_edge *edge = cgraph_create_edge_1 (caller, NULL, call_stmt,
count, freq);
tree target;
edge->indirect_unknown_callee = 1;
initialize_inline_failed (edge);
@ -932,6 +933,23 @@ cgraph_create_indirect_edge (struct cgraph_node *caller, gimple call_stmt,
edge->indirect_info = cgraph_allocate_init_indirect_info ();
edge->indirect_info->ecf_flags = ecf_flags;
/* Record polymorphic call info. */
if (call_stmt
&& (target = gimple_call_fn (call_stmt))
&& virtual_method_call_p (target))
{
tree type = obj_type_ref_class (target);
/* Only record types can have virtual calls. */
gcc_assert (TREE_CODE (type) == RECORD_TYPE);
edge->indirect_info->param_index = -1;
edge->indirect_info->otr_token
= tree_low_cst (OBJ_TYPE_REF_TOKEN (target), 1);
edge->indirect_info->otr_type = type;
edge->indirect_info->polymorphic = 1;
}
edge->next_callee = caller->indirect_calls;
if (caller->indirect_calls)
caller->indirect_calls->prev_callee = edge;

View File

@ -1105,7 +1105,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
gimple_call_set_fn (stmt, OBJ_TYPE_REF_EXPR (callee));
changed = true;
}
else
else if (virtual_method_call_p (callee))
{
tree obj = OBJ_TYPE_REF_OBJECT (callee);
tree binfo = gimple_extract_devirt_binfo_from_cst

View File

@ -734,7 +734,8 @@ initialize_node_lattices (struct cgraph_node *node)
}
for (ie = node->indirect_calls; ie; ie = ie->next_callee)
if (ie->indirect_info->polymorphic)
if (ie->indirect_info->polymorphic
&& ie->indirect_info->param_index >= 0)
{
gcc_checking_assert (ie->indirect_info->param_index >= 0);
ipa_get_parm_lattices (info,

View File

@ -1922,7 +1922,7 @@ ipa_analyze_call_uses (struct cgraph_node *node,
return;
if (TREE_CODE (target) == SSA_NAME)
ipa_analyze_indirect_call_uses (node, info, parms_ainfo, call, target);
else if (TREE_CODE (target) == OBJ_TYPE_REF)
else if (virtual_method_call_p (target))
ipa_analyze_virtual_call_uses (node, info, call, target);
}

View File

@ -11864,6 +11864,27 @@ types_same_for_odr (tree type1, tree type2)
return true;
}
/* TARGET is a call target of GIMPLE call statement
(obtained by gimple_call_fn). Return true if it is
OBJ_TYPE_REF representing an virtual call of C++ method.
(As opposed to OBJ_TYPE_REF representing objc calls
through a cast where middle-end devirtualization machinery
can't apply.) */
bool
virtual_method_call_p (tree target)
{
if (TREE_CODE (target) != OBJ_TYPE_REF)
return false;
target = TREE_TYPE (target);
gcc_checking_assert (TREE_CODE (target) == POINTER_TYPE);
target = TREE_TYPE (target);
if (TREE_CODE (target) == FUNCTION_TYPE)
return false;
gcc_checking_assert (TREE_CODE (target) == METHOD_TYPE);
return true;
}
/* REF is OBJ_TYPE_REF, return the class the ref corresponds to. */
tree

View File

@ -5974,6 +5974,7 @@ extern location_t tree_nonartificial_location (tree);
extern tree block_ultimate_origin (const_tree);
extern tree get_binfo_at_offset (tree, HOST_WIDE_INT, tree);
extern bool virtual_method_call_p (tree);
extern tree obj_type_ref_class (tree ref);
extern bool types_same_for_odr (tree type1, tree type2);
extern tree get_ref_base_and_extent (tree, HOST_WIDE_INT *,