+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.
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);
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);
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
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. */
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;
/* 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 ())
{
/* 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)
/* 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);
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;
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))