aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2014-10-03 21:52:11 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2014-10-03 19:52:11 +0000
commitf9bb202b35f949eecb48adf75f9a0c5b117978d2 (patch)
tree985ae03907469842ffadf25aece38775da66d63a
parent8a5b2f56c4c9d80c8ac2c31c82304681f4e9da80 (diff)
downloadgcc-f9bb202b35f949eecb48adf75f9a0c5b117978d2.zip
gcc-f9bb202b35f949eecb48adf75f9a0c5b117978d2.tar.gz
gcc-f9bb202b35f949eecb48adf75f9a0c5b117978d2.tar.bz2
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
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/cgraph.c7
-rw-r--r--gcc/cgraph.h5
-rw-r--r--gcc/cgraphclones.c1
-rw-r--r--gcc/ipa-prop.c7
-rw-r--r--gcc/lto-cgraph.c2
6 files changed, 33 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7e1272c..4bf61ab 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index fdcaf79..a46e188 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 8bc6fc9..5ed078a 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 37b234f..c487c13 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 5ac5dc5..c5bcb3a 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 0584946..a48e61e 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<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))