Esempio n. 1
0
enum value_range_type
get_range_info (const_tree name, double_int *min, double_int *max)
{
  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
  gcc_assert (min && max);
  range_info_def *ri = SSA_NAME_RANGE_INFO (name);

  /* Return VR_VARYING for SSA_NAMEs with NULL RANGE_INFO or SSA_NAMEs
     with integral types width > 2 * HOST_BITS_PER_WIDE_INT precision.  */
  if (!ri || (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (name)))
	      > 2 * HOST_BITS_PER_WIDE_INT))
    return VR_VARYING;

  *min = ri->min;
  *max = ri->max;
  return SSA_NAME_RANGE_TYPE (name);
}
Esempio n. 2
0
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);
    }
}
Esempio n. 3
0
tree
duplicate_ssa_name_fn (struct function *fn, tree name, gimple stmt)
{
  tree new_name = copy_ssa_name_fn (fn, name, stmt);
  if (POINTER_TYPE_P (TREE_TYPE (name)))
    {
      struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);

      if (old_ptr_info)
	duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
    }
  else
    {
      struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name);

      if (old_range_info)
	duplicate_ssa_name_range_info (new_name, SSA_NAME_RANGE_TYPE (name),
				       old_range_info);
    }

  return new_name;
}
Esempio n. 4
0
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));
    }
}
Esempio n. 5
0
static bool
fini_copy_prop (void)
{
  unsigned i;

  /* Set the final copy-of value for each variable by traversing the
     copy-of chains.  */
  for (i = 1; i < num_ssa_names; i++)
    {
      tree var = ssa_name (i);
      if (!var
	  || !copy_of[i].value
	  || copy_of[i].value == var)
	continue;

      /* In theory the points-to solution of all members of the
         copy chain is their intersection.  For now we do not bother
	 to compute this but only make sure we do not lose points-to
	 information completely by setting the points-to solution
	 of the representative to the first solution we find if
	 it doesn't have one already.  */
      if (copy_of[i].value != var
	  && TREE_CODE (copy_of[i].value) == SSA_NAME)
	{
	  basic_block copy_of_bb
	    = gimple_bb (SSA_NAME_DEF_STMT (copy_of[i].value));
	  basic_block var_bb = gimple_bb (SSA_NAME_DEF_STMT (var));
	  if (POINTER_TYPE_P (TREE_TYPE (var))
	      && SSA_NAME_PTR_INFO (var)
	      && !SSA_NAME_PTR_INFO (copy_of[i].value))
	    {
	      duplicate_ssa_name_ptr_info (copy_of[i].value,
					   SSA_NAME_PTR_INFO (var));
	      /* Points-to information is cfg insensitive,
		 but alignment info might be cfg sensitive, if it
		 e.g. is derived from VRP derived non-zero bits.
		 So, do not copy alignment info if the two SSA_NAMEs
		 aren't defined in the same basic block.  */
	      if (var_bb != copy_of_bb)
		mark_ptr_info_alignment_unknown
				(SSA_NAME_PTR_INFO (copy_of[i].value));
	    }
	  else if (!POINTER_TYPE_P (TREE_TYPE (var))
		   && SSA_NAME_RANGE_INFO (var)
		   && !SSA_NAME_RANGE_INFO (copy_of[i].value)
		   && var_bb == copy_of_bb)
	    duplicate_ssa_name_range_info (copy_of[i].value,
					   SSA_NAME_RANGE_TYPE (var),
					   SSA_NAME_RANGE_INFO (var));
	}
    }

  bool changed = substitute_and_fold (get_value, NULL, true);
  if (changed)
    {
      free_numbers_of_iterations_estimates ();
      if (scev_initialized_p ())
	scev_reset ();
    }

  free (copy_of);

  return changed;
}