Polly 23.0.0git
isl_ast_build_expr.c
Go to the documentation of this file.
1/*
2 * Copyright 2012-2014 Ecole Normale Superieure
3 * Copyright 2014 INRIA Rocquencourt
4 *
5 * Use of this software is governed by the MIT license
6 *
7 * Written by Sven Verdoolaege,
8 * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
9 * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
10 * B.P. 105 - 78153 Le Chesnay, France
11 */
12
13#include <isl/id.h>
14#include <isl/space.h>
15#include <isl/constraint.h>
16#include <isl/ilp.h>
17#include <isl/val.h>
18#include <isl_ast_build_expr.h>
19#include <isl_ast_private.h>
21#include <isl_sort.h>
22
23/* Compute the "opposite" of the (numerator of the) argument of a div
24 * with denominator "d".
25 *
26 * In particular, compute
27 *
28 * -aff + (d - 1)
29 */
39
40/* Internal data structure used inside isl_ast_expr_add_term.
41 * The domain of "build" is used to simplify the expressions.
42 * "build" needs to be set by the caller of isl_ast_expr_add_term.
43 * "ls" is the domain local space of the affine expression
44 * of which a term is being added.
45 * "cst" is the constant term of the expression in which the added term
46 * appears. It may be modified by isl_ast_expr_add_term.
47 *
48 * "v" is the coefficient of the term that is being constructed and
49 * is set internally by isl_ast_expr_add_term.
50 */
57
58/* Given the numerator "aff" of the argument of an integer division
59 * with denominator "d", check if it can be made non-negative over
60 * data->build->domain by stealing part of the constant term of
61 * the expression in which the integer division appears.
62 *
63 * In particular, the outer expression is of the form
64 *
65 * v * floor(aff/d) + cst
66 *
67 * We already know that "aff" itself may attain negative values.
68 * Here we check if aff + d*floor(cst/v) is non-negative, such
69 * that we could rewrite the expression to
70 *
71 * v * floor((aff + d*floor(cst/v))/d) + cst - v*floor(cst/v)
72 *
73 * Note that aff + d*floor(cst/v) can only possibly be non-negative
74 * if data->cst and data->v have the same sign.
75 * Similarly, if floor(cst/v) is zero, then there is no point in
76 * checking again.
77 */
80{
81 isl_aff *shifted;
82 isl_val *shift;
83 isl_bool is_zero;
84 isl_bool non_neg;
85
86 if (isl_val_sgn(data->cst) != isl_val_sgn(data->v))
87 return isl_bool_false;
88
89 shift = isl_val_div(isl_val_copy(data->cst), isl_val_copy(data->v));
90 shift = isl_val_floor(shift);
91 is_zero = isl_val_is_zero(shift);
92 if (is_zero < 0 || is_zero) {
93 isl_val_free(shift);
94 return isl_bool_not(is_zero);
95 }
96 shift = isl_val_mul(shift, isl_val_copy(d));
97 shifted = isl_aff_copy(aff);
98 shifted = isl_aff_add_constant_val(shifted, shift);
99 non_neg = isl_ast_build_aff_is_nonneg(data->build, shifted);
100 isl_aff_free(shifted);
101
102 return non_neg;
103}
104
105/* Given the numerator "aff" of the argument of an integer division
106 * with denominator "d", steal part of the constant term of
107 * the expression in which the integer division appears to make it
108 * non-negative over data->build->domain.
109 *
110 * In particular, the outer expression is of the form
111 *
112 * v * floor(aff/d) + cst
113 *
114 * We know that "aff" itself may attain negative values,
115 * but that aff + d*floor(cst/v) is non-negative.
116 * Find the minimal positive value that we need to add to "aff"
117 * to make it positive and adjust data->cst accordingly.
118 * That is, compute the minimal value "m" of "aff" over
119 * data->build->domain and take
120 *
121 * s = ceil(-m/d)
122 *
123 * such that
124 *
125 * aff + d * s >= 0
126 *
127 * and rewrite the expression to
128 *
129 * v * floor((aff + s*d)/d) + (cst - v*s)
130 */
133{
135 isl_val *shift, *t;
136
138 shift = isl_set_min_val(domain, aff);
140
141 shift = isl_val_neg(shift);
142 shift = isl_val_div(shift, isl_val_copy(d));
143 shift = isl_val_ceil(shift);
144
145 t = isl_val_copy(shift);
146 t = isl_val_mul(t, isl_val_copy(data->v));
147 data->cst = isl_val_sub(data->cst, t);
148
149 shift = isl_val_mul(shift, isl_val_copy(d));
150 return isl_aff_add_constant_val(aff, shift);
151}
152
153/* Construct an expression representing the binary operation "type"
154 * (some division or modulo) applied to the expressions
155 * constructed from "aff" and "v".
156 */
160{
161 isl_ast_expr *expr1, *expr2;
162
163 expr1 = isl_ast_expr_from_aff(aff, build);
164 expr2 = isl_ast_expr_from_val(v);
165 return isl_ast_expr_alloc_binary(type, expr1, expr2);
166}
167
168/* Create an isl_ast_expr evaluating the div at position "pos" in data->ls.
169 * The result is simplified in terms of data->build->domain.
170 * This function may change (the sign of) data->v.
171 *
172 * data->ls is known to be non-NULL.
173 *
174 * Let the div be of the form floor(e/d).
175 * If the ast_build_prefer_pdiv option is set then we check if "e"
176 * is non-negative, so that we can generate
177 *
178 * (pdiv_q, expr(e), expr(d))
179 *
180 * instead of
181 *
182 * (fdiv_q, expr(e), expr(d))
183 *
184 * If the ast_build_prefer_pdiv option is set and
185 * if "e" is not non-negative, then we check if "-e + d - 1" is non-negative.
186 * If so, we can rewrite
187 *
188 * floor(e/d) = -ceil(-e/d) = -floor((-e + d - 1)/d)
189 *
190 * and still use pdiv_q, while changing the sign of data->v.
191 *
192 * Otherwise, we check if
193 *
194 * e + d*floor(cst/v)
195 *
196 * is non-negative and if so, replace floor(e/d) by
197 *
198 * floor((e + s*d)/d) - s
199 *
200 * with s the minimal shift that makes the argument non-negative.
201 */
203 int pos)
204{
205 isl_ctx *ctx = isl_local_space_get_ctx(data->ls);
206 isl_aff *aff;
207 isl_val *d;
209
213
216 isl_bool non_neg;
217 non_neg = isl_ast_build_aff_is_nonneg(data->build, aff);
218 if (non_neg >= 0 && !non_neg) {
220 isl_val_copy(d));
221 non_neg = isl_ast_build_aff_is_nonneg(data->build, opp);
222 if (non_neg >= 0 && non_neg) {
223 data->v = isl_val_neg(data->v);
225 aff = opp;
226 } else
227 isl_aff_free(opp);
228 }
229 if (non_neg >= 0 && !non_neg) {
230 non_neg = is_non_neg_after_stealing(aff, d, data);
231 if (non_neg >= 0 && non_neg)
232 aff = steal_from_cst(aff, d, data);
233 }
234 if (non_neg < 0)
236 else if (non_neg)
238 }
239
240 return div_mod(type, aff, d, data->build);
241}
242
243/* Create an isl_ast_expr evaluating the specified dimension of data->ls.
244 * The result is simplified in terms of data->build->domain.
245 * This function may change (the sign of) data->v.
246 *
247 * The isl_ast_expr is constructed based on the type of the dimension.
248 * - divs are constructed by var_div
249 * - set variables are constructed from the iterator isl_ids in data->build
250 * - parameters are constructed from the isl_ids in data->ls
251 */
253 enum isl_dim_type type, int pos)
254{
255 isl_ctx *ctx = isl_local_space_get_ctx(data->ls);
256 isl_id *id;
257
258 if (type == isl_dim_div)
259 return var_div(data, pos);
260
261 if (type == isl_dim_set) {
263 return isl_ast_expr_from_id(id);
264 }
265
267 isl_die(ctx, isl_error_internal, "unnamed dimension",
268 return NULL);
270 return isl_ast_expr_from_id(id);
271}
272
273/* Does "expr" represent the zero integer?
274 */
276{
277 if (!expr)
278 return isl_bool_error;
279 if (expr->type != isl_ast_expr_int)
280 return isl_bool_false;
281 return isl_val_is_zero(expr->u.v);
282}
283
284/* Create a binary expression by calling "fn" on "expr1" and "expr2",
285 * provided neither of the two expressions is identically zero.
286 * Otherwise, return the non-zero expression (or zero if they are both zero).
287 */
290 __isl_take isl_ast_expr *expr2),
293{
294 if (!expr1 || !expr2)
295 goto error;
296
297 if (ast_expr_is_zero(expr1)) {
298 isl_ast_expr_free(expr1);
299 return expr2;
300 }
301
302 if (ast_expr_is_zero(expr2)) {
303 isl_ast_expr_free(expr2);
304 return expr1;
305 }
306
307 return fn(expr1, expr2);
308error:
309 isl_ast_expr_free(expr1);
310 isl_ast_expr_free(expr2);
311 return NULL;
312}
313
314/* Create an expression representing the sum of "expr1" and "expr2",
315 * provided neither of the two expressions is identically zero.
316 */
322
323/* Create an expression representing the disjunction of "expr1" and "expr2",
324 * provided neither of the two expressions is identically zero.
325 */
331
332/* Subtract expr2 from expr1.
333 *
334 * If expr2 is zero, we simply return expr1.
335 * If expr1 is zero, we return
336 *
337 * (isl_ast_expr_op_minus, expr2)
338 *
339 * Otherwise, we return
340 *
341 * (isl_ast_expr_op_sub, expr1, expr2)
342 */
345{
346 if (!expr1 || !expr2)
347 goto error;
348
349 if (ast_expr_is_zero(expr2)) {
350 isl_ast_expr_free(expr2);
351 return expr1;
352 }
353
354 if (ast_expr_is_zero(expr1)) {
355 isl_ast_expr_free(expr1);
356 return isl_ast_expr_neg(expr2);
357 }
358
359 return isl_ast_expr_sub(expr1, expr2);
360error:
361 isl_ast_expr_free(expr1);
362 isl_ast_expr_free(expr2);
363 return NULL;
364}
365
366/* Return an isl_ast_expr that represents
367 *
368 * v * (aff mod d)
369 *
370 * v is assumed to be non-negative.
371 * The result is simplified in terms of build->domain.
372 */
376{
377 isl_ast_expr *expr;
378 isl_ast_expr *c;
379
380 if (!aff)
381 return NULL;
382
384 isl_aff_copy(aff), isl_val_copy(d), build);
385
386 if (!isl_val_is_one(v)) {
388 expr = isl_ast_expr_mul(c, expr);
389 }
390
391 return expr;
392}
393
394/* Create an isl_ast_expr that scales "expr" by "v".
395 *
396 * If v is 1, we simply return expr.
397 * If v is -1, we return
398 *
399 * (isl_ast_expr_op_minus, expr)
400 *
401 * Otherwise, we return
402 *
403 * (isl_ast_expr_op_mul, expr(v), expr)
404 */
407{
408 isl_ast_expr *c;
409
410 if (!expr || !v)
411 goto error;
412 if (isl_val_is_one(v)) {
413 isl_val_free(v);
414 return expr;
415 }
416
417 if (isl_val_is_negone(v)) {
418 isl_val_free(v);
419 expr = isl_ast_expr_neg(expr);
420 } else {
422 expr = isl_ast_expr_mul(c, expr);
423 }
424
425 return expr;
426error:
427 isl_val_free(v);
428 isl_ast_expr_free(expr);
429 return NULL;
430}
431
432/* Add an expression for "*v" times the specified dimension of data->ls
433 * to expr.
434 * If the dimension is an integer division, then this function
435 * may modify data->cst in order to make the numerator non-negative.
436 * The result is simplified in terms of data->build->domain.
437 *
438 * Let e be the expression for the specified dimension,
439 * multiplied by the absolute value of "*v".
440 * If "*v" is negative, we create
441 *
442 * (isl_ast_expr_op_sub, expr, e)
443 *
444 * except when expr is trivially zero, in which case we create
445 *
446 * (isl_ast_expr_op_minus, e)
447 *
448 * instead.
449 *
450 * If "*v" is positive, we simply create
451 *
452 * (isl_ast_expr_op_add, expr, e)
453 *
454 */
458{
459 isl_ast_expr *term;
460
461 if (!expr)
462 return NULL;
463
464 data->v = v;
465 term = var(data, type, pos);
466 v = data->v;
467
468 if (isl_val_is_neg(v) && !ast_expr_is_zero(expr)) {
469 v = isl_val_neg(v);
470 term = scale(term, v);
471 return ast_expr_sub(expr, term);
472 } else {
473 term = scale(term, v);
474 return ast_expr_add(expr, term);
475 }
476}
477
478/* Add an expression for "v" to expr.
479 */
482{
483 isl_ast_expr *expr_int;
484
485 if (!expr || !v)
486 goto error;
487
488 if (isl_val_is_zero(v)) {
489 isl_val_free(v);
490 return expr;
491 }
492
493 if (isl_val_is_neg(v) && !ast_expr_is_zero(expr)) {
494 v = isl_val_neg(v);
495 expr_int = isl_ast_expr_from_val(v);
496 return ast_expr_sub(expr, expr_int);
497 } else {
498 expr_int = isl_ast_expr_from_val(v);
499 return ast_expr_add(expr, expr_int);
500 }
501error:
502 isl_ast_expr_free(expr);
503 isl_val_free(v);
504 return NULL;
505}
506
507/* Internal data structure used inside extract_modulos.
508 *
509 * If any modulo expressions are detected in "aff", then the
510 * expression is removed from "aff" and added to either "pos" or "neg"
511 * depending on the sign of the coefficient of the modulo expression
512 * inside "aff".
513 *
514 * "add" is an expression that needs to be added to "aff" at the end of
515 * the computation. It is NULL as long as no modulos have been extracted.
516 *
517 * "i" is the position in "aff" of the div under investigation
518 * "v" is the coefficient in "aff" of the div
519 * "div" is the argument of the div, with the denominator removed
520 * "d" is the original denominator of the argument of the div
521 *
522 * If set, then "partial" is the (positively weighted) sum
523 * of the affine expressions of one or more previously considered constraints
524 * that could still be complemented to an expression equal to "div".
525 * "nonneg" is an affine expression that is non-negative over "build"
526 * and that can be used to extract a modulo expression from "div".
527 * In particular, if "sign" is 1, then the coefficients of "nonneg"
528 * are equal to those of "div" modulo "d". If "sign" is -1, then
529 * the coefficients of "nonneg" are opposite to those of "div" modulo "d".
530 * If "sign" is 0, then no such affine expression has been found (yet).
531 */
550
551/* Does
552 *
553 * arg mod data->d
554 *
555 * represent (a special case of) a test for some linear expression
556 * being even?
557 *
558 * In particular, is it of the form
559 *
560 * (lin - 1) mod 2
561 *
562 * ?
563 */
566{
568 isl_val *cst;
569
570 res = isl_val_eq_si(data->d, 2);
571 if (res < 0 || !res)
572 return res;
573
575 res = isl_val_eq_si(cst, -1);
576 isl_val_free(cst);
577
578 return res;
579}
580
581/* Given that data->v * div_i in data->aff is equal to
582 *
583 * f * (term - (arg mod d))
584 *
585 * with data->d * f = data->v and "arg" non-negative on data->build, add
586 *
587 * f * term
588 *
589 * to data->add and
590 *
591 * abs(f) * (arg mod d)
592 *
593 * to data->neg or data->pos depending on the sign of -f.
594 *
595 * In the special case that "arg mod d" is of the form "(lin - 1) mod 2",
596 * with "lin" some linear expression, first replace
597 *
598 * f * (term - ((lin - 1) mod 2))
599 *
600 * by
601 *
602 * -f * (1 - term - (lin mod 2))
603 *
604 * These two are equal because
605 *
606 * ((lin - 1) mod 2) + (lin mod 2) = 1
607 *
608 * Also, if "lin - 1" is non-negative, then "lin" is non-negative too.
609 */
612{
613 isl_bool even;
614 isl_ast_expr *expr;
615 int s;
616
617 even = is_even_test(data, arg);
618 if (even < 0) {
620 } else if (even) {
621 term = oppose_div_arg(term, isl_val_copy(data->d));
622 data->v = isl_val_neg(data->v);
624 }
625
626 data->v = isl_val_div(data->v, isl_val_copy(data->d));
627 s = isl_val_sgn(data->v);
628 data->v = isl_val_abs(data->v);
629 expr = isl_ast_expr_mod(data->v, arg, data->d, data->build);
631 if (s > 0)
632 data->neg = ast_expr_add(data->neg, expr);
633 else
634 data->pos = ast_expr_add(data->pos, expr);
635 data->aff = isl_aff_set_coefficient_si(data->aff,
636 isl_dim_div, data->i, 0);
637 if (s < 0)
638 data->v = isl_val_neg(data->v);
639 term = isl_aff_scale_val(term, isl_val_copy(data->v));
640
641 if (!data->add)
642 data->add = term;
643 else
644 data->add = isl_aff_add(data->add, term);
645 if (!data->add)
646 return isl_stat_error;
647
648 return isl_stat_ok;
649}
650
651/* Given that data->v * div_i in data->aff is of the form
652 *
653 * f * d * floor(div/d)
654 *
655 * with div nonnegative on data->build, rewrite it as
656 *
657 * f * (div - (div mod d)) = f * div - f * (div mod d)
658 *
659 * and add
660 *
661 * f * div
662 *
663 * to data->add and
664 *
665 * abs(f) * (div mod d)
666 *
667 * to data->neg or data->pos depending on the sign of -f.
668 */
670{
671 return extract_term_and_mod(data, isl_aff_copy(data->div),
672 isl_aff_copy(data->div));
673}
674
675/* Given that data->v * div_i in data->aff is of the form
676 *
677 * f * d * floor(div/d) (1)
678 *
679 * check if div is non-negative on data->build and, if so,
680 * extract the corresponding modulo from data->aff.
681 * If not, then check if
682 *
683 * -div + d - 1
684 *
685 * is non-negative on data->build. If so, replace (1) by
686 *
687 * -f * d * floor((-div + d - 1)/d)
688 *
689 * and extract the corresponding modulo from data->aff.
690 *
691 * This function may modify data->div.
692 */
694{
695 isl_bool mod;
696
697 mod = isl_ast_build_aff_is_nonneg(data->build, data->div);
698 if (mod < 0)
699 goto error;
700 if (mod)
701 return extract_mod(data);
702
703 data->div = oppose_div_arg(data->div, isl_val_copy(data->d));
704 mod = isl_ast_build_aff_is_nonneg(data->build, data->div);
705 if (mod < 0)
706 goto error;
707 if (mod) {
708 data->v = isl_val_neg(data->v);
709 return extract_mod(data);
710 }
711
712 return isl_stat_ok;
713error:
714 data->aff = isl_aff_free(data->aff);
715 return isl_stat_error;
716}
717
718/* Does "c" have a constant term that is "too large"?
719 * Here, "too large" is fairly arbitrarily set to 1 << 15.
720 */
722{
723 isl_val *v;
724 int sign;
725
727 if (!v)
728 return isl_bool_error;
729 sign = isl_val_cmp_si(v, 1 << 15);
730 isl_val_free(v);
731 return isl_bool_ok(sign > 0);
732}
733
734/* Is the affine expression with constant term returned by "get_constant"
735 * "simpler" than data->nonneg
736 * for use in extracting a modulo expression?
737 *
738 * Currently, only this constant term is considered.
739 * In particular, we prefer the affine expression with the smallest constant
740 * term.
741 * This means that if there are two constraints, say x >= 0 and -x + 10 >= 0,
742 * then we would pick x >= 0
743 *
744 * More detailed heuristics could be used if it turns out that there is a need.
745 */
748 void *user), void *user)
749{
750 isl_val *v1, *v2;
751 isl_bool simpler;
752
753 if (!data->nonneg)
754 return isl_bool_true;
755
756 v1 = isl_val_abs(get_constant(data, user));
758 simpler = isl_val_lt(v1, v2);
759 isl_val_free(v1);
760 isl_val_free(v2);
761
762 return simpler;
763}
764
765/* Return the constant term of "c".
766 */
768 struct isl_extract_mod_data *data, void *user)
769{
770 isl_constraint *c = user;
771
773}
774
775/* Is the affine expression of constraint "c" "simpler" than data->nonneg
776 * for use in extracting a modulo expression?
777 *
778 * The test is based on the constant term of "c".
779 */
785
786/* Replace data->nonneg by the affine expression "aff" and
787 * set data->sign to "sign".
788 */
790 __isl_take isl_aff *aff, int sign)
791{
792 isl_aff_free(data->nonneg);
793 data->nonneg = aff;
794 data->sign = sign;
795
796 return isl_stat_non_null(data->nonneg);
797}
798
799/* If "c" is "simpler" than data->nonneg,
800 * then replace data->nonneg by the affine expression of "c" and
801 * set data->sign to "sign".
802 */
804 __isl_keep isl_constraint *c, int sign)
805{
806 isl_bool simpler;
807
808 simpler = mod_constraint_is_simpler(data, c);
809 if (simpler < 0 || !simpler)
810 return isl_stat_non_error_bool(simpler);
811
812 return replace_nonneg(data, isl_constraint_get_aff(c), sign);
813}
814
815/* Internal data structure used inside check_parallel_or_opposite.
816 *
817 * "data" is the information passed down from the caller.
818 * "c" is the constraint being inspected.
819 *
820 * "n" contains the number of parameters and the number of input dimensions and
821 * is set by the first call to parallel_or_opposite_scan.
822 * "parallel" is set as long as the coefficients of "c" are still potentially
823 * equal to those of data->div modulo data->d.
824 * "opposite" is set as long as the coefficients of "c" are still potentially
825 * opposite to those of data->div modulo data->d.
826 * "partial" is set if the coefficients of "c" are still potentially
827 * a subset of those of data->div.
828 * "final" is set is the coefficients in data->partial together with those
829 * of "c" still cover the coefficients of data->div.
830 *
831 * If "f" is set, then it is the factor with which the coefficients
832 * of "c" need to be multiplied to match those of data->div.
833 */
846
847/* Should the scan of coefficients be continued?
848 * That is, are the coefficients still (potentially) (partially) equal or
849 * opposite?
850 */
852{
853 if (stat->parallel < 0 || stat->opposite < 0 || stat->partial < 0)
854 return isl_bool_error;
855
856 return isl_bool_ok(stat->parallel || stat->opposite || stat->partial);
857}
858
859/* Is coefficient "i" of type "c_type" of stat->c potentially equal or
860 * opposite to coefficient "i" of type "a_type" of stat->data->div
861 * modulo stat->data->div?
862 * In particular, are they both zero or both non-zero?
863 *
864 * Note that while the coefficients of stat->data->div can be reasonably
865 * expected not to involve any coefficients that are multiples of stat->data->d,
866 * "c" may very well involve such coefficients.
867 * This means that some cases of equal or opposite constraints can be missed
868 * this way.
869 *
870 * If the coefficient of stat->data->div is zero, but that of "c" is not,
871 * then the coefficients of "c" cannot form a subset of those
872 * of stat->data->div.
873 * If the coefficient of stat->data->div is not zero,
874 * then check that it does not appear in both "c" and stat->data->partial.
875 * If it does not appear in either, then it must appear in some later constraint
876 * and "c" can therefore not be the last in the sequence of constraints
877 * that sum up to stat->data->div.
878 */
880 enum isl_dim_type c_type, enum isl_dim_type a_type, int i)
881{
882 isl_bool a, b;
883
884 a = isl_constraint_involves_dims(stat->c, c_type, i, 1);
885 b = isl_aff_involves_dims(stat->data->div, a_type, i, 1);
886 if (a < 0 || b < 0)
887 return isl_bool_error;
888 if (a != b)
889 stat->parallel = stat->opposite = isl_bool_false;
890 if (!stat->partial)
892 if (!b && a)
893 stat->partial = isl_bool_false;
894 if (b && (a || stat->final) && stat->data->partial) {
895 isl_bool c;
896
897 c = isl_aff_involves_dims(stat->data->partial, a_type, i, 1);
898 if (c < 0)
899 return isl_bool_error;
900 if (a && c)
901 stat->partial = isl_bool_false;
902 if (!a && !c)
903 stat->final = 0;
904 }
905
907}
908
909/* Update stat->partial based on the coefficient "v1" of stat->c and
910 * "v2" of stat->data->div, where "v2" is known not to be zero.
911 * "v1" may be modified by this function and the modified value is returned.
912 * This function may also set stat->f.
913 *
914 * If "v1" is zero, then no update needs to be performed.
915 * Otherwise, stat->partial can only remain set if "c" is part
916 * of some positively weighted sum that is equal to stat->data->div.
917 * This means that v2 divided by v1 needs to be a positive integer.
918 * This quotient is stored in stat->f. If this quotient has already
919 * been set for a previous coefficient, then it needs to be the same.
920 */
923{
924 if (!stat->partial)
925 return v1;
926 if (isl_val_is_zero(v1))
927 return v1;
928
929 stat->partial = isl_val_is_divisible_by(v2, v1);
930 if (stat->partial < 0 || !stat->partial)
931 return v1;
932
933 v1 = isl_val_div(isl_val_copy(v2), v1);
934 stat->partial = isl_val_is_pos(v1);
935 if (stat->partial < 0 || !stat->partial)
936 return v1;
937 if (!stat->f)
938 stat->f = isl_val_copy(v1);
939 stat->partial = isl_val_eq(v1, stat->f);
940 return v1;
941}
942
943/* Is coefficient "i" of type "c_type" of stat->c equal or
944 * opposite to coefficient "i" of type "a_type" of stat->data->div
945 * modulo stat->data->div, or
946 * could stat->c be part of a positively weighted sum equal to stat->data->div?
947 * This function may set stat->f (at most once).
948 *
949 * If the coefficient of stat->data->div is zero,
950 * then parallel_or_opposite_feasible has already checked
951 * that the coefficient of stat->c is zero as well,
952 * so no further checks are needed.
953 */
955 enum isl_dim_type c_type, enum isl_dim_type a_type, int i)
956{
957 isl_val *v1, *v2;
958 isl_bool b;
959
960 b = isl_aff_involves_dims(stat->data->div, a_type, i, 1);
961 if (b < 0 || !b)
962 return isl_bool_not(b);
963
964 v1 = isl_constraint_get_coefficient_val(stat->c, c_type, i);
965 v2 = isl_aff_get_coefficient_val(stat->data->div, a_type, i);
966 if (stat->parallel) {
967 v1 = isl_val_sub(v1, isl_val_copy(v2));
968 stat->parallel = isl_val_is_divisible_by(v1, stat->data->d);
969 v1 = isl_val_add(v1, isl_val_copy(v2));
970 }
971 if (stat->opposite) {
972 v1 = isl_val_add(v1, isl_val_copy(v2));
973 stat->opposite = isl_val_is_divisible_by(v1, stat->data->d);
974 }
975 v1 = update_is_partial(stat, v1, v2);
976 isl_val_free(v1);
977 isl_val_free(v2);
978
980}
981
982/* Scan the coefficients of stat->c to see if they are (potentially)
983 * equal or opposite to those of stat->data->div modulo stat->data->d,
984 * calling "fn" on each coefficient.
985 * IF "init" is set, then this is the first call to this function and
986 * then stat->n is initialized.
987 */
989 isl_bool (*fn)(struct isl_parallel_stat *stat,
990 enum isl_dim_type c_type, enum isl_dim_type a_type, int i),
991 int init)
992{
993 enum isl_dim_type c_type[2] = { isl_dim_param, isl_dim_set };
994 enum isl_dim_type a_type[2] = { isl_dim_param, isl_dim_in };
995 int i, t;
996
997 for (t = 0; t < 2; ++t) {
998 if (init) {
999 stat->n[t] = isl_constraint_dim(stat->c, c_type[t]);
1000 if (stat->n[t] < 0)
1001 return isl_bool_error;
1002 }
1003 for (i = 0; i < stat->n[t]; ++i) {
1004 isl_bool ok;
1005
1006 ok = fn(stat, c_type[t], a_type[t], i);
1007 if (ok < 0 || !ok)
1008 return ok;
1009 }
1010 }
1011
1012 return isl_bool_true;
1013}
1014
1015/* Update stat->data->partial with stat->c.
1016 *
1017 * In particular, if stat->c with weight stat->f turns out
1018 * to potentially be a part of a weighted sum equal to stat->data->div
1019 * (i.e., stat->partial is set), then add this scaled version of stat->c
1020 * to stat->data->partial or initialize stat->data->partial if it has not
1021 * been set yet.
1022 */
1024{
1025 isl_aff *aff;
1026
1027 if (!stat->partial)
1028 return isl_stat_ok;
1029
1030 aff = isl_constraint_get_aff(stat->c);
1032 if (!stat->data->partial)
1033 stat->data->partial = aff;
1034 else
1035 stat->data->partial = isl_aff_add(stat->data->partial, aff);
1036
1037 return isl_stat_non_null(stat->data->partial);
1038}
1039
1040/* Return the constant term of data->partial.
1041 */
1043 struct isl_extract_mod_data *data, void *user)
1044{
1045 return isl_aff_get_constant_val(data->partial);
1046}
1047
1048/* Is the affine expression data->partial "simpler" than data->nonneg
1049 * for use in extracting a modulo expression?
1050 *
1051 * The test is based on the constant term of data->partial.
1052 */
1054{
1055 return is_simpler(data, &get_partial_constant, NULL);
1056}
1057
1058/* If stat->data->partial is complete and is "simpler" than data->nonneg,
1059 * then replace stat->data->nonneg by stat->data->partial.
1060 */
1062{
1063 isl_bool simpler;
1065
1066 if (!stat->final)
1067 return isl_stat_ok;
1068
1069 simpler = partial_is_simpler(stat->data);
1070 if (simpler < 0 || !simpler)
1071 return isl_stat_non_error_bool(simpler);
1072
1073 partial = stat->data->partial;
1074 stat->data->partial = NULL;
1075
1076 return replace_nonneg(stat->data, partial, 1);
1077}
1078
1079/* Check if the coefficients of "c" are either equal or opposite to those
1080 * of data->div modulo data->d. If so, and if "c" is "simpler" than
1081 * data->nonneg, then replace data->nonneg by the affine expression of "c"
1082 * and set data->sign accordingly.
1083 * Also check if "c" is part of a positively weighted sum of constraints
1084 * that is equal to data->div, where each constraint has distinct non-zero
1085 * coefficients. If "c" does not involve any non-zero coefficients,
1086 * then it is not considered to be part of this sum. If "c" is
1087 * the last constraint in this sum (and the sum is "simpler" than data->nonneg)
1088 * then also replace data->nonneg by this sum.
1089 * If "c" is equal or opposite to data->div, then it is not considered
1090 * to be part of a sum.
1091 *
1092 * Both "c" and data->div are assumed not to involve any integer divisions.
1093 *
1094 * Before we start the actual comparison, we first quickly check if
1095 * "c" and data->div have the same non-zero coefficients.
1096 * If not, then we assume that "c" is not of the desired form.
1097 *
1098 * If the constant term is "too large", then the constraint is rejected.
1099 * We do this to avoid picking up constraints that bound a variable
1100 * by a very large number, say the largest or smallest possible
1101 * variable in the representation of some integer type.
1102 */
1105{
1106 struct isl_parallel_stat stat = {
1107 .data = data,
1108 .c = c,
1109 .parallel = isl_bool_true,
1110 .opposite = isl_bool_true,
1111 .partial = isl_bool_true,
1112 .final = data->partial != NULL,
1113 .f = NULL,
1114 };
1115 isl_bool skip, ok;
1116
1117 ok = parallel_or_opposite_scan(&stat,
1119 if (ok < 0 || !ok)
1120 return isl_stat_non_error_bool(ok);
1121
1122 skip = has_large_constant_term(c);
1123 if (skip < 0 || skip)
1124 return isl_stat_non_error_bool(skip);
1125
1126 if (stat.parallel || stat.opposite)
1127 stat.partial = isl_bool_false;
1128
1130 if (ok >= 0 && ok) {
1131 if (stat.partial && !stat.f)
1132 ok = isl_bool_false;
1133 else if (update_partial(&stat) < 0)
1134 ok = isl_bool_error;
1135 }
1136 isl_val_free(stat.f);
1137 if (ok < 0 || !ok)
1138 return isl_stat_non_error_bool(ok);
1139
1140 if (stat.partial)
1141 return replace_by_partial_if_simpler(&stat);
1142
1143 return replace_if_simpler(data, c, stat.parallel ? 1 : -1);
1144}
1145
1146/* Wrapper around check_parallel_or_opposite for use
1147 * as a isl_basic_set_foreach_constraint callback.
1148 */
1150 void *user)
1151{
1152 struct isl_extract_mod_data *data = user;
1153 isl_stat res;
1154
1157
1158 return res;
1159}
1160
1161/* Given that data->v * div_i in data->aff is of the form
1162 *
1163 * f * d * floor(div/d) (1)
1164 *
1165 * see if we can find an expression div' that is non-negative over data->build
1166 * and that is related to div through
1167 *
1168 * div' = div + d * e
1169 *
1170 * or
1171 *
1172 * div' = -div + d - 1 + d * e
1173 *
1174 * with e some affine expression.
1175 * If so, we write (1) as
1176 *
1177 * f * div + f * (div' mod d)
1178 *
1179 * or
1180 *
1181 * -f * (-div + d - 1) - f * (div' mod d)
1182 *
1183 * exploiting (in the second case) the fact that
1184 *
1185 * f * d * floor(div/d) = -f * d * floor((-div + d - 1)/d)
1186 *
1187 *
1188 * We first try to find an appropriate expression for div'
1189 * from the constraints of data->build->domain (which is therefore
1190 * guaranteed to be non-negative on data->build), where we remove
1191 * any integer divisions from the constraints and skip this step
1192 * if "div" itself involves any integer divisions.
1193 * The following cases are considered for div':
1194 * - individual constraints, or
1195 * - a sum of constraints that involve disjoint sets of variables and
1196 * where the sum is exactly equal to div (i.e., e = 0).
1197 * If we cannot find an appropriate expression this way, then
1198 * we pass control to extract_nonneg_mod where check
1199 * if div or "-div + d -1" themselves happen to be
1200 * non-negative on data->build.
1201 *
1202 * While looking for an appropriate constraint in data->build->domain,
1203 * we ignore the constant term, so after finding such a constraint,
1204 * we still need to fix up the constant term.
1205 * In particular, if a is the constant term of "div"
1206 * (or d - 1 - the constant term of "div" if data->sign < 0)
1207 * and b is the constant term of the constraint, then we need to find
1208 * a non-negative constant c such that
1209 *
1210 * b + c \equiv a mod d
1211 *
1212 * We therefore take
1213 *
1214 * c = (a - b) mod d
1215 *
1216 * and add it to b to obtain the constant term of div'.
1217 * If this constant term is "too negative", then we add an appropriate
1218 * multiple of d to make it positive.
1219 *
1220 *
1221 * Note that the above is only a very simple heuristic for finding an
1222 * appropriate expression. We could try a bit harder by also considering
1223 * arbitrary linear combinations of constraints,
1224 * although that could potentially be much more expensive as it involves
1225 * the solution of an LP problem.
1226 *
1227 * In particular, if v_i is a column vector representing constraint i,
1228 * w represents div and e_i is the i-th unit vector, then we are looking
1229 * for a solution of the constraints
1230 *
1231 * \sum_i lambda_i v_i = w + \sum_i alpha_i d e_i
1232 *
1233 * with \lambda_i >= 0 and alpha_i of unrestricted sign.
1234 * If we are not just interested in a non-negative expression, but
1235 * also in one with a minimal range, then we don't just want
1236 * c = \sum_i lambda_i v_i to be non-negative over the domain,
1237 * but also beta - c = \sum_i mu_i v_i, where beta is a scalar
1238 * that we want to minimize and we now also have to take into account
1239 * the constant terms of the constraints.
1240 * Alternatively, we could first compute the dual of the domain
1241 * and plug in the constraints on the coefficients.
1242 */
1244{
1246 isl_val *v1, *v2;
1247 isl_stat r;
1248 isl_size n;
1249
1250 if (!data->build)
1251 goto error;
1252
1253 n = isl_aff_dim(data->div, isl_dim_div);
1254 if (n < 0)
1255 goto error;
1256
1257 if (isl_aff_involves_dims(data->div, isl_dim_div, 0, n))
1258 return extract_nonneg_mod(data);
1259
1262 data->sign = 0;
1263 data->nonneg = NULL;
1264 data->partial = NULL;
1267 isl_aff_free(data->partial);
1269
1270 if (!data->sign || r < 0) {
1271 isl_aff_free(data->nonneg);
1272 if (r < 0)
1273 goto error;
1274 return extract_nonneg_mod(data);
1275 }
1276
1277 v1 = isl_aff_get_constant_val(data->div);
1278 v2 = isl_aff_get_constant_val(data->nonneg);
1279 if (data->sign < 0) {
1280 v1 = isl_val_neg(v1);
1281 v1 = isl_val_add(v1, isl_val_copy(data->d));
1282 v1 = isl_val_sub_ui(v1, 1);
1283 }
1284 v1 = isl_val_sub(v1, isl_val_copy(v2));
1285 v1 = isl_val_mod(v1, isl_val_copy(data->d));
1286 v1 = isl_val_add(v1, v2);
1287 v2 = isl_val_div(isl_val_copy(v1), isl_val_copy(data->d));
1288 v2 = isl_val_ceil(v2);
1289 if (isl_val_is_neg(v2)) {
1290 v2 = isl_val_mul(v2, isl_val_copy(data->d));
1291 v1 = isl_val_sub(v1, isl_val_copy(v2));
1292 }
1293 data->nonneg = isl_aff_set_constant_val(data->nonneg, v1);
1294 isl_val_free(v2);
1295
1296 if (data->sign < 0) {
1297 data->div = oppose_div_arg(data->div, isl_val_copy(data->d));
1298 data->v = isl_val_neg(data->v);
1299 }
1300
1301 return extract_term_and_mod(data,
1302 isl_aff_copy(data->div), data->nonneg);
1303error:
1304 data->aff = isl_aff_free(data->aff);
1305 return isl_stat_error;
1306}
1307
1308/* Check if "data->aff" involves any (implicit) modulo computations based
1309 * on div "data->i".
1310 * If so, remove them from aff and add expressions corresponding
1311 * to those modulo computations to data->pos and/or data->neg.
1312 *
1313 * "aff" is assumed to be an integer affine expression.
1314 *
1315 * In particular, check if (v * div_j) is of the form
1316 *
1317 * f * m * floor(a / m)
1318 *
1319 * and, if so, rewrite it as
1320 *
1321 * f * (a - (a mod m)) = f * a - f * (a mod m)
1322 *
1323 * and extract out -f * (a mod m).
1324 * In particular, if f > 0, we add (f * (a mod m)) to *neg.
1325 * If f < 0, we add ((-f) * (a mod m)) to *pos.
1326 *
1327 * Note that in order to represent "a mod m" as
1328 *
1329 * (isl_ast_expr_op_pdiv_r, a, m)
1330 *
1331 * we need to make sure that a is non-negative.
1332 * If not, we check if "-a + m - 1" is non-negative.
1333 * If so, we can rewrite
1334 *
1335 * floor(a/m) = -ceil(-a/m) = -floor((-a + m - 1)/m)
1336 *
1337 * and still extract a modulo.
1338 */
1339static int extract_modulo(struct isl_extract_mod_data *data)
1340{
1341 data->div = isl_aff_get_div(data->aff, data->i);
1342 data->d = isl_aff_get_denominator_val(data->div);
1343 if (isl_val_is_divisible_by(data->v, data->d)) {
1344 data->div = isl_aff_scale_val(data->div, isl_val_copy(data->d));
1345 if (try_extract_mod(data) < 0)
1346 data->aff = isl_aff_free(data->aff);
1347 }
1348 isl_aff_free(data->div);
1349 isl_val_free(data->d);
1350 return 0;
1351}
1352
1353/* Check if "aff" involves any (implicit) modulo computations.
1354 * If so, remove them from aff and add expressions corresponding
1355 * to those modulo computations to *pos and/or *neg.
1356 * We only do this if the option ast_build_prefer_pdiv is set.
1357 *
1358 * "aff" is assumed to be an integer affine expression.
1359 *
1360 * A modulo expression is of the form
1361 *
1362 * a mod m = a - m * floor(a / m)
1363 *
1364 * To detect them in aff, we look for terms of the form
1365 *
1366 * f * m * floor(a / m)
1367 *
1368 * rewrite them as
1369 *
1370 * f * (a - (a mod m)) = f * a - f * (a mod m)
1371 *
1372 * and extract out -f * (a mod m).
1373 * In particular, if f > 0, we add (f * (a mod m)) to *neg.
1374 * If f < 0, we add ((-f) * (a mod m)) to *pos.
1375 */
1379{
1380 struct isl_extract_mod_data data = { build, aff, *pos, *neg };
1381 isl_ctx *ctx;
1382 isl_size n;
1383
1384 if (!aff)
1385 return NULL;
1386
1387 ctx = isl_aff_get_ctx(aff);
1389 return aff;
1390
1391 n = isl_aff_dim(data.aff, isl_dim_div);
1392 if (n < 0)
1393 return isl_aff_free(aff);
1394 for (data.i = 0; data.i < n; ++data.i) {
1395 data.v = isl_aff_get_coefficient_val(data.aff,
1396 isl_dim_div, data.i);
1397 if (!data.v)
1398 return isl_aff_free(aff);
1399 if (isl_val_is_zero(data.v) ||
1400 isl_val_is_one(data.v) || isl_val_is_negone(data.v)) {
1401 isl_val_free(data.v);
1402 continue;
1403 }
1404 if (extract_modulo(&data) < 0)
1405 data.aff = isl_aff_free(data.aff);
1406 isl_val_free(data.v);
1407 if (!data.aff)
1408 break;
1409 }
1410
1411 if (data.add)
1412 data.aff = isl_aff_add(data.aff, data.add);
1413
1414 *pos = data.pos;
1415 *neg = data.neg;
1416 return data.aff;
1417}
1418
1419/* Call "fn" on every non-zero coefficient of "aff",
1420 * passing it in the type of dimension (in terms of the domain),
1421 * the position and the value, as long as "fn" returns isl_bool_true.
1422 * If "reverse" is set, then the coefficients are considered in reverse order
1423 * within each type.
1424 */
1426 int reverse,
1428 void *user),
1429 void *user)
1430{
1431 int i, j;
1434 isl_val *v;
1435
1436 for (i = 0; i < 3; ++i) {
1437 isl_size n;
1438
1439 n = isl_aff_dim(aff, t[i]);
1440 if (n < 0)
1441 return isl_bool_error;
1442 for (j = 0; j < n; ++j) {
1443 isl_bool ok;
1444 int pos;
1445
1446 pos = reverse ? n - 1 - j : j;
1448 ok = isl_val_is_zero(v);
1449 if (ok >= 0 && !ok)
1450 ok = fn(l[i], pos, v, user);
1451 else
1452 isl_val_free(v);
1453 if (ok < 0 || !ok)
1454 return ok;
1455 }
1456 }
1457
1458 return isl_bool_true;
1459}
1460
1461/* Internal data structure for extract_rational.
1462 *
1463 * "d" is the denominator of the original affine expression.
1464 * "ls" is its domain local space.
1465 * "rat" collects the rational part.
1466 */
1473
1474/* Given a non-zero term in an affine expression equal to "v" times
1475 * the variable of type "type" at position "pos",
1476 * add it to data->rat if "v" is not a multiple of data->d.
1477 */
1479 __isl_take isl_val *v, void *user)
1480{
1481 struct isl_ast_extract_rational_data *data = user;
1482 isl_aff *rat;
1483
1484 if (isl_val_is_divisible_by(v, data->d)) {
1485 isl_val_free(v);
1486 return isl_bool_true;
1487 }
1490 data->rat = isl_aff_add(data->rat, rat);
1491 return isl_bool_true;
1492}
1493
1494/* Check if aff involves any non-integer coefficients.
1495 * If so, split aff into
1496 *
1497 * aff = aff1 + (aff2 / d)
1498 *
1499 * with both aff1 and aff2 having only integer coefficients.
1500 * Return aff1 and add (aff2 / d) to *expr.
1501 */
1504{
1505 struct isl_ast_extract_rational_data data = { NULL };
1506 isl_ast_expr *rat_expr;
1507 isl_val *v;
1508
1509 if (!aff)
1510 return NULL;
1512 if (!data.d)
1513 goto error;
1514 if (isl_val_is_one(data.d)) {
1515 isl_val_free(data.d);
1516 return aff;
1517 }
1518
1520
1523
1524 if (every_non_zero_coefficient(aff, 0, &add_rational, &data) < 0)
1525 goto error;
1526
1528 if (isl_val_is_divisible_by(v, data.d)) {
1529 isl_val_free(v);
1530 } else {
1531 isl_aff *rat_0;
1532
1534 data.rat = isl_aff_add(data.rat, rat_0);
1535 }
1536
1538
1541
1542 rat_expr = div_mod(isl_ast_expr_op_div, data.rat, data.d, build);
1543 *expr = ast_expr_add(*expr, rat_expr);
1544
1545 return aff;
1546error:
1547 isl_aff_free(data.rat);
1550 isl_val_free(data.d);
1551 return NULL;
1552}
1553
1554/* Internal data structure for isl_ast_expr_from_aff.
1555 *
1556 * "term" contains the information for adding a term.
1557 * "expr" collects the results.
1558 */
1563
1564/* Given a non-zero term in an affine expression equal to "v" times
1565 * the variable of type "type" at position "pos",
1566 * add the corresponding AST expression to data->expr.
1567 */
1569 __isl_take isl_val *v, void *user)
1570{
1571 struct isl_ast_add_terms_data *data = user;
1572
1573 data->expr =
1574 isl_ast_expr_add_term(data->expr, type, pos, v, data->term);
1575
1576 return isl_bool_true;
1577}
1578
1579/* Add terms to "expr" for each variable in "aff".
1580 * The result is simplified in terms of data->build->domain.
1581 */
1584{
1585 struct isl_ast_add_terms_data terms_data = { data, expr };
1586
1587 if (every_non_zero_coefficient(aff, 0, &add_term, &terms_data) < 0)
1588 return isl_ast_expr_free(terms_data.expr);
1589
1590 return terms_data.expr;
1591}
1592
1593/* Construct an isl_ast_expr that evaluates the affine expression "aff".
1594 * The result is simplified in terms of build->domain.
1595 *
1596 * We first extract hidden modulo computations from the affine expression
1597 * and then add terms for each variable with a non-zero coefficient.
1598 * Finally, if the affine expression has a non-trivial denominator,
1599 * we divide the resulting isl_ast_expr by this denominator.
1600 */
1603{
1604 isl_ctx *ctx = isl_aff_get_ctx(aff);
1605 isl_ast_expr *expr, *expr_neg;
1606 struct isl_ast_add_term_data term_data;
1607
1608 if (!aff)
1609 return NULL;
1610
1611 expr = isl_ast_expr_alloc_int_si(ctx, 0);
1612 expr_neg = isl_ast_expr_alloc_int_si(ctx, 0);
1613
1614 aff = extract_rational(aff, &expr, build);
1615
1616 aff = extract_modulos(aff, &expr, &expr_neg, build);
1617 expr = ast_expr_sub(expr, expr_neg);
1618
1619 term_data.build = build;
1621 term_data.cst = isl_aff_get_constant_val(aff);
1622 expr = add_terms(expr, aff, &term_data);
1623
1624 expr = isl_ast_expr_add_int(expr, term_data.cst);
1625 isl_local_space_free(term_data.ls);
1626
1628 return expr;
1629}
1630
1631/* Internal data structure for coefficients_of_sign.
1632 *
1633 * "sign" is the sign of the coefficients that should be retained.
1634 * "aff" is the affine expression of which some coefficients are zeroed out.
1635 */
1640
1641/* Clear the specified coefficient of data->aff if the value "v"
1642 * does not have the required sign.
1643 */
1645 __isl_take isl_val *v, void *user)
1646{
1648
1649 if (type == isl_dim_set)
1650 type = isl_dim_in;
1651 if (data->sign * isl_val_sgn(v) < 0)
1652 data->aff = isl_aff_set_coefficient_si(data->aff, type, pos, 0);
1653 isl_val_free(v);
1654
1655 return isl_bool_true;
1656}
1657
1658/* Extract the coefficients of "aff" (excluding the constant term)
1659 * that have the given sign.
1660 *
1661 * Take a copy of "aff" and clear the coefficients that do not have
1662 * the required sign.
1663 * Consider the coefficients in reverse order since clearing
1664 * the coefficient of an integer division in data.aff
1665 * could result in the removal of that integer division from data.aff,
1666 * changing the positions of all subsequent integer divisions of data.aff,
1667 * while those of "aff" remain the same.
1668 */
1670 int sign)
1671{
1673
1674 data.sign = sign;
1675 data.aff = isl_aff_copy(aff);
1677 data.aff = isl_aff_free(data.aff);
1679
1680 data.aff = isl_aff_set_constant_si(data.aff, 0);
1681
1682 return data.aff;
1683}
1684
1685/* Should the constant term "v" be considered positive?
1686 *
1687 * A positive constant will be added to "pos" by the caller,
1688 * while a negative constant will be added to "neg".
1689 * If either "pos" or "neg" is exactly zero, then we prefer
1690 * to add the constant "v" to that side, irrespective of the sign of "v".
1691 * This results in slightly shorter expressions and may reduce the risk
1692 * of overflows.
1693 */
1696{
1697 isl_bool zero;
1698
1699 zero = ast_expr_is_zero(pos);
1700 if (zero < 0 || zero)
1701 return zero;
1702 zero = ast_expr_is_zero(neg);
1703 if (zero < 0 || zero)
1704 return isl_bool_not(zero);
1705 return isl_val_is_pos(v);
1706}
1707
1708/* Check if the equality
1709 *
1710 * aff = 0
1711 *
1712 * represents a stride constraint on the integer division "pos".
1713 *
1714 * In particular, if the integer division "pos" is equal to
1715 *
1716 * floor(e/d)
1717 *
1718 * then check if aff is equal to
1719 *
1720 * e - d floor(e/d)
1721 *
1722 * or its opposite.
1723 *
1724 * If so, the equality is exactly
1725 *
1726 * e mod d = 0
1727 *
1728 * Note that in principle we could also accept
1729 *
1730 * e - d floor(e'/d)
1731 *
1732 * where e and e' differ by a constant.
1733 */
1735{
1736 isl_aff *div;
1737 isl_val *c, *d;
1738 isl_bool eq;
1739
1740 div = isl_aff_get_div(aff, pos);
1743 eq = isl_val_abs_eq(c, d);
1744 if (eq >= 0 && eq) {
1745 aff = isl_aff_copy(aff);
1747 div = isl_aff_scale_val(div, d);
1748 if (isl_val_is_pos(c))
1749 div = isl_aff_neg(div);
1750 eq = isl_aff_plain_is_equal(div, aff);
1752 } else
1753 isl_val_free(d);
1754 isl_val_free(c);
1755 isl_aff_free(div);
1756
1757 return eq;
1758}
1759
1760/* Are all coefficients of "aff" (zero or) negative?
1761 */
1763{
1764 int i;
1765 isl_size n;
1766
1768 if (n < 0)
1769 return isl_bool_error;
1770 for (i = 0; i < n; ++i)
1772 return isl_bool_false;
1773
1775 if (n < 0)
1776 return isl_bool_error;
1777 for (i = 0; i < n; ++i)
1779 return isl_bool_false;
1780
1781 return isl_bool_true;
1782}
1783
1784/* Give an equality of the form
1785 *
1786 * aff = e - d floor(e/d) = 0
1787 *
1788 * or
1789 *
1790 * aff = -e + d floor(e/d) = 0
1791 *
1792 * with the integer division "pos" equal to floor(e/d),
1793 * construct the AST expression
1794 *
1795 * (isl_ast_expr_op_eq,
1796 * (isl_ast_expr_op_zdiv_r, expr(e), expr(d)), expr(0))
1797 *
1798 * If e only has negative coefficients, then construct
1799 *
1800 * (isl_ast_expr_op_eq,
1801 * (isl_ast_expr_op_zdiv_r, expr(-e), expr(d)), expr(0))
1802 *
1803 * instead.
1804 */
1807{
1809 isl_ctx *ctx;
1810 isl_val *c;
1811 isl_ast_expr *expr, *cst;
1812
1813 if (!aff)
1814 return NULL;
1815
1816 ctx = isl_aff_get_ctx(aff);
1817
1820
1822 if (all_neg < 0)
1823 aff = isl_aff_free(aff);
1824 else if (all_neg)
1825 aff = isl_aff_neg(aff);
1826
1828 expr = isl_ast_expr_from_aff(aff, build);
1829
1831 cst = isl_ast_expr_alloc_int_si(ctx, 0);
1833
1834 return expr;
1835}
1836
1837/* Construct an isl_ast_expr evaluating
1838 *
1839 * "expr_pos" == "expr_neg", if "eq" is set, or
1840 * "expr_pos" >= "expr_neg", if "eq" is not set
1841 *
1842 * However, if "expr_pos" is an integer constant (and "expr_neg" is not),
1843 * then the two expressions are interchanged. This ensures that,
1844 * e.g., "i <= 5" is constructed rather than "5 >= i".
1845 */
1847 __isl_take isl_ast_expr *expr_pos, __isl_take isl_ast_expr *expr_neg)
1848{
1849 isl_ast_expr *expr;
1851 int pos_is_cst, neg_is_cst;
1852
1853 pos_is_cst = isl_ast_expr_get_type(expr_pos) == isl_ast_expr_int;
1854 neg_is_cst = isl_ast_expr_get_type(expr_neg) == isl_ast_expr_int;
1855 if (pos_is_cst && !neg_is_cst) {
1857 expr = isl_ast_expr_alloc_binary(type, expr_neg, expr_pos);
1858 } else {
1860 expr = isl_ast_expr_alloc_binary(type, expr_pos, expr_neg);
1861 }
1862
1863 return expr;
1864}
1865
1866/* Construct an isl_ast_expr that evaluates the condition "aff" == 0
1867 * (if "eq" is set) or "aff" >= 0 (otherwise).
1868 * The result is simplified in terms of build->domain.
1869 *
1870 * We first extract hidden modulo computations from "aff"
1871 * and then collect all the terms with a positive coefficient in cons_pos
1872 * and the terms with a negative coefficient in cons_neg.
1873 *
1874 * The result is then essentially of the form
1875 *
1876 * (isl_ast_expr_op_ge, expr(pos), expr(-neg)))
1877 *
1878 * or
1879 *
1880 * (isl_ast_expr_op_eq, expr(pos), expr(-neg)))
1881 *
1882 * However, if there are no terms with positive coefficients (or no terms
1883 * with negative coefficients), then the constant term is added to "pos"
1884 * (or "neg"), ignoring the sign of the constant term.
1885 */
1888{
1889 isl_bool cst_is_pos;
1890 isl_ctx *ctx;
1891 isl_ast_expr *expr_pos;
1892 isl_ast_expr *expr_neg;
1893 isl_aff *aff_pos, *aff_neg;
1894 struct isl_ast_add_term_data data;
1895
1896 ctx = isl_aff_get_ctx(aff);
1897 expr_pos = isl_ast_expr_alloc_int_si(ctx, 0);
1898 expr_neg = isl_ast_expr_alloc_int_si(ctx, 0);
1899
1900 aff = extract_modulos(aff, &expr_pos, &expr_neg, build);
1901
1902 data.build = build;
1905
1906 aff_pos = coefficients_of_sign(isl_aff_copy(aff), 1);
1907 aff_neg = isl_aff_neg(coefficients_of_sign(aff, -1));
1908
1909 expr_pos = add_terms(expr_pos, aff_pos, &data);
1910 data.cst = isl_val_neg(data.cst);
1911 expr_neg = add_terms(expr_neg, aff_neg, &data);
1912 data.cst = isl_val_neg(data.cst);
1914
1915 cst_is_pos =
1916 constant_is_considered_positive(data.cst, expr_pos, expr_neg);
1917 if (cst_is_pos < 0)
1918 expr_pos = isl_ast_expr_free(expr_pos);
1919
1920 if (cst_is_pos) {
1921 expr_pos = isl_ast_expr_add_int(expr_pos, data.cst);
1922 } else {
1923 data.cst = isl_val_neg(data.cst);
1924 expr_neg = isl_ast_expr_add_int(expr_neg, data.cst);
1925 }
1926
1927 isl_aff_free(aff_pos);
1928 isl_aff_free(aff_neg);
1929 return construct_constraint_expr(eq, expr_pos, expr_neg);
1930}
1931
1932/* Construct an isl_ast_expr that evaluates the condition "constraint".
1933 * The result is simplified in terms of build->domain.
1934 *
1935 * We first check if the constraint is an equality of the form
1936 *
1937 * e - d floor(e/d) = 0
1938 *
1939 * i.e.,
1940 *
1941 * e mod d = 0
1942 *
1943 * If so, we convert it to
1944 *
1945 * (isl_ast_expr_op_eq,
1946 * (isl_ast_expr_op_zdiv_r, expr(e), expr(d)), expr(0))
1947 */
1950{
1951 int i;
1952 isl_size n;
1953 isl_aff *aff;
1954 isl_bool eq;
1955
1956 aff = isl_constraint_get_aff(constraint);
1957 eq = isl_constraint_is_equality(constraint);
1958 isl_constraint_free(constraint);
1959 if (eq < 0)
1960 goto error;
1961
1963 if (n < 0)
1964 aff = isl_aff_free(aff);
1965 if (eq && n > 0)
1966 for (i = 0; i < n; ++i) {
1967 isl_bool is_stride;
1968 is_stride = is_stride_constraint(aff, i);
1969 if (is_stride < 0)
1970 goto error;
1971 if (is_stride)
1973 }
1974
1976error:
1978 return NULL;
1979}
1980
1981/* Are "set" and "bset" disjoint?
1982 */
1985{
1986 isl_set *set2;
1987 isl_bool disjoint;
1988
1990 disjoint = isl_set_is_disjoint(set, set2);
1992
1993 return disjoint;
1994}
1995
1996/* Wrapper around isl_constraint_cmp_last_non_zero for use
1997 * as a callback to isl_constraint_list_sort.
1998 * If isl_constraint_cmp_last_non_zero cannot tell the constraints
1999 * apart, then use isl_constraint_plain_cmp instead.
2000 */
2003{
2004 int cmp;
2005
2007 if (cmp != 0)
2008 return cmp;
2009 return isl_constraint_plain_cmp(a, b);
2010}
2011
2012/* Construct an isl_ast_expr that evaluates the conditions defining "bset".
2013 * The result is simplified in terms of build->domain.
2014 *
2015 * If "bset" is empty (within the build domain), then return the expression "0".
2016 *
2017 * If "bset" is not bounded by any constraint, then we construct
2018 * the expression "1", i.e., "true".
2019 *
2020 * Otherwise, we sort the constraints, putting constraints that involve
2021 * integer divisions after those that do not, and construct an "and"
2022 * of the ast expressions of the individual constraints.
2023 *
2024 * Each constraint is added to the generated constraints of the build
2025 * after it has been converted to an AST expression so that it can be used
2026 * to simplify the following constraints. This may change the truth value
2027 * of subsequent constraints that do not satisfy the earlier constraints,
2028 * but this does not affect the outcome of the conjunction as it is
2029 * only true if all the conjuncts are true (no matter in what order
2030 * they are evaluated). In particular, the constraints that do not
2031 * involve integer divisions may serve to simplify some constraints
2032 * that do involve integer divisions.
2033 */
2036{
2037 int i;
2038 isl_bool disjoint;
2039 isl_size n;
2040 isl_constraint *c;
2041 isl_constraint_list *list;
2043 isl_set *set, *domain;
2044
2046 disjoint = is_disjoint(domain, bset);
2048
2049 if (disjoint < 0) {
2050 build = NULL;
2051 } else if (disjoint) {
2053 isl_basic_set_free(bset);
2055 }
2056
2058 isl_basic_set_free(bset);
2059 list = isl_constraint_list_sort(list, &cmp_constraint, NULL);
2060 n = isl_constraint_list_n_constraint(list);
2061 if (n < 0)
2062 build = NULL;
2063 if (n == 0) {
2064 isl_ctx *ctx = isl_constraint_list_get_ctx(list);
2065 isl_constraint_list_free(list);
2066 return isl_ast_expr_alloc_int_si(ctx, 1);
2067 }
2068
2070
2071 c = isl_constraint_list_get_constraint(list, 0);
2076
2077 for (i = 1; i < n; ++i) {
2078 isl_ast_expr *expr;
2079
2080 c = isl_constraint_list_get_constraint(list, i);
2085 res = isl_ast_expr_and(res, expr);
2086 }
2087
2088 isl_constraint_list_free(list);
2090 return res;
2091}
2092
2093/* Construct an isl_ast_expr that evaluates the conditions defining "set".
2094 * The result is simplified in terms of build->domain.
2095 *
2096 * If "set" is an (obviously) empty set, then return the expression "0".
2097 *
2098 * If there are multiple disjuncts in the description of the set,
2099 * then subsequent disjuncts are simplified in a context where
2100 * the previous disjuncts have been removed from build->domain.
2101 * In particular, constraints that ensure that there is no overlap
2102 * with these previous disjuncts, can be removed.
2103 * This is mostly useful for disjuncts that are only defined by
2104 * a single constraint (relative to the build domain) as the opposite
2105 * of that single constraint can then be removed from the other disjuncts.
2106 * In order not to increase the number of disjuncts in the build domain
2107 * after subtracting the previous disjuncts of "set", the simple hull
2108 * is computed after taking the difference with each of these disjuncts.
2109 * This means that constraints that prevent overlap with a union
2110 * of multiple previous disjuncts are not removed.
2111 *
2112 * "set" lives in the internal schedule space.
2113 */
2116{
2117 int i;
2118 isl_size n;
2119 isl_basic_set *bset;
2120 isl_basic_set_list *list;
2121 isl_set *domain;
2123
2126
2127 n = isl_basic_set_list_n_basic_set(list);
2128 if (n < 0)
2129 build = NULL;
2130 if (n == 0) {
2132 isl_basic_set_list_free(list);
2134 }
2135
2137
2138 bset = isl_basic_set_list_get_basic_set(list, 0);
2141
2142 for (i = 1; i < n; ++i) {
2143 isl_ast_expr *expr;
2144 isl_set *rest;
2145
2149 bset = isl_basic_set_list_get_basic_set(list, i);
2151 bset = isl_basic_set_gist(bset,
2154 res = ast_expr_or(res, expr);
2155 }
2156
2159 isl_basic_set_list_free(list);
2160 return res;
2161}
2162
2163/* Construct an isl_ast_expr that evaluates the conditions defining "set".
2164 * The result is simplified in terms of build->domain.
2165 *
2166 * If "set" is an (obviously) empty set, then return the expression "0".
2167 *
2168 * "set" lives in the external schedule space.
2169 *
2170 * The internal AST expression generation assumes that there are
2171 * no unknown divs, so make sure an explicit representation is available.
2172 * Since the set comes from the outside, it may have constraints that
2173 * are redundant with respect to the build domain. Remove them first.
2174 */
2193
2194/* State of data about previous pieces in
2195 * isl_ast_build_expr_from_pw_aff_internal.
2196 *
2197 * isl_state_none: no data about previous pieces
2198 * isl_state_single: data about a single previous piece
2199 * isl_state_min: data represents minimum of several pieces
2200 * isl_state_max: data represents maximum of several pieces
2201 */
2208
2209/* Internal date structure representing a single piece in the input of
2210 * isl_ast_build_expr_from_pw_aff_internal.
2211 *
2212 * If "state" is isl_state_none, then "set_list" and "aff_list" are not used.
2213 * If "state" is isl_state_single, then "set_list" and "aff_list" contain the
2214 * single previous subpiece.
2215 * If "state" is isl_state_min, then "set_list" and "aff_list" contain
2216 * a sequence of several previous subpieces that are equal to the minimum
2217 * of the entries in "aff_list" over the union of "set_list"
2218 * If "state" is isl_state_max, then "set_list" and "aff_list" contain
2219 * a sequence of several previous subpieces that are equal to the maximum
2220 * of the entries in "aff_list" over the union of "set_list"
2221 *
2222 * During the construction of the pieces, "set" is NULL.
2223 * After the construction, "set" is set to the union of the elements
2224 * in "set_list", at which point "set_list" is set to NULL.
2225 */
2232
2233/* Internal data structure for isl_ast_build_expr_from_pw_aff_internal.
2234 *
2235 * "build" specifies the domain against which the result is simplified.
2236 * "dom" is the domain of the entire isl_pw_aff.
2237 *
2238 * "n" is the number of pieces constructed already.
2239 * In particular, during the construction of the pieces, "n" points to
2240 * the piece that is being constructed. After the construction of the
2241 * pieces, "n" is set to the total number of pieces.
2242 * "max" is the total number of allocated entries.
2243 * "p" contains the individual pieces.
2244 */
2253
2254/* Initialize "data" based on "build" and "pa".
2255 */
2258{
2259 isl_size n;
2260 isl_ctx *ctx;
2261
2262 ctx = isl_pw_aff_get_ctx(pa);
2264 if (n < 0)
2265 return isl_stat_error;
2266 if (n == 0)
2268 "cannot handle void expression", return isl_stat_error);
2269 data->max = n;
2270 data->p = isl_calloc_array(ctx, struct isl_from_pw_aff_piece, n);
2271 if (!data->p)
2272 return isl_stat_error;
2273 data->build = build;
2275 data->n = 0;
2276
2277 return isl_stat_ok;
2278}
2279
2280/* Free all memory allocated for "data".
2281 */
2283{
2284 int i;
2285
2286 isl_set_free(data->dom);
2287 if (!data->p)
2288 return;
2289
2290 for (i = 0; i < data->max; ++i) {
2291 isl_set_free(data->p[i].set);
2292 isl_set_list_free(data->p[i].set_list);
2293 isl_aff_list_free(data->p[i].aff_list);
2294 }
2295 free(data->p);
2296}
2297
2298/* Initialize the current entry of "data" to an unused piece.
2299 */
2300static void set_none(struct isl_from_pw_aff_data *data)
2301{
2302 data->p[data->n].state = isl_state_none;
2303 data->p[data->n].set_list = NULL;
2304 data->p[data->n].aff_list = NULL;
2305}
2306
2307/* Store "set" and "aff" in the current entry of "data" as a single subpiece.
2308 */
2309static void set_single(struct isl_from_pw_aff_data *data,
2311{
2312 data->p[data->n].state = isl_state_single;
2313 data->p[data->n].set_list = isl_set_list_from_set(set);
2314 data->p[data->n].aff_list = isl_aff_list_from_aff(aff);
2315}
2316
2317/* Extend the current entry of "data" with "set" and "aff"
2318 * as a minimum expression.
2319 */
2322{
2323 int n = data->n;
2324 data->p[n].state = isl_state_min;
2325 data->p[n].set_list = isl_set_list_add(data->p[n].set_list, set);
2326 data->p[n].aff_list = isl_aff_list_add(data->p[n].aff_list, aff);
2327
2328 if (!data->p[n].set_list || !data->p[n].aff_list)
2329 return isl_stat_error;
2330 return isl_stat_ok;
2331}
2332
2333/* Extend the current entry of "data" with "set" and "aff"
2334 * as a maximum expression.
2335 */
2338{
2339 int n = data->n;
2340 data->p[n].state = isl_state_max;
2341 data->p[n].set_list = isl_set_list_add(data->p[n].set_list, set);
2342 data->p[n].aff_list = isl_aff_list_add(data->p[n].aff_list, aff);
2343
2344 if (!data->p[n].set_list || !data->p[n].aff_list)
2345 return isl_stat_error;
2346 return isl_stat_ok;
2347}
2348
2349/* Extend the domain of the current entry of "data", which is assumed
2350 * to contain a single subpiece, with "set". If "replace" is set,
2351 * then also replace the affine function by "aff". Otherwise,
2352 * simply free "aff".
2353 */
2356{
2357 int n = data->n;
2358 isl_set *set_n;
2359
2360 set_n = isl_set_list_get_set(data->p[n].set_list, 0);
2361 set_n = isl_set_union(set_n, set);
2362 data->p[n].set_list =
2363 isl_set_list_set_set(data->p[n].set_list, 0, set_n);
2364
2365 if (replace)
2366 data->p[n].aff_list =
2367 isl_aff_list_set_aff(data->p[n].aff_list, 0, aff);
2368 else
2370
2371 if (!data->p[n].set_list || !data->p[n].aff_list)
2372 return isl_stat_error;
2373 return isl_stat_ok;
2374}
2375
2376/* Construct an isl_ast_expr from "list" within "build".
2377 * If "state" is isl_state_single, then "list" contains a single entry and
2378 * an isl_ast_expr is constructed for that entry.
2379 * Otherwise a min or max expression is constructed from "list"
2380 * depending on "state".
2381 */
2383 __isl_take isl_aff_list *list, enum isl_from_pw_aff_state state,
2385{
2386 int i;
2387 isl_size n;
2388 isl_aff *aff;
2389 isl_ast_expr *expr = NULL;
2390 enum isl_ast_expr_op_type op_type;
2391
2392 if (state == isl_state_single) {
2393 aff = isl_aff_list_get_aff(list, 0);
2394 isl_aff_list_free(list);
2395 return isl_ast_expr_from_aff(aff, build);
2396 }
2397 n = isl_aff_list_n_aff(list);
2398 if (n < 0)
2399 goto error;
2402 expr = isl_ast_expr_alloc_op(isl_ast_build_get_ctx(build), op_type, n);
2403
2404 for (i = 0; i < n; ++i) {
2405 isl_ast_expr *expr_i;
2406
2407 aff = isl_aff_list_get_aff(list, i);
2408 expr_i = isl_ast_expr_from_aff(aff, build);
2409 expr = isl_ast_expr_op_add_arg(expr, expr_i);
2410 }
2411
2412 isl_aff_list_free(list);
2413 return expr;
2414error:
2415 isl_aff_list_free(list);
2416 isl_ast_expr_free(expr);
2417 return NULL;
2418}
2419
2420/* Extend the list of expressions in "next" to take into account
2421 * the piece at position "pos" in "data", allowing for a further extension
2422 * for the next piece(s).
2423 * In particular, "next" is extended with a select operation that selects
2424 * an isl_ast_expr corresponding to data->aff_list on data->set and
2425 * to an expression that will be filled in by later calls.
2426 * Return a pointer to the arguments of this select operation.
2427 * Afterwards, the state of "data" is set to isl_state_none.
2428 *
2429 * The constraints of data->set are added to the generated
2430 * constraints of the build such that they can be exploited to simplify
2431 * the AST expression constructed from data->aff_list.
2432 */
2433static isl_ast_expr_list **add_intermediate_piece(
2434 struct isl_from_pw_aff_data *data,
2435 int pos, isl_ast_expr_list **next)
2436{
2437 isl_ctx *ctx;
2438 isl_ast_build *build;
2440 isl_set *set, *gist;
2441
2442 set = data->p[pos].set;
2443 data->p[pos].set = NULL;
2444 ctx = isl_ast_build_get_ctx(data->build);
2449 build = isl_ast_build_copy(data->build);
2450 build = isl_ast_build_restrict_generated(build, set);
2452 data->p[pos].state, build);
2453 data->p[pos].aff_list = NULL;
2454 isl_ast_build_free(build);
2456 data->p[pos].state = isl_state_none;
2457 if (!ternary)
2458 return NULL;
2459
2460 *next = isl_ast_expr_list_add(*next, ternary);
2461 return &ternary->u.op.args;
2462}
2463
2464/* Extend the list of expressions in "next" to take into account
2465 * the final piece, located at position "pos" in "data".
2466 * In particular, "next" is extended with an expression
2467 * to evaluate data->aff_list and the domain is ignored.
2468 * Return isl_stat_ok on success and isl_stat_error on failure.
2469 *
2470 * The constraints of data->set are however added to the generated
2471 * constraints of the build such that they can be exploited to simplify
2472 * the AST expression constructed from data->aff_list.
2473 */
2475 int pos, isl_ast_expr_list **next)
2476{
2477 isl_ast_build *build;
2478 isl_ast_expr *last;
2479
2480 if (data->p[pos].state == isl_state_none)
2482 "cannot handle void expression", return isl_stat_error);
2483
2484 build = isl_ast_build_copy(data->build);
2485 build = isl_ast_build_restrict_generated(build, data->p[pos].set);
2486 data->p[pos].set = NULL;
2487 last = ast_expr_from_aff_list(data->p[pos].aff_list,
2488 data->p[pos].state, build);
2489 *next = isl_ast_expr_list_add(*next, last);
2490 data->p[pos].aff_list = NULL;
2491 isl_ast_build_free(build);
2492 data->p[pos].state = isl_state_none;
2493 if (!*next)
2494 return isl_stat_error;
2495
2496 return isl_stat_ok;
2497}
2498
2499/* Return -1 if the piece "p1" should be sorted before "p2"
2500 * and 1 if it should be sorted after "p2".
2501 * Return 0 if they do not need to be sorted in a specific order.
2502 *
2503 * Pieces are sorted according to the number of disjuncts
2504 * in their domains.
2505 */
2506static int sort_pieces_cmp(const void *p1, const void *p2, void *arg)
2507{
2508 const struct isl_from_pw_aff_piece *piece1 = p1;
2509 const struct isl_from_pw_aff_piece *piece2 = p2;
2510 isl_size n1, n2;
2511
2512 n1 = isl_set_n_basic_set(piece1->set);
2513 n2 = isl_set_n_basic_set(piece2->set);
2514
2515 return n1 - n2;
2516}
2517
2518/* Construct an isl_ast_expr from the pieces in "data".
2519 * Return the result or NULL on failure.
2520 *
2521 * When this function is called, data->n points to the current piece.
2522 * If this is an effective piece, then first increment data->n such
2523 * that data->n contains the number of pieces.
2524 * The "set_list" fields are subsequently replaced by the corresponding
2525 * "set" fields, after which the pieces are sorted according to
2526 * the number of disjuncts in these "set" fields.
2527 *
2528 * Construct intermediate AST expressions for the initial pieces and
2529 * finish off with the final pieces.
2530 *
2531 * Any piece that is not the very first is added to the list of arguments
2532 * of the previously constructed piece.
2533 * In order not to have to special case the first piece,
2534 * an extra list is created to hold the final result.
2535 */
2537{
2538 int i;
2539 isl_ctx *ctx;
2540 isl_ast_expr_list *res_list;
2541 isl_ast_expr_list **next = &res_list;
2543
2544 if (data->p[data->n].state != isl_state_none)
2545 data->n++;
2546 ctx = isl_ast_build_get_ctx(data->build);
2547 if (data->n == 0)
2549 "cannot handle void expression", return NULL);
2550
2551 for (i = 0; i < data->n; ++i) {
2552 data->p[i].set = isl_set_list_union(data->p[i].set_list);
2553 if (data->p[i].state != isl_state_single)
2554 data->p[i].set = isl_set_coalesce(data->p[i].set);
2555 data->p[i].set_list = NULL;
2556 }
2557
2558 if (isl_sort(data->p, data->n, sizeof(data->p[0]),
2559 &sort_pieces_cmp, NULL) < 0)
2560 return NULL;
2561
2562 res_list = isl_ast_expr_list_alloc(ctx, 1);
2563 if (!res_list)
2564 return NULL;
2565 for (i = 0; i + 1 < data->n; ++i) {
2566 next = add_intermediate_piece(data, i, next);
2567 if (!next)
2568 goto error;
2569 }
2570
2571 if (add_last_piece(data, data->n - 1, next) < 0)
2572 goto error;
2573
2574 res = isl_ast_expr_list_get_at(res_list, 0);
2575 isl_ast_expr_list_free(res_list);
2576 return res;
2577error:
2578 isl_ast_expr_list_free(res_list);
2579 return NULL;
2580}
2581
2582/* Is the domain of the current entry of "data", which is assumed
2583 * to contain a single subpiece, a subset of "set"?
2584 */
2587{
2589 isl_set *set_n;
2590
2591 set_n = isl_set_list_get_set(data->p[data->n].set_list, 0);
2592 subset = isl_set_is_subset(set_n, set);
2593 isl_set_free(set_n);
2594
2595 return subset;
2596}
2597
2598/* Is "aff" a rational expression, i.e., does it have a denominator
2599 * different from one?
2600 */
2602{
2603 isl_bool rational;
2604 isl_val *den;
2605
2607 rational = isl_bool_not(isl_val_is_one(den));
2608 isl_val_free(den);
2609
2610 return rational;
2611}
2612
2613/* Does "list" consist of a single rational affine expression?
2614 */
2616{
2617 isl_size n;
2618 isl_bool rational;
2619 isl_aff *aff;
2620
2621 n = isl_aff_list_n_aff(list);
2622 if (n < 0)
2623 return isl_bool_error;
2624 if (n != 1)
2625 return isl_bool_false;
2626 aff = isl_aff_list_get_aff(list, 0);
2627 rational = aff_is_rational(aff);
2629
2630 return rational;
2631}
2632
2633/* Can the list of subpieces in the last piece of "data" be extended with
2634 * "set" and "aff" based on "test"?
2635 * In particular, is it the case for each entry (set_i, aff_i) that
2636 *
2637 * test(aff, aff_i) holds on set_i, and
2638 * test(aff_i, aff) holds on set?
2639 *
2640 * "test" returns the set of elements where the tests holds, meaning
2641 * that test(aff_i, aff) holds on set if set is a subset of test(aff_i, aff).
2642 *
2643 * This function is used to detect min/max expressions.
2644 * If the ast_build_detect_min_max option is turned off, then
2645 * do not even try and perform any detection and return false instead.
2646 *
2647 * Rational affine expressions are not considered for min/max expressions
2648 * since the combined expression will be defined on the union of the domains,
2649 * while a rational expression may only yield integer values
2650 * on its own definition domain.
2651 */
2655 __isl_take isl_aff *aff2))
2656{
2657 int i;
2658 isl_size n;
2660 isl_ctx *ctx;
2661 isl_set *dom;
2662
2664 if (is_rational >= 0 && !is_rational)
2666 if (is_rational < 0 || is_rational)
2667 return isl_bool_not(is_rational);
2668
2669 ctx = isl_ast_build_get_ctx(data->build);
2671 return isl_bool_false;
2672
2673 n = isl_set_list_n_set(data->p[data->n].set_list);
2674 if (n < 0)
2675 return isl_bool_error;
2676
2677 dom = isl_ast_build_get_domain(data->build);
2679
2680 for (i = 0; i < n ; ++i) {
2681 isl_aff *aff_i;
2682 isl_set *valid;
2683 isl_set *dom, *required;
2684 isl_bool is_valid;
2685
2686 aff_i = isl_aff_list_get_aff(data->p[data->n].aff_list, i);
2687 valid = isl_set_from_basic_set(test(isl_aff_copy(aff), aff_i));
2688 required = isl_set_list_get_set(data->p[data->n].set_list, i);
2689 dom = isl_ast_build_get_domain(data->build);
2690 required = isl_set_intersect(dom, required);
2691 is_valid = isl_set_is_subset(required, valid);
2692 isl_set_free(required);
2693 isl_set_free(valid);
2694 if (is_valid < 0 || !is_valid) {
2696 return is_valid;
2697 }
2698
2699 aff_i = isl_aff_list_get_aff(data->p[data->n].aff_list, i);
2700 valid = isl_set_from_basic_set(test(aff_i, isl_aff_copy(aff)));
2701 is_valid = isl_set_is_subset(set, valid);
2702 isl_set_free(valid);
2703 if (is_valid < 0 || !is_valid) {
2705 return is_valid;
2706 }
2707 }
2708
2710 return isl_bool_true;
2711}
2712
2713/* Can the list of pieces in "data" be extended with "set" and "aff"
2714 * to form/preserve a minimum expression?
2715 * In particular, is it the case for each entry (set_i, aff_i) that
2716 *
2717 * aff >= aff_i on set_i, and
2718 * aff_i >= aff on set?
2719 */
2722{
2723 return extends(data, set, aff, &isl_aff_ge_basic_set);
2724}
2725
2726/* Can the list of pieces in "data" be extended with "set" and "aff"
2727 * to form/preserve a maximum expression?
2728 * In particular, is it the case for each entry (set_i, aff_i) that
2729 *
2730 * aff <= aff_i on set_i, and
2731 * aff_i <= aff on set?
2732 */
2735{
2736 return extends(data, set, aff, &isl_aff_le_basic_set);
2737}
2738
2739/* This function is called during the construction of an isl_ast_expr
2740 * that evaluates an isl_pw_aff.
2741 * If the last piece of "data" contains a single subpiece and
2742 * if its affine function is equal to "aff" on a part of the domain
2743 * that includes either "set" or the domain of that single subpiece,
2744 * then extend the domain of that single subpiece with "set".
2745 * If it was the original domain of the single subpiece where
2746 * the two affine functions are equal, then also replace
2747 * the affine function of the single subpiece by "aff".
2748 * If the last piece of "data" contains either a single subpiece
2749 * or a minimum, then check if this minimum expression can be extended
2750 * with (set, aff).
2751 * If so, extend the sequence and return.
2752 * Perform the same operation for maximum expressions.
2753 * If no such extension can be performed, then move to the next piece
2754 * in "data" (if the current piece contains any data), and then store
2755 * the current subpiece in the current piece of "data" for later handling.
2756 */
2758 __isl_take isl_aff *aff, void *user)
2759{
2760 struct isl_from_pw_aff_data *data = user;
2761 isl_bool test;
2762 enum isl_from_pw_aff_state state;
2763
2764 state = data->p[data->n].state;
2765 if (state == isl_state_single) {
2766 isl_aff *aff0;
2767 isl_set *eq;
2768 isl_bool subset1, subset2 = isl_bool_false;
2769 aff0 = isl_aff_list_get_aff(data->p[data->n].aff_list, 0);
2770 eq = isl_aff_eq_set(isl_aff_copy(aff), aff0);
2771 subset1 = isl_set_is_subset(set, eq);
2772 if (subset1 >= 0 && !subset1)
2773 subset2 = single_is_subset(data, eq);
2774 isl_set_free(eq);
2775 if (subset1 < 0 || subset2 < 0)
2776 goto error;
2777 if (subset1)
2778 return extend_domain(data, set, aff, 0);
2779 if (subset2)
2780 return extend_domain(data, set, aff, 1);
2781 }
2782 if (state == isl_state_single || state == isl_state_min) {
2783 test = extends_min(data, set, aff);
2784 if (test < 0)
2785 goto error;
2786 if (test)
2787 return extend_min(data, set, aff);
2788 }
2789 if (state == isl_state_single || state == isl_state_max) {
2790 test = extends_max(data, set, aff);
2791 if (test < 0)
2792 goto error;
2793 if (test)
2794 return extend_max(data, set, aff);
2795 }
2796 if (state != isl_state_none)
2797 data->n++;
2798 set_single(data, set, aff);
2799
2800 return isl_stat_ok;
2801error:
2804 return isl_stat_error;
2805}
2806
2807/* Construct an isl_ast_expr that evaluates "pa".
2808 * The result is simplified in terms of build->domain.
2809 *
2810 * The domain of "pa" lives in the internal schedule space.
2811 */
2814{
2815 struct isl_from_pw_aff_data data = { NULL };
2816 isl_ast_expr *res = NULL;
2817
2820 if (!pa)
2821 return NULL;
2822
2823 if (isl_from_pw_aff_data_init(&data, build, pa) < 0)
2824 goto error;
2825 set_none(&data);
2826
2828 res = build_pieces(&data);
2829
2832 return res;
2833error:
2836 return NULL;
2837}
2838
2839/* Construct an isl_ast_expr that evaluates "pa".
2840 * The result is simplified in terms of build->domain.
2841 *
2842 * The domain of "pa" lives in the external schedule space.
2843 */
2846{
2847 isl_ast_expr *expr;
2848 isl_bool needs_map;
2849
2851 if (needs_map < 0) {
2853 } else if (needs_map) {
2857 }
2859 return expr;
2860}
2861
2862/* Set the ids of the input dimensions of "mpa" to the iterator ids
2863 * of "build".
2864 *
2865 * The domain of "mpa" is assumed to live in the internal schedule domain.
2866 */
2869{
2870 int i;
2871 isl_size n;
2872
2873 n = isl_multi_pw_aff_dim(mpa, isl_dim_in);
2874 if (n < 0)
2875 return isl_multi_pw_aff_free(mpa);
2876 for (i = 0; i < n; ++i) {
2877 isl_id *id;
2878
2880 mpa = isl_multi_pw_aff_set_dim_id(mpa, isl_dim_in, i, id);
2881 }
2882
2883 return mpa;
2884}
2885
2886/* Construct an isl_ast_expr of type "type" with as first argument "arg0" and
2887 * the remaining arguments derived from "mpa".
2888 * That is, construct a call or access expression that calls/accesses "arg0"
2889 * with arguments/indices specified by "mpa".
2890 */
2894{
2895 int i;
2896 isl_size n;
2897 isl_ctx *ctx;
2898 isl_ast_expr *expr;
2899
2901
2902 n = isl_multi_pw_aff_dim(mpa, isl_dim_out);
2903 expr = n >= 0 ? isl_ast_expr_alloc_op(ctx, type, 1 + n) : NULL;
2904 expr = isl_ast_expr_op_add_arg(expr, arg0);
2905 for (i = 0; i < n; ++i) {
2906 isl_pw_aff *pa;
2908
2909 pa = isl_multi_pw_aff_get_pw_aff(mpa, i);
2911 expr = isl_ast_expr_op_add_arg(expr, arg);
2912 }
2913
2914 isl_multi_pw_aff_free(mpa);
2915 return expr;
2916}
2917
2921
2922/* Construct an isl_ast_expr that accesses the member specified by "mpa".
2923 * The range of "mpa" is assumed to be wrapped relation.
2924 * The domain of this wrapped relation specifies the structure being
2925 * accessed, while the range of this wrapped relation spacifies the
2926 * member of the structure being accessed.
2927 *
2928 * The domain of "mpa" is assumed to live in the internal schedule domain.
2929 */
2932{
2933 isl_id *id;
2935 isl_ast_expr *domain_expr, *expr;
2937
2938 domain = isl_multi_pw_aff_copy(mpa);
2939 domain = isl_multi_pw_aff_range_factor_domain(domain);
2941 type, domain);
2942 mpa = isl_multi_pw_aff_range_factor_range(mpa);
2943 if (!isl_multi_pw_aff_has_tuple_id(mpa, isl_dim_out))
2945 "missing field name", goto error);
2946 id = isl_multi_pw_aff_get_tuple_id(mpa, isl_dim_out);
2947 expr = isl_ast_expr_from_id(id);
2949 domain_expr, expr);
2950 return isl_ast_build_with_arguments(build, type, expr, mpa);
2951error:
2952 isl_multi_pw_aff_free(mpa);
2953 return NULL;
2954}
2955
2956/* Construct an isl_ast_expr of type "type" that calls or accesses
2957 * the element specified by "mpa".
2958 * The first argument is obtained from the output tuple name.
2959 * The remaining arguments are given by the piecewise affine expressions.
2960 *
2961 * If the range of "mpa" is a mapped relation, then we assume it
2962 * represents an access to a member of a structure.
2963 *
2964 * The domain of "mpa" is assumed to live in the internal schedule domain.
2965 */
2969{
2970 isl_ctx *ctx;
2971 isl_id *id;
2972 isl_ast_expr *expr;
2973
2974 if (!mpa)
2975 goto error;
2976
2978 isl_multi_pw_aff_range_is_wrapping(mpa))
2980
2981 mpa = set_iterator_names(build, mpa);
2982 if (!build || !mpa)
2983 goto error;
2984
2986
2987 if (isl_multi_pw_aff_has_tuple_id(mpa, isl_dim_out))
2988 id = isl_multi_pw_aff_get_tuple_id(mpa, isl_dim_out);
2989 else
2990 id = isl_id_alloc(ctx, "", NULL);
2991
2992 expr = isl_ast_expr_from_id(id);
2993 return isl_ast_build_with_arguments(build, type, expr, mpa);
2994error:
2995 isl_multi_pw_aff_free(mpa);
2996 return NULL;
2997}
2998
2999/* Construct an isl_ast_expr of type "type" that calls or accesses
3000 * the element specified by "pma".
3001 * The first argument is obtained from the output tuple name.
3002 * The remaining arguments are given by the piecewise affine expressions.
3003 *
3004 * The domain of "pma" is assumed to live in the internal schedule domain.
3005 */
3015
3016/* Construct an isl_ast_expr of type "type" that calls or accesses
3017 * the element specified by "mpa".
3018 * The first argument is obtained from the output tuple name.
3019 * The remaining arguments are given by the piecewise affine expressions.
3020 *
3021 * The domain of "mpa" is assumed to live in the external schedule domain.
3022 */
3026{
3027 isl_bool is_domain;
3028 isl_bool needs_map;
3029 isl_ast_expr *expr;
3030 isl_space *space_build, *space_mpa;
3031
3032 space_build = isl_ast_build_get_space(build, 0);
3033 space_mpa = isl_multi_pw_aff_get_space(mpa);
3034 is_domain = isl_space_tuple_is_equal(space_build, isl_dim_set,
3035 space_mpa, isl_dim_in);
3036 isl_space_free(space_build);
3037 isl_space_free(space_mpa);
3038 if (is_domain < 0)
3039 goto error;
3040 if (!is_domain)
3042 "spaces don't match", goto error);
3043
3045 if (needs_map < 0)
3046 goto error;
3047 if (needs_map) {
3051 }
3052
3054 return expr;
3055error:
3056 isl_multi_pw_aff_free(mpa);
3057 return NULL;
3058}
3059
3060/* Construct an isl_ast_expr that calls the domain element specified by "mpa".
3061 * The name of the function is obtained from the output tuple name.
3062 * The arguments are given by the piecewise affine expressions.
3063 *
3064 * The domain of "mpa" is assumed to live in the external schedule domain.
3065 */
3072
3073/* Construct an isl_ast_expr that accesses the array element specified by "mpa".
3074 * The name of the array is obtained from the output tuple name.
3075 * The index expressions are given by the piecewise affine expressions.
3076 *
3077 * The domain of "mpa" is assumed to live in the external schedule domain.
3078 */
3085
3086/* Construct an isl_ast_expr of type "type" that calls or accesses
3087 * the element specified by "pma".
3088 * The first argument is obtained from the output tuple name.
3089 * The remaining arguments are given by the piecewise affine expressions.
3090 *
3091 * The domain of "pma" is assumed to live in the external schedule domain.
3092 */
3102
3103/* Construct an isl_ast_expr that calls the domain element specified by "pma".
3104 * The name of the function is obtained from the output tuple name.
3105 * The arguments are given by the piecewise affine expressions.
3106 *
3107 * The domain of "pma" is assumed to live in the external schedule domain.
3108 */
3115
3116/* Construct an isl_ast_expr that accesses the array element specified by "pma".
3117 * The name of the array is obtained from the output tuple name.
3118 * The index expressions are given by the piecewise affine expressions.
3119 *
3120 * The domain of "pma" is assumed to live in the external schedule domain.
3121 */
3128
3129/* Construct an isl_ast_expr that calls the domain element
3130 * specified by "executed".
3131 *
3132 * "executed" is assumed to be single-valued, with a domain that lives
3133 * in the internal schedule space.
3134 */
static void replace(std::string &str, StringRef find, StringRef replace)
__isl_give isl_aff * isl_aff_add_constant_si(__isl_take isl_aff *aff, int v)
Definition isl_aff.c:1099
isl_ctx * isl_aff_get_ctx(__isl_keep isl_aff *aff)
Definition isl_aff.c:465
__isl_null isl_aff * isl_aff_free(__isl_take isl_aff *aff)
Definition isl_aff.c:449
isl_ctx * isl_pw_aff_get_ctx(__isl_keep isl_pw_aff *pwaff)
__isl_give isl_local_space * isl_aff_get_domain_local_space(__isl_keep isl_aff *aff)
Definition isl_aff.c:586
__isl_export __isl_give isl_pw_multi_aff * isl_pw_multi_aff_intersect_domain(__isl_take isl_pw_multi_aff *pma, __isl_take isl_set *set)
__isl_give isl_aff * isl_aff_val_on_domain(__isl_take isl_local_space *ls, __isl_take isl_val *val)
Definition isl_aff.c:331
__isl_give isl_aff * isl_aff_set_constant_si(__isl_take isl_aff *aff, int v)
Definition isl_aff.c:1160
__isl_give isl_val * isl_aff_get_coefficient_val(__isl_keep isl_aff *aff, enum isl_dim_type type, int pos)
Definition isl_aff.c:852
__isl_give isl_aff * isl_aff_var_on_domain(__isl_take isl_local_space *ls, enum isl_dim_type type, unsigned pos)
Definition isl_aff.c:370
__isl_overload __isl_give isl_pw_aff * isl_pw_aff_pullback_multi_aff(__isl_take isl_pw_aff *pa, __isl_take isl_multi_aff *ma)
__isl_export __isl_give isl_aff * isl_aff_neg(__isl_take isl_aff *aff)
Definition isl_aff.c:1451
__isl_overload __isl_give isl_aff * isl_aff_add_constant_val(__isl_take isl_aff *aff, __isl_take isl_val *v)
Definition isl_aff.c:1070
__isl_export isl_bool isl_aff_plain_is_equal(__isl_keep isl_aff *aff1, __isl_keep isl_aff *aff2)
Definition isl_aff.c:784
__isl_overload __isl_give isl_aff * isl_aff_scale_val(__isl_take isl_aff *aff, __isl_take isl_val *v)
Definition isl_aff.c:2075
__isl_give isl_val * isl_aff_get_denominator_val(__isl_keep isl_aff *aff)
Definition isl_aff.c:819
isl_stat isl_pw_aff_foreach_piece(__isl_keep isl_pw_aff *pwaff, isl_stat(*fn)(__isl_take isl_set *set, __isl_take isl_aff *aff, void *user), void *user)
__isl_give isl_aff * isl_aff_set_coefficient_si(__isl_take isl_aff *aff, enum isl_dim_type type, int pos, int v)
Definition isl_aff.c:1221
__isl_null isl_pw_aff * isl_pw_aff_free(__isl_take isl_pw_aff *pwaff)
__isl_overload __isl_give isl_aff * isl_aff_scale_down_val(__isl_take isl_aff *aff, __isl_take isl_val *v)
Definition isl_aff.c:2142
__isl_give isl_basic_set * isl_aff_ge_basic_set(__isl_take isl_aff *aff1, __isl_take isl_aff *aff2)
Definition isl_aff.c:2477
__isl_give isl_aff * isl_aff_copy(__isl_keep isl_aff *aff)
Definition isl_aff.c:145
__isl_give isl_aff * isl_aff_zero_on_domain(__isl_take isl_local_space *ls)
Definition isl_aff.c:235
isl_size isl_aff_dim(__isl_keep isl_aff *aff, enum isl_dim_type type)
Definition isl_aff.c:509
__isl_export __isl_give isl_aff * isl_aff_sub(__isl_take isl_aff *aff1, __isl_take isl_aff *aff2)
Definition isl_aff.c:2029
__isl_constructor __isl_give isl_multi_pw_aff * isl_multi_pw_aff_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma)
Definition isl_aff.c:7106
__isl_export __isl_give isl_val * isl_aff_get_constant_val(__isl_keep isl_aff *aff)
Definition isl_aff.c:834
__isl_give isl_pw_multi_aff * isl_pw_multi_aff_from_map(__isl_take isl_map *map)
Definition isl_aff.c:5617
__isl_export __isl_give isl_aff * isl_aff_add(__isl_take isl_aff *aff1, __isl_take isl_aff *aff2)
Definition isl_aff.c:1976
__isl_export __isl_give isl_set * isl_aff_eq_set(__isl_take isl_aff *aff1, __isl_take isl_aff *aff2)
Definition isl_aff.c:2567
int isl_aff_coefficient_sgn(__isl_keep isl_aff *aff, enum isl_dim_type type, int pos)
Definition isl_aff.c:882
__isl_give isl_basic_set * isl_aff_le_basic_set(__isl_take isl_aff *aff1, __isl_take isl_aff *aff2)
Definition isl_aff.c:2520
__isl_export __isl_give isl_pw_aff * isl_pw_aff_coalesce(__isl_take isl_pw_aff *pa)
isl_bool isl_aff_involves_dims(__isl_keep isl_aff *aff, enum isl_dim_type type, unsigned first, unsigned n)
__isl_give isl_aff * isl_aff_get_div(__isl_keep isl_aff *aff, int pos)
Definition isl_aff.c:1439
isl_size isl_pw_aff_n_piece(__isl_keep isl_pw_aff *pwaff)
__isl_export __isl_give isl_set * isl_pw_aff_domain(__isl_take isl_pw_aff *pwaff)
__isl_overload __isl_give isl_multi_pw_aff * isl_multi_pw_aff_pullback_multi_aff(__isl_take isl_multi_pw_aff *mpa, __isl_take isl_multi_aff *ma)
__isl_give isl_pw_aff * isl_pw_aff_copy(__isl_keep isl_pw_aff *pwaff)
__isl_give isl_aff * isl_aff_set_constant_val(__isl_take isl_aff *aff, __isl_take isl_val *v)
Definition isl_aff.c:932
struct isl_multi_aff isl_multi_aff
Definition aff_type.h:29
struct isl_multi_pw_aff isl_multi_pw_aff
Definition aff_type.h:43
__isl_null isl_ast_expr * isl_ast_expr_free(__isl_take isl_ast_expr *expr)
Definition isl_ast.c:243
__isl_give isl_ast_expr * isl_ast_expr_neg(__isl_take isl_ast_expr *expr)
Definition isl_ast.c:642
__isl_give isl_ast_expr * isl_ast_expr_or(__isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2)
Definition isl_ast.c:763
__isl_give isl_ast_expr * isl_ast_expr_mul(__isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2)
Definition isl_ast.c:710
__isl_give isl_ast_expr * isl_ast_expr_add(__isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2)
Definition isl_ast.c:694
__isl_give isl_ast_expr * isl_ast_expr_from_id(__isl_take isl_id *id)
Definition isl_ast.c:541
__isl_give isl_ast_expr * isl_ast_expr_sub(__isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2)
Definition isl_ast.c:702
__isl_give isl_ast_expr * isl_ast_expr_from_val(__isl_take isl_val *v)
Definition isl_ast.c:589
__isl_give isl_ast_expr * isl_ast_expr_and(__isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2)
Definition isl_ast.c:746
__isl_give isl_ast_node * isl_ast_node_alloc_user(__isl_take isl_ast_expr *expr)
Definition isl_ast.c:1030
__isl_give isl_ast_build * isl_ast_build_copy(__isl_keep isl_ast_build *build)
__isl_null isl_ast_build * isl_ast_build_free(__isl_take isl_ast_build *build)
isl_ctx * isl_ast_build_get_ctx(__isl_keep isl_ast_build *build)
int isl_options_get_ast_build_prefer_pdiv(isl_ctx *ctx)
int isl_options_get_ast_build_detect_min_max(isl_ctx *ctx)
@ isl_ast_expr_int
Definition ast_type.h:79
isl_ast_expr_op_type
Definition ast_type.h:16
@ isl_ast_expr_op_member
Definition ast_type.h:42
@ isl_ast_expr_op_pdiv_r
Definition ast_type.h:31
@ isl_ast_expr_op_min
Definition ast_type.h:23
@ isl_ast_expr_op_fdiv_q
Definition ast_type.h:29
@ isl_ast_expr_op_call
Definition ast_type.h:40
@ isl_ast_expr_op_le
Definition ast_type.h:36
@ isl_ast_expr_op_ge
Definition ast_type.h:38
@ isl_ast_expr_op_div
Definition ast_type.h:28
@ isl_ast_expr_op_select
Definition ast_type.h:34
@ isl_ast_expr_op_max
Definition ast_type.h:22
@ isl_ast_expr_op_access
Definition ast_type.h:41
@ isl_ast_expr_op_zdiv_r
Definition ast_type.h:32
@ isl_ast_expr_op_eq
Definition ast_type.h:35
@ isl_ast_expr_op_pdiv_q
Definition ast_type.h:30
isl_size isl_constraint_dim(__isl_keep isl_constraint *constraint, enum isl_dim_type type)
int isl_constraint_plain_cmp(__isl_keep isl_constraint *c1, __isl_keep isl_constraint *c2)
__isl_null isl_constraint * isl_constraint_free(__isl_take isl_constraint *c)
__isl_give isl_constraint * isl_constraint_copy(__isl_keep isl_constraint *c)
__isl_give isl_val * isl_constraint_get_constant_val(__isl_keep isl_constraint *constraint)
isl_bool isl_constraint_involves_dims(__isl_keep isl_constraint *constraint, enum isl_dim_type type, unsigned first, unsigned n)
__isl_give isl_constraint_list * isl_basic_set_get_constraint_list(__isl_keep isl_basic_set *bset)
isl_stat isl_basic_set_foreach_constraint(__isl_keep isl_basic_set *bset, isl_stat(*fn)(__isl_take isl_constraint *c, void *user), void *user)
__isl_give isl_basic_set * isl_basic_set_from_constraint(__isl_take isl_constraint *constraint)
__isl_give isl_val * isl_constraint_get_coefficient_val(__isl_keep isl_constraint *constraint, enum isl_dim_type type, int pos)
__isl_give isl_aff * isl_constraint_get_aff(__isl_keep isl_constraint *constraint)
int isl_constraint_cmp_last_non_zero(__isl_keep isl_constraint *c1, __isl_keep isl_constraint *c2)
isl_bool isl_constraint_is_equality(__isl_keep isl_constraint *constraint)
#define __isl_take
Definition ctx.h:23
isl_stat
Definition ctx.h:85
@ isl_stat_error
Definition ctx.h:86
@ isl_stat_ok
Definition ctx.h:87
#define __isl_give
Definition ctx.h:20
#define isl_die(ctx, errno, msg, code)
Definition ctx.h:139
isl_bool isl_bool_ok(int b)
Definition isl_ctx.c:58
@ isl_error_invalid
Definition ctx.h:81
@ isl_error_internal
Definition ctx.h:80
isl_stat isl_stat_non_null(const void *obj)
Definition isl_ctx.c:34
#define isl_calloc_array(ctx, type, n)
Definition ctx.h:134
#define __isl_keep
Definition ctx.h:26
int isl_size
Definition ctx.h:98
isl_stat isl_stat_non_error_bool(isl_bool b)
Definition isl_ctx.c:22
isl_bool isl_bool_not(isl_bool b)
Definition isl_ctx.c:44
isl_bool
Definition ctx.h:90
@ isl_bool_false
Definition ctx.h:92
@ isl_bool_true
Definition ctx.h:93
@ isl_bool_error
Definition ctx.h:91
isl_stat isl_stat(* fn)(__isl_take ISL_KEY *key, __isl_take ISL_VAL *val, void *user)
Definition hmap.h:37
isl_stat isl_stat void * user
Definition hmap.h:39
isl_bool isl_bool(* test)(__isl_keep ISL_KEY *key, __isl_keep ISL_VAL *val, void *user)
Definition hmap.h:41
__isl_give isl_id * isl_id_alloc(isl_ctx *ctx, __isl_keep const char *name, void *user)
__isl_export __isl_give isl_val * isl_set_min_val(__isl_keep isl_set *set, __isl_keep isl_aff *obj)
Definition isl_ilp.c:600
int GMPQAPI cmp(mp_rat op1, mp_rat op2)
void GMPZAPI neg(mp_int rop, mp_int op)
void GMPQAPI init(mp_rat x)
enum isl_ast_expr_type isl_ast_expr_get_type(__isl_keep isl_ast_expr *expr)
Definition isl_ast.c:276
__isl_give isl_ast_expr * isl_ast_expr_op_add_arg(__isl_take isl_ast_expr *expr, __isl_take isl_ast_expr *arg)
Definition isl_ast.c:448
__isl_give isl_ast_expr * isl_ast_expr_alloc_int_si(isl_ctx *ctx, int i)
Definition isl_ast.c:568
__isl_give isl_ast_expr * isl_ast_expr_alloc_binary(enum isl_ast_expr_op_type type, __isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2)
Definition isl_ast.c:666
__isl_give isl_ast_expr * isl_ast_expr_alloc_op(isl_ctx *ctx, enum isl_ast_expr_op_type op, int n_arg)
Definition isl_ast.c:186
isl_bool isl_ast_build_need_schedule_map(__isl_keep isl_ast_build *build)
isl_bool isl_ast_build_aff_is_nonneg(__isl_keep isl_ast_build *build, __isl_keep isl_aff *aff)
__isl_give isl_pw_aff * isl_ast_build_compute_gist_pw_aff(__isl_keep isl_ast_build *build, __isl_take isl_pw_aff *pa)
__isl_give isl_set * isl_ast_build_compute_gist(__isl_keep isl_ast_build *build, __isl_take isl_set *set)
__isl_give isl_space * isl_ast_build_get_space(__isl_keep isl_ast_build *build, int internal)
__isl_give isl_set * isl_ast_build_get_domain(__isl_keep isl_ast_build *build)
__isl_give isl_ast_build * isl_ast_build_restrict_generated(__isl_take isl_ast_build *build, __isl_take isl_set *set)
__isl_give isl_id * isl_ast_build_get_iterator_id(__isl_keep isl_ast_build *build, int pos)
__isl_give isl_pw_multi_aff * isl_ast_build_compute_gist_pw_multi_aff(__isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma)
__isl_give isl_multi_aff * isl_ast_build_get_schedule_map_multi_aff(__isl_keep isl_ast_build *build)
static isl_bool extends(struct isl_from_pw_aff_data *data, __isl_keep isl_set *set, __isl_keep isl_aff *aff, __isl_give isl_basic_set *(*test)(__isl_take isl_aff *aff1, __isl_take isl_aff *aff2))
static __isl_give isl_ast_expr * var(struct isl_ast_add_term_data *data, enum isl_dim_type type, int pos)
isl_from_pw_aff_state
@ isl_state_none
@ isl_state_max
@ isl_state_single
@ isl_state_min
static isl_bool parallel_or_opposite_scan(struct isl_parallel_stat *stat, isl_bool(*fn)(struct isl_parallel_stat *stat, enum isl_dim_type c_type, enum isl_dim_type a_type, int i), int init)
static isl_stat extend_min(struct isl_from_pw_aff_data *data, __isl_take isl_set *set, __isl_take isl_aff *aff)
static __isl_give isl_val * update_is_partial(struct isl_parallel_stat *stat, __isl_take isl_val *v1, __isl_keep isl_val *v2)
static __isl_give isl_ast_expr * isl_ast_expr_from_constraint_no_stride(int eq, __isl_take isl_aff *aff, __isl_keep isl_ast_build *build)
static isl_bool aff_is_rational(__isl_keep isl_aff *aff)
static __isl_give isl_ast_expr * isl_ast_build_from_multi_pw_aff_internal(__isl_keep isl_ast_build *build, enum isl_ast_expr_op_type type, __isl_take isl_multi_pw_aff *mpa)
static __isl_give isl_ast_expr * construct_constraint_expr(int eq, __isl_take isl_ast_expr *expr_pos, __isl_take isl_ast_expr *expr_neg)
__isl_give isl_ast_expr * isl_ast_build_expr_from_pw_aff_internal(__isl_keep isl_ast_build *build, __isl_take isl_pw_aff *pa)
static __isl_give isl_ast_expr * isl_ast_expr_add_term(__isl_take isl_ast_expr *expr, enum isl_dim_type type, int pos, __isl_take isl_val *v, struct isl_ast_add_term_data *data)
static isl_stat extend_domain(struct isl_from_pw_aff_data *data, __isl_take isl_set *set, __isl_take isl_aff *aff, int replace)
static isl_bool add_term(enum isl_dim_type type, int pos, __isl_take isl_val *v, void *user)
static isl_bool every_non_zero_coefficient(__isl_keep isl_aff *aff, int reverse, isl_bool(*fn)(enum isl_dim_type type, int pos, __isl_take isl_val *v, void *user), void *user)
static isl_stat check_parallel_or_opposite(struct isl_extract_mod_data *data, __isl_keep isl_constraint *c)
static __isl_give isl_ast_expr * ast_expr_or(__isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2)
__isl_give isl_ast_expr * isl_ast_build_call_from_pw_multi_aff(__isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma)
static __isl_give isl_ast_expr * ast_expr_binary_non_zero(__isl_give isl_ast_expr *(*fn)(__isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2), __isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2)
static isl_bool clear_opposite_sign(enum isl_dim_type type, int pos, __isl_take isl_val *v, void *user)
static void set_single(struct isl_from_pw_aff_data *data, __isl_take isl_set *set, __isl_take isl_aff *aff)
static isl_stat replace_nonneg(struct isl_extract_mod_data *data, __isl_take isl_aff *aff, int sign)
static __isl_give isl_ast_expr * isl_ast_build_from_multi_pw_aff_member(__isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa)
static __isl_give isl_aff * extract_rational(__isl_take isl_aff *aff, __isl_keep isl_ast_expr **expr, __isl_keep isl_ast_build *build)
static isl_bool ast_expr_is_zero(__isl_keep isl_ast_expr *expr)
static int extract_modulo(struct isl_extract_mod_data *data)
static int sort_pieces_cmp(const void *p1, const void *p2, void *arg)
static __isl_give isl_ast_expr * div_mod(enum isl_ast_expr_op_type type, __isl_take isl_aff *aff, __isl_take isl_val *v, __isl_keep isl_ast_build *build)
__isl_give isl_ast_expr * isl_ast_build_access_from_pw_multi_aff(__isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma)
static void set_none(struct isl_from_pw_aff_data *data)
static isl_bool constant_is_considered_positive(__isl_keep isl_val *v, __isl_keep isl_ast_expr *pos, __isl_keep isl_ast_expr *neg)
static isl_bool extends_max(struct isl_from_pw_aff_data *data, __isl_keep isl_set *set, __isl_keep isl_aff *aff)
static __isl_give isl_ast_expr * isl_ast_build_with_arguments(__isl_keep isl_ast_build *build, enum isl_ast_expr_op_type type, __isl_take isl_ast_expr *arg0, __isl_take isl_multi_pw_aff *mpa)
static __isl_give isl_aff * steal_from_cst(__isl_take isl_aff *aff, __isl_keep isl_val *d, struct isl_ast_add_term_data *data)
static isl_bool single_is_subset(struct isl_from_pw_aff_data *data, __isl_keep isl_set *set)
static __isl_give isl_aff * coefficients_of_sign(__isl_take isl_aff *aff, int sign)
static int cmp_constraint(__isl_keep isl_constraint *a, __isl_keep isl_constraint *b, void *user)
__isl_give isl_ast_expr * isl_ast_build_expr_from_set(__isl_keep isl_ast_build *build, __isl_take isl_set *set)
__isl_give isl_ast_expr * isl_ast_build_expr_from_pw_aff(__isl_keep isl_ast_build *build, __isl_take isl_pw_aff *pa)
static isl_stat isl_from_pw_aff_data_init(struct isl_from_pw_aff_data *data, __isl_keep isl_ast_build *build, __isl_keep isl_pw_aff *pa)
static isl_bool is_stride_constraint(__isl_keep isl_aff *aff, int pos)
__isl_give isl_ast_expr * isl_ast_expr_from_aff(__isl_take isl_aff *aff, __isl_keep isl_ast_build *build)
static __isl_give isl_ast_expr * extract_stride_constraint(__isl_take isl_aff *aff, int pos, __isl_keep isl_ast_build *build)
static isl_bool is_even_test(struct isl_extract_mod_data *data, __isl_keep isl_aff *arg)
static __isl_give isl_ast_expr * isl_ast_build_from_pw_multi_aff_internal(__isl_keep isl_ast_build *build, enum isl_ast_expr_op_type type, __isl_take isl_pw_multi_aff *pma)
static __isl_give isl_ast_expr * scale(__isl_take isl_ast_expr *expr, __isl_take isl_val *v)
__isl_give isl_ast_expr * isl_ast_build_expr_from_basic_set(__isl_keep isl_ast_build *build, __isl_take isl_basic_set *bset)
static isl_bool all_negative_coefficients(__isl_keep isl_aff *aff)
static __isl_give isl_ast_expr * isl_ast_expr_mod(__isl_keep isl_val *v, __isl_keep isl_aff *aff, __isl_keep isl_val *d, __isl_keep isl_ast_build *build)
static isl_ast_expr * build_pieces(struct isl_from_pw_aff_data *data)
static isl_stat add_last_piece(struct isl_from_pw_aff_data *data, int pos, isl_ast_expr_list **next)
static __isl_give isl_ast_expr * isl_ast_expr_add_int(__isl_take isl_ast_expr *expr, __isl_take isl_val *v)
static __isl_give isl_val * get_constraint_constant(struct isl_extract_mod_data *data, void *user)
static isl_stat ast_expr_from_pw_aff(__isl_take isl_set *set, __isl_take isl_aff *aff, void *user)
static isl_bool is_single_rational_aff(__isl_keep isl_aff_list *list)
static isl_stat replace_by_partial_if_simpler(struct isl_parallel_stat *stat)
static isl_bool is_disjoint(__isl_keep isl_set *set, __isl_keep isl_basic_set *bset)
static isl_stat check_parallel_or_opposite_wrap(__isl_take isl_constraint *c, void *user)
static isl_ast_expr_list ** add_intermediate_piece(struct isl_from_pw_aff_data *data, int pos, isl_ast_expr_list **next)
static isl_bool is_non_neg_after_stealing(__isl_keep isl_aff *aff, __isl_keep isl_val *d, struct isl_ast_add_term_data *data)
static isl_stat extract_mod(struct isl_extract_mod_data *data)
__isl_give isl_ast_expr * isl_ast_build_expr_from_set_internal(__isl_keep isl_ast_build *build, __isl_take isl_set *set)
static __isl_give isl_aff * extract_modulos(__isl_take isl_aff *aff, __isl_keep isl_ast_expr **pos, __isl_keep isl_ast_expr **neg, __isl_keep isl_ast_build *build)
static isl_bool parallel_or_opposite_feasible(struct isl_parallel_stat *stat, enum isl_dim_type c_type, enum isl_dim_type a_type, int i)
__isl_give isl_ast_node * isl_ast_build_call_from_executed(__isl_keep isl_ast_build *build, __isl_take isl_map *executed)
static isl_bool has_large_constant_term(__isl_keep isl_constraint *c)
static isl_bool extends_min(struct isl_from_pw_aff_data *data, __isl_keep isl_set *set, __isl_keep isl_aff *aff)
static isl_stat update_partial(struct isl_parallel_stat *stat)
static isl_bool add_rational(enum isl_dim_type type, int pos, __isl_take isl_val *v, void *user)
static __isl_give isl_aff * oppose_div_arg(__isl_take isl_aff *aff, __isl_take isl_val *d)
static __isl_give isl_ast_expr * isl_ast_build_from_pw_multi_aff(__isl_keep isl_ast_build *build, enum isl_ast_expr_op_type type, __isl_take isl_pw_multi_aff *pma)
static __isl_give isl_ast_expr * ast_expr_add(__isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2)
static isl_stat extract_nonneg_mod(struct isl_extract_mod_data *data)
static isl_bool partial_is_simpler(struct isl_extract_mod_data *data)
static isl_bool mod_constraint_is_simpler(struct isl_extract_mod_data *data, __isl_keep isl_constraint *c)
__isl_give isl_ast_expr * isl_ast_build_access_from_multi_pw_aff(__isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa)
static __isl_give isl_ast_expr * isl_ast_build_from_multi_pw_aff(__isl_keep isl_ast_build *build, enum isl_ast_expr_op_type type, __isl_take isl_multi_pw_aff *mpa)
static isl_bool parallel_or_opposite_continue(struct isl_parallel_stat *stat)
static isl_stat extend_max(struct isl_from_pw_aff_data *data, __isl_take isl_set *set, __isl_take isl_aff *aff)
static isl_stat replace_if_simpler(struct isl_extract_mod_data *data, __isl_keep isl_constraint *c, int sign)
static isl_stat try_extract_mod(struct isl_extract_mod_data *data)
__isl_give isl_ast_expr * isl_ast_build_call_from_multi_pw_aff(__isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa)
static __isl_give isl_ast_expr * isl_ast_expr_from_constraint(__isl_take isl_constraint *constraint, __isl_keep isl_ast_build *build)
static __isl_give isl_ast_expr * var_div(struct isl_ast_add_term_data *data, int pos)
static isl_stat extract_term_and_mod(struct isl_extract_mod_data *data, __isl_take isl_aff *term, __isl_take isl_aff *arg)
static isl_bool is_parallel_or_opposite(struct isl_parallel_stat *stat, enum isl_dim_type c_type, enum isl_dim_type a_type, int i)
static void isl_from_pw_aff_data_clear(struct isl_from_pw_aff_data *data)
static __isl_give isl_ast_expr * ast_expr_sub(__isl_take isl_ast_expr *expr1, __isl_take isl_ast_expr *expr2)
static __isl_give isl_multi_pw_aff * set_iterator_names(__isl_keep isl_ast_build *build, __isl_take isl_multi_pw_aff *mpa)
static isl_bool is_simpler(struct isl_extract_mod_data *data, __isl_give isl_val *get_constant(struct isl_extract_mod_data *data, void *user), void *user)
static __isl_give isl_ast_expr * add_terms(__isl_take isl_ast_expr *expr, __isl_keep isl_aff *aff, struct isl_ast_add_term_data *data)
static __isl_give isl_val * get_partial_constant(struct isl_extract_mod_data *data, void *user)
static __isl_give isl_ast_expr * ast_expr_from_aff_list(__isl_take isl_aff_list *list, enum isl_from_pw_aff_state state, __isl_keep isl_ast_build *build)
static int is_rational(__isl_keep isl_stream *s)
Definition isl_input.c:2774
static unsigned pos(__isl_keep isl_space *space, enum isl_dim_type type)
Definition isl_map.c:73
#define isl_basic_set_list
#define isl_set_list
#define isl_set
#define isl_basic_set
static int all_neg(int *row, int n)
int isl_sort(void *const pbase, size_t total_elems, size_t size, int(*cmp)(const void *, const void *, void *arg), void *arg)
Definition isl_sort.c:153
static isl_bool get_constant(struct isl_tab *tab, struct isl_tab_var *var, isl_int *value)
Definition isl_tab.c:3682
enum isl_fold type
Definition isl_test.c:3810
const char * pa
Definition isl_test.c:7116
const char * set
Definition isl_test.c:1364
const char * hull
Definition isl_test.c:1493
const char * ma
Definition isl_test.c:7330
const char * pma
Definition isl_test.c:2962
const char * aff
Definition isl_test.c:7073
const char * res
Definition isl_test.c:783
const char * set2
Definition isl_test.c:3999
int subset
Definition isl_test.c:4000
const char * arg
Definition isl_test.c:782
const char * gist
Definition isl_test.c:1736
const char * id
Definition isl_test.c:7074
t0 *a *b *t *a *b * t
__isl_give isl_aff * isl_local_space_get_div(__isl_keep isl_local_space *ls, int pos)
isl_ctx * isl_local_space_get_ctx(__isl_keep isl_local_space *ls)
__isl_null isl_local_space * isl_local_space_free(__isl_take isl_local_space *ls)
__isl_give isl_local_space * isl_local_space_copy(__isl_keep isl_local_space *ls)
__isl_give isl_id * isl_local_space_get_dim_id(__isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos)
isl_bool isl_local_space_has_dim_id(__isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos)
a(0)
b(9)
__isl_export __isl_give isl_set * isl_set_coalesce(__isl_take isl_set *set)
__isl_give isl_set * isl_set_list_union(__isl_take isl_set_list *list)
Definition isl_map.c:11350
__isl_export __isl_give isl_set * isl_set_subtract(__isl_take isl_set *set1, __isl_take isl_set *set2)
__isl_export __isl_give isl_set * isl_set_union(__isl_take isl_set *set1, __isl_take isl_set *set2)
Definition isl_map.c:8929
__isl_overload __isl_give isl_set * isl_set_preimage_multi_aff(__isl_take isl_set *set, __isl_take isl_multi_aff *ma)
Definition isl_map.c:14675
__isl_export isl_bool isl_set_is_disjoint(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
__isl_null isl_basic_set * isl_basic_set_free(__isl_take isl_basic_set *bset)
Definition isl_map.c:1523
__isl_give isl_basic_set * isl_set_simple_hull(__isl_take isl_set *set)
__isl_null isl_set * isl_set_free(__isl_take isl_set *set)
Definition isl_map.c:4055
__isl_export isl_bool isl_set_is_subset(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
__isl_give isl_set * isl_set_copy(__isl_keep isl_set *set)
Definition isl_map.c:1470
__isl_give isl_basic_set_list * isl_set_get_basic_set_list(__isl_keep isl_set *set)
Definition isl_map.c:11987
__isl_export __isl_give isl_set * isl_set_gist(__isl_take isl_set *set, __isl_take isl_set *context)
__isl_give isl_set * isl_set_compute_divs(__isl_take isl_set *set)
Definition isl_map.c:8772
__isl_give isl_basic_set * isl_basic_set_remove_divs(__isl_take isl_basic_set *bset)
Definition isl_map.c:2778
__isl_export __isl_give isl_basic_set * isl_basic_set_gist(__isl_take isl_basic_set *bset, __isl_take isl_basic_set *context)
__isl_export isl_size isl_set_n_basic_set(__isl_keep isl_set *set)
Definition isl_map.c:11928
__isl_export __isl_give isl_set * isl_set_intersect(__isl_take isl_set *set1, __isl_take isl_set *set2)
Definition isl_map.c:4521
__isl_constructor __isl_give isl_set * isl_set_from_basic_set(__isl_take isl_basic_set *bset)
Definition isl_map.c:4024
__isl_give isl_basic_set * isl_basic_set_copy(__isl_keep isl_basic_set *bset)
Definition isl_map.c:1465
__isl_null isl_space * isl_space_free(__isl_take isl_space *space)
Definition isl_space.c:478
isl_bool isl_space_tuple_is_equal(__isl_keep isl_space *space1, enum isl_dim_type type1, __isl_keep isl_space *space2, enum isl_dim_type type2)
Definition isl_space.c:1080
isl_dim_type
Definition space_type.h:13
@ isl_dim_param
Definition space_type.h:15
@ isl_dim_in
Definition space_type.h:16
@ isl_dim_set
Definition space_type.h:18
@ isl_dim_div
Definition space_type.h:19
@ isl_dim_out
Definition space_type.h:17
struct isl_ast_add_term_data * term
struct isl_from_pw_aff_piece * p
enum isl_from_pw_aff_state state
struct isl_extract_mod_data * data
static Signature domain
__isl_export __isl_give isl_val * isl_val_abs(__isl_take isl_val *v)
Definition isl_val.c:456
__isl_export isl_bool isl_val_lt(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
Definition isl_val.c:1285
__isl_export __isl_give isl_val * isl_val_mod(__isl_take isl_val *v1, __isl_take isl_val *v2)
Definition isl_val.c:979
__isl_give isl_val * isl_val_copy(__isl_keep isl_val *v)
Definition isl_val.c:219
__isl_export int isl_val_cmp_si(__isl_keep isl_val *v, long i)
Definition isl_val.c:1394
__isl_export isl_bool isl_val_is_negone(__isl_keep isl_val *v)
Definition isl_val.c:1214
__isl_export __isl_give isl_val * isl_val_floor(__isl_take isl_val *v)
Definition isl_val.c:470
__isl_export __isl_give isl_val * isl_val_ceil(__isl_take isl_val *v)
Definition isl_val.c:491
__isl_export __isl_give isl_val * isl_val_div(__isl_take isl_val *v1, __isl_take isl_val *v2)
Definition isl_val.c:875
__isl_give isl_val * isl_val_sub_ui(__isl_take isl_val *v1, unsigned long v2)
Definition isl_val.c:763
__isl_export __isl_give isl_val * isl_val_add(__isl_take isl_val *v1, __isl_take isl_val *v2)
Definition isl_val.c:626
__isl_export isl_bool isl_val_is_pos(__isl_keep isl_val *v)
Definition isl_val.c:1224
__isl_export __isl_give isl_val * isl_val_zero(isl_ctx *ctx)
Definition isl_val.c:41
__isl_export isl_bool isl_val_abs_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
Definition isl_val.c:1445
__isl_export int isl_val_sgn(__isl_keep isl_val *v)
Definition isl_val.c:1272
__isl_export isl_bool isl_val_is_divisible_by(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
Definition isl_val.c:964
__isl_export isl_bool isl_val_is_neg(__isl_keep isl_val *v)
Definition isl_val.c:1234
isl_bool isl_val_eq_si(__isl_keep isl_val *v, long i)
Definition isl_val.c:1434
__isl_null isl_val * isl_val_free(__isl_take isl_val *v)
Definition isl_val.c:263
__isl_export isl_bool isl_val_is_zero(__isl_keep isl_val *v)
Definition isl_val.c:1191
__isl_export __isl_give isl_val * isl_val_sub(__isl_take isl_val *v1, __isl_take isl_val *v2)
Definition isl_val.c:704
__isl_export isl_bool isl_val_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
Definition isl_val.c:1421
__isl_export isl_bool isl_val_is_one(__isl_keep isl_val *v)
Definition isl_val.c:1201
__isl_export __isl_give isl_val * isl_val_neg(__isl_take isl_val *v)
Definition isl_val.c:410
__isl_export __isl_give isl_val * isl_val_mul(__isl_take isl_val *v1, __isl_take isl_val *v2)
Definition isl_val.c:782
n
Definition youcefn.c:8