diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2014-09-25 03:48:34 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2014-09-25 01:48:34 +0000 |
commit | ba3923391e896c0efdfcd49eb0334525ed8bd2c0 (patch) | |
tree | d4102419e20affeb7736989b54eabee0db65012a /gcc/cgraph.h | |
parent | 20149bd284864c06f0051f50d73ff50be46505f8 (diff) | |
download | gcc-ba3923391e896c0efdfcd49eb0334525ed8bd2c0.zip gcc-ba3923391e896c0efdfcd49eb0334525ed8bd2c0.tar.gz gcc-ba3923391e896c0efdfcd49eb0334525ed8bd2c0.tar.bz2 |
cgraph.h (class ipa_polymorphic_call_context): Move here from ipa-utils.h; add stream_int and stream_out methods.
* cgraph.h (class ipa_polymorphic_call_context): Move here from
ipa-utils.h; add stream_int and stream_out methods.
(cgraph_indirect_call_info): Remove SPECILATIVE_OFFSET,
OUTER_TYPE, SPECULATIVE_OUTER_TYPE, MAYBE_IN_CONSTRUCTION
MAYBE_DERIVED_TYPE and SPECULATIEVE_MAYBE_DERIVED_TYPE;
add CONTEXT.
(ipa_polymorphic_call_context::ipa_polymorphic_call_context,
ipa_polymorphic_call_context::ipa_polymorphic_call_context,
ipa_polymorphic_call_context::clear_speculation,
ipa_polymorphic_call_context::clear_outer_type): Move here from
ipa-utils.h
* ipa-utils.h (class ipa_polymorphic_call_context): Move to cgraph.h
(ipa_polymorphic_call_context::ipa_polymorphic_call_context,
ipa_polymorphic_call_context::ipa_polymorphic_call_context,
ipa_polymorphic_call_context::clear_speculation,
ipa_polymorphic_call_context::clear_outer_type): Likewise.
* ipa-devirt.c: Include data-streamer.h, lto-streamer.h and
streamer-hooks.h
(ipa_polymorphic_call_context::stream_out): New method.
(ipa_polymorphic_call_context::stream_in): New method.
(noncall_stmt_may_be_vtbl_ptr_store): Add forgotten static.
* ipa-prop.c (ipa_analyze_indirect_call_uses): Do not care about
OUTER_TYPE.
(ipa_analyze_call_uses): Simplify.
(update_indirect_edges_after_inlining): Do not care about outer_type.
(ipa_write_indirect_edge_info): Update.
(ipa_write_indirect_edge_info): Likewise.
* cgraph.c (cgraph_node::create_indirect_edge): Simplify.
(dump_edge_flags): Break out from ...
(cgraph_node::dump): ... here; dump indirect edges.
From-SVN: r215575
Diffstat (limited to 'gcc/cgraph.h')
-rw-r--r-- | gcc/cgraph.h | 120 |
1 files changed, 111 insertions, 9 deletions
diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 7e90bf0..7481906 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -1267,19 +1267,83 @@ struct varpool_node_set_iterator unsigned index; }; +/* Context of polymorphic call. It represent information about the type of + instance that may reach the call. This is used by ipa-devirt walkers of the + type inheritance graph. */ + +class GTY(()) ipa_polymorphic_call_context { +public: + /* The called object appears in an object of type OUTER_TYPE + at offset OFFSET. When information is not 100% reliable, we + use SPECULATIVE_OUTER_TYPE and SPECULATIVE_OFFSET. */ + HOST_WIDE_INT offset; + HOST_WIDE_INT speculative_offset; + tree outer_type; + tree speculative_outer_type; + /* True if outer object may be in construction or destruction. */ + bool maybe_in_construction; + /* True if outer object may be of 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; + /* True if the context is invalid and all calls should be redirected + to BUILTIN_UNREACHABLE. */ + bool invalid; + + /* Build empty "I know nothing" context. */ + ipa_polymorphic_call_context (); + /* Build polymorphic call context for indirect call E. */ + ipa_polymorphic_call_context (cgraph_edge *e); + /* Build polymorphic call context for IP invariant CST. + If specified, OTR_TYPE specify the type of polymorphic call + that takes CST+OFFSET as a prameter. */ + ipa_polymorphic_call_context (tree cst, tree otr_type = NULL, + HOST_WIDE_INT offset = 0); + /* Build context for pointer REF contained in FNDECL at statement STMT. + if INSTANCE is non-NULL, return pointer to the object described by + the context. */ + ipa_polymorphic_call_context (tree fndecl, tree ref, gimple stmt, + tree *instance = NULL); + + /* Look for vtable stores or constructor calls to work out dynamic type + of memory location. */ + bool get_dynamic_type (tree, tree, tree, gimple); + + /* Make context non-speculative. */ + void clear_speculation (); + + /* Walk container types and modify context to point to actual class + containing EXPECTED_TYPE as base class. */ + bool restrict_to_inner_class (tree expected_type); + + /* Dump human readable context to F. */ + void dump (FILE *f) const; + void DEBUG_FUNCTION debug () const; + + /* LTO streaming. */ + void stream_out (struct output_block *) const; + void stream_in (struct lto_input_block *, struct data_in *data_in); + +private: + void set_by_decl (tree, HOST_WIDE_INT); + bool set_by_invariant (tree, tree, HOST_WIDE_INT); + void clear_outer_type (tree otr_type = NULL); +}; + /* Structure containing additional information about an indirect call. */ struct GTY(()) cgraph_indirect_call_info { - /* When polymorphic is set, this field contains offset where the object which - was actually used in the polymorphic resides within a larger structure. - If agg_contents is set, the field contains the offset within the aggregate - from which the address to call was loaded. */ - HOST_WIDE_INT offset, speculative_offset; + /* When agg_content is set, an offset where the call pointer is located + within the aggregate. */ + HOST_WIDE_INT offset; + /* Context of the polymorphic call; use only when POLYMORPHIC flag is set. */ + ipa_polymorphic_call_context context; /* OBJ_TYPE_REF_TOKEN of a polymorphic call (if polymorphic is set). */ HOST_WIDE_INT otr_token; /* Type of the object from OBJ_TYPE_REF_OBJECT. */ - tree otr_type, outer_type, speculative_outer_type; + tree otr_type; /* Index of the parameter that is called. */ int param_index; /* ECF flags determined from the caller. */ @@ -1300,9 +1364,6 @@ struct GTY(()) cgraph_indirect_call_info /* When the previous bit is set, this one determines whether the destination is loaded from a parameter passed by reference. */ unsigned by_ref : 1; - unsigned int maybe_in_construction : 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 { @@ -2532,4 +2593,45 @@ inline symtab_node * symtab_node::get_create (tree node) return cgraph_node::get_create (node); } +/* Build polymorphic call context for indirect call E. */ + +inline +ipa_polymorphic_call_context::ipa_polymorphic_call_context (cgraph_edge *e) +{ + gcc_checking_assert (e->indirect_info->polymorphic); + *this = e->indirect_info->context; +} + +/* Build empty "I know nothing" context. */ + +inline +ipa_polymorphic_call_context::ipa_polymorphic_call_context () +{ + clear_speculation (); + clear_outer_type (); + invalid = false; +} + +/* Make context non-speculative. */ + +inline void +ipa_polymorphic_call_context::clear_speculation () +{ + speculative_outer_type = NULL; + speculative_offset = 0; + speculative_maybe_derived_type = false; +} + +/* Produce context specifying all derrived types of OTR_TYPE. + If OTR_TYPE is NULL or type of the OBJ_TYPE_REF, the context is set + to dummy "I know nothing" setting. */ + +inline void +ipa_polymorphic_call_context::clear_outer_type (tree otr_type) +{ + outer_type = otr_type ? TYPE_MAIN_VARIANT (otr_type) : NULL; + offset = 0; + maybe_derived_type = true; + maybe_in_construction = true; +} #endif /* GCC_CGRAPH_H */ |