示例#1
0
/* Given a stride constraint on iterator i (specified by level) of the form
 *
 *	i = f(outer iterators) + stride * f(existentials)
 *
 * extract f as an isl_aff.
 */
static isl_aff *extract_stride_offset(__isl_keep isl_constraint *c,
	int level, CloogStride *stride)
{
	int i;
	isl_space *dim = isl_constraint_get_space(c);
	isl_local_space *ls = isl_local_space_from_space(dim);
	isl_aff *offset = isl_aff_zero_on_domain(ls);
	isl_int u;
	unsigned nparam, nvar;

	isl_int_init(u);

	nparam = isl_constraint_dim(c, isl_dim_param);
	nvar = isl_constraint_dim(c, isl_dim_set);

	for (i = 0; i < nparam; ++i) {
		isl_constraint_get_coefficient(c, isl_dim_param, i, &u);
		isl_int_mul(u, u, stride->factor);
		offset = isl_aff_set_coefficient(offset, isl_dim_param, i, u);
	}
	for (i = 0; i < nvar; ++i) {
		if (i == level - 1)
			continue;
		isl_constraint_get_coefficient(c, isl_dim_set, i, &u);
		isl_int_mul(u, u, stride->factor);
		offset = isl_aff_set_coefficient(offset, isl_dim_in, i, u);
	}
	isl_constraint_get_constant(c, &u);
	isl_int_mul(u, u, stride->factor);
	offset = isl_aff_set_constant(offset, u);

	isl_int_clear(u);

	return offset;
}
示例#2
0
/**
 * cloog_constraint_equal_type function :
 * This function returns the type of the equality in the constraint (line) of
 * (constraints) for the element (level). An equality is 'constant' iff all
 * other factors are null except the constant one. It is a 'pure item' iff
 * it is equal or opposite to a single variable or parameter.
 * Otherwise it is an 'affine expression'.
 * For instance:
 *   i = -13 is constant, i = j, j = -M are pure items,
 *   j = 2*M, i = j+1, 2*j = M are affine expressions.
 *
 * - constraints is the matrix of constraints,
 * - level is the column number in equal of the element which is 'equal to',
 */
static int cloog_constraint_equal_type(CloogConstraint *cc, int level)
{ 
	int i;
	isl_int c;
	int type = EQTYPE_NONE;
	struct isl_constraint *constraint = cloog_constraint_to_isl(cc);
    
	isl_int_init(c);
	isl_constraint_get_constant(constraint, &c);
	if (!isl_int_is_zero(c))
		type = EQTYPE_CONSTANT;
	isl_constraint_get_coefficient(constraint, isl_dim_set, level - 1, &c);
	if (!isl_int_is_one(c) && !isl_int_is_negone(c))
		type = EQTYPE_EXAFFINE;
	for (i = 0; i < isl_constraint_dim(constraint, isl_dim_param); ++i) {
		isl_constraint_get_coefficient(constraint, isl_dim_param, i, &c);
		if (isl_int_is_zero(c))
			continue;
		if ((!isl_int_is_one(c) && !isl_int_is_negone(c)) ||
		    type != EQTYPE_NONE) {
			type = EQTYPE_EXAFFINE;
			break;
		}
		type = EQTYPE_PUREITEM;
	}
	for (i = 0; i < isl_constraint_dim(constraint, isl_dim_set); ++i) {
		if (i == level - 1)
			continue;
		isl_constraint_get_coefficient(constraint, isl_dim_set, i, &c);
		if (isl_int_is_zero(c))
			continue;
		if ((!isl_int_is_one(c) && !isl_int_is_negone(c)) ||
		    type != EQTYPE_NONE) {
			type = EQTYPE_EXAFFINE;
			break;
		}
		type = EQTYPE_PUREITEM;
	}
	for (i = 0; i < isl_constraint_dim(constraint, isl_dim_div); ++i) {
		isl_constraint_get_coefficient(constraint, isl_dim_div, i, &c);
		if (isl_int_is_zero(c))
			continue;
		if ((!isl_int_is_one(c) && !isl_int_is_negone(c)) ||
		    type != EQTYPE_NONE) {
			type = EQTYPE_EXAFFINE;
			break;
		}
		type = EQTYPE_PUREITEM;
	}
	isl_int_clear(c);

	if (type == EQTYPE_NONE)
		type = EQTYPE_CONSTANT;

	return type;
}
示例#3
0
/// Add an isl constraint to an ScopLib matrix.
///
/// @param user The matrix
/// @param c The constraint
int ScopLib::accessToMatrix_constraint(isl_constraint *c, void *user) {
  scoplib_matrix_p m = (scoplib_matrix_p) user;

  int nb_params = isl_constraint_dim(c, isl_dim_param);
  int nb_in = isl_constraint_dim(c, isl_dim_in);
  int nb_div = isl_constraint_dim(c, isl_dim_div);

  assert(!nb_div && "Existentially quantified variables not yet supported");

  scoplib_vector_p vec =
    scoplib_vector_malloc(nb_params + nb_in + 2);

  isl_int v;
  isl_int_init(v);

  // The access dimension has to be one.
  isl_constraint_get_coefficient(c, isl_dim_out, 0, &v);
  assert((isl_int_is_one(v) || isl_int_is_negone(v))
         && "Access relations not supported in scoplib");
  bool inverse = isl_int_is_one(v);

  // Assign variables
  for (int i = 0; i < nb_in; ++i) {
    isl_constraint_get_coefficient(c, isl_dim_in, i, &v);

    if (inverse) isl_int_neg(v,v);

    isl_int_set(vec->p[i + 1], v);
  }

  // Assign parameters
  for (int i = 0; i < nb_params; ++i) {
    isl_constraint_get_coefficient(c, isl_dim_param, i, &v);

    if (inverse) isl_int_neg(v,v);

    isl_int_set(vec->p[nb_in + i + 1], v);
  }

  // Assign constant
  isl_constraint_get_constant(c, &v);

  if (inverse) isl_int_neg(v,v);

  isl_int_set(vec->p[nb_in + nb_params + 1], v);

  scoplib_matrix_insert_vector(m, vec, m->NbRows);

  isl_constraint_free(c);
  isl_int_clear(v);

  return 0;
}
示例#4
0
/// Add an isl constraint to an ScopLib matrix.
///
/// @param user The matrix
/// @param c The constraint
int ScopLib::scatteringToMatrix_constraint(isl_constraint *c, void *user) {
  scoplib_matrix_p m = (scoplib_matrix_p) user;

  int nb_params = isl_constraint_dim(c, isl_dim_param);
  int nb_in = isl_constraint_dim(c, isl_dim_in);
  int nb_div = isl_constraint_dim(c, isl_dim_div);

  assert(!nb_div && "Existentially quantified variables not yet supported");

  scoplib_vector_p vec =
    scoplib_vector_malloc(nb_params + nb_in + 2);

  // Assign type
  if (isl_constraint_is_equality(c))
    scoplib_vector_tag_equality(vec);
  else
    scoplib_vector_tag_inequality(vec);

  isl_int v;
  isl_int_init(v);

  // Assign variables
  for (int i = 0; i < nb_in; ++i) {
    isl_constraint_get_coefficient(c, isl_dim_in, i, &v);
    isl_int_set(vec->p[i + 1], v);
  }

  // Assign parameters
  for (int i = 0; i < nb_params; ++i) {
    isl_constraint_get_coefficient(c, isl_dim_param, i, &v);
    isl_int_set(vec->p[nb_in + i + 1], v);
  }

  // Assign constant
  isl_constraint_get_constant(c, &v);
  isl_int_set(vec->p[nb_in + nb_params + 1], v);

  scoplib_vector_p null =
    scoplib_vector_malloc(nb_params + nb_in + 2);

  vec = scoplib_vector_sub(null, vec);
  scoplib_matrix_insert_vector(m, vec, 0);

  isl_constraint_free(c);
  isl_int_clear(v);

  return 0;
}
示例#5
0
static struct cloog_isl_dim constraint_cloog_dim_to_isl_dim(
					CloogConstraint *constraint, int pos)
{
	enum isl_dim_type types[] = { isl_dim_set, isl_dim_div, isl_dim_param };
	int i;
	struct cloog_isl_dim ci_dim;

	for (i = 0; i < 3; ++i) {
		isl_constraint *c = cloog_constraint_to_isl(constraint);
		unsigned dim = isl_constraint_dim(c, types[i]);
		if (pos < dim) {
			ci_dim.type = types[i];
			ci_dim.pos = pos;
			return ci_dim;
		}
		pos -= dim;
	}
	assert(0);
}
示例#6
0
int cloog_constraint_total_dimension(CloogConstraint *constraint)
{
	isl_constraint *c;
	c = cloog_constraint_to_isl(constraint);
	return isl_constraint_dim(c, isl_dim_all);
}
示例#7
0
/* Check if constraint "c" imposes any stride on dimension data->pos
 * and, if so, update the stride information in "data".
 *
 * In order to impose a stride on the dimension, "c" needs to be an equality
 * and it needs to involve the dimension.  Note that "c" may also be
 * a div constraint and thus an inequality that we cannot use.
 *
 * Let c be of the form
 *
 *	h(p) + g * v * i + g * stride * f(alpha) = 0
 *
 * with h(p) an expression in terms of the parameters and other dimensions
 * and f(alpha) an expression in terms of the existentially quantified
 * variables.
 *
 * If "stride" is not zero and not one, then it represents a non-trivial stride
 * on "i".  We compute a and b such that
 *
 *	a v + b stride = 1
 *
 * We have
 *
 *	g v i = -h(p) + g stride f(alpha)
 *
 *	a g v i = -a h(p) + g stride f(alpha)
 *
 *	a g v i + b g stride i = -a h(p) + g stride * (...)
 *
 *	g i = -a h(p) + g stride * (...)
 *
 *	i = -a h(p)/g + stride * (...)
 *
 * The expression "-a h(p)/g" can therefore be used as offset.
 */
static isl_stat detect_stride(__isl_take isl_constraint *c, void *user)
{
	struct isl_detect_stride_data *data = user;
	int i, n_div;
	isl_ctx *ctx;
	isl_stat r = isl_stat_ok;
	isl_val *v, *stride, *m;
	isl_bool is_eq, relevant, has_stride;

	is_eq = isl_constraint_is_equality(c);
	relevant = isl_constraint_involves_dims(c, isl_dim_set, data->pos, 1);
	if (is_eq < 0 || relevant < 0)
		goto error;
	if (!is_eq || !relevant) {
		isl_constraint_free(c);
		return isl_stat_ok;
	}

	ctx = isl_constraint_get_ctx(c);
	stride = isl_val_zero(ctx);
	n_div = isl_constraint_dim(c, isl_dim_div);
	for (i = 0; i < n_div; ++i) {
		v = isl_constraint_get_coefficient_val(c, isl_dim_div, i);
		stride = isl_val_gcd(stride, v);
	}

	v = isl_constraint_get_coefficient_val(c, isl_dim_set, data->pos);
	m = isl_val_gcd(isl_val_copy(stride), isl_val_copy(v));
	stride = isl_val_div(stride, isl_val_copy(m));
	v = isl_val_div(v, isl_val_copy(m));

	has_stride = isl_val_gt_si(stride, 1);
	if (has_stride >= 0 && has_stride) {
		isl_aff *aff;
		isl_val *gcd, *a, *b;

		gcd = isl_val_gcdext(v, isl_val_copy(stride), &a, &b);
		isl_val_free(gcd);
		isl_val_free(b);

		aff = isl_constraint_get_aff(c);
		for (i = 0; i < n_div; ++i)
			aff = isl_aff_set_coefficient_si(aff,
							 isl_dim_div, i, 0);
		aff = isl_aff_set_coefficient_si(aff, isl_dim_in, data->pos, 0);
		aff = isl_aff_remove_unused_divs(aff);
		a = isl_val_neg(a);
		aff = isl_aff_scale_val(aff, a);
		aff = isl_aff_scale_down_val(aff, m);
		r = set_stride(data, stride, aff);
	} else {
		isl_val_free(stride);
		isl_val_free(m);
		isl_val_free(v);
	}

	isl_constraint_free(c);
	if (has_stride < 0)
		return isl_stat_error;
	return r;
error:
	isl_constraint_free(c);
	return isl_stat_error;
}