From f9bb202b35f949eecb48adf75f9a0c5b117978d2 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 3 Oct 2014 21:52:11 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 15 +++++++++++++++ gcc/cgraph.c | 7 +++++++ gcc/cgraph.h | 5 ++++- gcc/cgraphclones.c | 1 + gcc/ipa-prop.c | 7 ++++--- gcc/lto-cgraph.c | 2 ++ 6 files changed, 33 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7e1272c82c3..4bf61ab5212 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2014-10-03 Jan Hubicka + + * 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 * config/i386/i386.c (ix86_expand_vec_perm_vpermi2): Fix up formatting. diff --git a/gcc/cgraph.c b/gcc/cgraph.c index fdcaf79b358..a46e1883fd0 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -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); diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 8bc6fc945d1..5ed078acfa9 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -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. */ diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index 37b234f7891..c487c13f3db 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -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; diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 5ac5dc5200b..c5bcb3a908f 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -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); diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index 0584946d5b0..a48e61eb893 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -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 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)) -- 2.30.2