From ba3923391e896c0efdfcd49eb0334525ed8bd2c0 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 25 Sep 2014 03:48:34 +0200 Subject: 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 --- gcc/cgraph.h | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 111 insertions(+), 9 deletions(-) (limited to 'gcc/cgraph.h') 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 */ -- cgit v1.1