mirror of git://gcc.gnu.org/git/gcc.git
[PR 82808] Use proper result types for arithmetic jump functions
2017-11-28 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> Martin Jambor <mjambor@suse.cz> PR ipa/82808 * tree.h (expr_type_first_operand_type_p): Declare * tree.c (expr_type_first_operand_type_p): New function. * ipa-prop.h (ipa_get_type): Allow i to be out of bounds. (ipa_value_from_jfunc): Adjust declaration. * ipa-cp.c (ipa_get_jf_pass_through_result): New parameter RES_TYPE. Use it as result type for arithmetics, unless it is NULL in which case be more conservative. (ipa_value_from_jfunc): New parameter PARM_TYPE, pass it to ipa_get_jf_pass_through_result. (propagate_vals_across_pass_through): Likewise. (propagate_scalar_across_jump_function): New parameter PARM_TYPE, pass is to propagate_vals_across_pass_through. (propagate_constants_across_call): Pass PARM_TYPE to propagate_scalar_across_jump_function. (find_more_scalar_values_for_callers_subset): Pass parameter type to ipa_value_from_jfunc. (cgraph_edge_brings_all_scalars_for_node): Likewise. * ipa-fnsummary.c (evaluate_properties_for_edge): Renamed parms_info to caller_parms_info, pass parameter type to ipa_value_from_jfunc. * ipa-prop.c (try_make_edge_direct_simple_call): New parameter target_type, pass it to ipa_value_from_jfunc. (update_indirect_edges_after_inlining): Pass parameter type to try_make_edge_direct_simple_call. testsuite/ * gcc.dg/ipa/pr82808.c: New test. Co-Authored-By: Martin Jambor <mjambor@suse.cz> From-SVN: r255212
This commit is contained in:
parent
5e4a80e8a8
commit
e5cf5e116d
|
|
@ -1,3 +1,31 @@
|
||||||
|
2017-11-28 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
|
||||||
|
Martin Jambor <mjambor@suse.cz>
|
||||||
|
|
||||||
|
PR ipa/82808
|
||||||
|
* tree.h (expr_type_first_operand_type_p): Declare
|
||||||
|
* tree.c (expr_type_first_operand_type_p): New function.
|
||||||
|
* ipa-prop.h (ipa_get_type): Allow i to be out of bounds.
|
||||||
|
(ipa_value_from_jfunc): Adjust declaration.
|
||||||
|
* ipa-cp.c (ipa_get_jf_pass_through_result): New parameter RES_TYPE.
|
||||||
|
Use it as result type for arithmetics, unless it is NULL in which case
|
||||||
|
be more conservative.
|
||||||
|
(ipa_value_from_jfunc): New parameter PARM_TYPE, pass it to
|
||||||
|
ipa_get_jf_pass_through_result.
|
||||||
|
(propagate_vals_across_pass_through): Likewise.
|
||||||
|
(propagate_scalar_across_jump_function): New parameter PARM_TYPE, pass
|
||||||
|
is to propagate_vals_across_pass_through.
|
||||||
|
(propagate_constants_across_call): Pass PARM_TYPE to
|
||||||
|
propagate_scalar_across_jump_function.
|
||||||
|
(find_more_scalar_values_for_callers_subset): Pass parameter type to
|
||||||
|
ipa_value_from_jfunc.
|
||||||
|
(cgraph_edge_brings_all_scalars_for_node): Likewise.
|
||||||
|
* ipa-fnsummary.c (evaluate_properties_for_edge): Renamed parms_info
|
||||||
|
to caller_parms_info, pass parameter type to ipa_value_from_jfunc.
|
||||||
|
* ipa-prop.c (try_make_edge_direct_simple_call): New parameter
|
||||||
|
target_type, pass it to ipa_value_from_jfunc.
|
||||||
|
(update_indirect_edges_after_inlining): Pass parameter type to
|
||||||
|
try_make_edge_direct_simple_call.
|
||||||
|
|
||||||
2017-11-28 Jeff Law <law@redhat.com>
|
2017-11-28 Jeff Law <law@redhat.com>
|
||||||
|
|
||||||
* gimple-ssa-evrp-analyze.c
|
* gimple-ssa-evrp-analyze.c
|
||||||
|
|
|
||||||
67
gcc/ipa-cp.c
67
gcc/ipa-cp.c
|
|
@ -1220,33 +1220,38 @@ initialize_node_lattices (struct cgraph_node *node)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the result of a (possibly arithmetic) pass through jump function
|
/* Return the result of a (possibly arithmetic) pass through jump function
|
||||||
JFUNC on the constant value INPUT. Return NULL_TREE if that cannot be
|
JFUNC on the constant value INPUT. RES_TYPE is the type of the parameter
|
||||||
|
to which the result is passed. Return NULL_TREE if that cannot be
|
||||||
determined or be considered an interprocedural invariant. */
|
determined or be considered an interprocedural invariant. */
|
||||||
|
|
||||||
static tree
|
static tree
|
||||||
ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input)
|
ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input,
|
||||||
|
tree res_type)
|
||||||
{
|
{
|
||||||
tree restype, res;
|
tree res;
|
||||||
|
|
||||||
if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
|
if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
|
||||||
return input;
|
return input;
|
||||||
if (!is_gimple_ip_invariant (input))
|
if (!is_gimple_ip_invariant (input))
|
||||||
return NULL_TREE;
|
return NULL_TREE;
|
||||||
|
|
||||||
if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))
|
tree_code opcode = ipa_get_jf_pass_through_operation (jfunc);
|
||||||
== tcc_unary)
|
if (!res_type)
|
||||||
res = fold_unary (ipa_get_jf_pass_through_operation (jfunc),
|
|
||||||
TREE_TYPE (input), input);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))
|
if (TREE_CODE_CLASS (opcode) == tcc_comparison)
|
||||||
== tcc_comparison)
|
res_type = boolean_type_node;
|
||||||
restype = boolean_type_node;
|
else if (expr_type_first_operand_type_p (opcode))
|
||||||
|
res_type = TREE_TYPE (input);
|
||||||
else
|
else
|
||||||
restype = TREE_TYPE (input);
|
return NULL_TREE;
|
||||||
res = fold_binary (ipa_get_jf_pass_through_operation (jfunc), restype,
|
|
||||||
input, ipa_get_jf_pass_through_operand (jfunc));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TREE_CODE_CLASS (opcode) == tcc_unary)
|
||||||
|
res = fold_unary (opcode, res_type, input);
|
||||||
|
else
|
||||||
|
res = fold_binary (opcode, res_type, input,
|
||||||
|
ipa_get_jf_pass_through_operand (jfunc));
|
||||||
|
|
||||||
if (res && !is_gimple_ip_invariant (res))
|
if (res && !is_gimple_ip_invariant (res))
|
||||||
return NULL_TREE;
|
return NULL_TREE;
|
||||||
|
|
||||||
|
|
@ -1275,10 +1280,12 @@ ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input)
|
||||||
/* Determine whether JFUNC evaluates to a single known constant value and if
|
/* Determine whether JFUNC evaluates to a single known constant value and if
|
||||||
so, return it. Otherwise return NULL. INFO describes the caller node or
|
so, return it. Otherwise return NULL. INFO describes the caller node or
|
||||||
the one it is inlined to, so that pass-through jump functions can be
|
the one it is inlined to, so that pass-through jump functions can be
|
||||||
evaluated. */
|
evaluated. PARM_TYPE is the type of the parameter to which the result is
|
||||||
|
passed. */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc)
|
ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc,
|
||||||
|
tree parm_type)
|
||||||
{
|
{
|
||||||
if (jfunc->type == IPA_JF_CONST)
|
if (jfunc->type == IPA_JF_CONST)
|
||||||
return ipa_get_jf_constant (jfunc);
|
return ipa_get_jf_constant (jfunc);
|
||||||
|
|
@ -1312,7 +1319,7 @@ ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc)
|
||||||
return NULL_TREE;
|
return NULL_TREE;
|
||||||
|
|
||||||
if (jfunc->type == IPA_JF_PASS_THROUGH)
|
if (jfunc->type == IPA_JF_PASS_THROUGH)
|
||||||
return ipa_get_jf_pass_through_result (jfunc, input);
|
return ipa_get_jf_pass_through_result (jfunc, input, parm_type);
|
||||||
else
|
else
|
||||||
return ipa_get_jf_ancestor_result (jfunc, input);
|
return ipa_get_jf_ancestor_result (jfunc, input);
|
||||||
}
|
}
|
||||||
|
|
@ -1562,12 +1569,14 @@ ipcp_lattice<valtype>::add_value (valtype newval, cgraph_edge *cs,
|
||||||
|
|
||||||
/* Propagate values through a pass-through jump function JFUNC associated with
|
/* Propagate values through a pass-through jump function JFUNC associated with
|
||||||
edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
|
edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
|
||||||
is the index of the source parameter. */
|
is the index of the source parameter. PARM_TYPE is the type of the
|
||||||
|
parameter to which the result is passed. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
propagate_vals_across_pass_through (cgraph_edge *cs, ipa_jump_func *jfunc,
|
propagate_vals_across_pass_through (cgraph_edge *cs, ipa_jump_func *jfunc,
|
||||||
ipcp_lattice<tree> *src_lat,
|
ipcp_lattice<tree> *src_lat,
|
||||||
ipcp_lattice<tree> *dest_lat, int src_idx)
|
ipcp_lattice<tree> *dest_lat, int src_idx,
|
||||||
|
tree parm_type)
|
||||||
{
|
{
|
||||||
ipcp_value<tree> *src_val;
|
ipcp_value<tree> *src_val;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
@ -1581,7 +1590,8 @@ propagate_vals_across_pass_through (cgraph_edge *cs, ipa_jump_func *jfunc,
|
||||||
else
|
else
|
||||||
for (src_val = src_lat->values; src_val; src_val = src_val->next)
|
for (src_val = src_lat->values; src_val; src_val = src_val->next)
|
||||||
{
|
{
|
||||||
tree cstval = ipa_get_jf_pass_through_result (jfunc, src_val->value);
|
tree cstval = ipa_get_jf_pass_through_result (jfunc, src_val->value,
|
||||||
|
parm_type);
|
||||||
|
|
||||||
if (cstval)
|
if (cstval)
|
||||||
ret |= dest_lat->add_value (cstval, cs, src_val, src_idx);
|
ret |= dest_lat->add_value (cstval, cs, src_val, src_idx);
|
||||||
|
|
@ -1622,12 +1632,14 @@ propagate_vals_across_ancestor (struct cgraph_edge *cs,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Propagate scalar values across jump function JFUNC that is associated with
|
/* Propagate scalar values across jump function JFUNC that is associated with
|
||||||
edge CS and put the values into DEST_LAT. */
|
edge CS and put the values into DEST_LAT. PARM_TYPE is the type of the
|
||||||
|
parameter to which the result is passed. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
propagate_scalar_across_jump_function (struct cgraph_edge *cs,
|
propagate_scalar_across_jump_function (struct cgraph_edge *cs,
|
||||||
struct ipa_jump_func *jfunc,
|
struct ipa_jump_func *jfunc,
|
||||||
ipcp_lattice<tree> *dest_lat)
|
ipcp_lattice<tree> *dest_lat,
|
||||||
|
tree param_type)
|
||||||
{
|
{
|
||||||
if (dest_lat->bottom)
|
if (dest_lat->bottom)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1662,7 +1674,7 @@ propagate_scalar_across_jump_function (struct cgraph_edge *cs,
|
||||||
|
|
||||||
if (jfunc->type == IPA_JF_PASS_THROUGH)
|
if (jfunc->type == IPA_JF_PASS_THROUGH)
|
||||||
ret = propagate_vals_across_pass_through (cs, jfunc, src_lat,
|
ret = propagate_vals_across_pass_through (cs, jfunc, src_lat,
|
||||||
dest_lat, src_idx);
|
dest_lat, src_idx, param_type);
|
||||||
else
|
else
|
||||||
ret = propagate_vals_across_ancestor (cs, jfunc, src_lat, dest_lat,
|
ret = propagate_vals_across_ancestor (cs, jfunc, src_lat, dest_lat,
|
||||||
src_idx);
|
src_idx);
|
||||||
|
|
@ -2279,7 +2291,8 @@ propagate_constants_across_call (struct cgraph_edge *cs)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret |= propagate_scalar_across_jump_function (cs, jump_func,
|
ret |= propagate_scalar_across_jump_function (cs, jump_func,
|
||||||
&dest_plats->itself);
|
&dest_plats->itself,
|
||||||
|
param_type);
|
||||||
ret |= propagate_context_across_jump_function (cs, jump_func, i,
|
ret |= propagate_context_across_jump_function (cs, jump_func, i,
|
||||||
&dest_plats->ctxlat);
|
&dest_plats->ctxlat);
|
||||||
ret
|
ret
|
||||||
|
|
@ -3857,6 +3870,7 @@ find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
|
||||||
tree newval = NULL_TREE;
|
tree newval = NULL_TREE;
|
||||||
int j;
|
int j;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
tree type = ipa_get_type (info, i);
|
||||||
|
|
||||||
if (ipa_get_scalar_lat (info, i)->bottom || known_csts[i])
|
if (ipa_get_scalar_lat (info, i)->bottom || known_csts[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -3876,7 +3890,7 @@ find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
|
jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
|
||||||
t = ipa_value_from_jfunc (IPA_NODE_REF (cs->caller), jump_func);
|
t = ipa_value_from_jfunc (IPA_NODE_REF (cs->caller), jump_func, type);
|
||||||
if (!t
|
if (!t
|
||||||
|| (newval
|
|| (newval
|
||||||
&& !values_equal_for_ipcp_p (t, newval))
|
&& !values_equal_for_ipcp_p (t, newval))
|
||||||
|
|
@ -4352,7 +4366,8 @@ cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge *cs,
|
||||||
if (i >= ipa_get_cs_argument_count (args))
|
if (i >= ipa_get_cs_argument_count (args))
|
||||||
return false;
|
return false;
|
||||||
jump_func = ipa_get_ith_jump_func (args, i);
|
jump_func = ipa_get_ith_jump_func (args, i);
|
||||||
t = ipa_value_from_jfunc (caller_info, jump_func);
|
t = ipa_value_from_jfunc (caller_info, jump_func,
|
||||||
|
ipa_get_type (dest_info, i));
|
||||||
if (!t || !values_equal_for_ipcp_p (val, t))
|
if (!t || !values_equal_for_ipcp_p (val, t))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -443,15 +443,16 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
|
||||||
&& !e->call_stmt_cannot_inline_p
|
&& !e->call_stmt_cannot_inline_p
|
||||||
&& ((clause_ptr && info->conds) || known_vals_ptr || known_contexts_ptr))
|
&& ((clause_ptr && info->conds) || known_vals_ptr || known_contexts_ptr))
|
||||||
{
|
{
|
||||||
struct ipa_node_params *parms_info;
|
struct ipa_node_params *caller_parms_info, *callee_pi;
|
||||||
struct ipa_edge_args *args = IPA_EDGE_REF (e);
|
struct ipa_edge_args *args = IPA_EDGE_REF (e);
|
||||||
struct ipa_call_summary *es = ipa_call_summaries->get (e);
|
struct ipa_call_summary *es = ipa_call_summaries->get (e);
|
||||||
int i, count = ipa_get_cs_argument_count (args);
|
int i, count = ipa_get_cs_argument_count (args);
|
||||||
|
|
||||||
if (e->caller->global.inlined_to)
|
if (e->caller->global.inlined_to)
|
||||||
parms_info = IPA_NODE_REF (e->caller->global.inlined_to);
|
caller_parms_info = IPA_NODE_REF (e->caller->global.inlined_to);
|
||||||
else
|
else
|
||||||
parms_info = IPA_NODE_REF (e->caller);
|
caller_parms_info = IPA_NODE_REF (e->caller);
|
||||||
|
callee_pi = IPA_NODE_REF (e->callee);
|
||||||
|
|
||||||
if (count && (info->conds || known_vals_ptr))
|
if (count && (info->conds || known_vals_ptr))
|
||||||
known_vals.safe_grow_cleared (count);
|
known_vals.safe_grow_cleared (count);
|
||||||
|
|
@ -463,7 +464,8 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
|
struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
|
||||||
tree cst = ipa_value_from_jfunc (parms_info, jf);
|
tree cst = ipa_value_from_jfunc (caller_parms_info, jf,
|
||||||
|
ipa_get_type (callee_pi, i));
|
||||||
|
|
||||||
if (!cst && e->call_stmt
|
if (!cst && e->call_stmt
|
||||||
&& i < (int)gimple_call_num_args (e->call_stmt))
|
&& i < (int)gimple_call_num_args (e->call_stmt))
|
||||||
|
|
@ -482,8 +484,8 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
|
||||||
known_vals[i] = error_mark_node;
|
known_vals[i] = error_mark_node;
|
||||||
|
|
||||||
if (known_contexts_ptr)
|
if (known_contexts_ptr)
|
||||||
(*known_contexts_ptr)[i] = ipa_context_from_jfunc (parms_info, e,
|
(*known_contexts_ptr)[i]
|
||||||
i, jf);
|
= ipa_context_from_jfunc (caller_parms_info, e, i, jf);
|
||||||
/* TODO: When IPA-CP starts propagating and merging aggregate jump
|
/* TODO: When IPA-CP starts propagating and merging aggregate jump
|
||||||
functions, use its knowledge of the caller too, just like the
|
functions, use its knowledge of the caller too, just like the
|
||||||
scalar case above. */
|
scalar case above. */
|
||||||
|
|
|
||||||
|
|
@ -3207,19 +3207,20 @@ try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
|
||||||
|
|
||||||
/* Try to find a destination for indirect edge IE that corresponds to a simple
|
/* Try to find a destination for indirect edge IE that corresponds to a simple
|
||||||
call or a call of a member function pointer and where the destination is a
|
call or a call of a member function pointer and where the destination is a
|
||||||
pointer formal parameter described by jump function JFUNC. If it can be
|
pointer formal parameter described by jump function JFUNC. TARGET_TYPE is
|
||||||
determined, return the newly direct edge, otherwise return NULL.
|
the type of the parameter to which the result of JFUNC is passed. If it can
|
||||||
|
be determined, return the newly direct edge, otherwise return NULL.
|
||||||
NEW_ROOT_INFO is the node info that JFUNC lattices are relative to. */
|
NEW_ROOT_INFO is the node info that JFUNC lattices are relative to. */
|
||||||
|
|
||||||
static struct cgraph_edge *
|
static struct cgraph_edge *
|
||||||
try_make_edge_direct_simple_call (struct cgraph_edge *ie,
|
try_make_edge_direct_simple_call (struct cgraph_edge *ie,
|
||||||
struct ipa_jump_func *jfunc,
|
struct ipa_jump_func *jfunc, tree target_type,
|
||||||
struct ipa_node_params *new_root_info)
|
struct ipa_node_params *new_root_info)
|
||||||
{
|
{
|
||||||
struct cgraph_edge *cs;
|
struct cgraph_edge *cs;
|
||||||
tree target;
|
tree target;
|
||||||
bool agg_contents = ie->indirect_info->agg_contents;
|
bool agg_contents = ie->indirect_info->agg_contents;
|
||||||
tree scalar = ipa_value_from_jfunc (new_root_info, jfunc);
|
tree scalar = ipa_value_from_jfunc (new_root_info, jfunc, target_type);
|
||||||
if (agg_contents)
|
if (agg_contents)
|
||||||
{
|
{
|
||||||
bool from_global_constant;
|
bool from_global_constant;
|
||||||
|
|
@ -3397,7 +3398,7 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
|
||||||
{
|
{
|
||||||
struct ipa_edge_args *top;
|
struct ipa_edge_args *top;
|
||||||
struct cgraph_edge *ie, *next_ie, *new_direct_edge;
|
struct cgraph_edge *ie, *next_ie, *new_direct_edge;
|
||||||
struct ipa_node_params *new_root_info;
|
struct ipa_node_params *new_root_info, *inlined_node_info;
|
||||||
bool res = false;
|
bool res = false;
|
||||||
|
|
||||||
ipa_check_create_edge_args ();
|
ipa_check_create_edge_args ();
|
||||||
|
|
@ -3405,6 +3406,7 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
|
||||||
new_root_info = IPA_NODE_REF (cs->caller->global.inlined_to
|
new_root_info = IPA_NODE_REF (cs->caller->global.inlined_to
|
||||||
? cs->caller->global.inlined_to
|
? cs->caller->global.inlined_to
|
||||||
: cs->caller);
|
: cs->caller);
|
||||||
|
inlined_node_info = IPA_NODE_REF (cs->callee->function_symbol ());
|
||||||
|
|
||||||
for (ie = node->indirect_calls; ie; ie = next_ie)
|
for (ie = node->indirect_calls; ie; ie = next_ie)
|
||||||
{
|
{
|
||||||
|
|
@ -3445,8 +3447,13 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
|
||||||
new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc, ctx);
|
new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc, ctx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
|
{
|
||||||
new_root_info);
|
tree target_type = ipa_get_type (inlined_node_info, param_index);
|
||||||
|
new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
|
||||||
|
target_type,
|
||||||
|
new_root_info);
|
||||||
|
}
|
||||||
|
|
||||||
/* If speculation was removed, then we need to do nothing. */
|
/* If speculation was removed, then we need to do nothing. */
|
||||||
if (new_direct_edge && new_direct_edge != ie
|
if (new_direct_edge && new_direct_edge != ie
|
||||||
&& new_direct_edge->callee == spec_target)
|
&& new_direct_edge->callee == spec_target)
|
||||||
|
|
|
||||||
|
|
@ -464,7 +464,8 @@ ipa_get_param (struct ipa_node_params *info, int i)
|
||||||
static inline tree
|
static inline tree
|
||||||
ipa_get_type (struct ipa_node_params *info, int i)
|
ipa_get_type (struct ipa_node_params *info, int i)
|
||||||
{
|
{
|
||||||
gcc_checking_assert (info->descriptors);
|
if (vec_safe_length (info->descriptors) <= (unsigned) i)
|
||||||
|
return NULL;
|
||||||
tree t = (*info->descriptors)[i].decl_or_type;
|
tree t = (*info->descriptors)[i].decl_or_type;
|
||||||
if (!t)
|
if (!t)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -773,7 +774,7 @@ void ipcp_write_transformation_summaries (void);
|
||||||
void ipcp_read_transformation_summaries (void);
|
void ipcp_read_transformation_summaries (void);
|
||||||
int ipa_get_param_decl_index (struct ipa_node_params *, tree);
|
int ipa_get_param_decl_index (struct ipa_node_params *, tree);
|
||||||
tree ipa_value_from_jfunc (struct ipa_node_params *info,
|
tree ipa_value_from_jfunc (struct ipa_node_params *info,
|
||||||
struct ipa_jump_func *jfunc);
|
struct ipa_jump_func *jfunc, tree type);
|
||||||
unsigned int ipcp_transform_function (struct cgraph_node *node);
|
unsigned int ipcp_transform_function (struct cgraph_node *node);
|
||||||
ipa_polymorphic_call_context ipa_context_from_jfunc (ipa_node_params *,
|
ipa_polymorphic_call_context ipa_context_from_jfunc (ipa_node_params *,
|
||||||
cgraph_edge *,
|
cgraph_edge *,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
2017-11-28 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
|
||||||
|
Martin Jambor <mjambor@suse.cz>
|
||||||
|
|
||||||
|
PR ipa/82808
|
||||||
|
* gcc.dg/ipa/pr82808.c: New test.
|
||||||
|
|
||||||
2017-11-28 Julia Koval <julia.koval@intel.com>
|
2017-11-28 Julia Koval <julia.koval@intel.com>
|
||||||
|
|
||||||
* gcc.target/i386/avx-1.c: Handle new intrinsics.
|
* gcc.target/i386/avx-1.c: Handle new intrinsics.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* { dg-options "-O2" } */
|
||||||
|
/* { dg-do run } */
|
||||||
|
|
||||||
|
static void __attribute__((noinline))
|
||||||
|
foo (double *a, double x)
|
||||||
|
{
|
||||||
|
*a = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double __attribute__((noinline))
|
||||||
|
f_c1 (int m, double *a)
|
||||||
|
{
|
||||||
|
foo (a, m);
|
||||||
|
return *a;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (){
|
||||||
|
double data;
|
||||||
|
double ret = 0 ;
|
||||||
|
|
||||||
|
if ((ret = f_c1 (2, &data)) != 2)
|
||||||
|
{
|
||||||
|
__builtin_abort ();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
44
gcc/tree.c
44
gcc/tree.c
|
|
@ -13898,6 +13898,50 @@ arg_size_in_bytes (const_tree type)
|
||||||
return TYPE_EMPTY_P (type) ? size_zero_node : size_in_bytes (type);
|
return TYPE_EMPTY_P (type) ? size_zero_node : size_in_bytes (type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return true if an expression with CODE has to have the same result type as
|
||||||
|
its first operand. */
|
||||||
|
|
||||||
|
bool
|
||||||
|
expr_type_first_operand_type_p (tree_code code)
|
||||||
|
{
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case NEGATE_EXPR:
|
||||||
|
case ABS_EXPR:
|
||||||
|
case BIT_NOT_EXPR:
|
||||||
|
case PAREN_EXPR:
|
||||||
|
case CONJ_EXPR:
|
||||||
|
|
||||||
|
case PLUS_EXPR:
|
||||||
|
case MINUS_EXPR:
|
||||||
|
case MULT_EXPR:
|
||||||
|
case TRUNC_DIV_EXPR:
|
||||||
|
case CEIL_DIV_EXPR:
|
||||||
|
case FLOOR_DIV_EXPR:
|
||||||
|
case ROUND_DIV_EXPR:
|
||||||
|
case TRUNC_MOD_EXPR:
|
||||||
|
case CEIL_MOD_EXPR:
|
||||||
|
case FLOOR_MOD_EXPR:
|
||||||
|
case ROUND_MOD_EXPR:
|
||||||
|
case RDIV_EXPR:
|
||||||
|
case EXACT_DIV_EXPR:
|
||||||
|
case MIN_EXPR:
|
||||||
|
case MAX_EXPR:
|
||||||
|
case BIT_IOR_EXPR:
|
||||||
|
case BIT_XOR_EXPR:
|
||||||
|
case BIT_AND_EXPR:
|
||||||
|
|
||||||
|
case LSHIFT_EXPR:
|
||||||
|
case RSHIFT_EXPR:
|
||||||
|
case LROTATE_EXPR:
|
||||||
|
case RROTATE_EXPR:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* List of pointer types used to declare builtins before we have seen their
|
/* List of pointer types used to declare builtins before we have seen their
|
||||||
real declaration.
|
real declaration.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5445,6 +5445,7 @@ extern bool is_redundant_typedef (const_tree);
|
||||||
extern bool default_is_empty_record (const_tree);
|
extern bool default_is_empty_record (const_tree);
|
||||||
extern HOST_WIDE_INT arg_int_size_in_bytes (const_tree);
|
extern HOST_WIDE_INT arg_int_size_in_bytes (const_tree);
|
||||||
extern tree arg_size_in_bytes (const_tree);
|
extern tree arg_size_in_bytes (const_tree);
|
||||||
|
extern bool expr_type_first_operand_type_p (tree_code);
|
||||||
|
|
||||||
extern location_t
|
extern location_t
|
||||||
set_source_range (tree expr, location_t start, location_t finish);
|
set_source_range (tree expr, location_t start, location_t finish);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue