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); }
/** * 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); }
/* 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); }
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; }
/** * 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; }
/** * 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); }
/** * 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; }