Commit 3339f0bc by Jan Hubicka Committed by Jan Hubicka

cgraph.c (cgraph_node::create_indirect_edge): Copy speculative data.

	* cgraph.c (cgraph_node::create_indirect_edge): Copy speculative data.
	* cgraph.h (cgraph_indirect_call_info): Add speculative data.
	* gimple-fold.c (fold_gimple_assign): Fix check for virtual
	call.
	* ipa-devirt.c (ipa_dummy_polymorphic_call_context): Update
	(contains_type_p): Forward declare.
	(polymorphic_call_target_hasher::hash): Hash speculative info.
	(polymorphic_call_target_hasher::equal): Compare speculative info.
	(get_class_context): Handle speuclation.
	(contains_type_p): Update.
	(get_polymorphic_call_info_for_decl): Update.
	(walk_ssa_copies): Break out from ...
	(get_polymorphic_call_info): ... here; set speculative context
	before giving up.
	* ipa-prop.c (ipa_write_indirect_edge_info, ipa_read_indirect_edge_info):
	Stream speculative context.
	* ipa-utils.h (ipa_polymorphic_call_context): Add speculative info
	(SPECULATIVE_OFFSET, SPECULATIVE_OUTER_TYPE,
	SPECULATIVE_MAYBE_DERIVED_TYPE).
	(possible_polymorphic_call_targets overriders): Update.
	(dump_possible_polymorphic_call_targets overriders): Update.
	(dump_possible_polymorphic_call_target_p overriders): Update.

From-SVN: r213152
parent f8a39967
2014-07-28 Jan Hubicka <hubicka@ucw.cz> 2014-07-28 Jan Hubicka <hubicka@ucw.cz>
* cgraph.c (cgraph_node::create_indirect_edge): Copy speculative data.
* cgraph.h (cgraph_indirect_call_info): Add speculative data.
* gimple-fold.c (fold_gimple_assign): Fix check for virtual
call.
* ipa-devirt.c (ipa_dummy_polymorphic_call_context): Update
(contains_type_p): Forward declare.
(polymorphic_call_target_hasher::hash): Hash speculative info.
(polymorphic_call_target_hasher::equal): Compare speculative info.
(get_class_context): Handle speuclation.
(contains_type_p): Update.
(get_polymorphic_call_info_for_decl): Update.
(walk_ssa_copies): Break out from ...
(get_polymorphic_call_info): ... here; set speculative context
before giving up.
* ipa-prop.c (ipa_write_indirect_edge_info, ipa_read_indirect_edge_info):
Stream speculative context.
* ipa-utils.h (ipa_polymorphic_call_context): Add speculative info
(SPECULATIVE_OFFSET, SPECULATIVE_OUTER_TYPE,
SPECULATIVE_MAYBE_DERIVED_TYPE).
(possible_polymorphic_call_targets overriders): Update.
(dump_possible_polymorphic_call_targets overriders): Update.
(dump_possible_polymorphic_call_target_p overriders): Update.
2014-07-28 Jan Hubicka <hubicka@ucw.cz>
* gimple-fold.c (fold_gimple_assign): Fix condition guarding * gimple-fold.c (fold_gimple_assign): Fix condition guarding
ipa-devirt path; fix thinko there. ipa-devirt path; fix thinko there.
......
...@@ -973,10 +973,15 @@ cgraph_node::create_indirect_edge (gimple call_stmt, int ecf_flags, ...@@ -973,10 +973,15 @@ cgraph_node::create_indirect_edge (gimple call_stmt, int ecf_flags,
edge->indirect_info->otr_token = otr_token; edge->indirect_info->otr_token = otr_token;
edge->indirect_info->otr_type = otr_type; edge->indirect_info->otr_type = otr_type;
edge->indirect_info->outer_type = context.outer_type; edge->indirect_info->outer_type = context.outer_type;
edge->indirect_info->speculative_outer_type
= context.speculative_outer_type;
edge->indirect_info->offset = context.offset; edge->indirect_info->offset = context.offset;
edge->indirect_info->speculative_offset = context.speculative_offset;
edge->indirect_info->maybe_in_construction edge->indirect_info->maybe_in_construction
= context.maybe_in_construction; = context.maybe_in_construction;
edge->indirect_info->maybe_derived_type = context.maybe_derived_type; edge->indirect_info->maybe_derived_type = context.maybe_derived_type;
edge->indirect_info->speculative_maybe_derived_type
= context.speculative_maybe_derived_type;
} }
edge->next_callee = indirect_calls; edge->next_callee = indirect_calls;
...@@ -3043,12 +3048,9 @@ cgraph_node::get_body (void) ...@@ -3043,12 +3048,9 @@ cgraph_node::get_body (void)
data = lto_get_section_data (file_data, LTO_section_function_body, data = lto_get_section_data (file_data, LTO_section_function_body,
name, &len); name, &len);
if (!data) if (!data)
{
debug ();
fatal_error ("%s: section %s is missing", fatal_error ("%s: section %s is missing",
file_data->file_name, file_data->file_name,
name); name);
}
gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL); gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL);
......
...@@ -1243,11 +1243,11 @@ struct GTY(()) cgraph_indirect_call_info ...@@ -1243,11 +1243,11 @@ struct GTY(()) cgraph_indirect_call_info
was actually used in the polymorphic resides within a larger structure. was actually used in the polymorphic resides within a larger structure.
If agg_contents is set, the field contains the offset within the aggregate If agg_contents is set, the field contains the offset within the aggregate
from which the address to call was loaded. */ from which the address to call was loaded. */
HOST_WIDE_INT offset; HOST_WIDE_INT offset, speculative_offset;
/* OBJ_TYPE_REF_TOKEN of a polymorphic call (if polymorphic is set). */ /* OBJ_TYPE_REF_TOKEN of a polymorphic call (if polymorphic is set). */
HOST_WIDE_INT otr_token; HOST_WIDE_INT otr_token;
/* Type of the object from OBJ_TYPE_REF_OBJECT. */ /* Type of the object from OBJ_TYPE_REF_OBJECT. */
tree otr_type, outer_type; tree otr_type, outer_type, speculative_outer_type;
/* Index of the parameter that is called. */ /* Index of the parameter that is called. */
int param_index; int param_index;
/* ECF flags determined from the caller. */ /* ECF flags determined from the caller. */
...@@ -1270,6 +1270,7 @@ struct GTY(()) cgraph_indirect_call_info ...@@ -1270,6 +1270,7 @@ struct GTY(()) cgraph_indirect_call_info
unsigned by_ref : 1; unsigned by_ref : 1;
unsigned int maybe_in_construction : 1; unsigned int maybe_in_construction : 1;
unsigned int maybe_derived_type : 1; unsigned int maybe_derived_type : 1;
unsigned int speculative_maybe_derived_type : 1;
}; };
struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgraph_edge { struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgraph_edge {
......
...@@ -4693,6 +4693,7 @@ ipa_write_indirect_edge_info (struct output_block *ob, ...@@ -4693,6 +4693,7 @@ ipa_write_indirect_edge_info (struct output_block *ob,
bp_pack_value (&bp, ii->by_ref, 1); bp_pack_value (&bp, ii->by_ref, 1);
bp_pack_value (&bp, ii->maybe_in_construction, 1); bp_pack_value (&bp, ii->maybe_in_construction, 1);
bp_pack_value (&bp, ii->maybe_derived_type, 1); bp_pack_value (&bp, ii->maybe_derived_type, 1);
bp_pack_value (&bp, ii->speculative_maybe_derived_type, 1);
streamer_write_bitpack (&bp); streamer_write_bitpack (&bp);
if (ii->polymorphic) if (ii->polymorphic)
...@@ -4700,6 +4701,9 @@ ipa_write_indirect_edge_info (struct output_block *ob, ...@@ -4700,6 +4701,9 @@ ipa_write_indirect_edge_info (struct output_block *ob,
streamer_write_hwi (ob, ii->otr_token); streamer_write_hwi (ob, ii->otr_token);
stream_write_tree (ob, ii->otr_type, true); stream_write_tree (ob, ii->otr_type, true);
stream_write_tree (ob, ii->outer_type, true); stream_write_tree (ob, ii->outer_type, true);
stream_write_tree (ob, ii->speculative_outer_type, true);
if (ii->speculative_outer_type)
streamer_write_hwi (ob, ii->speculative_offset);
} }
} }
...@@ -4723,11 +4727,15 @@ ipa_read_indirect_edge_info (struct lto_input_block *ib, ...@@ -4723,11 +4727,15 @@ ipa_read_indirect_edge_info (struct lto_input_block *ib,
ii->by_ref = bp_unpack_value (&bp, 1); ii->by_ref = bp_unpack_value (&bp, 1);
ii->maybe_in_construction = bp_unpack_value (&bp, 1); ii->maybe_in_construction = bp_unpack_value (&bp, 1);
ii->maybe_derived_type = bp_unpack_value (&bp, 1); ii->maybe_derived_type = bp_unpack_value (&bp, 1);
ii->speculative_maybe_derived_type = bp_unpack_value (&bp, 1);
if (ii->polymorphic) if (ii->polymorphic)
{ {
ii->otr_token = (HOST_WIDE_INT) streamer_read_hwi (ib); ii->otr_token = (HOST_WIDE_INT) streamer_read_hwi (ib);
ii->otr_type = stream_read_tree (ib, data_in); ii->otr_type = stream_read_tree (ib, data_in);
ii->outer_type = stream_read_tree (ib, data_in); ii->outer_type = stream_read_tree (ib, data_in);
ii->speculative_outer_type = stream_read_tree (ib, data_in);
if (ii->speculative_outer_type)
ii->speculative_offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
} }
} }
......
...@@ -38,13 +38,19 @@ struct ipa_dfs_info { ...@@ -38,13 +38,19 @@ struct ipa_dfs_info {
type inheritance graph. */ type inheritance graph. */
struct ipa_polymorphic_call_context { struct ipa_polymorphic_call_context {
/* The called object appears in an object of type OUTER_TYPE /* The called object appears in an object of type OUTER_TYPE
at offset OFFSET. */ at offset OFFSET. When information is not 100% reliable, we
use SPECULATIVE_OUTER_TYPE and SPECULATIVE_OFFSET. */
HOST_WIDE_INT offset; HOST_WIDE_INT offset;
HOST_WIDE_INT speculative_offset;
tree outer_type; tree outer_type;
tree speculative_outer_type;
/* True if outer object may be in construction or destruction. */ /* True if outer object may be in construction or destruction. */
bool maybe_in_construction; bool maybe_in_construction;
/* True if outer object may be of derived type. */ /* True if outer object may be of derived type. */
bool maybe_derived_type; bool maybe_derived_type;
/* True if speculative outer object may be of derived type. We always
speculate that construction does not happen. */
bool speculative_maybe_derived_type;
}; };
/* Context representing "I know nothing". */ /* Context representing "I know nothing". */
...@@ -89,6 +95,7 @@ tree get_polymorphic_call_info (tree, tree, tree *, ...@@ -89,6 +95,7 @@ tree get_polymorphic_call_info (tree, tree, tree *,
HOST_WIDE_INT *, HOST_WIDE_INT *,
ipa_polymorphic_call_context *, ipa_polymorphic_call_context *,
gimple call = NULL); gimple call = NULL);
bool get_dynamic_type (tree, ipa_polymorphic_call_context *, tree, gimple);
bool get_polymorphic_call_info_from_invariant (ipa_polymorphic_call_context *, bool get_polymorphic_call_info_from_invariant (ipa_polymorphic_call_context *,
tree, tree, HOST_WIDE_INT); tree, tree, HOST_WIDE_INT);
bool decl_maybe_in_construction_p (tree, tree, gimple, tree); bool decl_maybe_in_construction_p (tree, tree, gimple, tree);
...@@ -114,9 +121,12 @@ possible_polymorphic_call_targets (struct cgraph_edge *e, ...@@ -114,9 +121,12 @@ possible_polymorphic_call_targets (struct cgraph_edge *e,
{ {
gcc_checking_assert (e->indirect_info->polymorphic); gcc_checking_assert (e->indirect_info->polymorphic);
ipa_polymorphic_call_context context = {e->indirect_info->offset, ipa_polymorphic_call_context context = {e->indirect_info->offset,
e->indirect_info->speculative_offset,
e->indirect_info->outer_type, e->indirect_info->outer_type,
e->indirect_info->speculative_outer_type,
e->indirect_info->maybe_in_construction, e->indirect_info->maybe_in_construction,
e->indirect_info->maybe_derived_type}; e->indirect_info->maybe_derived_type,
e->indirect_info->speculative_maybe_derived_type};
return possible_polymorphic_call_targets (e->indirect_info->otr_type, return possible_polymorphic_call_targets (e->indirect_info->otr_type,
e->indirect_info->otr_token, e->indirect_info->otr_token,
context, context,
...@@ -153,9 +163,12 @@ dump_possible_polymorphic_call_targets (FILE *f, struct cgraph_edge *e) ...@@ -153,9 +163,12 @@ dump_possible_polymorphic_call_targets (FILE *f, struct cgraph_edge *e)
{ {
gcc_checking_assert (e->indirect_info->polymorphic); gcc_checking_assert (e->indirect_info->polymorphic);
ipa_polymorphic_call_context context = {e->indirect_info->offset, ipa_polymorphic_call_context context = {e->indirect_info->offset,
e->indirect_info->speculative_offset,
e->indirect_info->outer_type, e->indirect_info->outer_type,
e->indirect_info->speculative_outer_type,
e->indirect_info->maybe_in_construction, e->indirect_info->maybe_in_construction,
e->indirect_info->maybe_derived_type}; e->indirect_info->maybe_derived_type,
e->indirect_info->speculative_maybe_derived_type};
dump_possible_polymorphic_call_targets (f, e->indirect_info->otr_type, dump_possible_polymorphic_call_targets (f, e->indirect_info->otr_type,
e->indirect_info->otr_token, e->indirect_info->otr_token,
context); context);
...@@ -168,10 +181,11 @@ inline bool ...@@ -168,10 +181,11 @@ inline bool
possible_polymorphic_call_target_p (struct cgraph_edge *e, possible_polymorphic_call_target_p (struct cgraph_edge *e,
struct cgraph_node *n) struct cgraph_node *n)
{ {
ipa_polymorphic_call_context context = {e->indirect_info->offset, ipa_polymorphic_call_context context = {e->indirect_info->offset, 0,
e->indirect_info->outer_type, e->indirect_info->outer_type, NULL,
e->indirect_info->maybe_in_construction, e->indirect_info->maybe_in_construction,
e->indirect_info->maybe_derived_type}; e->indirect_info->maybe_derived_type,
false};
return possible_polymorphic_call_target_p (e->indirect_info->otr_type, return possible_polymorphic_call_target_p (e->indirect_info->otr_type,
e->indirect_info->otr_token, e->indirect_info->otr_token,
context, n); context, n);
......
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