cgraph.h (cgraph_indirect_call_info): Removed field thunk_delta.

2011-09-02  Martin Jambor  <mjambor@suse.cz>

	* cgraph.h (cgraph_indirect_call_info): Removed field thunk_delta.
	* gimple-fold.c (gimple_get_virt_method_for_binfo): Rewritten to use
	BINFO_VTABLE.  Parameter delta removed, all callers updated.
	* tree.c (free_lang_data_in_binfo): Clear BINFO_VIRTUALs instead
	BINFO_VTABLE.
	* cgraph.c (cgraph_make_edge_direct): Removed parameter delta, updated
	all calls.
	* cgraphunit.c (cgraph_redirect_edge_call_stmt_to_callee): Removed
	handling of thunk_delta.
	* ipa-cp.c (get_indirect_edge_target): Removed parameter delta.
	(devirtualization_time_bonus): Do not handle thunk deltas.
	(ipcp_discover_new_direct_edges): Likewise.
	* ipa-prop.c (ipa_make_edge_direct_to_target): Likewise.
	(try_make_edge_direct_simple_call): Likewise.
	(try_make_edge_direct_virtual_call): Likewise.
	* lto-cgraph.c (output_cgraph_opt_summary_p): Likewise.  Mark
	parameter set as unused.
	(output_edge_opt_summary): Likewise.  Mark both parameters as unused.
	* lto-cgraph.c (output_cgraph_opt_summary_p): Likewise.  Mark
	parameter set as unused.
	(output_edge_opt_summary): Likewise.  Mark both parameters as unused.
	(input_edge_opt_summary): Likewise.
	* lto-streamer-out.c (lto_output_ts_binfo_tree_pointers): Do not stream
	BINFO_VIRTUALS at all.
	* lto-streamer-in.c (lto_input_ts_binfo_tree_pointers): Likewise.

	* testsuite/g++.dg/ipa/devirt-3.C: Added a distraction method.
	* testsuite/g++.dg/ipa/ivinline-7.C: Added a test for direct call
	discovery, xfailed test for inlining.
	* testsuite/g++.dg/ipa/ivinline-9.C: Likewise.

From-SVN: r178472
This commit is contained in:
Martin Jambor 2011-09-02 15:26:30 +02:00 committed by Martin Jambor
parent 5d882cc1da
commit 81fa35bd59
17 changed files with 135 additions and 151 deletions

View File

@ -1,3 +1,31 @@
2011-09-02 Martin Jambor <mjambor@suse.cz>
* cgraph.h (cgraph_indirect_call_info): Removed field thunk_delta.
* gimple-fold.c (gimple_get_virt_method_for_binfo): Rewritten to use
BINFO_VTABLE. Parameter delta removed, all callers updated.
* tree.c (free_lang_data_in_binfo): Clear BINFO_VIRTUALs instead
BINFO_VTABLE.
* cgraph.c (cgraph_make_edge_direct): Removed parameter delta, updated
all calls.
* cgraphunit.c (cgraph_redirect_edge_call_stmt_to_callee): Removed
handling of thunk_delta.
* ipa-cp.c (get_indirect_edge_target): Removed parameter delta.
(devirtualization_time_bonus): Do not handle thunk deltas.
(ipcp_discover_new_direct_edges): Likewise.
* ipa-prop.c (ipa_make_edge_direct_to_target): Likewise.
(try_make_edge_direct_simple_call): Likewise.
(try_make_edge_direct_virtual_call): Likewise.
* lto-cgraph.c (output_cgraph_opt_summary_p): Likewise. Mark
parameter set as unused.
(output_edge_opt_summary): Likewise. Mark both parameters as unused.
* lto-cgraph.c (output_cgraph_opt_summary_p): Likewise. Mark
parameter set as unused.
(output_edge_opt_summary): Likewise. Mark both parameters as unused.
(input_edge_opt_summary): Likewise.
* lto-streamer-out.c (lto_output_ts_binfo_tree_pointers): Do not stream
BINFO_VIRTUALS at all.
* lto-streamer-in.c (lto_input_ts_binfo_tree_pointers): Likewise.
2011-09-02 Richard Guenther <rguenther@suse.de>
* tree-ssa-ccp.c (fold_builtin_alloca_for_var): Do not

View File

@ -835,7 +835,7 @@ cgraph_set_call_stmt (struct cgraph_edge *e, gimple new_stmt)
struct cgraph_node *new_callee = cgraph_get_node (decl);
gcc_checking_assert (new_callee);
cgraph_make_edge_direct (e, new_callee, 0);
cgraph_make_edge_direct (e, new_callee);
}
push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
@ -1161,11 +1161,9 @@ cgraph_redirect_edge_callee (struct cgraph_edge *e, struct cgraph_node *n)
pointer (first parameter) to compensate for skipping a thunk adjustment. */
void
cgraph_make_edge_direct (struct cgraph_edge *edge, struct cgraph_node *callee,
HOST_WIDE_INT delta)
cgraph_make_edge_direct (struct cgraph_edge *edge, struct cgraph_node *callee)
{
edge->indirect_unknown_callee = 0;
edge->indirect_info->thunk_delta = delta;
/* Get the edge out of the indirect edge list. */
if (edge->prev_callee)

View File

@ -314,9 +314,6 @@ struct GTY(()) cgraph_indirect_call_info
HOST_WIDE_INT anc_offset;
/* OBJ_TYPE_REF_TOKEN of a polymorphic call (if polymorphic is set). */
HOST_WIDE_INT otr_token;
/* Delta by which must be added to this parameter to compensate for a skipped
this adjusting thunk. */
HOST_WIDE_INT thunk_delta;
/* Type of the object from OBJ_TYPE_REF_OBJECT. */
tree otr_type;
/* Index of the parameter that is called. */
@ -507,8 +504,7 @@ struct cgraph_node * cgraph_clone_node (struct cgraph_node *, tree, gcov_type,
struct cgraph_node *cgraph_create_function_alias (tree, tree);
void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *);
void cgraph_make_edge_direct (struct cgraph_edge *, struct cgraph_node *,
HOST_WIDE_INT);
void cgraph_make_edge_direct (struct cgraph_edge *, struct cgraph_node *);
bool cgraph_only_called_directly_p (struct cgraph_node *);
struct cgraph_asm_node *cgraph_add_asm_node (tree);

View File

@ -2367,7 +2367,6 @@ cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
tree decl = gimple_call_fndecl (e->call_stmt);
gimple new_stmt;
gimple_stmt_iterator gsi;
bool gsi_computed = false;
#ifdef ENABLE_CHECKING
struct cgraph_node *node;
#endif
@ -2398,21 +2397,6 @@ cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
}
}
if (e->indirect_info &&
e->indirect_info->thunk_delta != 0
&& (!e->callee->clone.combined_args_to_skip
|| !bitmap_bit_p (e->callee->clone.combined_args_to_skip, 0)))
{
if (cgraph_dump_file)
fprintf (cgraph_dump_file, " Thunk delta is "
HOST_WIDE_INT_PRINT_DEC "\n", e->indirect_info->thunk_delta);
gsi = gsi_for_stmt (e->call_stmt);
gsi_computed = true;
gimple_adjust_this_by_delta (&gsi,
size_int (e->indirect_info->thunk_delta));
e->indirect_info->thunk_delta = 0;
}
if (e->callee->clone.combined_args_to_skip)
{
int lp_nr;
@ -2426,8 +2410,7 @@ cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
&& TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME)
SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
if (!gsi_computed)
gsi = gsi_for_stmt (e->call_stmt);
gsi = gsi_for_stmt (e->call_stmt);
gsi_replace (&gsi, new_stmt, false);
/* We need to defer cleaning EH info on the new statement to
fixup-cfg. We may not have dominator information at this point

View File

@ -982,51 +982,6 @@ gimple_fold_builtin (gimple stmt)
return result;
}
/* Return a declaration of a function which an OBJ_TYPE_REF references. TOKEN
is integer form of OBJ_TYPE_REF_TOKEN of the reference expression.
KNOWN_BINFO carries the binfo describing the true type of
OBJ_TYPE_REF_OBJECT(REF). If a call to the function must be accompanied
with a this adjustment, the constant which should be added to this pointer
is stored to *DELTA. If REFUSE_THUNKS is true, return NULL if the function
is a thunk (other than a this adjustment which is dealt with by DELTA). */
tree
gimple_get_virt_method_for_binfo (HOST_WIDE_INT token, tree known_binfo,
tree *delta)
{
HOST_WIDE_INT i;
tree v, fndecl;
v = BINFO_VIRTUALS (known_binfo);
/* If there is no virtual methods leave the OBJ_TYPE_REF alone. */
if (!v)
return NULL_TREE;
i = 0;
while (i != token)
{
i += (TARGET_VTABLE_USES_DESCRIPTORS
? TARGET_VTABLE_USES_DESCRIPTORS : 1);
v = TREE_CHAIN (v);
}
/* If BV_VCALL_INDEX is non-NULL, give up. */
if (TREE_TYPE (v))
return NULL_TREE;
fndecl = TREE_VALUE (v);
/* When cgraph node is missing and function is not public, we cannot
devirtualize. This can happen in WHOPR when the actual method
ends up in other partition, because we found devirtualization
possibility too late. */
if (!can_refer_decl_in_current_unit_p (TREE_VALUE (v)))
return NULL_TREE;
*delta = TREE_PURPOSE (v);
gcc_checking_assert (host_integerp (*delta, 0));
return fndecl;
}
/* Generate code adjusting the first parameter of a call statement determined
by GSI by DELTA. */
@ -1149,7 +1104,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
callee = gimple_call_fn (stmt);
if (callee && TREE_CODE (callee) == OBJ_TYPE_REF)
{
tree binfo, fndecl, delta, obj;
tree binfo, fndecl, obj;
HOST_WIDE_INT token;
if (gimple_call_addr_fndecl (OBJ_TYPE_REF_EXPR (callee)) != NULL_TREE)
@ -1163,10 +1118,9 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
if (!binfo)
return false;
token = TREE_INT_CST_LOW (OBJ_TYPE_REF_TOKEN (callee));
fndecl = gimple_get_virt_method_for_binfo (token, binfo, &delta);
fndecl = gimple_get_virt_method_for_binfo (token, binfo);
if (!fndecl)
return false;
gcc_assert (integer_zerop (delta));
gimple_call_set_fndecl (stmt, fndecl);
return true;
}
@ -3064,6 +3018,60 @@ fold_const_aggregate_ref (tree t)
return fold_const_aggregate_ref_1 (t, NULL);
}
/* Return a declaration of a function which an OBJ_TYPE_REF references. TOKEN
is integer form of OBJ_TYPE_REF_TOKEN of the reference expression.
KNOWN_BINFO carries the binfo describing the true type of
OBJ_TYPE_REF_OBJECT(REF). */
tree
gimple_get_virt_method_for_binfo (HOST_WIDE_INT token, tree known_binfo)
{
unsigned HOST_WIDE_INT offset, size;
tree v, fn;
v = BINFO_VTABLE (known_binfo);
/* If there is no virtual methods table, leave the OBJ_TYPE_REF alone. */
if (!v)
return NULL_TREE;
if (TREE_CODE (v) == POINTER_PLUS_EXPR)
{
offset = tree_low_cst (TREE_OPERAND (v, 1), 1) * BITS_PER_UNIT;
v = TREE_OPERAND (v, 0);
}
else
offset = 0;
if (TREE_CODE (v) != ADDR_EXPR)
return NULL_TREE;
v = TREE_OPERAND (v, 0);
if (TREE_CODE (v) != VAR_DECL
|| !DECL_VIRTUAL_P (v)
|| !DECL_INITIAL (v))
return NULL_TREE;
gcc_checking_assert (TREE_CODE (TREE_TYPE (v)) == ARRAY_TYPE);
size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (v))), 1);
offset += token * size;
fn = fold_ctor_reference (TREE_TYPE (TREE_TYPE (v)), DECL_INITIAL (v),
offset, size);
if (!fn)
return NULL_TREE;
gcc_assert (TREE_CODE (fn) == ADDR_EXPR
|| TREE_CODE (fn) == FDESC_EXPR);
fn = TREE_OPERAND (fn, 0);
gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
/* When cgraph node is missing and function is not public, we cannot
devirtualize. This can happen in WHOPR when the actual method
ends up in other partition, because we found devirtualization
possibility too late. */
if (!can_refer_decl_in_current_unit_p (fn))
return NULL_TREE;
return fn;
}
/* Return true iff VAL is a gimple expression that is known to be
non-negative. Restricted to floating-point inputs. */

View File

@ -909,7 +909,7 @@ unsigned get_gimple_rhs_num_ops (enum tree_code);
gimple gimple_alloc_stat (enum gimple_code, unsigned MEM_STAT_DECL);
const char *gimple_decl_printable_name (tree, int);
bool gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace);
tree gimple_get_virt_method_for_binfo (HOST_WIDE_INT, tree, tree *);
tree gimple_get_virt_method_for_binfo (HOST_WIDE_INT, tree);
void gimple_adjust_this_by_delta (gimple_stmt_iterator *, tree);
tree gimple_extract_devirt_binfo_from_cst (tree);
/* Returns true iff T is a valid GIMPLE statement. */

View File

@ -1110,11 +1110,10 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
/* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
(which can contain both constants and binfos) or KNOWN_BINFOS (which can be
NULL) return the destination. If simple thunk delta must be applied too,
store it to DELTA. */
NULL) return the destination. */
static tree
get_indirect_edge_target (struct cgraph_edge *ie, tree *delta,
get_indirect_edge_target (struct cgraph_edge *ie,
VEC (tree, heap) *known_vals,
VEC (tree, heap) *known_binfos)
{
@ -1132,10 +1131,7 @@ get_indirect_edge_target (struct cgraph_edge *ie, tree *delta,
if (t &&
TREE_CODE (t) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
{
*delta = NULL_TREE;
return TREE_OPERAND (t, 0);
}
return TREE_OPERAND (t, 0);
else
return NULL_TREE;
}
@ -1159,7 +1155,7 @@ get_indirect_edge_target (struct cgraph_edge *ie, tree *delta,
binfo = get_binfo_at_offset (binfo, anc_offset, otr_type);
if (!binfo)
return NULL_TREE;
return gimple_get_virt_method_for_binfo (token, binfo, delta);
return gimple_get_virt_method_for_binfo (token, binfo);
}
else
{
@ -1168,7 +1164,7 @@ get_indirect_edge_target (struct cgraph_edge *ie, tree *delta,
binfo = get_binfo_at_offset (t, anc_offset, otr_type);
if (!binfo)
return NULL_TREE;
return gimple_get_virt_method_for_binfo (token, binfo, delta);
return gimple_get_virt_method_for_binfo (token, binfo);
}
}
@ -1187,9 +1183,9 @@ devirtualization_time_bonus (struct cgraph_node *node,
{
struct cgraph_node *callee;
struct inline_summary *isummary;
tree delta, target;
tree target;
target = get_indirect_edge_target (ie, &delta, known_csts, known_binfos);
target = get_indirect_edge_target (ie, known_csts, known_binfos);
if (!target)
continue;
@ -1674,12 +1670,12 @@ ipcp_discover_new_direct_edges (struct cgraph_node *node,
for (ie = node->indirect_calls; ie; ie = next_ie)
{
tree delta, target;
tree target;
next_ie = ie->next_callee;
target = get_indirect_edge_target (ie, &delta, known_vals, NULL);
target = get_indirect_edge_target (ie, known_vals, NULL);
if (target)
ipa_make_edge_direct_to_target (ie, target, delta);
ipa_make_edge_direct_to_target (ie, target);
}
}

View File

@ -1614,12 +1614,10 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
}
/* If TARGET is an addr_expr of a function declaration, make it the destination
of an indirect edge IE and return the edge. Otherwise, return NULL. Delta,
if non-NULL, is an integer constant that must be added to this pointer
(first parameter). */
of an indirect edge IE and return the edge. Otherwise, return NULL. */
struct cgraph_edge *
ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target, tree delta)
ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
{
struct cgraph_node *callee;
@ -1632,11 +1630,11 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target, tree delta)
return NULL;
ipa_check_create_node_params ();
/* We can not make edges to inline clones. It is bug that someone removed the cgraph
node too early. */
/* We can not make edges to inline clones. It is bug that someone removed
the cgraph node too early. */
gcc_assert (!callee->global.inlined_to);
cgraph_make_edge_direct (ie, callee, delta ? tree_low_cst (delta, 0) : 0);
cgraph_make_edge_direct (ie, callee);
if (dump_file)
{
fprintf (dump_file, "ipa-prop: Discovered %s call to a known target "
@ -1648,13 +1646,6 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target, tree delta)
print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
else
fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
if (delta)
{
fprintf (dump_file, " Thunk delta is ");
print_generic_expr (dump_file, delta, 0);
fprintf (dump_file, "\n");
}
}
callee = cgraph_function_or_thunk_node (callee, NULL);
@ -1683,7 +1674,7 @@ try_make_edge_direct_simple_call (struct cgraph_edge *ie,
else
return NULL;
return ipa_make_edge_direct_to_target (ie, target, NULL_TREE);
return ipa_make_edge_direct_to_target (ie, target);
}
/* Try to find a destination for indirect edge IE that corresponds to a
@ -1695,7 +1686,7 @@ static struct cgraph_edge *
try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
struct ipa_jump_func *jfunc)
{
tree binfo, type, target, delta;
tree binfo, type, target;
HOST_WIDE_INT token;
if (jfunc->type == IPA_JF_KNOWN_TYPE)
@ -1710,12 +1701,12 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
type = ie->indirect_info->otr_type;
binfo = get_binfo_at_offset (binfo, ie->indirect_info->anc_offset, type);
if (binfo)
target = gimple_get_virt_method_for_binfo (token, binfo, &delta);
target = gimple_get_virt_method_for_binfo (token, binfo);
else
return NULL;
if (target)
return ipa_make_edge_direct_to_target (ie, target, delta);
return ipa_make_edge_direct_to_target (ie, target);
else
return NULL;
}

View File

@ -367,8 +367,7 @@ bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
VEC (cgraph_edge_p, heap) **new_edges);
/* Indirect edge and binfo processing. */
struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree,
tree);
struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree);
/* Functions related to both. */
void ipa_analyze_node (struct cgraph_node *);

View File

@ -1501,22 +1501,9 @@ input_cgraph (void)
/* True when we need optimization summary for NODE. */
static int
output_cgraph_opt_summary_p (struct cgraph_node *node, cgraph_node_set set)
output_cgraph_opt_summary_p (struct cgraph_node *node,
cgraph_node_set set ATTRIBUTE_UNUSED)
{
struct cgraph_edge *e;
if (cgraph_node_in_set_p (node, set))
{
for (e = node->callees; e; e = e->next_callee)
if (e->indirect_info
&& e->indirect_info->thunk_delta != 0)
return true;
for (e = node->indirect_calls; e; e = e->next_callee)
if (e->indirect_info->thunk_delta != 0)
return true;
}
return (node->clone_of
&& (node->clone.tree_map
|| node->clone.args_to_skip
@ -1525,13 +1512,9 @@ output_cgraph_opt_summary_p (struct cgraph_node *node, cgraph_node_set set)
/* Output optimization summary for EDGE to OB. */
static void
output_edge_opt_summary (struct output_block *ob,
struct cgraph_edge *edge)
output_edge_opt_summary (struct output_block *ob ATTRIBUTE_UNUSED,
struct cgraph_edge *edge ATTRIBUTE_UNUSED)
{
if (edge->indirect_info)
streamer_write_hwi (ob, edge->indirect_info->thunk_delta);
else
streamer_write_hwi (ob, 0);
}
/* Output optimization summary for NODE to OB. */
@ -1631,17 +1614,9 @@ output_cgraph_opt_summary (cgraph_node_set set)
/* Input optimisation summary of EDGE. */
static void
input_edge_opt_summary (struct cgraph_edge *edge,
struct lto_input_block *ib_main)
input_edge_opt_summary (struct cgraph_edge *edge ATTRIBUTE_UNUSED,
struct lto_input_block *ib_main ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT thunk_delta;
thunk_delta = streamer_read_hwi (ib_main);
if (thunk_delta != 0)
{
gcc_assert (!edge->indirect_info);
edge->indirect_info = cgraph_allocate_init_indirect_info ();
edge->indirect_info->thunk_delta = thunk_delta;
}
}
/* Input optimisation summary of NODE. */

View File

@ -1,3 +1,10 @@
2011-09-02 Martin Jambor <mjambor@suse.cz>
* g++.dg/ipa/devirt-3.C: Added a distraction method.
* g++.dg/ipa/ivinline-7.C: Added a test for direct call discovery,
xfailed test for inlining.
* g++.dg/ipa/ivinline-9.C: Likewise.
2011-09-01 Ira Rosen <ira.rosen@linaro.org>
PR tree-optimization/50178

View File

@ -9,6 +9,7 @@ class A
{
public:
int data;
virtual float distraction (float f);
virtual int foo (int i);
};
@ -24,6 +25,12 @@ public:
virtual int foo (int i);
};
float A::distraction (float f)
{
f += 6.2;
return f/2;
}
int A::foo (int i)
{
return i + 1;

View File

@ -75,5 +75,6 @@ int main (int argc, char *argv[])
return 0;
}
/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main" "inline" } } */
/* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*B::.*foo" "inline" } } */
/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main" "inline" { xfail *-*-* } } } */
/* { dg-final { cleanup-ipa-dump "inline" } } */

View File

@ -89,5 +89,6 @@ int main (int argc, char *argv[])
return 0;
}
/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main" "inline" } } */
/* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*B::.*foo" "inline" } } */
/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main" "inline" { xfail *-*-* } } } */
/* { dg-final { cleanup-ipa-dump "inline" } } */

View File

@ -841,7 +841,6 @@ lto_input_ts_binfo_tree_pointers (struct lto_input_block *ib,
BINFO_OFFSET (expr) = stream_read_tree (ib, data_in);
BINFO_VTABLE (expr) = stream_read_tree (ib, data_in);
BINFO_VIRTUALS (expr) = stream_read_tree (ib, data_in);
BINFO_VPTR_FIELD (expr) = stream_read_tree (ib, data_in);
len = streamer_read_uhwi (ib);

View File

@ -701,11 +701,6 @@ write_ts_binfo_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
stream_write_tree (ob, BINFO_OFFSET (expr), ref_p);
stream_write_tree (ob, BINFO_VTABLE (expr), ref_p);
/* BINFO_VIRTUALS is used to drive type based devirtualizatoin. It often links
together large portions of programs making it harder to partition. Becuase
devirtualization is interesting before inlining, only, there is no real
need to ship it into ltrans partition. */
stream_write_tree (ob, flag_wpa ? NULL : BINFO_VIRTUALS (expr), ref_p);
stream_write_tree (ob, BINFO_VPTR_FIELD (expr), ref_p);
streamer_write_uhwi (ob, VEC_length (tree, BINFO_BASE_ACCESSES (expr)));

View File

@ -4397,7 +4397,7 @@ free_lang_data_in_one_sizepos (tree *expr_p)
/* Reset all the fields in a binfo node BINFO. We only keep
BINFO_VIRTUALS, which is used by gimple_fold_obj_type_ref. */
BINFO_VTABLE, which is used by gimple_fold_obj_type_ref. */
static void
free_lang_data_in_binfo (tree binfo)
@ -4407,7 +4407,7 @@ free_lang_data_in_binfo (tree binfo)
gcc_assert (TREE_CODE (binfo) == TREE_BINFO);
BINFO_VTABLE (binfo) = NULL_TREE;
BINFO_VIRTUALS (binfo) = NULL_TREE;
BINFO_BASE_ACCESSES (binfo) = NULL;
BINFO_INHERITANCE_CHAIN (binfo) = NULL_TREE;
BINFO_SUBVTT_INDEX (binfo) = NULL_TREE;