4 #include <cloog/isl/cloog.h>
5 #include <cloog/isl/backend.h>
9 #include <isl/val_gmp.h>
12 #define ALLOC(type) (type*)malloc(sizeof(type))
13 #define ALLOCN(type,n) (type*)malloc((n)*sizeof(type))
15 __isl_give isl_val
*cloog_int_to_isl_val(isl_ctx
* ctx
, cloog_int_t c
)
18 #if defined(CLOOG_INT_INT)
19 v
= isl_val_int_from_si(ctx
, c
);
20 #elif defined(CLOOG_INT_LONG)
21 v
= isl_val_int_from_si(ctx
, c
);
22 #elif defined(CLOOG_INT_LONG_LONG)
23 v
= isl_val_int_from_si(ctx
, c
);
24 #elif defined(CLOOG_INT_GMP)
25 v
= isl_val_int_from_gmp(ctx
, c
);
27 #error "No integer type defined"
33 * CLooG'll be dealing in integers so we expect numerator/1 form
34 * from isl_val. Thus get numerator to assign to cloog_int
36 void isl_val_to_cloog_int(__isl_keep isl_val
*val
, cloog_int_t
*cint
)
38 assert(isl_val_is_int(val
));
39 #if defined(CLOOG_INT_INT)
40 *cint
= isl_val_get_num_si(val
);
41 #elif defined(CLOOG_INT_LONG)
42 *cint
= isl_val_get_num_si(val
);
43 #elif defined(CLOOG_INT_LONG_LONG)
44 *cint
= isl_val_get_num_si(val
);
45 #elif defined(CLOOG_INT_GMP)
46 isl_val_get_num_gmp(val
, *cint
);
48 #error "No integer type defined"
53 CloogConstraintSet
*cloog_constraint_set_from_isl_basic_set(struct isl_basic_set
*bset
)
55 return (CloogConstraintSet
*)bset
;
58 CloogConstraint
*cloog_constraint_from_isl_constraint(struct isl_constraint
*constraint
)
60 return (CloogConstraint
*)constraint
;
63 isl_constraint
*cloog_constraint_to_isl(CloogConstraint
*constraint
)
65 return (isl_constraint
*)constraint
;
68 isl_basic_set
*cloog_constraints_set_to_isl(CloogConstraintSet
*constraints
)
70 return (isl_basic_set
*)constraints
;
74 /******************************************************************************
75 * Memory leaks hunting *
76 ******************************************************************************/
80 void cloog_constraint_set_free(CloogConstraintSet
*constraints
)
82 isl_basic_set_free(cloog_constraints_set_to_isl(constraints
));
86 int cloog_constraint_set_contains_level(CloogConstraintSet
*constraints
,
87 int level
, int nb_parameters
)
90 bset
= cloog_constraints_set_to_isl(constraints
);
91 return isl_basic_set_dim(bset
, isl_dim_set
) >= level
;
94 struct cloog_isl_dim
{
95 enum isl_dim_type type
;
99 static struct cloog_isl_dim
basic_set_cloog_dim_to_isl_dim(
100 __isl_keep isl_basic_set
*bset
, int pos
)
102 enum isl_dim_type types
[] = { isl_dim_set
, isl_dim_div
, isl_dim_param
};
104 struct cloog_isl_dim ci_dim
;
106 for (i
= 0; i
< 3; ++i
) {
107 unsigned dim
= isl_basic_set_dim(bset
, types
[i
]);
109 ci_dim
.type
= types
[i
];
118 static struct cloog_isl_dim
set_cloog_dim_to_isl_dim(
119 CloogConstraintSet
*constraints
, int pos
)
123 bset
= cloog_constraints_set_to_isl(constraints
);
124 return basic_set_cloog_dim_to_isl_dim(bset
, pos
);
127 /* Check if the variable at position level is defined by an
128 * equality. If so, return the row number. Otherwise, return -1.
130 CloogConstraint
*cloog_constraint_set_defining_equality(
131 CloogConstraintSet
*constraints
, int level
)
133 struct isl_constraint
*c
;
134 struct cloog_isl_dim dim
;
137 bset
= cloog_constraints_set_to_isl(constraints
);
138 dim
= set_cloog_dim_to_isl_dim(constraints
, level
- 1);
139 if (isl_basic_set_has_defining_equality(bset
, dim
.type
, dim
.pos
, &c
))
140 return cloog_constraint_from_isl_constraint(c
);
146 struct cloog_isl_other
{
154 /* Set other->found to 1 if the given constraint involves other->level
155 * and is different from other->u and other->l.
157 static int check_other_constraint(__isl_take isl_constraint
*c
, void *user
)
159 struct cloog_isl_other
*other
= user
;
162 if (!isl_constraint_is_equal(c
, other
->l
) &&
163 !isl_constraint_is_equal(c
, other
->u
)) {
164 cc
= cloog_constraint_from_isl_constraint(c
);
165 if (cloog_constraint_involves(cc
, other
->level
- 1))
169 isl_constraint_free(c
);
171 return other
->found
? -1 : 0;
175 /* Check if the variable (e) at position level is defined by a
176 * pair of inequalities
177 * <a, i> + -m e + <b, p> + k1 >= 0
178 * <-a, i> + m e + <-b, p> + k2 >= 0
179 * with 0 <= k1 + k2 < m
180 * If so return the row number of the upper bound and set *lower
181 * to the row number of the lower bound. If not, return -1.
183 * If the variable at position level occurs in any other constraint,
184 * then we currently return -1. The modulo guard that we would generate
185 * would still be correct, but we would also need to generate
186 * guards corresponding to the other constraints, and this has not
187 * been implemented yet.
189 CloogConstraint
*cloog_constraint_set_defining_inequalities(
190 CloogConstraintSet
*constraints
,
191 int level
, CloogConstraint
**lower
, int nb_par
)
193 struct isl_constraint
*u
;
194 struct isl_constraint
*l
;
195 struct cloog_isl_dim dim
;
196 struct isl_basic_set
*bset
;
197 struct cloog_isl_other other
;
199 bset
= cloog_constraints_set_to_isl(constraints
);
200 dim
= set_cloog_dim_to_isl_dim(constraints
, level
- 1);
201 if (!isl_basic_set_has_defining_inequalities(bset
, dim
.type
, dim
.pos
,
203 return cloog_constraint_invalid();
209 isl_basic_set_foreach_constraint(bset
, &check_other_constraint
, &other
);
211 isl_constraint_free(l
);
212 isl_constraint_free(u
);
216 *lower
= cloog_constraint_from_isl_constraint(l
);
217 return cloog_constraint_from_isl_constraint(u
);
220 int cloog_constraint_set_total_dimension(CloogConstraintSet
*constraints
)
223 bset
= cloog_constraints_set_to_isl(constraints
);
224 return isl_basic_set_total_dim(bset
);
227 int cloog_constraint_set_n_iterators(CloogConstraintSet
*constraints
, int n_par
)
230 bset
= cloog_constraints_set_to_isl(constraints
);
231 return isl_basic_set_dim(bset
, isl_dim_set
);
235 /******************************************************************************
236 * Equalities spreading functions *
237 ******************************************************************************/
240 /* Equalities are stored inside a Matrix data structure called "equal".
241 * This matrix has (nb_scattering + nb_iterators + 1) rows (i.e. total
242 * dimensions + 1, the "+ 1" is because a statement can be included inside an
243 * external loop without iteration domain), and (nb_scattering + nb_iterators +
244 * nb_parameters + 2) columns (all unknowns plus the scalar plus the equality
245 * type). The ith row corresponds to the equality "= 0" for the ith dimension
246 * iterator. The first column gives the equality type (0: no equality, then
247 * EQTYPE_* -see pprint.h-). At each recursion of pprint, if an equality for
248 * the current level is found, the corresponding row is updated. Then the
249 * equality if it exists is used to simplify expressions (e.g. if we have
250 * "i+1" while we know that "i=2", we simplify it in "3"). At the end of
251 * the pprint call, the corresponding row is reset to zero.
254 CloogEqualities
*cloog_equal_alloc(int n
, int nb_levels
, int nb_parameters
)
257 CloogEqualities
*equal
= ALLOC(CloogEqualities
);
259 equal
->total_dim
= nb_levels
- 1 + nb_parameters
;
261 equal
->constraints
= ALLOCN(isl_constraint
*, n
);
262 equal
->types
= ALLOCN(int, n
);
263 for (i
= 0; i
< n
; ++i
) {
264 equal
->constraints
[i
] = NULL
;
265 equal
->types
[i
] = EQTYPE_NONE
;
270 int cloog_equal_total_dimension(CloogEqualities
*equal
)
272 return equal
->total_dim
;
275 void cloog_equal_free(CloogEqualities
*equal
)
279 for (i
= 0; i
< equal
->n
; ++i
)
280 isl_constraint_free(equal
->constraints
[i
]);
281 free(equal
->constraints
);
286 int cloog_equal_count(CloogEqualities
*equal
)
293 * cloog_constraint_equal_type function :
294 * This function returns the type of the equality in the constraint (line) of
295 * (constraints) for the element (level). An equality is 'constant' iff all
296 * other factors are null except the constant one. It is a 'pure item' iff
297 * it is equal or opposite to a single variable or parameter.
298 * Otherwise it is an 'affine expression'.
300 * i = -13 is constant, i = j, j = -M are pure items,
301 * j = 2*M, i = j+1, 2*j = M are affine expressions.
303 * - constraints is the matrix of constraints,
304 * - level is the column number in equal of the element which is 'equal to',
306 static int cloog_constraint_equal_type(CloogConstraint
*cc
, int level
)
310 int type
= EQTYPE_NONE
;
311 struct isl_constraint
*constraint
= cloog_constraint_to_isl(cc
);
313 c
= isl_constraint_get_constant_val(constraint
);
314 if (!isl_val_is_zero(c
))
315 type
= EQTYPE_CONSTANT
;
317 c
= isl_constraint_get_coefficient_val(constraint
, isl_dim_set
, level
- 1);
318 if (!isl_val_is_one(c
) && !isl_val_is_negone(c
))
319 type
= EQTYPE_EXAFFINE
;
321 for (i
= 0; i
< isl_constraint_dim(constraint
, isl_dim_param
); ++i
) {
322 c
= isl_constraint_get_coefficient_val(constraint
, isl_dim_param
, i
);
323 if (isl_val_is_zero(c
)){
327 if ((!isl_val_is_one(c
) && !isl_val_is_negone(c
)) ||
328 type
!= EQTYPE_NONE
) {
329 type
= EQTYPE_EXAFFINE
;
333 type
= EQTYPE_PUREITEM
;
336 for (i
= 0; i
< isl_constraint_dim(constraint
, isl_dim_set
); ++i
) {
339 c
= isl_constraint_get_coefficient_val(constraint
, isl_dim_set
, i
);
340 if (isl_val_is_zero(c
)){
344 if ((!isl_val_is_one(c
) && !isl_val_is_negone(c
)) ||
345 type
!= EQTYPE_NONE
) {
346 type
= EQTYPE_EXAFFINE
;
350 type
= EQTYPE_PUREITEM
;
353 for (i
= 0; i
< isl_constraint_dim(constraint
, isl_dim_div
); ++i
) {
354 c
= isl_constraint_get_coefficient_val(constraint
, isl_dim_div
, i
);
355 if (isl_val_is_zero(c
)){
359 if ((!isl_val_is_one(c
) && !isl_val_is_negone(c
)) ||
360 type
!= EQTYPE_NONE
) {
361 type
= EQTYPE_EXAFFINE
;
365 type
= EQTYPE_PUREITEM
;
369 if (type
== EQTYPE_NONE
)
370 type
= EQTYPE_CONSTANT
;
376 int cloog_equal_type(CloogEqualities
*equal
, int level
)
378 return equal
->types
[level
-1];
383 * cloog_equal_add function:
384 * This function updates the row (level-1) of the equality matrix (equal) with
385 * the row that corresponds to the row (line) of the matrix (matrix).
386 * - equal is the matrix of equalities,
387 * - matrix is the matrix of constraints,
388 * - level is the column number in matrix of the element which is 'equal to',
389 * - line is the line number in matrix of the constraint we want to study,
390 * - the infos structure gives the user all options on code printing and more.
392 * line is set to an invalid constraint for equalities that CLooG itself has
393 * discovered because the lower and upper bound of a loop happened to be equal.
394 * This situation shouldn't happen in the isl port since isl should
395 * have found the equality itself.
397 void cloog_equal_add(CloogEqualities
*equal
, CloogConstraintSet
*matrix
,
398 int level
, CloogConstraint
*line
, int nb_par
)
401 assert(cloog_constraint_is_valid(line
));
403 equal
->types
[level
-1] = cloog_constraint_equal_type(line
, level
);
404 c
= cloog_constraint_to_isl(line
);
405 equal
->constraints
[level
- 1] = isl_constraint_copy(c
);
410 * cloog_equal_del function :
411 * This function reset the equality corresponding to the iterator (level)
412 * in the equality matrix (equal).
413 * - July 2nd 2002: first version.
415 void cloog_equal_del(CloogEqualities
*equal
, int level
)
417 equal
->types
[level
-1] = EQTYPE_NONE
;
418 isl_constraint_free(equal
->constraints
[level
- 1]);
419 equal
->constraints
[level
-1] = NULL
;
424 /******************************************************************************
425 * Processing functions *
426 ******************************************************************************/
429 * Function cloog_constraint_set_normalize:
430 * This function will modify the constraint system in such a way that when
431 * there is an equality depending on the element at level 'level', there are
432 * no more (in)equalities depending on this element.
434 * The simplified form of isl automatically satisfies this condition.
436 void cloog_constraint_set_normalize(CloogConstraintSet
*matrix
, int level
)
443 * cloog_constraint_set_copy function:
444 * this functions builds and returns a "soft copy" of a CloogConstraintSet data
447 * NOTE: this function used to return a "hard copy" (not a pointer copy) but isl
448 * doesn't provide isl_basic_set_dup() anymore and a soft copy works as well.
450 CloogConstraintSet
*cloog_constraint_set_copy(CloogConstraintSet
*constraints
)
453 bset
= cloog_constraints_set_to_isl(constraints
);
454 return cloog_constraint_set_from_isl_basic_set(isl_basic_set_copy(bset
));
459 * cloog_constraint_set_simplify function:
460 * this function simplify all constraints inside the matrix "matrix" thanks to
461 * an equality matrix "equal" that gives for some elements of the affine
462 * constraint an equality with other elements, preferably constants.
463 * For instance, if a row of the matrix contains i+j+3>=0 and the equality
464 * matrix gives i=n and j=2, the constraint is simplified to n+3>=0. The
465 * simplified constraints are returned back inside a new simplified matrix.
466 * - matrix is the set of constraints to simplify,
467 * - equal is the matrix of equalities,
468 * - level is a level we don't want to simplify (-1 if none),
469 * - nb_par is the number of parameters of the program.
471 * isl should have performed these simplifications already in isl_set_gist.
473 CloogConstraintSet
*cloog_constraint_set_simplify(CloogConstraintSet
*matrix
,
474 CloogEqualities
*equal
, int level
, int nb_par
)
476 return cloog_constraint_set_copy(matrix
);
480 static struct cloog_isl_dim
constraint_cloog_dim_to_isl_dim(
481 CloogConstraint
*constraint
, int pos
)
483 enum isl_dim_type types
[] = { isl_dim_set
, isl_dim_div
, isl_dim_param
};
485 struct cloog_isl_dim ci_dim
;
487 for (i
= 0; i
< 3; ++i
) {
488 isl_constraint
*c
= cloog_constraint_to_isl(constraint
);
489 unsigned dim
= isl_constraint_dim(c
, types
[i
]);
491 ci_dim
.type
= types
[i
];
500 static struct clast_expr
*div_expr(CloogConstraint
*constraint
, int pos
,
504 unsigned dim
= cloog_constraint_total_dimension(constraint
);
506 struct clast_reduction
*r
;
507 struct clast_expr
*e
= NULL
;
511 cloog_int_init(cint
);
512 div
= isl_constraint_get_div(cloog_constraint_to_isl(constraint
), pos
);
514 for (i
= 0, nb_elts
= 0; i
< dim
; ++i
) {
515 struct cloog_isl_dim dim
;
517 dim
= constraint_cloog_dim_to_isl_dim(constraint
, i
);
518 if (dim
.type
== isl_dim_set
)
519 dim
.type
= isl_dim_in
;
520 c
= isl_aff_get_coefficient_val(div
, dim
.type
, dim
.pos
);
521 if (!isl_val_is_zero(c
))
526 c
= isl_aff_get_constant_val(div
);
527 if (!isl_val_is_zero(c
))
531 r
= new_clast_reduction(clast_red_sum
, nb_elts
);
532 for (i
= 0, nb_elts
= 0; i
< dim
; ++i
) {
533 struct clast_expr
*v
;
534 struct cloog_isl_dim dim
;
536 dim
= constraint_cloog_dim_to_isl_dim(constraint
, i
);
537 if (dim
.type
== isl_dim_set
)
538 dim
.type
= isl_dim_in
;
539 c
= isl_aff_get_coefficient_val(div
, dim
.type
, dim
.pos
);
540 if (isl_val_is_zero(c
)){
545 v
= cloog_constraint_variable_expr(constraint
, 1 + i
, names
);
547 /* We are interested only in the numerator */
548 cloog_int_set_si(cint
, isl_val_get_num_si(c
));
549 r
->elts
[nb_elts
++] = &new_clast_term(cint
, v
)->expr
;
554 c
= isl_aff_get_constant_val(div
);
555 if (!isl_val_is_zero(c
)) {
556 /* We are interested only in the numerator */
557 cloog_int_set_si(cint
, isl_val_get_num_si(c
));
558 r
->elts
[nb_elts
++] = &new_clast_term(cint
, NULL
)->expr
;
562 c
= isl_aff_get_denominator_val(div
);
563 isl_val_to_cloog_int(c
, &cint
);
565 e
= &new_clast_binary(clast_bin_fdiv
, &r
->expr
, cint
)->expr
;
567 cloog_int_clear(cint
);
575 * Return clast_expr corresponding to the variable "level" (1 based) in
576 * the given constraint.
578 struct clast_expr
*cloog_constraint_variable_expr(CloogConstraint
*constraint
,
579 int level
, CloogNames
*names
)
581 struct cloog_isl_dim dim
;
586 dim
= constraint_cloog_dim_to_isl_dim(constraint
, level
- 1);
587 if (dim
.type
== isl_dim_div
)
588 return div_expr(constraint
, dim
.pos
, names
);
590 if (dim
.type
== isl_dim_set
)
591 name
= cloog_names_name_at_level(names
, level
);
593 name
= names
->parameters
[dim
.pos
];
595 return &new_clast_name(name
)->expr
;
600 * Return true if constraint c involves variable v (zero-based).
602 int cloog_constraint_involves(CloogConstraint
*constraint
, int v
)
607 c
= cloog_constraint_coefficient_get_val(constraint
, v
);
608 res
= !isl_val_is_zero(c
);
613 int cloog_constraint_is_lower_bound(CloogConstraint
*constraint
, int v
)
618 c
= cloog_constraint_coefficient_get_val(constraint
, v
);
619 res
= isl_val_is_pos(c
);
624 int cloog_constraint_is_upper_bound(CloogConstraint
*constraint
, int v
)
629 c
= cloog_constraint_coefficient_get_val(constraint
, v
);
630 res
= isl_val_is_neg(c
);
635 int cloog_constraint_is_equality(CloogConstraint
*constraint
)
637 return isl_constraint_is_equality(cloog_constraint_to_isl(constraint
));
640 CloogConstraintSet
*cloog_constraint_set_drop_constraint(
641 CloogConstraintSet
*constraints
, CloogConstraint
*constraint
)
646 bset
= cloog_constraints_set_to_isl(constraints
);
647 c
= cloog_constraint_to_isl(cloog_constraint_copy(constraint
));
648 bset
= isl_basic_set_drop_constraint(bset
, c
);
649 return cloog_constraint_set_from_isl_basic_set(bset
);
652 void cloog_constraint_coefficient_get(CloogConstraint
*constraint
,
653 int var
, cloog_int_t
*val
)
655 struct cloog_isl_dim dim
;
662 dim
= constraint_cloog_dim_to_isl_dim(constraint
, var
);
663 c
= cloog_constraint_to_isl(constraint
);
664 ival
= isl_constraint_get_coefficient_val(c
, dim
.type
, dim
.pos
);
666 isl_val_to_cloog_int(ival
, val
);
670 isl_val
*cloog_constraint_coefficient_get_val(CloogConstraint
*constraint
,
673 struct cloog_isl_dim dim
;
680 dim
= constraint_cloog_dim_to_isl_dim(constraint
, var
);
681 c
= cloog_constraint_to_isl(constraint
);
682 val
= isl_constraint_get_coefficient_val(c
, dim
.type
, dim
.pos
);
688 void cloog_constraint_coefficient_set(CloogConstraint
*constraint
,
689 int var
, cloog_int_t val
)
691 struct cloog_isl_dim dim
;
696 dim
= constraint_cloog_dim_to_isl_dim(constraint
, var
);
697 c
= cloog_constraint_to_isl(constraint
);
698 isl_constraint_set_coefficient_val(c
, dim
.type
, dim
.pos
,
699 cloog_int_to_isl_val(isl_constraint_get_ctx(c
), val
));
702 void cloog_constraint_constant_get(CloogConstraint
*constraint
, cloog_int_t
*val
)
705 ival
= isl_constraint_get_constant_val(cloog_constraint_to_isl(constraint
));
706 isl_val_to_cloog_int(ival
, val
);
711 __isl_give isl_val
*cloog_constraint_constant_get_val(CloogConstraint
*constraint
)
713 return isl_constraint_get_constant_val(cloog_constraint_to_isl(constraint
));
719 * Copy the coefficient of constraint c into dst in PolyLib order,
720 * i.e., first the coefficients of the variables, then the coefficients
721 * of the parameters and finally the constant.
723 void cloog_constraint_copy_coefficients(CloogConstraint
*constraint
,
729 dim
= cloog_constraint_total_dimension(constraint
);
731 for (i
= 0; i
< dim
; ++i
)
732 cloog_constraint_coefficient_get(constraint
, i
, dst
+i
);
733 cloog_constraint_constant_get(constraint
, dst
+dim
);
736 CloogConstraint
*cloog_constraint_invalid(void)
741 int cloog_constraint_is_valid(CloogConstraint
*constraint
)
743 return constraint
!= NULL
;
746 int cloog_constraint_total_dimension(CloogConstraint
*constraint
)
749 c
= cloog_constraint_to_isl(constraint
);
750 return isl_constraint_dim(c
, isl_dim_all
);
755 * Check whether there is any need for the constraint "upper" on
756 * "level" to get reduced.
757 * In case of the isl backend, there should be no need to do so
758 * if the level corresponds to an existentially quantified variable.
759 * Moreover, the way reduction is performed does not work for such
760 * variables since its position might chance during the construction
761 * of a set for reduction.
763 int cloog_constraint_needs_reduction(CloogConstraint
*upper
, int level
)
767 struct cloog_isl_dim dim
;
769 c
= cloog_constraint_to_isl(upper
);
770 bset
= isl_basic_set_from_constraint(isl_constraint_copy(c
));
771 dim
= basic_set_cloog_dim_to_isl_dim(bset
, level
- 1);
772 isl_basic_set_free(bset
);
774 return dim
.type
== isl_dim_set
;
779 * Create a CloogConstraintSet containing enough information to perform
780 * a reduction on the upper equality (in this case lower is an invalid
781 * CloogConstraint) or the pair of inequalities upper and lower
782 * from within insert_modulo_guard.
783 * In the isl backend, we return a CloogConstraintSet containing both
784 * bounds, as the stride may change during the reduction and we may
785 * need to recompute the bound on the modulo expression.
787 CloogConstraintSet
*cloog_constraint_set_for_reduction(CloogConstraint
*upper
,
788 CloogConstraint
*lower
)
790 struct isl_basic_set
*bset
;
793 c
= cloog_constraint_to_isl(upper
);
794 bset
= isl_basic_set_from_constraint(isl_constraint_copy(c
));
795 if (cloog_constraint_is_valid(lower
)) {
796 c
= cloog_constraint_to_isl(lower
);
797 bset
= isl_basic_set_add_constraint(bset
,
798 isl_constraint_copy(c
));
800 return cloog_constraint_set_from_isl_basic_set(bset
);
804 static int add_constant_term(CloogConstraint
*c
, void *user
)
806 isl_val
**bound
= (isl_val
**)user
;
809 v
= cloog_constraint_constant_get_val(c
);
810 *bound
= isl_val_add(*bound
, v
);
816 /* Return an isl_basic_set representation of the equality stored
817 * at position i in the given CloogEqualities.
819 static __isl_give isl_basic_set
*equality_to_basic_set(CloogEqualities
*equal
,
827 c
= isl_constraint_copy(equal
->constraints
[i
]);
828 bset
= isl_basic_set_from_constraint(c
);
829 nparam
= isl_basic_set_dim(bset
, isl_dim_param
);
830 nvar
= isl_basic_set_dim(bset
, isl_dim_set
);
831 bset
= isl_basic_set_add_dims(bset
, isl_dim_set
,
832 equal
->total_dim
- (nparam
+ nvar
));
837 * Reduce the modulo guard expressed by "constraints" using equalities
838 * found in outer nesting levels (stored in "equal").
839 * The modulo guard may be an equality or a pair of inequalities.
840 * In case of a pair of inequalities, *bound contains the bound on the
841 * corresponding modulo expression. If any reduction is performed
842 * then this bound is recomputed.
844 * "level" may not correspond to an existentially quantified variable.
846 * We first check if there are any equalities we can use. If not,
847 * there is again nothing to reduce.
848 * For the actual reduction, we use isl_basic_set_gist, but this
849 * function will only perform the reduction we want here if the
850 * the variable that imposes the modulo constraint has been projected
851 * out (i.e., turned into an existentially quantified variable).
852 * After the call to isl_basic_set_gist, we need to move the
853 * existential variable back into the position where the calling
854 * function expects it (assuming there are any constraints left).
855 * We do this by adding an equality between the given dimension and
856 * the existentially quantified variable.
858 * If there are no existentially quantified variables left, then
859 * we don't need to add this equality.
860 * If, on the other hand, the resulting basic set involves more
861 * than one existentially quantified variable, then the caller
862 * will not be able to handle the result, so we just return the
863 * original input instead.
865 CloogConstraintSet
*cloog_constraint_set_reduce(CloogConstraintSet
*constraints
,
866 int level
, CloogEqualities
*equal
, int nb_par
, cloog_int_t
*bound
)
870 struct isl_basic_set
*eq
;
871 struct isl_basic_map
*id
;
872 struct cloog_isl_dim dim
;
873 struct isl_constraint
*c
;
874 unsigned constraints_dim
;
876 isl_basic_set
*bset
, *orig
;
878 bset
= cloog_constraints_set_to_isl(constraints
);
879 orig
= isl_basic_set_copy(bset
);
880 dim
= set_cloog_dim_to_isl_dim(constraints
, level
- 1);
881 assert(dim
.type
== isl_dim_set
);
884 for (j
= 0; j
< level
- 1; ++j
) {
885 isl_basic_set
*bset_j
;
886 if (equal
->types
[j
] != EQTYPE_EXAFFINE
)
888 bset_j
= equality_to_basic_set(equal
, j
);
892 eq
= isl_basic_set_intersect(eq
, bset_j
);
895 isl_basic_set_free(orig
);
896 return cloog_constraint_set_from_isl_basic_set(bset
);
899 idim
= isl_space_map_from_set(isl_basic_set_get_space(bset
));
900 id
= isl_basic_map_identity(idim
);
901 id
= isl_basic_map_remove_dims(id
, isl_dim_out
, dim
.pos
, 1);
902 bset
= isl_basic_set_apply(bset
, isl_basic_map_copy(id
));
903 bset
= isl_basic_set_apply(bset
, isl_basic_map_reverse(id
));
905 constraints_dim
= isl_basic_set_dim(bset
, isl_dim_set
);
906 eq
= isl_basic_set_remove_dims(eq
, isl_dim_set
, constraints_dim
,
907 isl_basic_set_dim(eq
, isl_dim_set
) - constraints_dim
);
908 bset
= isl_basic_set_gist(bset
, eq
);
909 n_div
= isl_basic_set_dim(bset
, isl_dim_div
);
911 isl_basic_set_free(bset
);
912 return cloog_constraint_set_from_isl_basic_set(orig
);
915 isl_basic_set_free(orig
);
916 return cloog_constraint_set_from_isl_basic_set(bset
);
919 c
= isl_equality_alloc(isl_basic_set_get_local_space(bset
));
920 c
= isl_constraint_set_coefficient_si(c
, isl_dim_div
, 0, 1);
921 c
= isl_constraint_set_coefficient_si(c
, isl_dim_set
, dim
.pos
, -1);
922 bset
= isl_basic_set_add_constraint(bset
, c
);
924 cloog_int_set_si(*bound
, 0);
925 isl_val
*v
= cloog_int_to_isl_val(isl_basic_set_get_ctx(bset
), *bound
);
926 constraints
= cloog_constraint_set_from_isl_basic_set(bset
);
927 cloog_constraint_set_foreach_constraint(constraints
,
928 add_constant_term
, &v
);
929 isl_val_to_cloog_int(v
, bound
); //return the value to bound
932 isl_basic_set_free(orig
);
933 return cloog_constraint_set_from_isl_basic_set(bset
);
936 CloogConstraint
*cloog_constraint_copy(CloogConstraint
*constraint
)
938 return cloog_constraint_from_isl_constraint(
939 isl_constraint_copy(cloog_constraint_to_isl(constraint
)));
942 void cloog_constraint_release(CloogConstraint
*constraint
)
944 isl_constraint_free(cloog_constraint_to_isl(constraint
));
947 struct cloog_isl_foreach
{
948 int (*fn
)(CloogConstraint
*constraint
, void *user
);
952 static int cloog_isl_foreach_cb(__isl_take isl_constraint
*c
, void *user
)
954 struct cloog_isl_foreach
*data
= (struct cloog_isl_foreach
*)user
;
957 if (isl_constraint_is_div_constraint(c
)) {
958 isl_constraint_free(c
);
962 ret
= data
->fn(cloog_constraint_from_isl_constraint(c
), data
->user
);
964 isl_constraint_free(c
);
969 int cloog_constraint_set_foreach_constraint(CloogConstraintSet
*constraints
,
970 int (*fn
)(CloogConstraint
*constraint
, void *user
), void *user
)
972 struct cloog_isl_foreach data
= { fn
, user
};
975 bset
= cloog_constraints_set_to_isl(constraints
);
976 return isl_basic_set_foreach_constraint(bset
,
977 cloog_isl_foreach_cb
, &data
);
980 CloogConstraint
*cloog_equal_constraint(CloogEqualities
*equal
, int j
)
984 c
= isl_constraint_copy(equal
->constraints
[j
]);
985 return cloog_constraint_from_isl_constraint(c
);
988 /* Given a stride constraint on iterator i (specified by level) of the form
990 * i = f(outer iterators) + stride * f(existentials)
992 * extract f as an isl_aff.
994 static isl_aff
*extract_stride_offset(__isl_keep isl_constraint
*c
,
995 int level
, CloogStride
*stride
)
998 isl_space
*dim
= isl_constraint_get_space(c
);
999 isl_local_space
*ls
= isl_local_space_from_space(dim
);
1000 isl_aff
*offset
= isl_aff_zero_on_domain(ls
);
1002 unsigned nparam
, nvar
;
1004 nparam
= isl_constraint_dim(c
, isl_dim_param
);
1005 nvar
= isl_constraint_dim(c
, isl_dim_set
);
1007 for (i
= 0; i
< nparam
; ++i
) {
1008 u
= isl_constraint_get_coefficient_val(c
, isl_dim_param
, i
);
1009 u
= isl_val_mul(u
, cloog_int_to_isl_val(isl_constraint_get_ctx(c
), stride
->factor
));
1010 offset
= isl_aff_set_coefficient_val(offset
, isl_dim_param
, i
, u
);
1012 for (i
= 0; i
< nvar
; ++i
) {
1015 u
= isl_constraint_get_coefficient_val(c
, isl_dim_set
, i
);
1016 u
= isl_val_mul(u
, cloog_int_to_isl_val(isl_constraint_get_ctx(c
), stride
->factor
));
1017 offset
= isl_aff_set_coefficient_val(offset
, isl_dim_in
, i
, u
);
1019 u
= isl_constraint_get_constant_val(c
);
1020 u
= isl_val_mul(u
, cloog_int_to_isl_val(isl_constraint_get_ctx(c
), stride
->factor
));
1021 offset
= isl_aff_set_constant_val(offset
, u
);
1026 /* Update the given lower bound on level such that it satisfies the stride
1027 * constraint. The computation performed here is essentially the same
1028 * as that performed in constraint_stride_lower_c.
1030 * We update the constraint
1036 * i >= s * ceil((-f/a - d)/s) + d
1038 * with s the stride and d the offset encoded in the stride constraint.
1040 CloogConstraint
*cloog_constraint_stride_lower_bound(CloogConstraint
*c
,
1041 int level
, CloogStride
*stride
)
1043 isl_constraint
*stride_c
= cloog_constraint_to_isl(stride
->constraint
);
1044 isl_constraint
*bound
= cloog_constraint_to_isl(c
);
1048 lower
= isl_constraint_get_bound(bound
, isl_dim_set
, level
- 1);
1049 isl_constraint_free(bound
);
1051 offset
= extract_stride_offset(stride_c
, level
, stride
);
1053 lower
= isl_aff_sub(lower
, isl_aff_copy(offset
));
1054 lower
= isl_aff_scale_down_val(lower
, cloog_int_to_isl_val(isl_constraint_get_ctx(stride_c
), stride
->stride
));
1055 lower
= isl_aff_ceil(lower
);
1056 lower
= isl_aff_scale_val(lower
, cloog_int_to_isl_val(isl_constraint_get_ctx(stride_c
), stride
->stride
));
1057 lower
= isl_aff_add(lower
, offset
);
1058 lower
= isl_aff_neg(lower
);
1059 lower
= isl_aff_add_coefficient_si(lower
, isl_dim_in
, level
- 1, 1);
1061 bound
= isl_inequality_from_aff(lower
);
1063 return cloog_constraint_from_isl_constraint(bound
);