summaryrefslogtreecommitdiff
path: root/gcc/tree-ssanames.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssanames.c')
-rw-r--r--gcc/tree-ssanames.c77
1 files changed, 35 insertions, 42 deletions
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 4e576977235..be358e1d97d 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -186,19 +186,23 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
/* Store range information RANGE_TYPE, MIN, and MAX to tree ssa_name NAME. */
void
-set_range_info (tree name, enum value_range_type range_type, double_int min,
- double_int max)
+set_range_info (tree name, enum value_range_type range_type,
+ const wide_int_ref &min, const wide_int_ref &max)
{
gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
gcc_assert (range_type == VR_RANGE || range_type == VR_ANTI_RANGE);
range_info_def *ri = SSA_NAME_RANGE_INFO (name);
+ unsigned int precision = TYPE_PRECISION (TREE_TYPE (name));
/* Allocate if not available. */
if (ri == NULL)
{
- ri = ggc_alloc_cleared_range_info_def ();
+ size_t size = (sizeof (range_info_def)
+ + trailing_wide_ints <3>::extra_size (precision));
+ ri = ggc_alloc_range_info_def (size);
+ ri->ints.set_precision (precision);
SSA_NAME_RANGE_INFO (name) = ri;
- ri->nonzero_bits = double_int::mask (TYPE_PRECISION (TREE_TYPE (name)));
+ ri->set_nonzero_bits (wi::shwi (-1, precision));
}
/* Record the range type. */
@@ -206,25 +210,16 @@ set_range_info (tree name, enum value_range_type range_type, double_int min,
SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE);
/* Set the values. */
- ri->min = min;
- ri->max = max;
+ ri->set_min (min);
+ ri->set_max (max);
/* If it is a range, try to improve nonzero_bits from the min/max. */
if (range_type == VR_RANGE)
{
- int prec = TYPE_PRECISION (TREE_TYPE (name));
- double_int xorv;
-
- min = min.zext (prec);
- max = max.zext (prec);
- xorv = min ^ max;
- if (xorv.high)
- xorv = double_int::mask (2 * HOST_BITS_PER_WIDE_INT
- - clz_hwi (xorv.high));
- else if (xorv.low)
- xorv = double_int::mask (HOST_BITS_PER_WIDE_INT
- - clz_hwi (xorv.low));
- ri->nonzero_bits = ri->nonzero_bits & (min | xorv);
+ wide_int xorv = ri->get_min () ^ ri->get_max ();
+ if (xorv != 0)
+ xorv = wi::mask (precision - wi::clz (xorv), false, precision);
+ ri->set_nonzero_bits (ri->get_nonzero_bits () & (ri->get_min () | xorv));
}
}
@@ -234,7 +229,7 @@ set_range_info (tree name, enum value_range_type range_type, double_int min,
is used to determine if MIN and MAX are valid values. */
enum value_range_type
-get_range_info (const_tree name, double_int *min, double_int *max)
+get_range_info (const_tree name, wide_int *min, wide_int *max)
{
gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
gcc_assert (min && max);
@@ -246,50 +241,45 @@ get_range_info (const_tree name, double_int *min, double_int *max)
> 2 * HOST_BITS_PER_WIDE_INT))
return VR_VARYING;
- *min = ri->min;
- *max = ri->max;
+ *min = ri->get_min ();
+ *max = ri->get_max ();
return SSA_NAME_RANGE_TYPE (name);
}
/* Change non-zero bits bitmask of NAME. */
void
-set_nonzero_bits (tree name, double_int mask)
+set_nonzero_bits (tree name, const wide_int_ref &mask)
{
gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
if (SSA_NAME_RANGE_INFO (name) == NULL)
set_range_info (name, VR_RANGE,
- tree_to_double_int (TYPE_MIN_VALUE (TREE_TYPE (name))),
- tree_to_double_int (TYPE_MAX_VALUE (TREE_TYPE (name))));
+ TYPE_MIN_VALUE (TREE_TYPE (name)),
+ TYPE_MAX_VALUE (TREE_TYPE (name)));
range_info_def *ri = SSA_NAME_RANGE_INFO (name);
- ri->nonzero_bits
- = mask & double_int::mask (TYPE_PRECISION (TREE_TYPE (name)));
+ ri->set_nonzero_bits (mask);
}
-/* Return a double_int with potentially non-zero bits in SSA_NAME
- NAME, or double_int_minus_one if unknown. */
+/* Return a widest_int with potentially non-zero bits in SSA_NAME
+ NAME, or -1 if unknown. */
-double_int
+wide_int
get_nonzero_bits (const_tree name)
{
+ unsigned int precision = TYPE_PRECISION (TREE_TYPE (name));
if (POINTER_TYPE_P (TREE_TYPE (name)))
{
struct ptr_info_def *pi = SSA_NAME_PTR_INFO (name);
if (pi && pi->align)
- {
- double_int al = double_int::from_uhwi (pi->align - 1);
- return ((double_int::mask (TYPE_PRECISION (TREE_TYPE (name))) & ~al)
- | double_int::from_uhwi (pi->misalign));
- }
- return double_int_minus_one;
+ return wi::shwi (-(int) pi->align | pi->misalign, precision);
+ return wi::shwi (-1, precision);
}
range_info_def *ri = SSA_NAME_RANGE_INFO (name);
- if (!ri || (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (name)))
- > 2 * HOST_BITS_PER_WIDE_INT))
- return double_int_minus_one;
+ if (!ri)
+ return wi::shwi (-1, precision);
- return ri->nonzero_bits;
+ return ri->get_nonzero_bits ();
}
/* We no longer need the SSA_NAME expression VAR, release it so that
@@ -502,8 +492,11 @@ duplicate_ssa_name_range_info (tree name, enum value_range_type range_type,
if (!range_info)
return;
- new_range_info = ggc_alloc_range_info_def ();
- *new_range_info = *range_info;
+ unsigned int precision = TYPE_PRECISION (TREE_TYPE (name));
+ size_t size = (sizeof (range_info_def)
+ + trailing_wide_ints <3>::extra_size (precision));
+ new_range_info = ggc_alloc_range_info_def (size);
+ memcpy (new_range_info, range_info, size);
gcc_assert (range_type == VR_RANGE || range_type == VR_ANTI_RANGE);
SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE);