Add gimple_range_type for statements.
The existing mechanisms for picking up the type of a statement are inconsistent with the needs of ranger. Encapsulate all the bits required to pick up the return type of a statement in one place, and check whether the type is supported. * gimple-range-fold.cc (adjust_pointer_diff_expr): Use gimple_range_type. (fold_using_range::fold_stmt): Ditto. (fold_using_range::range_of_range_op): Ditto. (fold_using_range::range_of_phi): Ditto. (fold_using_range::range_of_call): Ditto. (fold_using_range::range_of_builtin_ubsan_call): Ditto. (fold_using_range::range_of_builtin_call): Ditto. (fold_using_range::range_of_cond_expr): Ditto. * gimple-range-fold.h (gimple_range_type): New.
This commit is contained in:
parent
f0500db369
commit
478cc962ad
@ -362,7 +362,7 @@ adjust_pointer_diff_expr (irange &res, const gimple *diff_stmt)
|
||||
{
|
||||
tree max = vrp_val_max (ptrdiff_type_node);
|
||||
wide_int wmax = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max)));
|
||||
tree expr_type = gimple_expr_type (diff_stmt);
|
||||
tree expr_type = gimple_range_type (diff_stmt);
|
||||
tree range_min = build_zero_cst (expr_type);
|
||||
tree range_max = wide_int_to_tree (expr_type, wmax - 1);
|
||||
int_range<2> r (range_min, range_max);
|
||||
@ -522,16 +522,8 @@ fold_using_range::fold_stmt (irange &r, gimple *s, fur_source &src, tree name)
|
||||
|
||||
if (!res)
|
||||
{
|
||||
// If no name is specified, try the expression kind.
|
||||
if (!name)
|
||||
{
|
||||
tree t = gimple_expr_type (s);
|
||||
if (!irange::supports_type_p (t))
|
||||
return false;
|
||||
r.set_varying (t);
|
||||
return true;
|
||||
}
|
||||
if (!gimple_range_ssa_p (name))
|
||||
// If no name specified or range is unsupported, bail.
|
||||
if (!name || !gimple_range_ssa_p (name))
|
||||
return false;
|
||||
// We don't understand the stmt, so return the global range.
|
||||
r = gimple_range_global (name);
|
||||
@ -558,10 +550,11 @@ bool
|
||||
fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src)
|
||||
{
|
||||
int_range_max range1, range2;
|
||||
tree type = gimple_expr_type (s);
|
||||
tree type = gimple_range_type (s);
|
||||
if (!type)
|
||||
return false;
|
||||
range_operator *handler = gimple_range_handler (s);
|
||||
gcc_checking_assert (handler);
|
||||
gcc_checking_assert (irange::supports_type_p (type));
|
||||
|
||||
tree lhs = gimple_get_lhs (s);
|
||||
tree op1 = gimple_range_operand1 (s);
|
||||
@ -719,11 +712,11 @@ bool
|
||||
fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src)
|
||||
{
|
||||
tree phi_def = gimple_phi_result (phi);
|
||||
tree type = TREE_TYPE (phi_def);
|
||||
tree type = gimple_range_type (phi);
|
||||
int_range_max arg_range;
|
||||
unsigned x;
|
||||
|
||||
if (!irange::supports_type_p (type))
|
||||
if (!type)
|
||||
return false;
|
||||
|
||||
// Start with an empty range, unioning in each argument's range.
|
||||
@ -780,13 +773,13 @@ fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src)
|
||||
bool
|
||||
fold_using_range::range_of_call (irange &r, gcall *call, fur_source &src)
|
||||
{
|
||||
tree type = gimple_call_return_type (call);
|
||||
tree type = gimple_range_type (call);
|
||||
if (!type)
|
||||
return false;
|
||||
|
||||
tree lhs = gimple_call_lhs (call);
|
||||
bool strict_overflow_p;
|
||||
|
||||
if (!irange::supports_type_p (type))
|
||||
return false;
|
||||
|
||||
if (range_of_builtin_call (r, call, src))
|
||||
;
|
||||
else if (gimple_stmt_nonnegative_warnv_p (call, &strict_overflow_p))
|
||||
@ -817,7 +810,7 @@ fold_using_range::range_of_builtin_ubsan_call (irange &r, gcall *call,
|
||||
{
|
||||
gcc_checking_assert (code == PLUS_EXPR || code == MINUS_EXPR
|
||||
|| code == MULT_EXPR);
|
||||
tree type = gimple_call_return_type (call);
|
||||
tree type = gimple_range_type (call);
|
||||
range_operator *op = range_op_handler (code, type);
|
||||
gcc_checking_assert (op);
|
||||
int_range_max ir0, ir1;
|
||||
@ -853,7 +846,7 @@ fold_using_range::range_of_builtin_call (irange &r, gcall *call,
|
||||
if (func == CFN_LAST)
|
||||
return false;
|
||||
|
||||
tree type = gimple_call_return_type (call);
|
||||
tree type = gimple_range_type (call);
|
||||
tree arg;
|
||||
int mini, maxi, zerov = 0, prec;
|
||||
scalar_int_mode mode;
|
||||
@ -1094,12 +1087,12 @@ fold_using_range::range_of_cond_expr (irange &r, gassign *s, fur_source &src)
|
||||
tree op1 = gimple_assign_rhs2 (s);
|
||||
tree op2 = gimple_assign_rhs3 (s);
|
||||
|
||||
gcc_checking_assert (gimple_assign_rhs_code (s) == COND_EXPR);
|
||||
gcc_checking_assert (useless_type_conversion_p (TREE_TYPE (op1),
|
||||
TREE_TYPE (op2)));
|
||||
if (!irange::supports_type_p (TREE_TYPE (op1)))
|
||||
tree type = gimple_range_type (s);
|
||||
if (!type)
|
||||
return false;
|
||||
|
||||
gcc_checking_assert (gimple_assign_rhs_code (s) == COND_EXPR);
|
||||
gcc_checking_assert (range_compatible_p (TREE_TYPE (op1), TREE_TYPE (op2)));
|
||||
src.get_operand (cond_range, cond);
|
||||
src.get_operand (range1, op1);
|
||||
src.get_operand (range2, op2);
|
||||
@ -1118,6 +1111,7 @@ fold_using_range::range_of_cond_expr (irange &r, gassign *s, fur_source &src)
|
||||
r = range1;
|
||||
r.union_ (range2);
|
||||
}
|
||||
gcc_checking_assert (range_compatible_p (r.type (), type));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,36 @@ gimple_range_handler (const gimple *s)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Return the type of range which statement S calculates. If the type is
|
||||
// unsupported or no type can be determined, return NULL_TREE.
|
||||
|
||||
static inline tree
|
||||
gimple_range_type (const gimple *s)
|
||||
{
|
||||
tree lhs = gimple_get_lhs (s);
|
||||
tree type = NULL_TREE;
|
||||
if (lhs)
|
||||
type = TREE_TYPE (lhs);
|
||||
else
|
||||
{
|
||||
enum gimple_code code = gimple_code (s);
|
||||
if (code == GIMPLE_COND)
|
||||
type = boolean_type_node;
|
||||
else if (code == GIMPLE_PHI)
|
||||
type = TREE_TYPE (gimple_phi_result (s));
|
||||
else if (code == GIMPLE_CALL)
|
||||
{
|
||||
type = gimple_call_fntype (s);
|
||||
// If it has a type, get the return type.
|
||||
if (type)
|
||||
type = TREE_TYPE (type);
|
||||
}
|
||||
}
|
||||
if (irange::supports_type_p (type))
|
||||
return type;
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
// Return EXP if it is an SSA_NAME with a type supported by gimple ranges.
|
||||
|
||||
static inline tree
|
||||
|
Loading…
Reference in New Issue
Block a user