Commit e5cf5e11 by Prathamesh Kulkarni Committed by Martin Jambor

[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
parent 5e4a80e8
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
...@@ -1220,33 +1220,38 @@ initialize_node_lattices (struct cgraph_node *node) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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
{
tree target_type = ipa_get_type (inlined_node_info, param_index);
new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc, new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
target_type,
new_root_info); 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) ...@@ -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); ...@@ -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 *,
......
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.
......
/* { 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;
}
...@@ -13898,6 +13898,50 @@ arg_size_in_bytes (const_tree type) ...@@ -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); ...@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment