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:
parent
5d882cc1da
commit
81fa35bd59
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
24
gcc/ipa-cp.c
24
gcc/ipa-cp.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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" } } */
|
||||
|
|
|
@ -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" } } */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue