#include "attribs.h"
#include "dbgcnt.h"
#include "symtab-clones.h"
+#include "gimple-range.h"
template <typename valtype> class ipcp_value;
enum tree_code operation,
tree dst_type, tree src_type)
{
- range_fold_unary_expr (dst_vr, operation, dst_type, src_vr, src_type);
- if (dst_vr->varying_p () || dst_vr->undefined_p ())
+ if (!irange::supports_p (dst_type) || !irange::supports_p (src_type))
return false;
- return true;
+
+ range_op_handler handler (operation, dst_type);
+ return (handler
+ && handler.fold_range (*dst_vr, dst_type,
+ *src_vr, value_range (dst_type))
+ && !dst_vr->varying_p ()
+ && !dst_vr->undefined_p ());
}
/* Determine value_range of JFUNC given that INFO describes the caller node or
value_range op_res, res;
tree op = ipa_get_jf_pass_through_operand (jfunc);
value_range op_vr (op, op);
+ range_op_handler handler (operation, vr_type);
+
+ if (!handler
+ || !op_res.supports_type_p (vr_type)
+ || !handler.fold_range (op_res, vr_type, srcvr, op_vr))
+ op_res.set_varying (vr_type);
- range_fold_binary_expr (&op_res, operation, vr_type, &srcvr, &op_vr);
if (ipa_vr_operation_and_type_effects (&res,
&op_res,
NOP_EXPR, parm_type,
tree op = ipa_get_jf_pass_through_operand (jfunc);
value_range op_vr (op, op);
value_range op_res,res;
+ range_op_handler handler (operation, operand_type);
+
+ if (!handler
+ || !op_res.supports_type_p (operand_type)
+ || !handler.fold_range (op_res, operand_type,
+ src_lats->m_value_range.m_vr, op_vr))
+ op_res.set_varying (operand_type);
- range_fold_binary_expr (&op_res, operation, operand_type,
- &src_lats->m_value_range.m_vr, &op_vr);
ipa_vr_operation_and_type_effects (&vr,
&op_res,
NOP_EXPR, param_type,
&& (TYPE_SIZE (c->type) == TYPE_SIZE (vr.type ())))
{
if (!useless_type_conversion_p (c->type, vr.type ()))
- {
- value_range res;
- range_fold_unary_expr (&res, NOP_EXPR,
- c->type, &vr, vr.type ());
- vr = res;
- }
- tree type = c->type;
+ range_cast (vr, c->type);
for (j = 0; vec_safe_iterate (c->param_ops, j, &op); j++)
{
value_range res;
if (!op->val[0])
- range_fold_unary_expr (&res, op->code, op->type, &vr, type);
+ {
+ range_op_handler handler (op->code, op->type);
+ if (!handler
+ || !res.supports_type_p (op->type)
+ || !handler.fold_range (res, op->type, vr,
+ value_range (op->type)))
+ res.set_varying (op->type);
+ }
else if (!op->val[1])
{
value_range op0 (op->val[0], op->val[0]);
- range_fold_binary_expr (&res, op->code, op->type,
- op->index ? &op0 : &vr,
- op->index ? &vr : &op0);
+ range_op_handler handler (op->code, op->type);
+
+ if (!handler
+ || !res.supports_type_p (op->type)
+ || !handler.fold_range (res, op->type,
+ op->index ? op0 : vr,
+ op->index ? vr : op0))
+ res.set_varying (op->type);
}
else
res.set_varying (op->type);
- type = op->type;
vr = res;
}
if (!vr.varying_p () && !vr.undefined_p ())
{
value_range res;
- value_range val_vr (c->val, c->val);
- range_fold_binary_expr (&res, c->code, boolean_type_node,
- &vr,
- &val_vr);
+ value_range val_vr;
+ if (TREE_CODE (c->val) == INTEGER_CST)
+ val_vr.set (c->val, c->val);
+ else
+ val_vr.set_varying (TREE_TYPE (c->val));
+ range_op_handler handler (c->code, boolean_type_node);
+
+ if (!handler
+ || !res.supports_type_p (boolean_type_node)
+ || !handler.fold_range (res, boolean_type_node, vr, val_vr))
+ res.set_varying (boolean_type_node);
+
if (res.zero_p ())
continue;
}
&& get_range_query (cfun)->range_of_expr (vr, arg)
&& !vr.undefined_p ())
{
- value_range resvr;
- range_fold_unary_expr (&resvr, NOP_EXPR, param_type,
- &vr, TREE_TYPE (arg));
+ value_range resvr = vr;
+ range_cast (resvr, param_type);
if (!resvr.undefined_p () && !resvr.varying_p ())
ipa_set_jfunc_vr (jfunc, &resvr);
else
vr0.set_varying (TREE_TYPE (init));
tree tem = wide_int_to_tree (TREE_TYPE (init), wtmp);
vr1.set (tem, tem);
- range_fold_binary_expr (&maxvr, PLUS_EXPR,
- TREE_TYPE (init), &vr0, &vr1);
+
+ range_op_handler handler (PLUS_EXPR, TREE_TYPE (init));
+ if (!handler.fold_range (maxvr, TREE_TYPE (init), vr0, vr1))
+ maxvr.set_varying (TREE_TYPE (init));
/* Likewise if the addition did. */
if (maxvr.kind () == VR_RANGE)