/* Creates a duplicate of the range_info_def at RANGE_INFO of type RANGE_TYPE for use by the SSA name NAME. */ void duplicate_ssa_name_range_info (tree name, enum value_range_type range_type, struct range_info_def *range_info) { struct range_info_def *new_range_info; gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); gcc_assert (!SSA_NAME_RANGE_INFO (name)); gcc_assert (!SSA_NAME_ANTI_RANGE_P (name)); if (!range_info) return; new_range_info = ggc_alloc_range_info_def (); *new_range_info = *range_info; gcc_assert (range_type == VR_RANGE || range_type == VR_ANTI_RANGE); SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE); SSA_NAME_RANGE_INFO (name) = new_range_info; }
/* Creates a duplicate of the range_info_def at RANGE_INFO of type RANGE_TYPE for use by the SSA name NAME. */ void duplicate_ssa_name_range_info (tree name, enum value_range_type range_type, struct range_info_def *range_info) { struct range_info_def *new_range_info; gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name))); gcc_assert (!SSA_NAME_RANGE_INFO (name)); gcc_assert (!SSA_NAME_ANTI_RANGE_P (name)); if (!range_info) return; 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 = static_cast<range_info_def *> (ggc_internal_alloc (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); SSA_NAME_RANGE_INFO (name) = new_range_info; }
void set_range_info (tree name, enum value_range_type range_type, double_int min, double_int 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); /* Allocate if not available. */ if (ri == NULL) { ri = ggc_alloc_cleared_range_info_def (); SSA_NAME_RANGE_INFO (name) = ri; ri->nonzero_bits = double_int::mask (TYPE_PRECISION (TREE_TYPE (name))); } /* Record the range type. */ if (SSA_NAME_RANGE_TYPE (name) != range_type) SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE); /* Set the values. */ ri->min = min; ri->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); } }
void 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) { size_t size = (sizeof (range_info_def) + trailing_wide_ints <3>::extra_size (precision)); ri = static_cast<range_info_def *> (ggc_internal_alloc (size)); ri->ints.set_precision (precision); SSA_NAME_RANGE_INFO (name) = ri; ri->set_nonzero_bits (wi::shwi (-1, precision)); } /* Record the range type. */ if (SSA_NAME_RANGE_TYPE (name) != range_type) SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE); /* Set the values. */ 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) { 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)); } }