clast.c: don't construct set for reduction for local variables
[cloog/uuh.git] / source / isl / constraints.c
blob9893c61abdbfc096f996377bf2633017420cc9d0
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <ctype.h>
4 #include <cloog/isl/cloog.h>
5 #include <cloog/isl/backend.h>
6 #include <isl/set.h>
9 #define ALLOC(type) (type*)malloc(sizeof(type))
10 #define ALLOCN(type,n) (type*)malloc((n)*sizeof(type))
12 CloogConstraintSet *cloog_constraint_set_from_isl_basic_set(struct isl_basic_set *bset)
14 return (CloogConstraintSet *)bset;
17 CloogConstraint *cloog_constraint_from_isl_constraint(struct isl_constraint *constraint)
19 return (CloogConstraint *)constraint;
22 isl_basic_set *cloog_constraints_set_to_isl(CloogConstraintSet *constraints)
24 return (isl_basic_set *)constraints;
28 /******************************************************************************
29 * Memory leaks hunting *
30 ******************************************************************************/
34 void cloog_constraint_set_free(CloogConstraintSet *constraints)
36 isl_basic_set_free(cloog_constraints_set_to_isl(constraints));
40 int cloog_constraint_set_contains_level(CloogConstraintSet *constraints,
41 int level, int nb_parameters)
43 isl_basic_set *bset;
44 bset = cloog_constraints_set_to_isl(constraints);
45 return isl_basic_set_dim(bset, isl_dim_set) >= level;
48 struct cloog_isl_dim {
49 enum isl_dim_type type;
50 int pos;
53 static struct cloog_isl_dim basic_set_cloog_dim_to_isl_dim(
54 __isl_keep isl_basic_set *bset, int pos)
56 enum isl_dim_type types[] = { isl_dim_set, isl_dim_div, isl_dim_param };
57 int i;
58 struct cloog_isl_dim ci_dim;
60 for (i = 0; i < 3; ++i) {
61 unsigned dim = isl_basic_set_dim(bset, types[i]);
62 if (pos < dim) {
63 ci_dim.type = types[i];
64 ci_dim.pos = pos;
65 return ci_dim;
67 pos -= dim;
69 assert(0);
72 static struct cloog_isl_dim set_cloog_dim_to_isl_dim(
73 CloogConstraintSet *constraints, int pos)
75 isl_basic_set *bset;
77 bset = cloog_constraints_set_to_isl(constraints);
78 return basic_set_cloog_dim_to_isl_dim(bset, pos);
81 /* Check if the variable at position level is defined by an
82 * equality. If so, return the row number. Otherwise, return -1.
84 CloogConstraint *cloog_constraint_set_defining_equality(
85 CloogConstraintSet *constraints, int level)
87 struct isl_constraint *c;
88 struct cloog_isl_dim dim;
89 isl_basic_set *bset;
91 bset = cloog_constraints_set_to_isl(constraints);
92 dim = set_cloog_dim_to_isl_dim(constraints, level - 1);
93 if (isl_basic_set_has_defining_equality(bset, dim.type, dim.pos, &c))
94 return cloog_constraint_from_isl_constraint(c);
95 else
96 return NULL;
100 /* Check if the variable (e) at position level is defined by a
101 * pair of inequalities
102 * <a, i> + -m e + <b, p> + k1 >= 0
103 * <-a, i> + m e + <-b, p> + k2 >= 0
104 * with 0 <= k1 + k2 < m
105 * If so return the row number of the upper bound and set *lower
106 * to the row number of the lower bound. If not, return -1.
108 * If the variable at position level occurs in any other constraint,
109 * then we currently return -1. The modulo guard that we would generate
110 * would still be correct, but we would also need to generate
111 * guards corresponding to the other constraints, and this has not
112 * been implemented yet.
114 CloogConstraint *cloog_constraint_set_defining_inequalities(
115 CloogConstraintSet *constraints,
116 int level, CloogConstraint **lower, int nb_par)
118 struct isl_constraint *u;
119 struct isl_constraint *l;
120 struct isl_constraint *c;
121 struct cloog_isl_dim dim;
122 struct isl_basic_set *bset;
124 bset = cloog_constraints_set_to_isl(constraints);
125 dim = set_cloog_dim_to_isl_dim(constraints, level - 1);
126 if (!isl_basic_set_has_defining_inequalities(bset, dim.type, dim.pos,
127 &l, &u))
128 return cloog_constraint_invalid();
129 for (c = isl_basic_set_first_constraint(isl_basic_set_copy(bset)); c;
130 c = isl_constraint_next(c)) {
131 if (isl_constraint_is_equal(c, l))
132 continue;
133 if (isl_constraint_is_equal(c, u))
134 continue;
135 *lower = cloog_constraint_from_isl_constraint(c);
136 if (cloog_constraint_involves(*lower, level-1)) {
137 isl_constraint_free(l);
138 isl_constraint_free(u);
139 *lower = NULL;
140 isl_constraint_free(c);
141 return NULL;
144 *lower = cloog_constraint_from_isl_constraint(l);
145 return cloog_constraint_from_isl_constraint(u);
148 int cloog_constraint_set_total_dimension(CloogConstraintSet *constraints)
150 isl_basic_set *bset;
151 bset = cloog_constraints_set_to_isl(constraints);
152 return isl_basic_set_total_dim(bset);
155 int cloog_constraint_set_n_iterators(CloogConstraintSet *constraints, int n_par)
157 isl_basic_set *bset;
158 bset = cloog_constraints_set_to_isl(constraints);
159 return isl_basic_set_dim(bset, isl_dim_set);
163 /******************************************************************************
164 * Equalities spreading functions *
165 ******************************************************************************/
168 /* Equalities are stored inside a Matrix data structure called "equal".
169 * This matrix has (nb_scattering + nb_iterators + 1) rows (i.e. total
170 * dimensions + 1, the "+ 1" is because a statement can be included inside an
171 * external loop without iteration domain), and (nb_scattering + nb_iterators +
172 * nb_parameters + 2) columns (all unknowns plus the scalar plus the equality
173 * type). The ith row corresponds to the equality "= 0" for the ith dimension
174 * iterator. The first column gives the equality type (0: no equality, then
175 * EQTYPE_* -see pprint.h-). At each recursion of pprint, if an equality for
176 * the current level is found, the corresponding row is updated. Then the
177 * equality if it exists is used to simplify expressions (e.g. if we have
178 * "i+1" while we know that "i=2", we simplify it in "3"). At the end of
179 * the pprint call, the corresponding row is reset to zero.
182 CloogEqualities *cloog_equal_alloc(int n, int nb_levels, int nb_parameters)
184 int i;
185 CloogEqualities *equal = ALLOC(CloogEqualities);
187 equal->total_dim = nb_levels - 1 + nb_parameters;
188 equal->n = n;
189 equal->constraints = ALLOCN(CloogConstraintSet *, n);
190 equal->types = ALLOCN(int, n);
191 for (i = 0; i < n; ++i) {
192 equal->constraints[i] = NULL;
193 equal->types[i] = EQTYPE_NONE;
195 return equal;
198 int cloog_equal_total_dimension(CloogEqualities *equal)
200 return equal->total_dim;
203 void cloog_equal_free(CloogEqualities *equal)
205 int i;
206 isl_basic_set *bset;
208 for (i = 0; i < equal->n; ++i) {
209 bset = cloog_constraints_set_to_isl(equal->constraints[i]);
210 isl_basic_set_free(bset);
212 free(equal->constraints);
213 free(equal->types);
214 free(equal);
217 int cloog_equal_count(CloogEqualities *equal)
219 return equal->n;
224 * cloog_constraint_equal_type function :
225 * This function returns the type of the equality in the constraint (line) of
226 * (constraints) for the element (level). An equality is 'constant' iff all
227 * other factors are null except the constant one. It is a 'pure item' iff
228 * it is equal or opposite to a single variable or parameter.
229 * Otherwise it is an 'affine expression'.
230 * For instance:
231 * i = -13 is constant, i = j, j = -M are pure items,
232 * j = 2*M, i = j+1, 2*j = M are affine expressions.
234 * - constraints is the matrix of constraints,
235 * - level is the column number in equal of the element which is 'equal to',
237 static int cloog_constraint_equal_type(CloogConstraint *cc, int level)
239 int i;
240 isl_int c;
241 int type = EQTYPE_NONE;
242 struct isl_constraint *constraint = &cc->isl;
244 isl_int_init(c);
245 isl_constraint_get_constant(constraint, &c);
246 if (!isl_int_is_zero(c))
247 type = EQTYPE_CONSTANT;
248 isl_constraint_get_coefficient(constraint, isl_dim_set, level - 1, &c);
249 if (!isl_int_is_one(c) && !isl_int_is_negone(c))
250 type = EQTYPE_EXAFFINE;
251 for (i = 0; i < isl_constraint_dim(constraint, isl_dim_param); ++i) {
252 isl_constraint_get_coefficient(constraint, isl_dim_param, i, &c);
253 if (isl_int_is_zero(c))
254 continue;
255 if ((!isl_int_is_one(c) && !isl_int_is_negone(c)) ||
256 type != EQTYPE_NONE) {
257 type = EQTYPE_EXAFFINE;
258 break;
260 type = EQTYPE_PUREITEM;
262 for (i = 0; i < isl_constraint_dim(constraint, isl_dim_set); ++i) {
263 if (i == level - 1)
264 continue;
265 isl_constraint_get_coefficient(constraint, isl_dim_set, i, &c);
266 if (isl_int_is_zero(c))
267 continue;
268 if ((!isl_int_is_one(c) && !isl_int_is_negone(c)) ||
269 type != EQTYPE_NONE) {
270 type = EQTYPE_EXAFFINE;
271 break;
273 type = EQTYPE_PUREITEM;
275 for (i = 0; i < isl_constraint_dim(constraint, isl_dim_div); ++i) {
276 isl_constraint_get_coefficient(constraint, isl_dim_div, i, &c);
277 if (isl_int_is_zero(c))
278 continue;
279 if ((!isl_int_is_one(c) && !isl_int_is_negone(c)) ||
280 type != EQTYPE_NONE) {
281 type = EQTYPE_EXAFFINE;
282 break;
284 type = EQTYPE_PUREITEM;
286 isl_int_clear(c);
288 if (type == EQTYPE_NONE)
289 type = EQTYPE_CONSTANT;
291 return type;
295 int cloog_equal_type(CloogEqualities *equal, int level)
297 return equal->types[level-1];
302 * cloog_equal_add function:
303 * This function updates the row (level-1) of the equality matrix (equal) with
304 * the row that corresponds to the row (line) of the matrix (matrix).
305 * - equal is the matrix of equalities,
306 * - matrix is the matrix of constraints,
307 * - level is the column number in matrix of the element which is 'equal to',
308 * - line is the line number in matrix of the constraint we want to study,
309 * - the infos structure gives the user all options on code printing and more.
311 * line is set to an invalid constraint for equalities that CLooG itself has
312 * discovered because the lower and upper bound of a loop happened to be equal.
313 * This situation shouldn't happen in the isl port since isl should
314 * have found the equality itself.
316 void cloog_equal_add(CloogEqualities *equal, CloogConstraintSet *matrix,
317 int level, CloogConstraint *line, int nb_par)
319 struct isl_basic_set *bset;
320 unsigned nparam;
321 assert(cloog_constraint_is_valid(line));
323 equal->types[level-1] = cloog_constraint_equal_type(line, level);
324 bset = isl_basic_set_from_constraint(isl_constraint_copy(&line->isl));
325 nparam = isl_basic_set_n_param(bset);
326 bset = isl_basic_set_extend(bset, nparam,
327 equal->total_dim - nparam, 0, 0, 0);
328 bset = isl_basic_set_finalize(bset);
329 equal->constraints[level-1] =
330 cloog_constraint_set_from_isl_basic_set(bset);
335 * cloog_equal_del function :
336 * This function reset the equality corresponding to the iterator (level)
337 * in the equality matrix (equal).
338 * - July 2nd 2002: first version.
340 void cloog_equal_del(CloogEqualities *equal, int level)
342 isl_basic_set *bset;
343 bset = cloog_constraints_set_to_isl(equal->constraints[level - 1]);
344 equal->types[level-1] = EQTYPE_NONE;
345 isl_basic_set_free(bset);
346 equal->constraints[level-1] = NULL;
351 /******************************************************************************
352 * Processing functions *
353 ******************************************************************************/
356 * Function cloog_constraint_set_normalize:
357 * This function will modify the constraint system in such a way that when
358 * there is an equality depending on the element at level 'level', there are
359 * no more (in)equalities depending on this element.
361 * The simplified form of isl automatically satisfies this condition.
363 void cloog_constraint_set_normalize(CloogConstraintSet *matrix, int level)
370 * cloog_constraint_set_copy function:
371 * this functions builds and returns a "hard copy" (not a pointer copy) of a
372 * CloogConstraintSet data structure.
374 CloogConstraintSet *cloog_constraint_set_copy(CloogConstraintSet *constraints)
376 isl_basic_set *bset;
377 bset = cloog_constraints_set_to_isl(constraints);
378 return cloog_constraint_set_from_isl_basic_set(isl_basic_set_dup(bset));
383 * cloog_constraint_set_simplify function:
384 * this function simplify all constraints inside the matrix "matrix" thanks to
385 * an equality matrix "equal" that gives for some elements of the affine
386 * constraint an equality with other elements, preferably constants.
387 * For instance, if a row of the matrix contains i+j+3>=0 and the equality
388 * matrix gives i=n and j=2, the constraint is simplified to n+3>=0. The
389 * simplified constraints are returned back inside a new simplified matrix.
390 * - matrix is the set of constraints to simplify,
391 * - equal is the matrix of equalities,
392 * - level is a level we don't want to simplify (-1 if none),
393 * - nb_par is the number of parameters of the program.
395 * isl should have performed these simplifications already in isl_set_gist.
397 CloogConstraintSet *cloog_constraint_set_simplify(CloogConstraintSet *matrix,
398 CloogEqualities *equal, int level, int nb_par)
400 return cloog_constraint_set_copy(matrix);
404 static struct cloog_isl_dim constraint_cloog_dim_to_isl_dim(
405 CloogConstraint *constraint, int pos)
407 enum isl_dim_type types[] = { isl_dim_set, isl_dim_div, isl_dim_param };
408 int i;
409 struct cloog_isl_dim ci_dim;
411 for (i = 0; i < 3; ++i) {
412 unsigned dim = isl_constraint_dim(&constraint->isl, types[i]);
413 if (pos < dim) {
414 ci_dim.type = types[i];
415 ci_dim.pos = pos;
416 return ci_dim;
418 pos -= dim;
420 assert(0);
423 static struct clast_expr *div_expr(CloogConstraint *constraint, int pos,
424 CloogNames *names)
426 int i, nb_elts;
427 unsigned dim = cloog_constraint_total_dimension(constraint);
428 cloog_int_t c;
429 struct clast_reduction *r;
430 struct clast_expr *e = NULL;
431 struct isl_div *div;
433 div = isl_constraint_div(&constraint->isl, pos);
435 cloog_int_init(c);
436 for (i = 0, nb_elts = 0; i < dim; ++i) {
437 struct cloog_isl_dim dim;
439 dim = constraint_cloog_dim_to_isl_dim(constraint, i);
440 isl_div_get_coefficient(div, dim.type, dim.pos, &c);
441 if (!cloog_int_is_zero(c))
442 ++nb_elts;
444 isl_div_get_constant(div, &c);
445 if (!cloog_int_is_zero(c))
446 ++nb_elts;
448 r = new_clast_reduction(clast_red_sum, nb_elts);
449 for (i = 0, nb_elts = 0; i < dim; ++i) {
450 struct clast_expr *v;
451 struct cloog_isl_dim dim;
453 dim = constraint_cloog_dim_to_isl_dim(constraint, i);
454 isl_div_get_coefficient(div, dim.type, dim.pos, &c);
455 if (cloog_int_is_zero(c))
456 continue;
458 v = cloog_constraint_variable_expr(constraint, 1 + i, names);
460 r->elts[nb_elts++] = &new_clast_term(c, v)->expr;
462 isl_div_get_constant(div, &c);
463 if (!cloog_int_is_zero(c))
464 r->elts[nb_elts++] = &new_clast_term(c, NULL)->expr;
466 isl_div_get_denominator(div, &c);
467 e = &new_clast_binary(clast_bin_fdiv, &r->expr, c)->expr;
469 cloog_int_clear(c);
471 isl_div_free(div);
473 return e;
477 * Return clast_expr corresponding to the variable "level" (1 based) in
478 * the given constraint.
480 struct clast_expr *cloog_constraint_variable_expr(CloogConstraint *constraint,
481 int level, CloogNames *names)
483 struct cloog_isl_dim dim;
484 const char *name;
486 assert(constraint);
488 dim = constraint_cloog_dim_to_isl_dim(constraint, level - 1);
489 if (dim.type == isl_dim_div)
490 return div_expr(constraint, dim.pos, names);
492 if (dim.type == isl_dim_set)
493 name = cloog_names_name_at_level(names, level);
494 else
495 name = names->parameters[dim.pos];
497 return &new_clast_name(name)->expr;
502 * Return true if constraint c involves variable v (zero-based).
504 int cloog_constraint_involves(CloogConstraint *constraint, int v)
506 isl_int c;
507 int res;
509 isl_int_init(c);
510 cloog_constraint_coefficient_get(constraint, v, &c);
511 res = !isl_int_is_zero(c);
512 isl_int_clear(c);
513 return res;
516 int cloog_constraint_is_lower_bound(CloogConstraint *constraint, int v)
518 isl_int c;
519 int res;
521 isl_int_init(c);
522 cloog_constraint_coefficient_get(constraint, v, &c);
523 res = isl_int_is_pos(c);
524 isl_int_clear(c);
525 return res;
528 int cloog_constraint_is_upper_bound(CloogConstraint *constraint, int v)
530 isl_int c;
531 int res;
533 isl_int_init(c);
534 cloog_constraint_coefficient_get(constraint, v, &c);
535 res = isl_int_is_neg(c);
536 isl_int_clear(c);
537 return res;
540 int cloog_constraint_is_equality(CloogConstraint *constraint)
542 return isl_constraint_is_equality(&constraint->isl);
545 void cloog_constraint_clear(CloogConstraint *constraint)
547 isl_constraint_clear(&constraint->isl);
550 void cloog_constraint_coefficient_get(CloogConstraint *constraint,
551 int var, cloog_int_t *val)
553 struct cloog_isl_dim dim;
555 if (!constraint)
556 return;
558 dim = constraint_cloog_dim_to_isl_dim(constraint, var);
559 isl_constraint_get_coefficient(&constraint->isl, dim.type, dim.pos, val);
562 void cloog_constraint_coefficient_set(CloogConstraint *constraint,
563 int var, cloog_int_t val)
565 struct cloog_isl_dim dim;
567 assert(constraint);
569 dim = constraint_cloog_dim_to_isl_dim(constraint, var);
570 isl_constraint_set_coefficient(&constraint->isl, dim.type, dim.pos, val);
573 void cloog_constraint_constant_get(CloogConstraint *constraint, cloog_int_t *val)
575 isl_constraint_get_constant(&constraint->isl, val);
579 * Copy the coefficient of constraint c into dst in PolyLib order,
580 * i.e., first the coefficients of the variables, then the coefficients
581 * of the parameters and finally the constant.
583 void cloog_constraint_copy_coefficients(CloogConstraint *constraint,
584 cloog_int_t *dst)
586 int i;
587 unsigned dim;
589 dim = isl_constraint_dim(&constraint->isl, isl_dim_all);
591 for (i = 0; i < dim; ++i)
592 cloog_constraint_coefficient_get(constraint, i, dst+i);
593 cloog_constraint_constant_get(constraint, dst+dim);
596 CloogConstraint *cloog_constraint_invalid(void)
598 return NULL;
601 int cloog_constraint_is_valid(CloogConstraint *constraint)
603 return constraint != NULL;
606 int cloog_constraint_total_dimension(CloogConstraint *constraint)
608 return isl_constraint_dim(&constraint->isl, isl_dim_all);
613 * Check whether there is any need for the constraint "upper" on
614 * "level" to get reduced.
615 * In case of the isl backend, there should be no need to do so
616 * if the level corresponds to an existentially quantified variable.
617 * Moreover, the way reduction is performed does not work for such
618 * variables since its position might chance during the construction
619 * of a set for reduction.
621 int cloog_constraint_needs_reduction(CloogConstraint *upper, int level)
623 isl_basic_set *bset;
624 struct cloog_isl_dim dim;
626 bset = isl_basic_set_from_constraint(isl_constraint_copy(&upper->isl));
627 dim = basic_set_cloog_dim_to_isl_dim(bset, level - 1);
628 isl_basic_set_free(bset);
630 return dim.type == isl_dim_set;
635 * Create a CloogConstraintSet containing enough information to perform
636 * a reduction on the upper equality (in this case lower is an invalid
637 * CloogConstraint) or the pair of inequalities upper and lower
638 * from within insert_modulo_guard.
639 * In the isl backend, we return a CloogConstraintSet containing both
640 * bounds, as the stride may change during the reduction and we may
641 * need to recompute the bound on the modulo expression.
643 CloogConstraintSet *cloog_constraint_set_for_reduction(CloogConstraint *upper,
644 CloogConstraint *lower)
646 struct isl_basic_set *bset;
648 bset = isl_basic_set_from_constraint(isl_constraint_copy(&upper->isl));
649 if (cloog_constraint_is_valid(lower))
650 bset = isl_basic_set_add_constraint(bset,
651 isl_constraint_copy(&lower->isl));
652 return cloog_constraint_set_from_isl_basic_set(bset);
656 static int add_constant_term(CloogConstraint *c, void *user)
658 isl_int *bound = (isl_int *)user;
659 isl_int v;
661 isl_int_init(v);
663 cloog_constraint_constant_get(c, &v);
664 isl_int_add(*bound, *bound, v);
666 isl_int_clear(v);
668 return 0;
672 * Reduce the modulo guard expressed by "constraints" using equalities
673 * found in outer nesting levels (stored in "equal").
674 * The modulo guard may be an equality or a pair of inequalities.
675 * In case of a pair of inequalities, *bound contains the bound on the
676 * corresponding modulo expression. If any reduction is performed
677 * then this bound is recomputed.
679 * "level" may not correspond to an existentially quantified variable.
681 * We first check if there are any equalities we can use. If not,
682 * there is again nothing to reduce.
683 * For the actual reduction, we use isl_basic_set_gist, but this
684 * function will only perform the reduction we want hear if the
685 * the variable that imposes the modulo constraint has been projected
686 * out (i.e., turned into an existentially quantified variable).
687 * After the call to isl_basic_set_gist, we need to move the
688 * existential variable back into the position where the calling
689 * function expects it (assuming there are any constraints left).
690 * We do this by adding equality between the given dimension and
691 * the existentially quantified variable.
693 CloogConstraintSet *cloog_constraint_set_reduce(CloogConstraintSet *constraints,
694 int level, CloogEqualities *equal, int nb_par, cloog_int_t *bound)
696 int j;
697 isl_ctx *ctx;
698 struct isl_basic_set *eq;
699 struct isl_basic_map *id;
700 struct cloog_isl_dim dim;
701 struct isl_constraint *c;
702 struct isl_div *div;
703 unsigned constraints_dim;
704 int pos;
705 isl_basic_set *bset;
707 bset = cloog_constraints_set_to_isl(constraints);
708 ctx = isl_basic_set_get_ctx(bset);
709 dim = set_cloog_dim_to_isl_dim(constraints, level - 1);
710 assert(dim.type == isl_dim_set);
712 eq = NULL;
713 for (j = 0; j < level - 1; ++j) {
714 isl_basic_set *bset_j;
715 if (equal->types[j] != EQTYPE_EXAFFINE)
716 continue;
717 bset_j = cloog_constraints_set_to_isl(equal->constraints[j]);
718 if (!eq)
719 eq = isl_basic_set_copy(bset_j);
720 else
721 eq = isl_basic_set_intersect(eq,
722 isl_basic_set_copy(bset_j));
724 if (!eq)
725 return constraints;
727 id = isl_basic_map_identity(isl_basic_set_get_dim(bset));
728 id = isl_basic_map_remove_dims(id, isl_dim_out, dim.pos, 1);
729 bset = isl_basic_set_apply(bset, isl_basic_map_copy(id));
730 bset = isl_basic_set_apply(bset, isl_basic_map_reverse(id));
732 constraints_dim = isl_basic_set_dim(bset, isl_dim_set);
733 eq = isl_basic_set_remove_dims(eq, isl_dim_set, constraints_dim,
734 isl_basic_set_dim(eq, isl_dim_set) - constraints_dim);
735 bset = isl_basic_set_gist(bset, eq);
736 if (isl_basic_set_dim(bset, isl_dim_div) != 1)
737 return cloog_constraint_set_from_isl_basic_set(bset);
739 div = isl_basic_set_div(isl_basic_set_copy(bset), 0);
740 c = isl_equality_alloc(isl_basic_set_get_dim(bset));
741 c = isl_constraint_add_div(c, div, &pos);
742 isl_constraint_set_coefficient(c, isl_dim_set, dim.pos, ctx->one);
743 isl_constraint_set_coefficient(c, isl_dim_div, pos, ctx->negone);
744 bset = isl_basic_set_add_constraint(bset, c);
746 isl_int_set_si(*bound, 0);
747 constraints = cloog_constraint_set_from_isl_basic_set(bset);
748 cloog_constraint_set_foreach_constraint(constraints,
749 add_constant_term, bound);
751 return cloog_constraint_set_from_isl_basic_set(bset);
754 CloogConstraint *cloog_constraint_copy(CloogConstraint *constraint)
756 return cloog_constraint_from_isl_constraint(
757 isl_constraint_copy(&constraint->isl));
760 void cloog_constraint_release(CloogConstraint *constraint)
762 isl_constraint_free(&constraint->isl);
765 struct cloog_isl_foreach {
766 int (*fn)(CloogConstraint *constraint, void *user);
767 void *user;
770 static int cloog_isl_foreach_cb(__isl_take isl_constraint *c, void *user)
772 struct cloog_isl_foreach *data = (struct cloog_isl_foreach *)user;
773 int ret;
775 if (isl_constraint_is_div_constraint(c)) {
776 isl_constraint_free(c);
777 return 0;
780 ret = data->fn(cloog_constraint_from_isl_constraint(c), data->user);
782 isl_constraint_free(c);
784 return ret;
787 int cloog_constraint_set_foreach_constraint(CloogConstraintSet *constraints,
788 int (*fn)(CloogConstraint *constraint, void *user), void *user)
790 struct cloog_isl_foreach data = { fn, user };
791 isl_basic_set *bset;
793 bset = cloog_constraints_set_to_isl(constraints);
794 return isl_basic_set_foreach_constraint(bset,
795 cloog_isl_foreach_cb, &data);
798 CloogConstraint *cloog_equal_constraint(CloogEqualities *equal, int j)
800 isl_basic_set *bset;
801 bset = cloog_constraints_set_to_isl(equal->constraints[j]);
802 return cloog_constraint_from_isl_constraint(
803 isl_basic_set_first_constraint(isl_basic_set_copy(bset)));