+2014-09-24 Jan Hubicka <hubicka@ucw.cz>
+
+ * 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.
+
2014-09-24 Jan Hubicka <hubicka@ucw.cz>
* ipa-utils.h (polymorphic_call_context): Add
= tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
edge->indirect_info->otr_type = obj_type_ref_class (target);
gcc_assert (TREE_CODE (edge->indirect_info->otr_type) == RECORD_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->speculative_offset = context.speculative_offset;
- edge->indirect_info->maybe_in_construction
- = context.maybe_in_construction;
- edge->indirect_info->maybe_derived_type = context.maybe_derived_type;
- edge->indirect_info->speculative_maybe_derived_type
- = context.speculative_maybe_derived_type;
+ edge->indirect_info->context = context;
}
edge->next_callee = indirect_calls;
const char * const cgraph_availability_names[] =
{"unset", "not_available", "overwritable", "available", "local"};
+/* Output flags of edge E. */
+
+static void
+dump_edge_flags (FILE *f, struct cgraph_edge *edge)
+{
+ if (edge->speculative)
+ fprintf (f, "(speculative) ");
+ if (!edge->inline_failed)
+ fprintf (f, "(inlined) ");
+ if (edge->indirect_inlining_edge)
+ fprintf (f, "(indirect_inlining) ");
+ if (edge->count)
+ fprintf (f, "(%"PRId64"x) ",
+ (int64_t)edge->count);
+ if (edge->frequency)
+ fprintf (f, "(%.2f per call) ",
+ edge->frequency / (double)CGRAPH_FREQ_BASE);
+ if (edge->can_throw_external)
+ fprintf (f, "(can throw external) ");
+}
/* Dump call graph node to file F. */
cgraph_node::dump (FILE *f)
{
cgraph_edge *edge;
- int indirect_calls_count = 0;
dump_base (f);
{
fprintf (f, "%s/%i ", edge->caller->asm_name (),
edge->caller->order);
- if (count)
- fprintf (f, "(%"PRId64"x) ",
- (int64_t)count);
- if (frequency)
- fprintf (f, "(%.2f per call) ",
- frequency / (double)CGRAPH_FREQ_BASE);
- if (edge->speculative)
- fprintf (f, "(speculative) ");
- if (!edge->inline_failed)
- fprintf (f, "(inlined) ");
- if (edge->indirect_inlining_edge)
- fprintf (f, "(indirect_inlining) ");
- if (edge->can_throw_external)
- fprintf (f, "(can throw external) ");
+ dump_edge_flags (f, edge);
}
fprintf (f, "\n Calls: ");
{
fprintf (f, "%s/%i ", edge->callee->asm_name (),
edge->callee->order);
- if (edge->speculative)
- fprintf (f, "(speculative) ");
- if (!edge->inline_failed)
- fprintf (f, "(inlined) ");
- if (edge->indirect_inlining_edge)
- fprintf (f, "(indirect_inlining) ");
- if (edge->count)
- fprintf (f, "(%"PRId64"x) ",
- (int64_t)count);
- if (edge->frequency)
- fprintf (f, "(%.2f per call) ",
- frequency / (double)CGRAPH_FREQ_BASE);
- if (edge->can_throw_external)
- fprintf (f, "(can throw external) ");
+ dump_edge_flags (f, edge);
}
fprintf (f, "\n");
for (edge = indirect_calls; edge; edge = edge->next_callee)
- indirect_calls_count++;
- if (indirect_calls_count)
- fprintf (f, " Has %i outgoing edges for indirect calls.\n",
- indirect_calls_count);
+ {
+ if (edge->indirect_info->polymorphic)
+ {
+ fprintf (f, " Polymorphic indirect call of type ");
+ print_generic_expr (f, edge->indirect_info->otr_type, TDF_SLIM);
+ fprintf (f, " token:%i", (int) edge->indirect_info->otr_token);
+ }
+ else
+ fprintf (f, " Indirect call");
+ dump_edge_flags (f, edge);
+ if (edge->indirect_info->param_index != -1)
+ {
+ fprintf (f, " of param:%i", edge->indirect_info->param_index);
+ if (edge->indirect_info->agg_contents)
+ fprintf (f, " loaded from %s %s at offset %i",
+ edge->indirect_info->member_ptr ? "member ptr" : "aggregate",
+ edge->indirect_info->by_ref ? "passed by reference":"",
+ (int)edge->indirect_info->offset);
+ }
+ fprintf (f, "\n");
+ if (edge->indirect_info->polymorphic)
+ edge->indirect_info->context.dump (f);
+ }
}
/* Dump call graph node NODE to stderr. */
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. */
/* 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 {
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 */
#include "stor-layout.h"
#include "intl.h"
#include "hash-map.h"
+#include "data-streamer.h"
+#include "lto-streamer.h"
+#include "streamer-hooks.h"
/* Hash based set of pairs of types. */
typedef struct
dump (stderr);
}
+/* Stream out the context to OB. */
+
+void
+ipa_polymorphic_call_context::stream_out (struct output_block *ob) const
+{
+ struct bitpack_d bp = bitpack_create (ob->main_stream);
+
+ bp_pack_value (&bp, invalid, 1);
+ bp_pack_value (&bp, maybe_in_construction, 1);
+ bp_pack_value (&bp, maybe_derived_type, 1);
+ bp_pack_value (&bp, speculative_maybe_derived_type, 1);
+ bp_pack_value (&bp, outer_type != NULL, 1);
+ bp_pack_value (&bp, offset != 0, 1);
+ bp_pack_value (&bp, speculative_outer_type != NULL, 1);
+ streamer_write_bitpack (&bp);
+
+ if (outer_type != NULL)
+ stream_write_tree (ob, outer_type, true);
+ if (offset)
+ streamer_write_hwi (ob, offset);
+ if (speculative_outer_type != NULL)
+ {
+ stream_write_tree (ob, speculative_outer_type, true);
+ streamer_write_hwi (ob, speculative_offset);
+ }
+ else
+ gcc_assert (!speculative_offset);
+}
+
+/* Stream in the context from IB and DATA_IN. */
+
+void
+ipa_polymorphic_call_context::stream_in (struct lto_input_block *ib,
+ struct data_in *data_in)
+{
+ struct bitpack_d bp = streamer_read_bitpack (ib);
+
+ invalid = bp_unpack_value (&bp, 1);
+ maybe_in_construction = bp_unpack_value (&bp, 1);
+ maybe_derived_type = bp_unpack_value (&bp, 1);
+ speculative_maybe_derived_type = bp_unpack_value (&bp, 1);
+ bool outer_type_p = bp_unpack_value (&bp, 1);
+ bool offset_p = bp_unpack_value (&bp, 1);
+ bool speculative_outer_type_p = bp_unpack_value (&bp, 1);
+
+ if (outer_type_p)
+ outer_type = stream_read_tree (ib, data_in);
+ else
+ outer_type = NULL;
+ if (offset_p)
+ offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
+ else
+ offset = 0;
+ if (speculative_outer_type_p)
+ {
+ speculative_outer_type = stream_read_tree (ib, data_in);
+ speculative_offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
+ }
+ else
+ {
+ speculative_outer_type = NULL;
+ speculative_offset = 0;
+ }
+}
+
/* Proudce polymorphic call context for call method of instance
that is located within BASE (that is assumed to be a decl) at offset OFF. */
We take advantage of fact that vtable stores must appear within constructor
and destructor functions. */
-bool
+static bool
noncall_stmt_may_be_vtbl_ptr_store (gimple stmt)
{
if (is_gimple_assign (stmt))
}
else
fprintf (f, "\n");
+ if (ii->polymorphic)
+ ii->context.dump (f);
ipa_print_node_jump_functions_for_edge (f, cs);
}
}
NULL, &by_ref))
{
struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
- if (cs->indirect_info->offset != offset)
- cs->indirect_info->outer_type = NULL;
cs->indirect_info->offset = offset;
cs->indirect_info->agg_contents = 1;
cs->indirect_info->by_ref = by_ref;
&& parm_preserved_before_stmt_p (fbi, index, call, rec))
{
struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
- if (cs->indirect_info->offset != offset)
- cs->indirect_info->outer_type = NULL;
cs->indirect_info->offset = offset;
cs->indirect_info->agg_contents = 1;
cs->indirect_info->member_ptr = 1;
if (cs->indirect_info->polymorphic)
{
- tree otr_type;
- HOST_WIDE_INT otr_token;
tree instance;
tree target = gimple_call_fn (call);
ipa_polymorphic_call_context context (current_function_decl,
target, call, &instance);
- otr_type = obj_type_ref_class (target);
- otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
+ gcc_checking_assert (cs->indirect_info->otr_type
+ == obj_type_ref_class (target));
+ gcc_checking_assert (cs->indirect_info->otr_token
+ == tree_to_shwi (OBJ_TYPE_REF_TOKEN (target)));
if (context.get_dynamic_type (instance,
OBJ_TYPE_REF_OBJECT (target),
- otr_type, call)
- && context.offset == cs->indirect_info->offset)
- {
- gcc_assert (TREE_CODE (otr_type) == RECORD_TYPE);
- cs->indirect_info->polymorphic = true;
- cs->indirect_info->param_index = -1;
- cs->indirect_info->otr_token = otr_token;
- cs->indirect_info->otr_type = otr_type;
- cs->indirect_info->outer_type = context.outer_type;
- cs->indirect_info->speculative_outer_type = context.speculative_outer_type;
- cs->indirect_info->offset = context.offset;
- cs->indirect_info->speculative_offset = context.speculative_offset;
- cs->indirect_info->maybe_in_construction
- = context.maybe_in_construction;
- cs->indirect_info->maybe_derived_type = context.maybe_derived_type;
- cs->indirect_info->speculative_maybe_derived_type
- = context.speculative_maybe_derived_type;
- }
+ obj_type_ref_class (target), call))
+ cs->indirect_info->context = context;
}
if (TREE_CODE (target) == SSA_NAME)
else
{
ici->param_index = ipa_get_jf_ancestor_formal_id (jfunc);
- if (ipa_get_jf_ancestor_offset (jfunc))
- ici->outer_type = NULL;
ici->offset += ipa_get_jf_ancestor_offset (jfunc);
}
}
struct bitpack_d bp;
streamer_write_hwi (ob, ii->param_index);
- streamer_write_hwi (ob, ii->offset);
bp = bitpack_create (ob->main_stream);
bp_pack_value (&bp, ii->polymorphic, 1);
bp_pack_value (&bp, ii->agg_contents, 1);
bp_pack_value (&bp, ii->member_ptr, 1);
bp_pack_value (&bp, ii->by_ref, 1);
- bp_pack_value (&bp, ii->maybe_in_construction, 1);
- bp_pack_value (&bp, ii->maybe_derived_type, 1);
- bp_pack_value (&bp, ii->speculative_maybe_derived_type, 1);
streamer_write_bitpack (&bp);
+ if (ii->agg_contents || ii->polymorphic)
+ streamer_write_hwi (ob, ii->offset);
+ else
+ gcc_assert (ii->offset == 0);
if (ii->polymorphic)
{
streamer_write_hwi (ob, ii->otr_token);
stream_write_tree (ob, ii->otr_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);
+ ii->context.stream_out (ob);
}
}
static void
ipa_read_indirect_edge_info (struct lto_input_block *ib,
- struct data_in *data_in ATTRIBUTE_UNUSED,
+ struct data_in *data_in,
struct cgraph_edge *cs)
{
struct cgraph_indirect_call_info *ii = cs->indirect_info;
struct bitpack_d bp;
ii->param_index = (int) streamer_read_hwi (ib);
- ii->offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
bp = streamer_read_bitpack (ib);
ii->polymorphic = bp_unpack_value (&bp, 1);
ii->agg_contents = bp_unpack_value (&bp, 1);
ii->member_ptr = bp_unpack_value (&bp, 1);
ii->by_ref = bp_unpack_value (&bp, 1);
- ii->maybe_in_construction = 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->agg_contents || ii->polymorphic)
+ ii->offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
+ else
+ ii->offset = 0;
if (ii->polymorphic)
{
ii->otr_token = (HOST_WIDE_INT) streamer_read_hwi (ib);
ii->otr_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);
+ ii->context.stream_in (ib, data_in);
}
}
PTR aux;
};
-/* Context of polymorphic call. This is used by ipa-devirt walkers of the
- type inheritance graph. */
-
-class 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;
-
-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);
-};
-
-/* 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);
-
- offset = e->indirect_info->offset;
- speculative_offset = e->indirect_info->speculative_offset;
- outer_type = e->indirect_info->outer_type;
- speculative_outer_type = e->indirect_info->speculative_outer_type;
- maybe_in_construction = e->indirect_info->maybe_in_construction;
- maybe_derived_type = e->indirect_info->maybe_derived_type;
- speculative_maybe_derived_type = e->indirect_info->speculative_maybe_derived_type;
- invalid = false;
-}
-
-/* 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;
-}
/* In ipa-utils.c */
void ipa_print_order (FILE*, const char *, struct cgraph_node**, int);