summaryrefslogtreecommitdiff
path: root/gcc/cgraph.h
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2014-09-25 03:48:34 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2014-09-25 01:48:34 +0000
commitba3923391e896c0efdfcd49eb0334525ed8bd2c0 (patch)
treed4102419e20affeb7736989b54eabee0db65012a /gcc/cgraph.h
parent20149bd284864c06f0051f50d73ff50be46505f8 (diff)
downloadgcc-ba3923391e896c0efdfcd49eb0334525ed8bd2c0.tar.gz
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.h120
1 files changed, 111 insertions, 9 deletions
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 7e90bf07521..74819064fff 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 */