cgraph.h (struct indirect_call_info): Add IN_POLYMORPHIC_CDTOR

* cgraph.h (struct indirect_call_info): Add IN_POLYMORPHIC_CDTOR
	* lto-cgraph.c (lto_output_edge, input_edge): Stream
	in_polymorphic_cdtor
	* cgraph.c (symbol_table::create_edge): Compute in_polymorphic_cdtor.
	(cgraph_edge::make_speculative): Copy in_polymorphic_cdtor.
	* cgraphclones.c (cgraph_edge::clone): Likewise.
	* ipa-prop.c (update_jump_functions_after_inlining, 
	try_make_edge_direct_virtual_call): Pass in_polymorphic_cdtor
	to possible_dynamic_type_change.
	(decl_maybe_in_construction_p): Allow empty OUTER_TYPE and BASE.
	(ipa_polymorphic_call_context::possible_dynamic_type_change): Add
	IN_POLY_CDOTR argument.

From-SVN: r215871
This commit is contained in:
Jan Hubicka 2014-10-03 21:52:11 +02:00 committed by Jan Hubicka
parent 8a5b2f56c4
commit f9bb202b35
6 changed files with 33 additions and 4 deletions

View file

@ -1,3 +1,18 @@
2014-10-03 Jan Hubicka <hubicka@ucw.cz>
* cgraph.h (struct indirect_call_info): Add IN_POLYMORPHIC_CDTOR
* lto-cgraph.c (lto_output_edge, input_edge): Stream
in_polymorphic_cdtor
* cgraph.c (symbol_table::create_edge): Compute in_polymorphic_cdtor.
(cgraph_edge::make_speculative): Copy in_polymorphic_cdtor.
* cgraphclones.c (cgraph_edge::clone): Likewise.
* ipa-prop.c (update_jump_functions_after_inlining,
try_make_edge_direct_virtual_call): Pass in_polymorphic_cdtor
to possible_dynamic_type_change.
(decl_maybe_in_construction_p): Allow empty OUTER_TYPE and BASE.
(ipa_polymorphic_call_context::possible_dynamic_type_change): Add
IN_POLY_CDOTR argument.
2014-10-03 Jakub Jelinek <jakub@redhat.com>
* config/i386/i386.c (ix86_expand_vec_perm_vpermi2): Fix up formatting.

View file

@ -819,6 +819,12 @@ symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee,
edge->indirect_inlining_edge = 0;
edge->speculative = false;
edge->indirect_unknown_callee = indir_unknown_callee;
if (flag_devirtualize && call_stmt && DECL_STRUCT_FUNCTION (caller->decl))
edge->in_polymorphic_cdtor
= decl_maybe_in_construction_p (NULL, NULL, call_stmt,
caller->decl);
else
edge->in_polymorphic_cdtor = caller->thunk.thunk_p;
if (call_stmt && caller->call_site_hash)
cgraph_add_edge_to_call_site_hash (edge);
@ -1033,6 +1039,7 @@ cgraph_edge::make_speculative (cgraph_node *n2, gcov_type direct_count,
else
e2->can_throw_external = can_throw_external;
e2->lto_stmt_uid = lto_stmt_uid;
e2->in_polymorphic_cdtor = in_polymorphic_cdtor;
count -= e2->count;
frequency -= e2->frequency;
symtab->call_edge_duplication_hooks (this, e2);

View file

@ -1333,7 +1333,7 @@ public:
void offset_by (HOST_WIDE_INT);
/* Use when we can not track dynamic type change. This speculatively assume
type change is not happening. */
void possible_dynamic_type_change (tree otr_type = NULL);
void possible_dynamic_type_change (bool, tree otr_type = NULL);
/* Assume that both THIS and a given context is valid and strenghten THIS
if possible. Return true if any strenghtening was made.
If actual type the context is being used in is known, OTR_TYPE should be
@ -1512,6 +1512,9 @@ struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgrap
Optimizers may later redirect direct call to clone, so 1) and 3)
do not need to necesarily agree with destination. */
unsigned int speculative : 1;
/* Set to true when caller is a constructor or destructor of polymorphic
type. */
unsigned in_polymorphic_cdtor : 1;
private:
/* Remove the edge from the list of the callers of the callee. */

View file

@ -159,6 +159,7 @@ cgraph_edge::clone (cgraph_node *n, gimple call_stmt, unsigned stmt_uid,
new_edge->can_throw_external = can_throw_external;
new_edge->call_stmt_cannot_inline_p = call_stmt_cannot_inline_p;
new_edge->speculative = speculative;
new_edge->in_polymorphic_cdtor = in_polymorphic_cdtor;
if (update_original)
{
count -= new_edge->count;

View file

@ -2652,7 +2652,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
/* TODO: Make type preserved safe WRT contexts. */
if (!dst->value.ancestor.agg_preserved)
ctx.possible_dynamic_type_change ();
ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
ctx.offset_by (dst->value.ancestor.offset);
if (!ctx.useless_p ())
{
@ -2722,7 +2722,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
/* TODO: Make type preserved safe WRT contexts. */
if (!dst->value.ancestor.agg_preserved)
ctx.possible_dynamic_type_change ();
ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
if (!ctx.useless_p ())
{
if (!dst_ctx)
@ -3128,7 +3128,8 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
/* TODO: We want to record if type change happens.
Old code did not do that that seems like a bug. */
ctx.possible_dynamic_type_change (ie->indirect_info->otr_type);
ctx.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
ie->indirect_info->otr_type);
updated = ie->indirect_info->context.combine_with
(ctx, ie->indirect_info->otr_type);

View file

@ -284,6 +284,7 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge,
bp_pack_value (&bp, edge->speculative, 1);
bp_pack_value (&bp, edge->call_stmt_cannot_inline_p, 1);
bp_pack_value (&bp, edge->can_throw_external, 1);
bp_pack_value (&bp, edge->in_polymorphic_cdtor, 1);
if (edge->indirect_unknown_callee)
{
int flags = edge->indirect_info->ecf_flags;
@ -1366,6 +1367,7 @@ input_edge (struct lto_input_block *ib, vec<symtab_node *> nodes,
edge->inline_failed = inline_failed;
edge->call_stmt_cannot_inline_p = bp_unpack_value (&bp, 1);
edge->can_throw_external = bp_unpack_value (&bp, 1);
edge->in_polymorphic_cdtor = bp_unpack_value (&bp, 1);
if (indirect)
{
if (bp_unpack_value (&bp, 1))