Commit f9bb202b by Jan Hubicka Committed by Jan Hubicka

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
parent 8a5b2f56
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> 2014-10-03 Jakub Jelinek <jakub@redhat.com>
* config/i386/i386.c (ix86_expand_vec_perm_vpermi2): Fix up formatting. * config/i386/i386.c (ix86_expand_vec_perm_vpermi2): Fix up formatting.
...@@ -819,6 +819,12 @@ symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee, ...@@ -819,6 +819,12 @@ symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee,
edge->indirect_inlining_edge = 0; edge->indirect_inlining_edge = 0;
edge->speculative = false; edge->speculative = false;
edge->indirect_unknown_callee = indir_unknown_callee; 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) if (call_stmt && caller->call_site_hash)
cgraph_add_edge_to_call_site_hash (edge); cgraph_add_edge_to_call_site_hash (edge);
...@@ -1033,6 +1039,7 @@ cgraph_edge::make_speculative (cgraph_node *n2, gcov_type direct_count, ...@@ -1033,6 +1039,7 @@ cgraph_edge::make_speculative (cgraph_node *n2, gcov_type direct_count,
else else
e2->can_throw_external = can_throw_external; e2->can_throw_external = can_throw_external;
e2->lto_stmt_uid = lto_stmt_uid; e2->lto_stmt_uid = lto_stmt_uid;
e2->in_polymorphic_cdtor = in_polymorphic_cdtor;
count -= e2->count; count -= e2->count;
frequency -= e2->frequency; frequency -= e2->frequency;
symtab->call_edge_duplication_hooks (this, e2); symtab->call_edge_duplication_hooks (this, e2);
......
...@@ -1333,7 +1333,7 @@ public: ...@@ -1333,7 +1333,7 @@ public:
void offset_by (HOST_WIDE_INT); void offset_by (HOST_WIDE_INT);
/* Use when we can not track dynamic type change. This speculatively assume /* Use when we can not track dynamic type change. This speculatively assume
type change is not happening. */ 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 /* Assume that both THIS and a given context is valid and strenghten THIS
if possible. Return true if any strenghtening was made. if possible. Return true if any strenghtening was made.
If actual type the context is being used in is known, OTR_TYPE should be 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 ...@@ -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) Optimizers may later redirect direct call to clone, so 1) and 3)
do not need to necesarily agree with destination. */ do not need to necesarily agree with destination. */
unsigned int speculative : 1; unsigned int speculative : 1;
/* Set to true when caller is a constructor or destructor of polymorphic
type. */
unsigned in_polymorphic_cdtor : 1;
private: private:
/* Remove the edge from the list of the callers of the callee. */ /* Remove the edge from the list of the callers of the callee. */
......
...@@ -159,6 +159,7 @@ cgraph_edge::clone (cgraph_node *n, gimple call_stmt, unsigned stmt_uid, ...@@ -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->can_throw_external = can_throw_external;
new_edge->call_stmt_cannot_inline_p = call_stmt_cannot_inline_p; new_edge->call_stmt_cannot_inline_p = call_stmt_cannot_inline_p;
new_edge->speculative = speculative; new_edge->speculative = speculative;
new_edge->in_polymorphic_cdtor = in_polymorphic_cdtor;
if (update_original) if (update_original)
{ {
count -= new_edge->count; count -= new_edge->count;
......
...@@ -2652,7 +2652,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs, ...@@ -2652,7 +2652,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
/* TODO: Make type preserved safe WRT contexts. */ /* TODO: Make type preserved safe WRT contexts. */
if (!dst->value.ancestor.agg_preserved) 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); ctx.offset_by (dst->value.ancestor.offset);
if (!ctx.useless_p ()) if (!ctx.useless_p ())
{ {
...@@ -2722,7 +2722,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs, ...@@ -2722,7 +2722,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
/* TODO: Make type preserved safe WRT contexts. */ /* TODO: Make type preserved safe WRT contexts. */
if (!dst->value.ancestor.agg_preserved) 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 (!ctx.useless_p ())
{ {
if (!dst_ctx) if (!dst_ctx)
...@@ -3128,7 +3128,8 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie, ...@@ -3128,7 +3128,8 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
/* TODO: We want to record if type change happens. /* TODO: We want to record if type change happens.
Old code did not do that that seems like a bug. */ 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 updated = ie->indirect_info->context.combine_with
(ctx, ie->indirect_info->otr_type); (ctx, ie->indirect_info->otr_type);
......
...@@ -284,6 +284,7 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge, ...@@ -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->speculative, 1);
bp_pack_value (&bp, edge->call_stmt_cannot_inline_p, 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->can_throw_external, 1);
bp_pack_value (&bp, edge->in_polymorphic_cdtor, 1);
if (edge->indirect_unknown_callee) if (edge->indirect_unknown_callee)
{ {
int flags = edge->indirect_info->ecf_flags; int flags = edge->indirect_info->ecf_flags;
...@@ -1366,6 +1367,7 @@ input_edge (struct lto_input_block *ib, vec<symtab_node *> nodes, ...@@ -1366,6 +1367,7 @@ input_edge (struct lto_input_block *ib, vec<symtab_node *> nodes,
edge->inline_failed = inline_failed; edge->inline_failed = inline_failed;
edge->call_stmt_cannot_inline_p = bp_unpack_value (&bp, 1); edge->call_stmt_cannot_inline_p = bp_unpack_value (&bp, 1);
edge->can_throw_external = 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 (indirect)
{ {
if (bp_unpack_value (&bp, 1)) if (bp_unpack_value (&bp, 1))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment