示例#1
0
static bool
ref_same_as_full_array (gfc_ref *full_ref, gfc_ref *ref)
{
  int i;
  bool upper_or_lower;

  if (full_ref->type != REF_ARRAY)
    return false;
  if (full_ref->u.ar.type != AR_FULL)
    return false;
  if (ref->type != REF_ARRAY)
    return false;
  if (ref->u.ar.type != AR_SECTION)
    return false;

  for (i = 0; i < ref->u.ar.dimen; i++)
    {
      /* If we have a single element in the reference, we need to check
	 that the array has a single element and that we actually reference
	 the correct element.  */
      if (ref->u.ar.dimen_type[i] == DIMEN_ELEMENT)
	{
	  if (!full_ref->u.ar.as
	      || !full_ref->u.ar.as->lower[i]
	      || !full_ref->u.ar.as->upper[i]
	      || gfc_dep_compare_expr (full_ref->u.ar.as->lower[i],
				       full_ref->u.ar.as->upper[i])
	      || !ref->u.ar.start[i]
	      || gfc_dep_compare_expr (ref->u.ar.start[i],
				       full_ref->u.ar.as->lower[i]))
	    return false;
	}

      /* Check the strides.  */
      if (full_ref->u.ar.stride[i] && !gfc_expr_is_one (full_ref->u.ar.stride[i], 0))
	return false;
      if (ref->u.ar.stride[i] && !gfc_expr_is_one (ref->u.ar.stride[i], 0))
	return false;

      upper_or_lower = false;
      /* Check the lower bound.  */
      if (ref->u.ar.start[i]
	  && (ref->u.ar.as
	        && full_ref->u.ar.as->lower[i]
	        && gfc_dep_compare_expr (ref->u.ar.start[i],
				         full_ref->u.ar.as->lower[i]) == 0))
	upper_or_lower =  true;
      /* Check the upper bound.  */
      if (ref->u.ar.end[i]
	  && (ref->u.ar.as
	        && full_ref->u.ar.as->upper[i]
	        && gfc_dep_compare_expr (ref->u.ar.end[i],
				         full_ref->u.ar.as->upper[i]) == 0))
	upper_or_lower =  true;
      if (!upper_or_lower)
	return false;
    }
  return true;
}
示例#2
0
bool
gfc_full_array_ref_p (gfc_ref *ref)
{
  int i;

  if (ref->type != REF_ARRAY)
    return false;
  if (ref->u.ar.type == AR_FULL)
    return true;
  if (ref->u.ar.type != AR_SECTION)
    return false;
  if (ref->next)
    return false;

  for (i = 0; i < ref->u.ar.dimen; i++)
    {
      /* Check the lower bound.  */
      if (ref->u.ar.start[i]
	  && (!ref->u.ar.as
	      || !ref->u.ar.as->lower[i]
	      || gfc_dep_compare_expr (ref->u.ar.start[i],
				       ref->u.ar.as->lower[i])))
	return false;
      /* Check the upper bound.  */
      if (ref->u.ar.end[i]
	  && (!ref->u.ar.as
	      || !ref->u.ar.as->upper[i]
	      || gfc_dep_compare_expr (ref->u.ar.end[i],
				       ref->u.ar.as->upper[i])))
	return false;
      /* Check the stride.  */
      if (ref->u.ar.stride[i]
	  && !gfc_expr_is_one (ref->u.ar.stride[i], 0))
	return false;
    }
  return true;
}
示例#3
0
int
gfc_is_same_range (gfc_array_ref *ar1, gfc_array_ref *ar2, int n, int def)
{
  gfc_expr *e1;
  gfc_expr *e2;
  int i;

  /* TODO: More sophisticated range comparison.  */
  gcc_assert (ar1 && ar2);

  gcc_assert (ar1->dimen_type[n] == ar2->dimen_type[n]);

  e1 = ar1->stride[n];
  e2 = ar2->stride[n];
  /* Check for mismatching strides.  A NULL stride means a stride of 1.  */
  if (e1 && !e2)
    {
      i = gfc_expr_is_one (e1, -1);
      if (i == -1)
	return def;
      else if (i == 0)
	return 0;
    }
  else if (e2 && !e1)
    {
      i = gfc_expr_is_one (e2, -1);
      if (i == -1)
	return def;
      else if (i == 0)
	return 0;
    }
  else if (e1 && e2)
    {
      i = gfc_dep_compare_expr (e1, e2);
      if (i == -2)
	return def;
      else if (i != 0)
	return 0;
    }
  /* The strides match.  */

  /* Check the range start.  */
  e1 = ar1->start[n];
  e2 = ar2->start[n];
  if (e1 || e2)
    {
      /* Use the bound of the array if no bound is specified.  */
      if (ar1->as && !e1)
	e1 = ar1->as->lower[n];

      if (ar2->as && !e2)
	e2 = ar2->as->lower[n];

      /* Check we have values for both.  */
      if (!(e1 && e2))
	return def;

      i = gfc_dep_compare_expr (e1, e2);
      if (i == -2)
	return def;
      else if (i != 0)
	return 0;
    }

  /* Check the range end.  */
  e1 = ar1->end[n];
  e2 = ar2->end[n];
  if (e1 || e2)
    {
      /* Use the bound of the array if no bound is specified.  */
      if (ar1->as && !e1)
	e1 = ar1->as->upper[n];

      if (ar2->as && !e2)
	e2 = ar2->as->upper[n];

      /* Check we have values for both.  */
      if (!(e1 && e2))
	return def;

      i = gfc_dep_compare_expr (e1, e2);
      if (i == -2)
	return def;
      else if (i != 0)
	return 0;
    }

  return 1;
}
示例#4
0
bool
gfc_full_array_ref_p (gfc_ref *ref, bool *contiguous)
{
  int i;
  int n;
  bool lbound_OK = true;
  bool ubound_OK = true;

  if (contiguous)
    *contiguous = false;

  if (ref->type != REF_ARRAY)
    return false;

  if (ref->u.ar.type == AR_FULL)
    {
      if (contiguous)
	*contiguous = true;
      return true;
    }

  if (ref->u.ar.type != AR_SECTION)
    return false;
  if (ref->next)
    return false;

  for (i = 0; i < ref->u.ar.dimen; i++)
    {
      /* If we have a single element in the reference, for the reference
	 to be full, we need to ascertain that the array has a single
	 element in this dimension and that we actually reference the
	 correct element.  */
      if (ref->u.ar.dimen_type[i] == DIMEN_ELEMENT)
	{
	  /* This is unconditionally a contiguous reference if all the
	     remaining dimensions are elements.  */
	  if (contiguous)
	    {
	      *contiguous = true;
	      for (n = i + 1; n < ref->u.ar.dimen; n++)
		if (ref->u.ar.dimen_type[n] != DIMEN_ELEMENT)
		  *contiguous = false;
	    }

	  if (!ref->u.ar.as
	      || !ref->u.ar.as->lower[i]
	      || !ref->u.ar.as->upper[i]
	      || gfc_dep_compare_expr (ref->u.ar.as->lower[i],
				       ref->u.ar.as->upper[i])
	      || !ref->u.ar.start[i]
	      || gfc_dep_compare_expr (ref->u.ar.start[i],
				       ref->u.ar.as->lower[i]))
	    return false;
	  else
	    continue;
	}

      /* Check the lower bound.  */
      if (ref->u.ar.start[i]
	  && (!ref->u.ar.as
	      || !ref->u.ar.as->lower[i]
	      || gfc_dep_compare_expr (ref->u.ar.start[i],
				       ref->u.ar.as->lower[i])))
	lbound_OK = false;
      /* Check the upper bound.  */
      if (ref->u.ar.end[i]
	  && (!ref->u.ar.as
	      || !ref->u.ar.as->upper[i]
	      || gfc_dep_compare_expr (ref->u.ar.end[i],
				       ref->u.ar.as->upper[i])))
	ubound_OK = false;
      /* Check the stride.  */
      if (ref->u.ar.stride[i]
	    && !gfc_expr_is_one (ref->u.ar.stride[i], 0))
	return false;

      /* This is unconditionally a contiguous reference as long as all
	 the subsequent dimensions are elements.  */
      if (contiguous)
	{
	  *contiguous = true;
	  for (n = i + 1; n < ref->u.ar.dimen; n++)
	    if (ref->u.ar.dimen_type[n] != DIMEN_ELEMENT)
	      *contiguous = false;
	}

      if (!lbound_OK || !ubound_OK)
	return false;
    }
  return true;
}