Esempio n. 1
0
void cloog_constraint_clear(CloogConstraint *constraint)
{
	int k;

	for (k = 1; k <= constraint->set->M.NbColumns - 2; k++)
		cloog_int_set_si(constraint->line[0][k], 0);
}
Esempio n. 2
0
/**
 * cloog_equal_add function:
 * This function updates the row (level-1) of the equality matrix (equal) with
 * the row that corresponds to the row (line) of the matrix (matrix).
 * - equal is the matrix of equalities,
 * - matrix is the matrix of constraints,
 * - level is the column number in matrix of the element which is 'equal to',
 * - line is the line number in matrix of the constraint we want to study,
 * - the infos structure gives the user all options on code printing and more.
 **
 * - July     2nd 2002: first version. 
 * - October 19th 2005: Addition of the once-time-loop specific processing.
 */
void cloog_equal_add(CloogEqualities *equal, CloogConstraintSet *constraints,
			int level, CloogConstraint *line, int nb_par)
{ 
  int j;
  CloogConstraint *i = cloog_constraint_invalid();
  CloogMatrix *matrix = &constraints->M;

  /* If we are in the case of a loop running once, this means that the equality
   * comes from an inequality. Here we find this inequality.
   */
  if (!cloog_constraint_is_valid(line))
  { for (i = cloog_constraint_first(constraints);
	 cloog_constraint_is_valid(i); i = cloog_constraint_next(i))
    if ((!cloog_int_is_zero(i->line[0][0]))&& (!cloog_int_is_zero(i->line[0][level])))
    { line = i ;
      
      /* Since in once-time-loops, equalities derive from inequalities, we
       * may have to offset the values. For instance if we have 2i>=3, the
       * equality is in fact i=2. This may happen when the level coefficient is
       * not 1 or -1 and the scalar value is not zero. In any other case (e.g.,
       * if the inequality is an expression including outer loop counters or
       * parameters) the once time loop would not have been detected
       * because of floord and ceild functions.
       */
      if (cloog_int_ne_si(i->line[0][level],1) &&
          cloog_int_ne_si(i->line[0][level],-1) &&
	  !cloog_int_is_zero(i->line[0][matrix->NbColumns-1])) {
	cloog_int_t denominator;
        
	cloog_int_init(denominator);
	cloog_int_abs(denominator, i->line[0][level]);
	cloog_int_fdiv_q(i->line[0][matrix->NbColumns-1],
			 i->line[0][matrix->NbColumns-1], denominator);
	cloog_int_set_si(i->line[0][level], cloog_int_sgn(i->line[0][level]));
	cloog_int_clear(denominator);
      }
            
      break ;
    }
  }
  assert(cloog_constraint_is_valid(line));
  
  /* We update the line of equal corresponding to level:
   * - the first element gives the equality type,
   */
  equal->types[level-1] = cloog_constraint_equal_type(line, level);
  /* - the other elements corresponding to the equality itself
   *   (the iterators up to level, then the parameters and the scalar).
   */
  for (j=1;j<=level;j++)
      cloog_int_set(equal->constraints->M.p[level-1][j], line->line[0][j]);
  for (j = 0; j < nb_par + 1; j++)
      cloog_int_set(equal->constraints->M.p[level-1][equal->constraints->M.NbColumns-j-1],
		   line->line[0][line->set->M.NbColumns-j-1]);
  
  if (cloog_constraint_is_valid(i))
    cloog_constraint_release(line);
  cloog_equal_update(equal, level, nb_par);
}
Esempio n. 3
0
/* Computes x, y and g such that g = gcd(a,b) and a*x+b*y = g */
static void Euclid(cloog_int_t a, cloog_int_t b,
			cloog_int_t *x, cloog_int_t *y, cloog_int_t *g)
{
    cloog_int_t c, d, e, f, tmp;

    cloog_int_init(c);
    cloog_int_init(d);
    cloog_int_init(e);
    cloog_int_init(f);
    cloog_int_init(tmp);
    cloog_int_abs(c, a);
    cloog_int_abs(d, b);
    cloog_int_set_si(e, 1);
    cloog_int_set_si(f, 0);
    while (cloog_int_is_pos(d)) {
	cloog_int_tdiv_q(tmp, c, d);
	cloog_int_mul(tmp, tmp, f);
	cloog_int_sub(e, e, tmp);
	cloog_int_tdiv_q(tmp, c, d);
	cloog_int_mul(tmp, tmp, d);
	cloog_int_sub(c, c, tmp);
	cloog_int_swap(c, d);
	cloog_int_swap(e, f);
    }
    cloog_int_set(*g, c);
    if (cloog_int_is_zero(a))
	cloog_int_set_si(*x, 0);
    else if (cloog_int_is_pos(a))
	cloog_int_set(*x, e);
    else cloog_int_neg(*x, e);
    if (cloog_int_is_zero(b))
	cloog_int_set_si(*y, 0);
    else {
	cloog_int_mul(tmp, a, *x);
	cloog_int_sub(tmp, c, tmp);
	cloog_int_divexact(*y, tmp, b);
    }
    cloog_int_clear(c);
    cloog_int_clear(d);
    cloog_int_clear(e);
    cloog_int_clear(f);
    cloog_int_clear(tmp);
}
Esempio n. 4
0
static
CloogMatrix* convert_to_cloogmatrix(scoplib_matrix_p mat)
{
  CloogMatrix* ret = cloog_matrix_alloc (mat->NbRows, mat->NbColumns);

  int i, j;
  for (i = 0; i < mat->NbRows; ++i)
    for (j = 0; j < mat->NbColumns; ++j)
      cloog_int_set_si(ret->p[i][j], SCOPVAL_get_si(mat->p[i][j]));

  return ret;
}
Esempio n. 5
0
/**
 * cloog_matrix_alloc:
 * Allocate a CloogMatrix data structure with NbRows rows and NbColumns columns.
 * All values are initialized to 0.
 * This method returns a pointer to the data structure if successful or a NULL
 * pointer otherwise.
 */
CloogMatrix *cloog_matrix_alloc(unsigned NbRows, unsigned NbColumns)
{
  CloogMatrix *matrix;
  cloog_int_t **p, *q;
  unsigned int i, j;

  matrix = (CloogMatrix *)malloc(sizeof(CloogMatrix));

  if (!matrix)
    return NULL;

  matrix->NbRows = NbRows;
  matrix->NbColumns = NbColumns;

  if (!NbRows || !NbColumns) {
    matrix->p = NULL;
    matrix->p_Init = NULL;
    return matrix;
  }

  p = (cloog_int_t **)malloc(NbRows * sizeof(cloog_int_t *));

  if (p == NULL) {
    free (matrix);
    return NULL;
  }

  q = (cloog_int_t *)malloc(NbRows * NbColumns * sizeof(cloog_int_t));

  if (q == NULL) {
    free (matrix);
    free (p);
    return NULL;
  }

  matrix->p = p;
  matrix->p_Init = q;

  for (i = 0; i < NbRows; i++) {
    *p++ = q;
    for (j = 0; j < NbColumns; j++) {
      cloog_int_init(*(q+j));
      cloog_int_set_si(*(q+j), 0);
    }
    q += NbColumns;
  }

  return matrix;
}
Esempio n. 6
0
/**
 * cloog_constraint_set_simplify function:
 * this function simplify all constraints inside the matrix "matrix" thanks to
 * an equality matrix "equal" that gives for some elements of the affine
 * constraint an equality with other elements, preferably constants.
 * For instance, if a row of the matrix contains i+j+3>=0 and the equality
 * matrix gives i=n and j=2, the constraint is simplified to n+3>=0. The
 * simplified constraints are returned back inside a new simplified matrix.
 * - matrix is the set of constraints to simplify,
 * - equal is the matrix of equalities,
 * - level is a level we don't want to simplify (-1 if none),
 * - nb_par is the number of parameters of the program.
 **
 * - November 4th 2005: first version.
 */
CloogConstraintSet *cloog_constraint_set_simplify(CloogConstraintSet *constraints,
	CloogEqualities *equal, int level, int nb_par)
{ int i, j, k ;
	struct cloog_vec *vector;
  CloogMatrix *simplified;
  CloogMatrix *matrix = &constraints->M;
  
  if (matrix == NULL)
  return NULL ;
  
  /* The simplified matrix is such that each row has been simplified thanks
   * tho the "equal" matrix. We allocate the memory for the simplified matrix,
   * then for each row of the original matrix, we compute the simplified
   * vector and we copy its content into the according simplified row.
   */
  simplified = cloog_matrix_alloc(matrix->NbRows, matrix->NbColumns);
  for (i=0;i<matrix->NbRows;i++)
  { vector = cloog_equal_vector_simplify(equal, matrix->p[i],
					  matrix->NbColumns, level, nb_par);
    for (j=0;j<matrix->NbColumns;j++)
    cloog_int_set(simplified->p[i][j], vector->p[j]);
    
    cloog_vec_free(vector);
  }
  
  /* After simplification, it may happen that few constraints are the same,
   * we remove them here by replacing them with 0=0 constraints.
   */
  for (i=0;i<simplified->NbRows;i++)
  for (j=i+1;j<simplified->NbRows;j++)
  { for (k=0;k<simplified->NbColumns;k++)
    if (cloog_int_ne(simplified->p[i][k],simplified->p[j][k]))
    break ;
    
    if (k == matrix->NbColumns)
    { for (k=0;k<matrix->NbColumns;k++)
        cloog_int_set_si(simplified->p[j][k],0);
    }
  }
  
  return cloog_constraint_set_from_cloog_matrix(simplified);
}
Esempio n. 7
0
/**
 * Reduce the modulo guard expressed by "contraints" using equalities
 * found in outer nesting levels (stored in "equal").
 * The modulo guard may be an equality or a pair of inequalities.
 * In case of a pair of inequalities, "constraints" only contains the
 * upper bound and *bound contains the bound on the
 * corresponding modulo expression.  The bound is left untouched by
 * this function.
 */
CloogConstraintSet *cloog_constraint_set_reduce(CloogConstraintSet *constraints,
	int level, CloogEqualities *equal, int nb_par, cloog_int_t *bound)
{
  int i, j, k, len, len2, nb_iter;
  struct cloog_vec *line_vector2;
  cloog_int_t *line, *line2, val, x, y, g;

  len = constraints->M.NbColumns;
  len2 = cloog_equal_total_dimension(equal) + 2;
  nb_iter = len - 2 - nb_par;

  cloog_int_init(val);
  cloog_int_init(x);
  cloog_int_init(y);
  cloog_int_init(g);

  line_vector2 = cloog_vec_alloc(len2);
  line2 = line_vector2->p;

  line = constraints->M.p[0];
  if (cloog_int_is_pos(line[level]))
    cloog_seq_neg(line+1, line+1, len-1);
  cloog_int_neg(line[level], line[level]);
  assert(cloog_int_is_pos(line[level]));

  for (i = nb_iter; i >= 1; --i) {
    if (i == level)
      continue;
    cloog_int_fdiv_r(line[i], line[i], line[level]);
    if (cloog_int_is_zero(line[i]))
      continue;

    /* Look for an earlier variable that is also a multiple of line[level]
     * and check whether we can use the corresponding affine expression
     * to "reduce" the modulo guard, where reduction means that we eliminate
     * a variable, possibly at the expense of introducing other variables
     * with smaller index.
     */
    for (j = level-1; j >= 0; --j) {
      CloogConstraint *equal_constraint;
      if (cloog_equal_type(equal, j+1) != EQTYPE_EXAFFINE)
	continue;
      equal_constraint = cloog_equal_constraint(equal, j);
      cloog_constraint_coefficient_get(equal_constraint, j, &val);
      if (!cloog_int_is_divisible_by(val, line[level])) {
	cloog_constraint_release(equal_constraint);
	continue;
      }
      cloog_constraint_coefficient_get(equal_constraint, i-1, &val);
      if (cloog_int_is_divisible_by(val, line[level])) {
	cloog_constraint_release(equal_constraint);
	continue;
      }
      for (k = j; k > i; --k) {
	cloog_constraint_coefficient_get(equal_constraint, k-1, &val);
	if (cloog_int_is_zero(val))
	  continue;
	if (!cloog_int_is_divisible_by(val, line[level]))
	  break;
      }
      if (k > i) {
	 cloog_constraint_release(equal_constraint);
	 continue;
      }
      cloog_constraint_coefficient_get(equal_constraint, i-1, &val);
      Euclid(val, line[level], &x, &y, &g);
      if (!cloog_int_is_divisible_by(val, line[i])) {
	cloog_constraint_release(equal_constraint);
	continue;
      }
      cloog_int_divexact(val, line[i], g);
      cloog_int_neg(val, val);
      cloog_int_mul(val, val, x);
      cloog_int_set_si(y, 1);
      /* Add (equal->p[j][i])^{-1} * line[i] times the equality */
      cloog_constraint_copy_coefficients(equal_constraint, line2+1);
      cloog_seq_combine(line+1, y, line+1, val, line2+1, i);
      cloog_seq_combine(line+len-nb_par-1, y, line+len-nb_par-1,
					   val, line2+len2-nb_par-1, nb_par+1);
      cloog_constraint_release(equal_constraint);
      break;
    }
  }

  cloog_vec_free(line_vector2);

  cloog_int_clear(val);
  cloog_int_clear(x);
  cloog_int_clear(y);
  cloog_int_clear(g);

  /* Make sure the line is not inverted again in the calling function. */
  cloog_int_neg(line[level], line[level]);

  return constraints;
}