8 #include "isl_map_private.h"
9 #include "isl_map_piplib.h"
10 #include "isl_sample.h"
13 static struct isl_basic_map *basic_map_init(struct isl_ctx *ctx,
14 struct isl_basic_map *bmap,
15 unsigned nparam, unsigned n_in, unsigned n_out, unsigned extra,
16 unsigned n_eq, unsigned n_ineq)
19 size_t row_size = 1 + nparam + n_in + n_out + extra;
21 bmap->block = isl_blk_alloc(ctx, (n_eq + n_ineq) * row_size);
22 if (!bmap->block.data) {
27 bmap->eq = isl_alloc_array(ctx, isl_int *, n_eq + n_ineq);
29 isl_blk_free(ctx, bmap->block);
35 bmap->block2.size = 0;
36 bmap->block2.data = NULL;
39 bmap->block2 = isl_blk_alloc(ctx, extra * (1 + row_size));
40 if (!bmap->block2.data) {
42 isl_blk_free(ctx, bmap->block);
47 bmap->div = isl_alloc_array(ctx, isl_int *, extra);
49 isl_blk_free(ctx, bmap->block2);
51 isl_blk_free(ctx, bmap->block);
57 for (i = 0; i < n_eq + n_ineq; ++i)
58 bmap->eq[i] = bmap->block.data + i * row_size;
60 for (i = 0; i < extra; ++i)
61 bmap->div[i] = bmap->block2.data + i * (1 + row_size);
65 bmap->c_size = n_eq + n_ineq;
66 bmap->ineq = bmap->eq + n_eq;
67 bmap->nparam = nparam;
78 struct isl_basic_set *isl_basic_set_alloc(struct isl_ctx *ctx,
79 unsigned nparam, unsigned dim, unsigned extra,
80 unsigned n_eq, unsigned n_ineq)
82 struct isl_basic_map *bmap;
83 bmap = isl_basic_map_alloc(ctx, nparam, 0, dim, extra, n_eq, n_ineq);
84 return (struct isl_basic_set *)bmap;
87 struct isl_basic_map *isl_basic_map_alloc(struct isl_ctx *ctx,
88 unsigned nparam, unsigned in, unsigned out, unsigned extra,
89 unsigned n_eq, unsigned n_ineq)
91 struct isl_basic_map *bmap;
93 bmap = isl_alloc_type(ctx, struct isl_basic_map);
97 return basic_map_init(ctx, bmap,
98 nparam, in, out, extra, n_eq, n_ineq);
101 static void dup_constraints(struct isl_ctx *ctx,
102 struct isl_basic_map *dst, struct isl_basic_map *src)
105 unsigned total = src->nparam + src->n_in + src->n_out + src->n_div;
107 for (i = 0; i < src->n_eq; ++i) {
108 int j = isl_basic_map_alloc_equality(ctx, dst);
109 isl_seq_cpy(dst->eq[j], src->eq[i], 1+total);
112 for (i = 0; i < src->n_ineq; ++i) {
113 int j = isl_basic_map_alloc_inequality(ctx, dst);
114 isl_seq_cpy(dst->ineq[j], src->ineq[i], 1+total);
117 for (i = 0; i < src->n_div; ++i) {
118 int j = isl_basic_map_alloc_div(ctx, dst);
119 isl_seq_cpy(dst->div[j], src->div[i], 1+1+total);
121 F_SET(dst, ISL_BASIC_SET_FINAL);
124 struct isl_basic_map *isl_basic_map_dup(struct isl_ctx *ctx,
125 struct isl_basic_map *bmap)
127 struct isl_basic_map *dup;
129 dup = isl_basic_map_alloc(ctx, bmap->nparam,
130 bmap->n_in, bmap->n_out,
131 bmap->n_div, bmap->n_eq, bmap->n_ineq);
134 dup_constraints(ctx, dup, bmap);
138 struct isl_basic_set *isl_basic_set_dup(struct isl_ctx *ctx,
139 struct isl_basic_set *bset)
141 struct isl_basic_map *dup;
143 dup = isl_basic_map_dup(ctx, (struct isl_basic_map *)bset);
144 return (struct isl_basic_set *)dup;
147 struct isl_basic_set *isl_basic_set_copy(struct isl_ctx *ctx,
148 struct isl_basic_set *bset)
153 if (F_ISSET(bset, ISL_BASIC_SET_FINAL)) {
157 return isl_basic_set_dup(ctx, bset);
160 struct isl_set *isl_set_copy(struct isl_ctx *ctx, struct isl_set *set)
169 struct isl_basic_map *isl_basic_map_copy(struct isl_ctx *ctx,
170 struct isl_basic_map *bmap)
175 if (F_ISSET(bmap, ISL_BASIC_SET_FINAL)) {
179 return isl_basic_map_dup(ctx, bmap);
182 struct isl_map *isl_map_copy(struct isl_ctx *ctx, struct isl_map *map)
191 void isl_basic_map_free(struct isl_ctx *ctx, struct isl_basic_map *bmap)
200 isl_blk_free(ctx, bmap->block2);
202 isl_blk_free(ctx, bmap->block);
206 void isl_basic_set_free(struct isl_ctx *ctx, struct isl_basic_set *bset)
208 isl_basic_map_free(ctx, (struct isl_basic_map *)bset);
211 int isl_basic_map_alloc_equality(struct isl_ctx *ctx,
212 struct isl_basic_map *bmap)
216 isl_assert(ctx, bmap->n_eq + bmap->n_ineq < bmap->c_size, return -1);
217 isl_assert(ctx, bmap->eq + bmap->n_eq <= bmap->ineq, return -1);
218 if (bmap->eq + bmap->n_eq == bmap->ineq) {
220 int j = isl_basic_map_alloc_inequality(ctx, bmap);
224 bmap->ineq[0] = bmap->ineq[j];
232 int isl_basic_map_free_equality(struct isl_ctx *ctx,
233 struct isl_basic_map *bmap, unsigned n)
235 isl_assert(ctx, n <= bmap->n_eq, return -1);
240 int isl_basic_map_drop_equality(struct isl_ctx *ctx,
241 struct isl_basic_map *bmap, unsigned pos)
244 isl_assert(ctx, pos < bmap->n_eq, return -1);
246 if (pos != bmap->n_eq - 1) {
248 bmap->eq[pos] = bmap->eq[bmap->n_eq - 1];
249 bmap->eq[bmap->n_eq - 1] = t;
255 void isl_basic_map_inequality_to_equality(struct isl_ctx *ctx,
256 struct isl_basic_map *bmap, unsigned pos)
261 bmap->ineq[pos] = bmap->ineq[0];
262 bmap->ineq[0] = bmap->eq[bmap->n_eq];
263 bmap->eq[bmap->n_eq] = t;
269 int isl_basic_map_alloc_inequality(struct isl_ctx *ctx,
270 struct isl_basic_map *bmap)
272 isl_assert(ctx, (bmap->ineq - bmap->eq) + bmap->n_ineq < bmap->c_size,
274 return bmap->n_ineq++;
277 int isl_basic_map_free_inequality(struct isl_ctx *ctx,
278 struct isl_basic_map *bmap, unsigned n)
280 isl_assert(ctx, n <= bmap->n_ineq, return -1);
285 int isl_basic_map_drop_inequality(struct isl_ctx *ctx,
286 struct isl_basic_map *bmap, unsigned pos)
289 isl_assert(ctx, pos < bmap->n_ineq, return -1);
291 if (pos != bmap->n_ineq - 1) {
293 bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
294 bmap->ineq[bmap->n_ineq - 1] = t;
300 int isl_basic_map_alloc_div(struct isl_ctx *ctx,
301 struct isl_basic_map *bmap)
303 isl_assert(ctx, bmap->n_div < bmap->extra, return -1);
304 return bmap->n_div++;
307 int isl_basic_map_free_div(struct isl_ctx *ctx,
308 struct isl_basic_map *bmap, unsigned n)
310 isl_assert(ctx, n <= bmap->n_div, return -1);
315 /* Copy constraint from src to dst, putting the vars of src at offset
316 * dim_off in dst and the divs of src at offset div_off in dst.
317 * If both sets are actually map, then dim_off applies to the input
320 static void copy_constraint(struct isl_basic_map *dst_map, isl_int *dst,
321 struct isl_basic_map *src_map, isl_int *src,
322 unsigned in_off, unsigned out_off, unsigned div_off)
324 isl_int_set(dst[0], src[0]);
325 isl_seq_cpy(dst+1, src+1, isl_min(dst_map->nparam, src_map->nparam));
326 isl_seq_cpy(dst+1+dst_map->nparam+in_off,
327 src+1+src_map->nparam,
328 isl_min(dst_map->n_in-in_off, src_map->n_in));
329 isl_seq_cpy(dst+1+dst_map->nparam+dst_map->n_in+out_off,
330 src+1+src_map->nparam+src_map->n_in,
331 isl_min(dst_map->n_out-out_off, src_map->n_out));
332 isl_seq_cpy(dst+1+dst_map->nparam+dst_map->n_in+dst_map->n_out+div_off,
333 src+1+src_map->nparam+src_map->n_in+src_map->n_out,
334 isl_min(dst_map->extra-div_off, src_map->extra));
337 static void copy_div(struct isl_basic_map *dst_map, isl_int *dst,
338 struct isl_basic_map *src_map, isl_int *src,
339 unsigned in_off, unsigned out_off, unsigned div_off)
341 isl_int_set(dst[0], src[0]);
342 copy_constraint(dst_map, dst+1, src_map, src+1, in_off, out_off, div_off);
345 static struct isl_basic_map *add_constraints(struct isl_ctx *ctx,
346 struct isl_basic_map *bmap1,
347 struct isl_basic_map *bmap2, unsigned i_pos, unsigned o_pos)
350 unsigned div_off = bmap1->n_div;
352 for (i = 0; i < bmap2->n_eq; ++i) {
353 int i1 = isl_basic_map_alloc_equality(ctx, bmap1);
356 copy_constraint(bmap1, bmap1->eq[i1], bmap2, bmap2->eq[i],
357 i_pos, o_pos, div_off);
360 for (i = 0; i < bmap2->n_ineq; ++i) {
361 int i1 = isl_basic_map_alloc_inequality(ctx, bmap1);
364 copy_constraint(bmap1, bmap1->ineq[i1], bmap2, bmap2->ineq[i],
365 i_pos, o_pos, div_off);
368 for (i = 0; i < bmap2->n_div; ++i) {
369 int i1 = isl_basic_map_alloc_div(ctx, bmap1);
372 copy_div(bmap1, bmap1->div[i1], bmap2, bmap2->div[i],
373 i_pos, o_pos, div_off);
376 isl_basic_map_free(ctx, bmap2);
381 isl_basic_map_free(ctx, bmap1);
382 isl_basic_map_free(ctx, bmap2);
386 struct isl_basic_map *isl_basic_map_extend(struct isl_ctx *ctx,
387 struct isl_basic_map *base,
388 unsigned nparam, unsigned n_in, unsigned n_out, unsigned extra,
389 unsigned n_eq, unsigned n_ineq)
391 struct isl_basic_map *ext;
394 base = isl_basic_map_cow(ctx, base);
398 dims_ok = base && base->nparam == nparam &&
399 base->n_in == n_in && base->n_out == n_out &&
400 base->extra >= base->n_div + extra;
402 if (dims_ok && n_eq == 0 && n_ineq == 0)
406 isl_assert(ctx, base->nparam <= nparam, goto error);
407 isl_assert(ctx, base->n_in <= n_in, goto error);
408 isl_assert(ctx, base->n_out <= n_out, goto error);
409 extra += base->extra;
411 n_ineq += base->n_ineq;
414 ext = isl_basic_map_alloc(ctx, nparam, n_in, n_out,
415 extra, n_eq, n_ineq);
421 ext = add_constraints(ctx, ext, base, 0, 0);
426 isl_basic_map_free(ctx, base);
430 struct isl_basic_set *isl_basic_set_extend(struct isl_ctx *ctx,
431 struct isl_basic_set *base,
432 unsigned nparam, unsigned dim, unsigned extra,
433 unsigned n_eq, unsigned n_ineq)
435 return (struct isl_basic_set *)
436 isl_basic_map_extend(ctx, (struct isl_basic_map *)base,
437 nparam, 0, dim, extra, n_eq, n_ineq);
440 struct isl_basic_set *isl_basic_set_cow(struct isl_ctx *ctx,
441 struct isl_basic_set *bset)
443 return (struct isl_basic_set *)
444 isl_basic_map_cow(ctx, (struct isl_basic_map *)bset);
447 struct isl_basic_map *isl_basic_map_cow(struct isl_ctx *ctx,
448 struct isl_basic_map *bmap)
455 bmap = isl_basic_map_dup(ctx, bmap);
457 F_CLR(bmap, ISL_BASIC_SET_FINAL);
461 static struct isl_set *isl_set_cow(struct isl_ctx *ctx, struct isl_set *set)
466 return isl_set_dup(ctx, set);
469 struct isl_map *isl_map_cow(struct isl_ctx *ctx, struct isl_map *map)
474 return isl_map_dup(ctx, map);
477 static void swap_vars(struct isl_blk blk, isl_int *a,
478 unsigned a_len, unsigned b_len)
480 isl_seq_cpy(blk.data, a+a_len, b_len);
481 isl_seq_cpy(blk.data+b_len, a, a_len);
482 isl_seq_cpy(a, blk.data, b_len+a_len);
485 struct isl_basic_set *isl_basic_set_swap_vars(struct isl_ctx *ctx,
486 struct isl_basic_set *bset, unsigned n)
494 isl_assert(ctx, n <= bset->dim, goto error);
499 bset = isl_basic_set_cow(ctx, bset);
503 blk = isl_blk_alloc(ctx, bset->dim);
507 for (i = 0; i < bset->n_eq; ++i)
509 bset->eq[i]+1+bset->nparam, n, bset->dim - n);
511 for (i = 0; i < bset->n_ineq; ++i)
513 bset->ineq[i]+1+bset->nparam, n, bset->dim - n);
515 for (i = 0; i < bset->n_div; ++i)
517 bset->div[i]+1+1+bset->nparam, n, bset->dim - n);
519 isl_blk_free(ctx, blk);
524 isl_basic_set_free(ctx, bset);
528 struct isl_set *isl_set_swap_vars(struct isl_ctx *ctx,
529 struct isl_set *set, unsigned n)
532 set = isl_set_cow(ctx, set);
536 for (i = 0; i < set->n; ++i) {
537 set->p[i] = isl_basic_set_swap_vars(ctx, set->p[i], n);
539 isl_set_free(ctx, set);
546 static void constraint_drop_vars(isl_int *c, unsigned n, unsigned rem)
548 isl_seq_cpy(c, c + n, rem);
549 isl_seq_clr(c + rem, n);
552 struct isl_basic_set *isl_basic_set_drop_vars(struct isl_ctx *ctx,
553 struct isl_basic_set *bset, unsigned first, unsigned n)
560 isl_assert(ctx, first + n <= bset->dim, goto error);
565 bset = isl_basic_set_cow(ctx, bset);
569 for (i = 0; i < bset->n_eq; ++i)
570 constraint_drop_vars(bset->eq[i]+1+bset->nparam+first, n,
571 (bset->dim-first-n)+bset->extra);
573 for (i = 0; i < bset->n_ineq; ++i)
574 constraint_drop_vars(bset->ineq[i]+1+bset->nparam+first, n,
575 (bset->dim-first-n)+bset->extra);
577 for (i = 0; i < bset->n_div; ++i)
578 constraint_drop_vars(bset->div[i]+1+1+bset->nparam+first, n,
579 (bset->dim-first-n)+bset->extra);
584 return isl_basic_set_finalize(ctx, bset);
586 isl_basic_set_free(ctx, bset);
591 * We don't cow, as the div is assumed to be redundant.
593 static struct isl_basic_map *isl_basic_map_drop_div(struct isl_ctx *ctx,
594 struct isl_basic_map *bmap, unsigned div)
602 pos = 1 + bmap->nparam + bmap->n_in + bmap->n_out + div;
604 isl_assert(ctx, div < bmap->n_div, goto error);
606 for (i = 0; i < bmap->n_eq; ++i)
607 constraint_drop_vars(bmap->eq[i]+pos, 1, bmap->extra-div-1);
609 for (i = 0; i < bmap->n_ineq; ++i) {
610 if (!isl_int_is_zero(bmap->ineq[i][pos])) {
611 isl_basic_map_drop_inequality(ctx, bmap, i);
615 constraint_drop_vars(bmap->ineq[i]+pos, 1, bmap->extra-div-1);
618 for (i = 0; i < bmap->n_div; ++i)
619 constraint_drop_vars(bmap->div[i]+1+pos, 1, bmap->extra-div-1);
621 if (div != bmap->n_div - 1) {
623 isl_int *t = bmap->div[div];
625 for (j = div; j < bmap->n_div - 1; ++j)
626 bmap->div[j] = bmap->div[j+1];
628 bmap->div[bmap->n_div - 1] = t;
630 isl_basic_map_free_div(ctx, bmap, 1);
634 isl_basic_map_free(ctx, bmap);
638 static void eliminate_div(struct isl_ctx *ctx, struct isl_basic_map *bmap,
639 isl_int *eq, unsigned div)
642 unsigned pos = 1 + bmap->nparam + bmap->n_in + bmap->n_out + div;
644 len = 1 + bmap->nparam + bmap->n_in + bmap->n_out + bmap->n_div;
646 for (i = 0; i < bmap->n_eq; ++i)
647 if (bmap->eq[i] != eq)
648 isl_seq_elim(bmap->eq[i], eq, pos, len, NULL);
650 for (i = 0; i < bmap->n_ineq; ++i)
651 isl_seq_elim(bmap->ineq[i], eq, pos, len, NULL);
653 /* We need to be careful about circular definitions,
654 * so for now we just remove the definitions of other divs that
655 * depend on this div and (possibly) recompute them later.
657 for (i = 0; i < bmap->n_div; ++i)
658 if (!isl_int_is_zero(bmap->div[i][0]) &&
659 !isl_int_is_zero(bmap->div[i][1 + pos]))
660 isl_seq_clr(bmap->div[i], 1 + len);
662 isl_basic_map_drop_div(ctx, bmap, div);
665 struct isl_basic_map *isl_basic_map_set_to_empty(
666 struct isl_ctx *ctx, struct isl_basic_map *bmap)
672 total = bmap->nparam + bmap->n_in + bmap->n_out;
673 isl_basic_map_free_div(ctx, bmap, bmap->n_div);
674 isl_basic_map_free_inequality(ctx, bmap, bmap->n_ineq);
676 isl_basic_map_free_equality(ctx, bmap, bmap->n_eq-1);
678 isl_basic_map_alloc_equality(ctx, bmap);
682 isl_int_set_si(bmap->eq[i][0], 1);
683 isl_seq_clr(bmap->eq[i]+1, total);
684 F_SET(bmap, ISL_BASIC_MAP_EMPTY);
685 return isl_basic_map_finalize(ctx, bmap);
687 isl_basic_map_free(ctx, bmap);
691 struct isl_basic_set *isl_basic_set_set_to_empty(
692 struct isl_ctx *ctx, struct isl_basic_set *bset)
694 return (struct isl_basic_set *)
695 isl_basic_map_set_to_empty(ctx, (struct isl_basic_map *)bset);
698 static void swap_equality(struct isl_basic_map *bmap, int a, int b)
700 isl_int *t = bmap->eq[a];
701 bmap->eq[a] = bmap->eq[b];
705 static void swap_inequality(struct isl_basic_map *bmap, int a, int b)
707 isl_int *t = bmap->ineq[a];
708 bmap->ineq[a] = bmap->ineq[b];
712 static void swap_div(struct isl_basic_map *bmap, int a, int b)
715 unsigned off = bmap->nparam + bmap->n_in + bmap->n_out;
716 isl_int *t = bmap->div[a];
717 bmap->div[a] = bmap->div[b];
720 for (i = 0; i < bmap->n_eq; ++i)
721 isl_int_swap(bmap->eq[i][1+off+a], bmap->eq[i][1+off+b]);
723 for (i = 0; i < bmap->n_ineq; ++i)
724 isl_int_swap(bmap->ineq[i][1+off+a], bmap->ineq[i][1+off+b]);
726 for (i = 0; i < bmap->n_div; ++i)
727 isl_int_swap(bmap->div[i][1+1+off+a], bmap->div[i][1+1+off+b]);
730 struct isl_basic_map *isl_basic_map_gauss(struct isl_ctx *ctx,
731 struct isl_basic_map *bmap, int *progress)
742 total_var = bmap->nparam + bmap->n_in + bmap->n_out;
743 total = total_var + bmap->n_div;
745 last_var = total - 1;
746 for (done = 0; done < bmap->n_eq; ++done) {
747 for (; last_var >= 0; --last_var) {
748 for (k = done; k < bmap->n_eq; ++k)
749 if (!isl_int_is_zero(bmap->eq[k][1+last_var]))
757 swap_equality(bmap, k, done);
758 if (isl_int_is_neg(bmap->eq[done][1+last_var]))
759 isl_seq_neg(bmap->eq[done], bmap->eq[done], 1+total);
761 for (k = 0; k < bmap->n_eq; ++k) {
764 if (isl_int_is_zero(bmap->eq[k][1+last_var]))
768 isl_seq_elim(bmap->eq[k], bmap->eq[done],
769 1+last_var, 1+total, NULL);
772 for (k = 0; k < bmap->n_ineq; ++k) {
773 if (isl_int_is_zero(bmap->ineq[k][1+last_var]))
777 isl_seq_elim(bmap->ineq[k], bmap->eq[done],
778 1+last_var, 1+total, NULL);
781 for (k = 0; k < bmap->n_div; ++k) {
782 if (isl_int_is_zero(bmap->div[k][0]))
784 if (isl_int_is_zero(bmap->div[k][1+1+last_var]))
788 isl_seq_elim(bmap->div[k]+1, bmap->eq[done],
789 1+last_var, 1+total, &bmap->div[k][0]);
792 if (last_var >= total_var &&
793 isl_int_is_zero(bmap->div[last_var - total_var][0])) {
794 unsigned div = last_var - total_var;
795 isl_seq_neg(bmap->div[div]+1, bmap->eq[done], 1+total);
796 isl_int_set_si(bmap->div[div][1+1+last_var], 0);
797 isl_int_set(bmap->div[div][0],
798 bmap->eq[done][1+last_var]);
801 if (done == bmap->n_eq)
803 for (k = done; k < bmap->n_eq; ++k) {
804 if (isl_int_is_zero(bmap->eq[k][0]))
806 return isl_basic_map_set_to_empty(ctx, bmap);
808 isl_basic_map_free_equality(ctx, bmap, bmap->n_eq-done);
812 struct isl_basic_set *isl_basic_set_gauss(struct isl_ctx *ctx,
813 struct isl_basic_set *bset, int *progress)
815 return (struct isl_basic_set*)isl_basic_map_gauss(ctx,
816 (struct isl_basic_map *)bset, progress);
819 static unsigned int round_up(unsigned int v)
830 static int hash_index(int *index, unsigned int size, int bits,
831 struct isl_basic_map *bmap, int k)
834 unsigned total = bmap->nparam + bmap->n_in + bmap->n_out + bmap->n_div;
835 u_int32_t hash = isl_seq_hash(bmap->ineq[k]+1, total, bits);
836 for (h = hash; index[h]; h = (h+1) % size)
837 if (k != index[h]-1 &&
838 isl_seq_eq(bmap->ineq[k]+1,
839 bmap->ineq[index[h]-1]+1, total))
844 static struct isl_basic_map *remove_duplicate_constraints(
846 struct isl_basic_map *bmap, int *progress)
852 unsigned total = bmap->nparam + bmap->n_in + bmap->n_out + bmap->n_div;
855 if (bmap->n_ineq <= 1)
858 size = round_up(4 * (bmap->n_ineq+1) / 3 - 1);
859 bits = ffs(size) - 1;
860 index = isl_alloc_array(ctx, int, size);
861 memset(index, 0, size * sizeof(int));
865 index[isl_seq_hash(bmap->ineq[0]+1, total, bits)] = 1;
866 for (k = 1; k < bmap->n_ineq; ++k) {
867 h = hash_index(index, size, bits, bmap, k);
874 if (isl_int_lt(bmap->ineq[k][0], bmap->ineq[l][0]))
875 swap_inequality(bmap, k, l);
876 isl_basic_map_drop_inequality(ctx, bmap, k);
880 for (k = 0; k < bmap->n_ineq-1; ++k) {
881 isl_seq_neg(bmap->ineq[k]+1, bmap->ineq[k]+1, total);
882 h = hash_index(index, size, bits, bmap, k);
883 isl_seq_neg(bmap->ineq[k]+1, bmap->ineq[k]+1, total);
887 isl_int_add(sum, bmap->ineq[k][0], bmap->ineq[l][0]);
888 if (isl_int_is_pos(sum))
890 if (isl_int_is_zero(sum)) {
891 /* We need to break out of the loop after these
892 * changes since the contents of the hash
893 * will no longer be valid.
894 * Plus, we probably we want to regauss first.
896 isl_basic_map_drop_inequality(ctx, bmap, l);
897 isl_basic_map_inequality_to_equality(ctx, bmap, k);
899 bmap = isl_basic_map_set_to_empty(ctx, bmap);
908 static struct isl_basic_map *remove_duplicate_divs(struct isl_ctx *ctx,
909 struct isl_basic_map *bmap, int *progress)
916 unsigned total_var = bmap->nparam + bmap->n_in + bmap->n_out;
917 unsigned total = total_var + bmap->n_div;
919 if (bmap->n_div <= 1)
922 for (k = bmap->n_div - 1; k >= 0; --k)
923 if (!isl_int_is_zero(bmap->div[k][0]))
928 size = round_up(4 * bmap->n_div / 3 - 1);
929 bits = ffs(size) - 1;
930 index = isl_alloc_array(ctx, int, size);
931 memset(index, 0, size * sizeof(int));
934 eq = isl_blk_alloc(ctx, 1+total);
938 isl_seq_clr(eq.data, 1+total);
939 index[isl_seq_hash(bmap->div[k], 2+total, bits)] = k + 1;
940 for (--k; k >= 0; --k) {
943 if (isl_int_is_zero(bmap->div[k][0]))
946 hash = isl_seq_hash(bmap->div[k], 2+total, bits);
947 for (h = hash; index[h]; h = (h+1) % size)
948 if (isl_seq_eq(bmap->div[k],
949 bmap->div[index[h]-1], 2+total))
954 isl_int_set_si(eq.data[1+total_var+k], -1);
955 isl_int_set_si(eq.data[1+total_var+l], 1);
956 eliminate_div(ctx, bmap, eq.data, l);
957 isl_int_set_si(eq.data[1+total_var+k], 0);
958 isl_int_set_si(eq.data[1+total_var+l], 0);
963 isl_blk_free(ctx, eq);
969 static struct isl_basic_map *eliminate_divs(
970 struct isl_ctx *ctx, struct isl_basic_map *bmap,
981 off = 1 + bmap->nparam + bmap->n_in + bmap->n_out;
983 for (d = bmap->n_div - 1; d >= 0 ; --d) {
984 for (i = 0; i < bmap->n_eq; ++i) {
985 if (!isl_int_is_one(bmap->eq[i][off + d]) &&
986 !isl_int_is_negone(bmap->eq[i][off + d]))
990 eliminate_div(ctx, bmap, bmap->eq[i], d);
991 isl_basic_map_drop_equality(ctx, bmap, i);
995 return eliminate_divs(ctx, bmap, progress);
999 static struct isl_basic_map *normalize_constraints(
1000 struct isl_ctx *ctx, struct isl_basic_map *bmap)
1004 unsigned total = bmap->nparam + bmap->n_in + bmap->n_out + bmap->n_div;
1007 for (i = bmap->n_eq - 1; i >= 0; --i) {
1008 isl_seq_gcd(bmap->eq[i]+1, total, &gcd);
1009 if (isl_int_is_zero(gcd)) {
1010 if (!isl_int_is_zero(bmap->eq[i][0])) {
1011 bmap = isl_basic_map_set_to_empty(ctx, bmap);
1014 isl_basic_map_drop_equality(ctx, bmap, i);
1017 if (isl_int_is_one(gcd))
1019 if (!isl_int_is_divisible_by(bmap->eq[i][0], gcd)) {
1020 bmap = isl_basic_map_set_to_empty(ctx, bmap);
1023 isl_seq_scale_down(bmap->eq[i], bmap->eq[i], gcd, 1+total);
1026 for (i = bmap->n_ineq - 1; i >= 0; --i) {
1027 isl_seq_gcd(bmap->ineq[i]+1, total, &gcd);
1028 if (isl_int_is_zero(gcd)) {
1029 if (isl_int_is_neg(bmap->ineq[i][0])) {
1030 bmap = isl_basic_map_set_to_empty(ctx, bmap);
1033 isl_basic_map_drop_inequality(ctx, bmap, i);
1036 if (isl_int_is_one(gcd))
1038 isl_int_fdiv_q(bmap->ineq[i][0], bmap->ineq[i][0], gcd);
1039 isl_seq_scale_down(bmap->ineq[i]+1, bmap->ineq[i]+1, gcd, total);
1046 struct isl_basic_map *isl_basic_map_simplify(
1047 struct isl_ctx *ctx, struct isl_basic_map *bmap)
1054 bmap = normalize_constraints(ctx, bmap);
1055 bmap = eliminate_divs(ctx, bmap, &progress);
1056 bmap = isl_basic_map_gauss(ctx, bmap, &progress);
1057 bmap = remove_duplicate_divs(ctx, bmap, &progress);
1058 bmap = remove_duplicate_constraints(ctx, bmap, &progress);
1063 struct isl_basic_set *isl_basic_set_simplify(
1064 struct isl_ctx *ctx, struct isl_basic_set *bset)
1066 return (struct isl_basic_set *)
1067 isl_basic_map_simplify(ctx,
1068 (struct isl_basic_map *)bset);
1071 static void dump_term(struct isl_basic_map *bmap,
1072 isl_int c, int pos, FILE *out)
1074 unsigned in = bmap->n_in;
1075 unsigned dim = bmap->n_in + bmap->n_out;
1077 isl_int_print(out, c);
1079 if (!isl_int_is_one(c))
1080 isl_int_print(out, c);
1081 if (pos < 1 + bmap->nparam)
1082 fprintf(out, "p%d", pos - 1);
1083 else if (pos < 1 + bmap->nparam + in)
1084 fprintf(out, "i%d", pos - 1 - bmap->nparam);
1085 else if (pos < 1 + bmap->nparam + dim)
1086 fprintf(out, "o%d", pos - 1 - bmap->nparam - in);
1088 fprintf(out, "e%d", pos - 1 - bmap->nparam - dim);
1092 static void dump_constraint_sign(struct isl_basic_map *bmap, isl_int *c,
1093 int sign, FILE *out)
1097 unsigned len = 1 + bmap->nparam + bmap->n_in + bmap->n_out + bmap->n_div;
1101 for (i = 0, first = 1; i < len; ++i) {
1102 if (isl_int_sgn(c[i]) * sign <= 0)
1105 fprintf(out, " + ");
1107 isl_int_abs(v, c[i]);
1108 dump_term(bmap, v, i, out);
1115 static void dump_constraint(struct isl_basic_map *bmap, isl_int *c,
1116 const char *op, FILE *out, int indent)
1118 fprintf(out, "%*s", indent, "");
1120 dump_constraint_sign(bmap, c, 1, out);
1121 fprintf(out, " %s ", op);
1122 dump_constraint_sign(bmap, c, -1, out);
1127 static void dump_constraints(struct isl_basic_map *bmap,
1128 isl_int **c, unsigned n,
1129 const char *op, FILE *out, int indent)
1133 for (i = 0; i < n; ++i)
1134 dump_constraint(bmap, c[i], op, out, indent);
1137 static void dump_affine(struct isl_basic_map *bmap, isl_int *exp, FILE *out)
1141 unsigned total = bmap->nparam + bmap->n_in + bmap->n_out + bmap->n_div;
1143 for (j = 0; j < 1 + total; ++j) {
1144 if (isl_int_is_zero(exp[j]))
1146 if (!first && isl_int_is_pos(exp[j]))
1148 dump_term(bmap, exp[j], j, out);
1153 static void dump(struct isl_basic_map *bmap, FILE *out, int indent)
1157 dump_constraints(bmap, bmap->eq, bmap->n_eq, "=", out, indent);
1158 dump_constraints(bmap, bmap->ineq, bmap->n_ineq, ">=", out, indent);
1160 for (i = 0; i < bmap->n_div; ++i) {
1161 fprintf(out, "%*s", indent, "");
1162 fprintf(out, "e%d = [(", i);
1163 dump_affine(bmap, bmap->div[i]+1, out);
1165 isl_int_print(out, bmap->div[i][0]);
1166 fprintf(out, "]\n");
1170 void isl_basic_set_dump(struct isl_ctx *ctx, struct isl_basic_set *bset,
1171 FILE *out, int indent)
1173 fprintf(out, "%*s", indent, "");
1174 fprintf(out, "nparam: %d, dim: %d, extra: %d\n",
1175 bset->nparam, bset->dim, bset->extra);
1176 dump((struct isl_basic_map *)bset, out, indent);
1179 void isl_basic_map_dump(struct isl_ctx *ctx, struct isl_basic_map *bmap,
1180 FILE *out, int indent)
1182 fprintf(out, "%*s", indent, "");
1183 fprintf(out, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d\n",
1185 bmap->nparam, bmap->n_in, bmap->n_out, bmap->extra);
1186 dump(bmap, out, indent);
1189 int isl_inequality_negate(struct isl_ctx *ctx,
1190 struct isl_basic_map *bmap, unsigned pos)
1192 unsigned total = bmap->nparam + bmap->n_in + bmap->n_out + bmap->n_div;
1193 isl_assert(ctx, pos < bmap->n_ineq, return -1);
1194 isl_seq_neg(bmap->ineq[pos], bmap->ineq[pos], 1 + total);
1195 isl_int_sub_ui(bmap->ineq[pos][0], bmap->ineq[pos][0], 1);
1199 struct isl_set *isl_set_alloc(struct isl_ctx *ctx,
1200 unsigned nparam, unsigned dim, int n, unsigned flags)
1202 struct isl_set *set;
1204 set = isl_alloc(ctx, struct isl_set,
1205 sizeof(struct isl_set) +
1206 n * sizeof(struct isl_basic_set *));
1213 set->nparam = nparam;
1220 struct isl_set *isl_set_dup(struct isl_ctx *ctx, struct isl_set *set)
1223 struct isl_set *dup;
1225 dup = isl_set_alloc(ctx, set->nparam, set->dim, set->n, set->flags);
1228 for (i = 0; i < set->n; ++i)
1229 dup = isl_set_add(ctx, dup,
1230 isl_basic_set_dup(ctx, set->p[i]));
1234 struct isl_set *isl_set_from_basic_set(struct isl_ctx *ctx,
1235 struct isl_basic_set *bset)
1237 struct isl_set *set;
1239 set = isl_set_alloc(ctx, bset->nparam, bset->dim, 1, ISL_MAP_DISJOINT);
1241 isl_basic_set_free(ctx, bset);
1244 return isl_set_add(ctx, set, bset);
1247 struct isl_map *isl_map_from_basic_map(struct isl_ctx *ctx,
1248 struct isl_basic_map *bmap)
1250 struct isl_map *map;
1252 map = isl_map_alloc(ctx, bmap->nparam, bmap->n_in, bmap->n_out, 1,
1255 isl_basic_map_free(ctx, bmap);
1258 return isl_map_add(ctx, map, bmap);
1261 struct isl_set *isl_set_add(struct isl_ctx *ctx, struct isl_set *set,
1262 struct isl_basic_set *bset)
1266 isl_assert(ctx, set->nparam == bset->nparam, goto error);
1267 isl_assert(ctx, set->dim == bset->dim, goto error);
1268 isl_assert(ctx, set->n < set->size, goto error);
1269 set->p[set->n] = bset;
1274 isl_set_free(ctx, set);
1276 isl_basic_set_free(ctx, bset);
1280 void isl_set_free(struct isl_ctx *ctx, struct isl_set *set)
1290 for (i = 0; i < set->n; ++i)
1291 isl_basic_set_free(ctx, set->p[i]);
1295 void isl_set_dump(struct isl_ctx *ctx, struct isl_set *set, FILE *out,
1301 fprintf(out, "null set\n");
1305 fprintf(out, "%*s", indent, "");
1306 fprintf(out, "ref: %d, n: %d\n", set->ref, set->n);
1307 for (i = 0; i < set->n; ++i) {
1308 fprintf(out, "%*s", indent, "");
1309 fprintf(out, "basic set %d:\n", i);
1310 isl_basic_set_dump(ctx, set->p[i], out, indent+4);
1314 void isl_map_dump(struct isl_ctx *ctx, struct isl_map *map, FILE *out,
1319 fprintf(out, "%*s", indent, "");
1320 fprintf(out, "ref: %d, n: %d, nparam: %d, in: %d, out: %d\n",
1321 map->ref, map->n, map->nparam, map->n_in, map->n_out);
1322 for (i = 0; i < map->n; ++i) {
1323 fprintf(out, "%*s", indent, "");
1324 fprintf(out, "basic map %d:\n", i);
1325 isl_basic_map_dump(ctx, map->p[i], out, indent+4);
1329 struct isl_basic_map *isl_basic_map_intersect_domain(
1330 struct isl_ctx *ctx, struct isl_basic_map *bmap,
1331 struct isl_basic_set *bset)
1333 struct isl_basic_map *bmap_domain;
1338 isl_assert(ctx, bset->dim == bmap->n_in, goto error);
1339 isl_assert(ctx, bset->nparam == bmap->nparam, goto error);
1341 bmap = isl_basic_map_extend(ctx, bmap,
1342 bset->nparam, bmap->n_in, bmap->n_out,
1343 bset->n_div, bset->n_eq, bset->n_ineq);
1346 bmap_domain = isl_basic_map_from_basic_set(ctx, bset,
1348 bmap = add_constraints(ctx, bmap, bmap_domain, 0, 0);
1350 bmap = isl_basic_map_simplify(ctx, bmap);
1351 return isl_basic_map_finalize(ctx, bmap);
1353 isl_basic_map_free(ctx, bmap);
1354 isl_basic_set_free(ctx, bset);
1358 struct isl_basic_map *isl_basic_map_intersect_range(
1359 struct isl_ctx *ctx, struct isl_basic_map *bmap,
1360 struct isl_basic_set *bset)
1362 struct isl_basic_map *bmap_range;
1367 isl_assert(ctx, bset->dim == bmap->n_out, goto error);
1368 isl_assert(ctx, bset->nparam == bmap->nparam, goto error);
1370 bmap = isl_basic_map_extend(ctx, bmap,
1371 bset->nparam, bmap->n_in, bmap->n_out,
1372 bset->n_div, bset->n_eq, bset->n_ineq);
1375 bmap_range = isl_basic_map_from_basic_set(ctx, bset,
1377 bmap = add_constraints(ctx, bmap, bmap_range, 0, 0);
1379 bmap = isl_basic_map_simplify(ctx, bmap);
1380 return isl_basic_map_finalize(ctx, bmap);
1382 isl_basic_map_free(ctx, bmap);
1383 isl_basic_set_free(ctx, bset);
1387 struct isl_basic_map *isl_basic_map_intersect(
1388 struct isl_ctx *ctx, struct isl_basic_map *bmap1,
1389 struct isl_basic_map *bmap2)
1391 isl_assert(ctx, bmap1->nparam == bmap2->nparam, goto error);
1392 isl_assert(ctx, bmap1->n_in == bmap2->n_in, goto error);
1393 isl_assert(ctx, bmap1->n_out == bmap2->n_out, goto error);
1395 bmap1 = isl_basic_map_extend(ctx, bmap1,
1396 bmap1->nparam, bmap1->n_in, bmap1->n_out,
1397 bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
1400 bmap1 = add_constraints(ctx, bmap1, bmap2, 0, 0);
1402 bmap1 = isl_basic_map_simplify(ctx, bmap1);
1403 return isl_basic_map_finalize(ctx, bmap1);
1405 isl_basic_map_free(ctx, bmap1);
1406 isl_basic_map_free(ctx, bmap2);
1410 struct isl_basic_set *isl_basic_set_intersect(
1411 struct isl_ctx *ctx, struct isl_basic_set *bset1,
1412 struct isl_basic_set *bset2)
1414 return (struct isl_basic_set *)
1415 isl_basic_map_intersect(ctx,
1416 (struct isl_basic_map *)bset1,
1417 (struct isl_basic_map *)bset2);
1420 struct isl_map *isl_map_intersect(struct isl_ctx *ctx, struct isl_map *map1,
1421 struct isl_map *map2)
1424 struct isl_map *result;
1430 if (F_ISSET(map1, ISL_MAP_DISJOINT) &&
1431 F_ISSET(map2, ISL_MAP_DISJOINT))
1432 FL_SET(flags, ISL_MAP_DISJOINT);
1434 result = isl_map_alloc(ctx, map1->nparam, map1->n_in, map1->n_out,
1435 map1->n * map2->n, flags);
1438 for (i = 0; i < map1->n; ++i)
1439 for (j = 0; j < map2->n; ++j) {
1440 struct isl_basic_map *part;
1441 part = isl_basic_map_intersect(ctx,
1442 isl_basic_map_copy(ctx, map1->p[i]),
1443 isl_basic_map_copy(ctx, map2->p[j]));
1444 if (isl_basic_map_is_empty(ctx, part))
1445 isl_basic_map_free(ctx, part);
1447 result = isl_map_add(ctx, result, part);
1451 isl_map_free(ctx, map1);
1452 isl_map_free(ctx, map2);
1455 isl_map_free(ctx, map1);
1456 isl_map_free(ctx, map2);
1460 struct isl_basic_map *isl_basic_map_reverse(struct isl_ctx *ctx,
1461 struct isl_basic_map *bmap)
1463 struct isl_basic_set *bset;
1468 bmap = isl_basic_map_cow(ctx, bmap);
1472 bset = isl_basic_set_from_basic_map(ctx, bmap);
1473 bset = isl_basic_set_swap_vars(ctx, bset, in);
1474 return isl_basic_map_from_basic_set(ctx, bset, bset->dim-in, in);
1477 /* Turn final n dimensions into existentially quantified variables.
1479 struct isl_basic_set *isl_basic_set_project_out(
1480 struct isl_ctx *ctx, struct isl_basic_set *bset,
1481 unsigned n, unsigned flags)
1491 isl_assert(ctx, n <= bset->dim, goto error);
1496 bset = isl_basic_set_cow(ctx, bset);
1498 row_size = 1 + bset->nparam + bset->dim + bset->extra;
1499 old = bset->block2.data;
1500 bset->block2 = isl_blk_extend(ctx, bset->block2,
1501 (bset->extra + n) * (1 + row_size));
1502 if (!bset->block2.data)
1504 new_div = isl_alloc_array(ctx, isl_int *, bset->extra + n);
1507 for (i = 0; i < n; ++i) {
1508 new_div[i] = bset->block2.data +
1509 (bset->extra + i) * (1 + row_size);
1510 isl_seq_clr(new_div[i], 1 + row_size);
1512 for (i = 0; i < bset->extra; ++i)
1513 new_div[n + i] = bset->block2.data + (bset->div[i] - old);
1515 bset->div = new_div;
1519 bset = isl_basic_set_simplify(ctx, bset);
1520 return isl_basic_set_finalize(ctx, bset);
1522 isl_basic_set_free(ctx, bset);
1526 struct isl_basic_map *isl_basic_map_apply_range(
1527 struct isl_ctx *ctx, struct isl_basic_map *bmap1,
1528 struct isl_basic_map *bmap2)
1530 struct isl_basic_set *bset;
1531 unsigned n_in, n_out;
1533 if (!bmap1 || !bmap2)
1536 isl_assert(ctx, bmap1->n_out == bmap2->n_in, goto error);
1537 isl_assert(ctx, bmap1->nparam == bmap2->nparam, goto error);
1540 n_out = bmap2->n_out;
1542 bmap2 = isl_basic_map_reverse(ctx, bmap2);
1545 bmap1 = isl_basic_map_extend(ctx, bmap1, bmap1->nparam,
1546 bmap1->n_in + bmap2->n_in, bmap1->n_out,
1547 bmap2->extra, bmap2->n_eq, bmap2->n_ineq);
1550 bmap1 = add_constraints(ctx, bmap1, bmap2, bmap1->n_in - bmap2->n_in, 0);
1551 bmap1 = isl_basic_map_simplify(ctx, bmap1);
1552 bset = isl_basic_set_from_basic_map(ctx, bmap1);
1553 bset = isl_basic_set_project_out(ctx, bset,
1554 bset->dim - (n_in + n_out), 0);
1555 return isl_basic_map_from_basic_set(ctx, bset, n_in, n_out);
1557 isl_basic_map_free(ctx, bmap1);
1558 isl_basic_map_free(ctx, bmap2);
1562 struct isl_basic_map *isl_basic_map_apply_domain(
1563 struct isl_ctx *ctx, struct isl_basic_map *bmap1,
1564 struct isl_basic_map *bmap2)
1566 if (!bmap1 || !bmap2)
1569 isl_assert(ctx, bmap1->n_in == bmap2->n_in, goto error);
1570 isl_assert(ctx, bmap1->nparam == bmap2->nparam, goto error);
1572 bmap1 = isl_basic_map_reverse(ctx, bmap1);
1573 bmap1 = isl_basic_map_apply_range(ctx, bmap1, bmap2);
1574 return isl_basic_map_reverse(ctx, bmap1);
1576 isl_basic_map_free(ctx, bmap1);
1577 isl_basic_map_free(ctx, bmap2);
1581 static struct isl_basic_map *var_equal(struct isl_ctx *ctx,
1582 struct isl_basic_map *bmap, unsigned pos)
1585 i = isl_basic_map_alloc_equality(ctx, bmap);
1588 isl_seq_clr(bmap->eq[i],
1589 1 + bmap->nparam + bmap->n_in + bmap->n_out + bmap->extra);
1590 isl_int_set_si(bmap->eq[i][1+bmap->nparam+pos], -1);
1591 isl_int_set_si(bmap->eq[i][1+bmap->nparam+bmap->n_in+pos], 1);
1592 return isl_basic_map_finalize(ctx, bmap);
1594 isl_basic_map_free(ctx, bmap);
1598 static struct isl_basic_map *var_more(struct isl_ctx *ctx,
1599 struct isl_basic_map *bmap, unsigned pos)
1602 i = isl_basic_map_alloc_inequality(ctx, bmap);
1605 isl_seq_clr(bmap->ineq[i],
1606 1 + bmap->nparam + bmap->n_in + bmap->n_out + bmap->extra);
1607 isl_int_set_si(bmap->ineq[i][0], -1);
1608 isl_int_set_si(bmap->ineq[i][1+bmap->nparam+pos], -1);
1609 isl_int_set_si(bmap->ineq[i][1+bmap->nparam+bmap->n_in+pos], 1);
1610 return isl_basic_map_finalize(ctx, bmap);
1612 isl_basic_map_free(ctx, bmap);
1616 static struct isl_basic_map *var_less(struct isl_ctx *ctx,
1617 struct isl_basic_map *bmap, unsigned pos)
1620 i = isl_basic_map_alloc_inequality(ctx, bmap);
1623 isl_seq_clr(bmap->ineq[i],
1624 1 + bmap->nparam + bmap->n_in + bmap->n_out + bmap->extra);
1625 isl_int_set_si(bmap->ineq[i][0], -1);
1626 isl_int_set_si(bmap->ineq[i][1+bmap->nparam+pos], 1);
1627 isl_int_set_si(bmap->ineq[i][1+bmap->nparam+bmap->n_in+pos], -1);
1628 return isl_basic_map_finalize(ctx, bmap);
1630 isl_basic_map_free(ctx, bmap);
1634 struct isl_basic_map *isl_basic_map_equal(struct isl_ctx *ctx,
1635 unsigned nparam, unsigned in, unsigned out, unsigned n_equal)
1638 struct isl_basic_map *bmap;
1639 bmap = isl_basic_map_alloc(ctx, nparam, in, out, 0, n_equal, 0);
1642 for (i = 0; i < n_equal && bmap; ++i)
1643 bmap = var_equal(ctx, bmap, i);
1644 return isl_basic_map_finalize(ctx, bmap);
1647 struct isl_basic_map *isl_basic_map_less_at(struct isl_ctx *ctx,
1648 unsigned nparam, unsigned in, unsigned out, unsigned pos)
1651 struct isl_basic_map *bmap;
1652 bmap = isl_basic_map_alloc(ctx, nparam, in, out, 0, pos, 1);
1655 for (i = 0; i < pos && bmap; ++i)
1656 bmap = var_equal(ctx, bmap, i);
1658 bmap = var_less(ctx, bmap, pos);
1659 return isl_basic_map_finalize(ctx, bmap);
1662 struct isl_basic_map *isl_basic_map_more_at(struct isl_ctx *ctx,
1663 unsigned nparam, unsigned in, unsigned out, unsigned pos)
1666 struct isl_basic_map *bmap;
1667 bmap = isl_basic_map_alloc(ctx, nparam, in, out, 0, pos, 1);
1670 for (i = 0; i < pos && bmap; ++i)
1671 bmap = var_equal(ctx, bmap, i);
1673 bmap = var_more(ctx, bmap, pos);
1674 return isl_basic_map_finalize(ctx, bmap);
1677 struct isl_basic_map *isl_basic_map_from_basic_set(
1678 struct isl_ctx *ctx, struct isl_basic_set *bset,
1679 unsigned n_in, unsigned n_out)
1681 struct isl_basic_map *bmap;
1683 bset = isl_basic_set_cow(ctx, bset);
1687 isl_assert(ctx, bset->dim == n_in + n_out, goto error);
1688 bmap = (struct isl_basic_map *) bset;
1690 bmap->n_out = n_out;
1691 return isl_basic_map_finalize(ctx, bmap);
1693 isl_basic_set_free(ctx, bset);
1697 struct isl_basic_set *isl_basic_set_from_basic_map(
1698 struct isl_ctx *ctx, struct isl_basic_map *bmap)
1702 if (bmap->n_in == 0)
1703 return (struct isl_basic_set *)bmap;
1704 bmap = isl_basic_map_cow(ctx, bmap);
1707 bmap->n_out += bmap->n_in;
1709 bmap = isl_basic_map_finalize(ctx, bmap);
1710 return (struct isl_basic_set *)bmap;
1715 static struct isl_basic_set *isl_basic_map_underlying_set(
1716 struct isl_ctx *ctx, struct isl_basic_map *bmap)
1720 if (bmap->nparam == 0 && bmap->n_in == 0 && bmap->n_div == 0)
1721 return (struct isl_basic_set *)bmap;
1722 bmap = isl_basic_map_cow(ctx, bmap);
1725 bmap->n_out += bmap->nparam + bmap->n_in + bmap->n_div;
1729 bmap = isl_basic_map_finalize(ctx, bmap);
1730 return (struct isl_basic_set *)bmap;
1735 struct isl_basic_set *isl_basic_map_domain(struct isl_ctx *ctx,
1736 struct isl_basic_map *bmap)
1738 struct isl_basic_set *domain;
1742 n_out = bmap->n_out;
1743 domain = isl_basic_set_from_basic_map(ctx, bmap);
1744 return isl_basic_set_project_out(ctx, domain, n_out, 0);
1747 struct isl_basic_set *isl_basic_map_range(struct isl_ctx *ctx,
1748 struct isl_basic_map *bmap)
1750 return isl_basic_map_domain(ctx,
1751 isl_basic_map_reverse(ctx, bmap));
1754 struct isl_set *isl_map_range(struct isl_ctx *ctx, struct isl_map *map)
1757 struct isl_set *set;
1761 map = isl_map_cow(ctx, map);
1765 set = (struct isl_set *) map;
1767 for (i = 0; i < map->n; ++i) {
1768 set->p[i] = isl_basic_map_range(ctx, map->p[i]);
1772 F_CLR(set, ISL_MAP_DISJOINT);
1775 isl_map_free(ctx, map);
1779 struct isl_map *isl_map_from_set(
1780 struct isl_ctx *ctx, struct isl_set *set,
1781 unsigned n_in, unsigned n_out)
1784 struct isl_map *map = NULL;
1788 isl_assert(ctx, set->dim == n_in + n_out, goto error);
1789 set = isl_set_cow(ctx, set);
1792 map = (struct isl_map *)set;
1793 for (i = 0; i < set->n; ++i) {
1794 map->p[i] = isl_basic_map_from_basic_set(ctx,
1795 set->p[i], n_in, n_out);
1803 isl_set_free(ctx, set);
1807 struct isl_map *isl_map_alloc(struct isl_ctx *ctx,
1808 unsigned nparam, unsigned in, unsigned out, int n,
1811 struct isl_map *map;
1813 map = isl_alloc(ctx, struct isl_map,
1814 sizeof(struct isl_map) +
1815 n * sizeof(struct isl_basic_map *));
1822 map->nparam = nparam;
1829 struct isl_basic_map *isl_basic_map_empty(struct isl_ctx *ctx,
1830 unsigned nparam, unsigned in, unsigned out)
1832 struct isl_basic_map *bmap;
1833 bmap = isl_basic_map_alloc(ctx, nparam, in, out, 0, 1, 0);
1834 bmap = isl_basic_map_set_to_empty(ctx, bmap);
1838 struct isl_map *isl_map_empty(struct isl_ctx *ctx,
1839 unsigned nparam, unsigned in, unsigned out)
1841 return isl_map_alloc(ctx, nparam, in, out, 0, ISL_MAP_DISJOINT);
1844 struct isl_set *isl_set_empty(struct isl_ctx *ctx,
1845 unsigned nparam, unsigned dim)
1847 return isl_set_alloc(ctx, nparam, dim, 0, ISL_MAP_DISJOINT);
1850 struct isl_map *isl_map_dup(struct isl_ctx *ctx, struct isl_map *map)
1853 struct isl_map *dup;
1855 dup = isl_map_alloc(ctx, map->nparam, map->n_in, map->n_out, map->n,
1857 for (i = 0; i < map->n; ++i)
1858 dup = isl_map_add(ctx, dup,
1859 isl_basic_map_dup(ctx, map->p[i]));
1863 struct isl_map *isl_map_add(struct isl_ctx *ctx, struct isl_map *map,
1864 struct isl_basic_map *bmap)
1868 isl_assert(ctx, map->nparam == bmap->nparam, goto error);
1869 isl_assert(ctx, map->n_in == bmap->n_in, goto error);
1870 isl_assert(ctx, map->n_out == bmap->n_out, goto error);
1871 isl_assert(ctx, map->n < map->size, goto error);
1872 map->p[map->n] = bmap;
1877 isl_map_free(ctx, map);
1879 isl_basic_map_free(ctx, bmap);
1883 void isl_map_free(struct isl_ctx *ctx, struct isl_map *map)
1893 for (i = 0; i < map->n; ++i)
1894 isl_basic_map_free(ctx, map->p[i]);
1898 struct isl_map *isl_map_extend(struct isl_ctx *ctx, struct isl_map *base,
1899 unsigned nparam, unsigned n_in, unsigned n_out)
1903 base = isl_map_cow(ctx, base);
1907 isl_assert(ctx, base->nparam <= nparam, goto error);
1908 isl_assert(ctx, base->n_in <= n_in, goto error);
1909 isl_assert(ctx, base->n_out <= n_out, goto error);
1910 base->nparam = nparam;
1912 base->n_out = n_out;
1913 for (i = 0; i < base->n; ++i) {
1914 base->p[i] = isl_basic_map_extend(ctx, base->p[i],
1915 nparam, n_in, n_out, 0, 0, 0);
1921 isl_map_free(ctx, base);
1925 struct isl_basic_map *isl_basic_map_fix_input_si(struct isl_ctx *ctx,
1926 struct isl_basic_map *bmap,
1927 unsigned input, int value)
1931 bmap = isl_basic_map_cow(ctx, bmap);
1934 isl_assert(ctx, input < bmap->n_in, goto error);
1936 bmap = isl_basic_map_extend(ctx, bmap,
1937 bmap->nparam, bmap->n_in, bmap->n_out, 0, 1, 0);
1938 j = isl_basic_map_alloc_equality(ctx, bmap);
1941 isl_int_set_si(bmap->eq[j][1+bmap->nparam+input], -1);
1942 isl_int_set_si(bmap->eq[j][0], value);
1943 bmap = isl_basic_map_simplify(ctx, bmap);
1944 return isl_basic_map_finalize(ctx, bmap);
1946 isl_basic_map_free(ctx, bmap);
1950 struct isl_map *isl_map_fix_input_si(struct isl_ctx *ctx, struct isl_map *map,
1951 unsigned input, int value)
1955 map = isl_map_cow(ctx, map);
1959 isl_assert(ctx, input < map->n_in, goto error);
1960 for (i = 0; i < map->n; ++i) {
1961 map->p[i] = isl_basic_map_fix_input_si(ctx, map->p[i],
1968 isl_map_free(ctx, map);
1972 struct isl_map *isl_map_reverse(struct isl_ctx *ctx, struct isl_map *map)
1977 map = isl_map_cow(ctx, map);
1982 map->n_in = map->n_out;
1984 for (i = 0; i < map->n; ++i) {
1985 map->p[i] = isl_basic_map_reverse(ctx, map->p[i]);
1991 isl_map_free(ctx, map);
1995 struct isl_map *isl_basic_map_lexmax(struct isl_ctx *ctx,
1996 struct isl_basic_map *bmap, struct isl_basic_set *dom,
1997 struct isl_set **empty)
1999 return isl_pip_basic_map_lexmax(ctx, bmap, dom, empty);
2002 struct isl_map *isl_basic_map_lexmin(struct isl_ctx *ctx,
2003 struct isl_basic_map *bmap, struct isl_basic_set *dom,
2004 struct isl_set **empty)
2006 return isl_pip_basic_map_lexmin(ctx, bmap, dom, empty);
2009 struct isl_set *isl_basic_set_lexmin(struct isl_ctx *ctx,
2010 struct isl_basic_set *bset)
2012 struct isl_basic_map *bmap = NULL;
2013 struct isl_basic_set *dom = NULL;
2014 struct isl_map *min;
2018 bmap = isl_basic_map_from_basic_set(ctx, bset, 0, bset->dim);
2021 dom = isl_basic_set_alloc(ctx, bmap->nparam, 0, 0, 0, 0);
2024 min = isl_basic_map_lexmin(ctx, bmap, dom, NULL);
2025 return isl_map_range(ctx, min);
2027 isl_basic_map_free(ctx, bmap);
2031 struct isl_map *isl_basic_map_compute_divs(struct isl_ctx *ctx,
2032 struct isl_basic_map *bmap)
2034 if (bmap->n_div == 0)
2035 return isl_map_from_basic_map(ctx, bmap);
2036 return isl_pip_basic_map_compute_divs(ctx, bmap);
2039 struct isl_map *isl_map_compute_divs(struct isl_ctx *ctx, struct isl_map *map)
2042 struct isl_map *res;
2048 res = isl_basic_map_compute_divs(ctx,
2049 isl_basic_map_copy(ctx, map->p[0]));
2050 for (i = 1 ; i < map->n; ++i) {
2052 r2 = isl_basic_map_compute_divs(ctx,
2053 isl_basic_map_copy(ctx, map->p[i]));
2054 if (F_ISSET(map, ISL_MAP_DISJOINT))
2055 res = isl_map_union_disjoint(ctx, res, r2);
2057 res = isl_map_union(ctx, res, r2);
2059 isl_map_free(ctx, map);
2064 struct isl_set *isl_basic_set_compute_divs(struct isl_ctx *ctx,
2065 struct isl_basic_set *bset)
2067 return (struct isl_set *)
2068 isl_basic_map_compute_divs(ctx,
2069 (struct isl_basic_map *)bset);
2072 struct isl_set *isl_map_domain(struct isl_ctx *ctx, struct isl_map *map)
2075 struct isl_set *set;
2080 map = isl_map_cow(ctx, map);
2084 set = (struct isl_set *)map;
2085 set->dim = map->n_in;
2087 for (i = 0; i < map->n; ++i) {
2088 set->p[i] = isl_basic_map_domain(ctx, map->p[i]);
2092 F_CLR(set, ISL_MAP_DISJOINT);
2095 isl_map_free(ctx, map);
2099 struct isl_map *isl_map_union_disjoint(struct isl_ctx *ctx,
2100 struct isl_map *map1, struct isl_map *map2)
2104 struct isl_map *map = NULL;
2110 isl_map_free(ctx, map1);
2114 isl_map_free(ctx, map2);
2118 isl_assert(ctx, map1->nparam == map2->nparam, goto error);
2119 isl_assert(ctx, map1->n_in == map2->n_in, goto error);
2120 isl_assert(ctx, map1->n_out == map2->n_out, goto error);
2122 if (F_ISSET(map1, ISL_MAP_DISJOINT) &&
2123 F_ISSET(map2, ISL_MAP_DISJOINT))
2124 FL_SET(flags, ISL_MAP_DISJOINT);
2126 map = isl_map_alloc(ctx, map1->nparam, map1->n_in, map1->n_out,
2127 map1->n + map2->n, flags);
2130 for (i = 0; i < map1->n; ++i) {
2131 map = isl_map_add(ctx, map,
2132 isl_basic_map_copy(ctx, map1->p[i]));
2136 for (i = 0; i < map2->n; ++i) {
2137 map = isl_map_add(ctx, map,
2138 isl_basic_map_copy(ctx, map2->p[i]));
2142 isl_map_free(ctx, map1);
2143 isl_map_free(ctx, map2);
2146 isl_map_free(ctx, map);
2147 isl_map_free(ctx, map1);
2148 isl_map_free(ctx, map2);
2152 struct isl_map *isl_map_union(struct isl_ctx *ctx,
2153 struct isl_map *map1, struct isl_map *map2)
2155 map1 = isl_map_union_disjoint(ctx, map1, map2);
2159 F_CLR(map1, ISL_MAP_DISJOINT);
2163 struct isl_set *isl_set_union_disjoint(struct isl_ctx *ctx,
2164 struct isl_set *set1, struct isl_set *set2)
2166 return (struct isl_set *)
2167 isl_map_union_disjoint(ctx,
2168 (struct isl_map *)set1, (struct isl_map *)set2);
2171 struct isl_set *isl_set_union(struct isl_ctx *ctx,
2172 struct isl_set *set1, struct isl_set *set2)
2174 return (struct isl_set *)
2176 (struct isl_map *)set1, (struct isl_map *)set2);
2179 struct isl_map *isl_map_intersect_range(
2180 struct isl_ctx *ctx, struct isl_map *map,
2181 struct isl_set *set)
2184 struct isl_map *result;
2190 if (F_ISSET(map, ISL_MAP_DISJOINT) &&
2191 F_ISSET(set, ISL_MAP_DISJOINT))
2192 FL_SET(flags, ISL_MAP_DISJOINT);
2194 result = isl_map_alloc(ctx, map->nparam, map->n_in, map->n_out,
2195 map->n * set->n, flags);
2198 for (i = 0; i < map->n; ++i)
2199 for (j = 0; j < set->n; ++j) {
2200 result = isl_map_add(ctx, result,
2201 isl_basic_map_intersect_range(ctx,
2202 isl_basic_map_copy(ctx, map->p[i]),
2203 isl_basic_set_copy(ctx, set->p[j])));
2207 isl_map_free(ctx, map);
2208 isl_set_free(ctx, set);
2211 isl_map_free(ctx, map);
2212 isl_set_free(ctx, set);
2216 struct isl_map *isl_map_intersect_domain(
2217 struct isl_ctx *ctx, struct isl_map *map,
2218 struct isl_set *set)
2220 return isl_map_reverse(ctx,
2221 isl_map_intersect_range(ctx, isl_map_reverse(ctx, map), set));
2224 struct isl_map *isl_map_apply_domain(
2225 struct isl_ctx *ctx, struct isl_map *map1,
2226 struct isl_map *map2)
2230 map1 = isl_map_reverse(ctx, map1);
2231 map1 = isl_map_apply_range(ctx, map1, map2);
2232 return isl_map_reverse(ctx, map1);
2234 isl_map_free(ctx, map1);
2235 isl_map_free(ctx, map2);
2239 struct isl_map *isl_map_apply_range(
2240 struct isl_ctx *ctx, struct isl_map *map1,
2241 struct isl_map *map2)
2243 struct isl_map *result;
2249 isl_assert(ctx, map1->nparam == map2->nparam, goto error);
2250 isl_assert(ctx, map1->n_out == map2->n_in, goto error);
2252 result = isl_map_alloc(ctx, map1->nparam, map1->n_in, map2->n_out,
2253 map1->n * map2->n, 0);
2256 for (i = 0; i < map1->n; ++i)
2257 for (j = 0; j < map2->n; ++j) {
2258 result = isl_map_add(ctx, result,
2259 isl_basic_map_apply_range(ctx,
2260 isl_basic_map_copy(ctx, map1->p[i]),
2261 isl_basic_map_copy(ctx, map2->p[j])));
2265 isl_map_free(ctx, map1);
2266 isl_map_free(ctx, map2);
2269 isl_map_free(ctx, map1);
2270 isl_map_free(ctx, map2);
2275 * returns range - domain
2277 struct isl_basic_set *isl_basic_map_deltas(struct isl_ctx *ctx,
2278 struct isl_basic_map *bmap)
2280 struct isl_basic_set *bset;
2286 isl_assert(ctx, bmap->n_in == bmap->n_out, goto error);
2288 bset = isl_basic_set_from_basic_map(ctx, bmap);
2289 bset = isl_basic_set_extend(ctx, bset, bset->nparam, 3*dim, 0,
2291 bset = isl_basic_set_swap_vars(ctx, bset, 2*dim);
2292 for (i = 0; i < dim; ++i) {
2293 int j = isl_basic_map_alloc_equality(ctx,
2294 (struct isl_basic_map *)bset);
2297 isl_int_set_si(bset->eq[j][1+bset->nparam+i], 1);
2298 isl_int_set_si(bset->eq[j][1+bset->nparam+dim+i], 1);
2299 isl_int_set_si(bset->eq[j][1+bset->nparam+2*dim+i], -1);
2301 return isl_basic_set_project_out(ctx, bset, 2*dim, 0);
2303 isl_basic_map_free(ctx, bmap);
2307 /* If the only constraints a div d=floor(f/m)
2308 * appears in are its two defining constraints
2311 * -(f - (m - 1)) + m d >= 0
2313 * then it can safely be removed.
2315 static int div_is_redundant(struct isl_ctx *ctx, struct isl_basic_map *bmap,
2319 unsigned pos = 1 + bmap->nparam + bmap->n_in + bmap->n_out + div;
2321 for (i = 0; i < bmap->n_eq; ++i)
2322 if (!isl_int_is_zero(bmap->eq[i][pos]))
2325 for (i = 0; i < bmap->n_ineq; ++i) {
2326 if (isl_int_is_zero(bmap->ineq[i][pos]))
2328 if (isl_int_eq(bmap->ineq[i][pos], bmap->div[div][0])) {
2330 isl_int_sub(bmap->div[div][1],
2331 bmap->div[div][1], bmap->div[div][0]);
2332 isl_int_add_ui(bmap->div[div][1], bmap->div[div][1], 1);
2333 neg = isl_seq_is_neg(bmap->ineq[i], bmap->div[div]+1, pos);
2334 isl_int_sub_ui(bmap->div[div][1], bmap->div[div][1], 1);
2335 isl_int_add(bmap->div[div][1],
2336 bmap->div[div][1], bmap->div[div][0]);
2339 if (isl_seq_first_non_zero(bmap->ineq[i]+pos+1,
2340 bmap->n_div-div-1) != -1)
2342 } else if (isl_int_abs_eq(bmap->ineq[i][pos], bmap->div[div][0])) {
2343 if (!isl_seq_eq(bmap->ineq[i], bmap->div[div]+1, pos))
2345 if (isl_seq_first_non_zero(bmap->ineq[i]+pos+1,
2346 bmap->n_div-div-1) != -1)
2352 for (i = 0; i < bmap->n_div; ++i)
2353 if (!isl_int_is_zero(bmap->div[i][1+pos]))
2360 * Remove divs that don't occur in any of the constraints or other divs.
2361 * These can arise when dropping some of the variables in a quast
2362 * returned by piplib.
2364 static struct isl_basic_map *remove_redundant_divs(struct isl_ctx *ctx,
2365 struct isl_basic_map *bmap)
2369 for (i = bmap->n_div-1; i >= 0; --i) {
2370 if (!div_is_redundant(ctx, bmap, i))
2372 bmap = isl_basic_map_drop_div(ctx, bmap, i);
2377 struct isl_basic_map *isl_basic_map_finalize(struct isl_ctx *ctx,
2378 struct isl_basic_map *bmap)
2380 bmap = remove_redundant_divs(ctx, bmap);
2383 F_SET(bmap, ISL_BASIC_SET_FINAL);
2387 struct isl_basic_set *isl_basic_set_finalize(struct isl_ctx *ctx,
2388 struct isl_basic_set *bset)
2390 return (struct isl_basic_set *)
2391 isl_basic_map_finalize(ctx,
2392 (struct isl_basic_map *)bset);
2395 struct isl_set *isl_set_finalize(struct isl_ctx *ctx, struct isl_set *set)
2401 for (i = 0; i < set->n; ++i) {
2402 set->p[i] = isl_basic_set_finalize(ctx, set->p[i]);
2408 isl_set_free(ctx, set);
2412 struct isl_map *isl_map_finalize(struct isl_ctx *ctx, struct isl_map *map)
2418 for (i = 0; i < map->n; ++i) {
2419 map->p[i] = isl_basic_map_finalize(ctx, map->p[i]);
2425 isl_map_free(ctx, map);
2429 struct isl_basic_map *isl_basic_map_identity(struct isl_ctx *ctx,
2430 unsigned nparam, unsigned dim)
2432 struct isl_basic_map *bmap;
2435 bmap = isl_basic_map_alloc(ctx, nparam, dim, dim, 0, dim, 0);
2439 for (i = 0; i < dim; ++i) {
2440 int j = isl_basic_map_alloc_equality(ctx, bmap);
2443 isl_int_set_si(bmap->eq[j][1+nparam+i], 1);
2444 isl_int_set_si(bmap->eq[j][1+nparam+dim+i], -1);
2446 return isl_basic_map_finalize(ctx, bmap);
2448 isl_basic_map_free(ctx, bmap);
2452 struct isl_map *isl_map_identity(struct isl_ctx *ctx,
2453 unsigned nparam, unsigned dim)
2455 struct isl_map *map = isl_map_alloc(ctx, nparam, dim, dim, 1,
2459 map = isl_map_add(ctx, map,
2460 isl_basic_map_identity(ctx, nparam, dim));
2463 isl_map_free(ctx, map);
2467 int isl_set_is_equal(struct isl_ctx *ctx,
2468 struct isl_set *set1, struct isl_set *set2)
2470 return isl_map_is_equal(ctx,
2471 (struct isl_map *)set1, (struct isl_map *)set2);
2474 int isl_set_is_subset(struct isl_ctx *ctx,
2475 struct isl_set *set1, struct isl_set *set2)
2477 return isl_map_is_subset(ctx,
2478 (struct isl_map *)set1, (struct isl_map *)set2);
2481 int isl_basic_map_is_subset(struct isl_ctx *ctx,
2482 struct isl_basic_map *bmap1,
2483 struct isl_basic_map *bmap2)
2486 struct isl_map *map1;
2487 struct isl_map *map2;
2489 if (!bmap1 || !bmap2)
2492 map1 = isl_map_from_basic_map(ctx,
2493 isl_basic_map_copy(ctx, bmap1));
2494 map2 = isl_map_from_basic_map(ctx,
2495 isl_basic_map_copy(ctx, bmap2));
2497 is_subset = isl_map_is_subset(ctx, map1, map2);
2499 isl_map_free(ctx, map1);
2500 isl_map_free(ctx, map2);
2505 int isl_map_is_empty(struct isl_ctx *ctx, struct isl_map *map)
2512 for (i = 0; i < map->n; ++i) {
2513 is_empty = isl_basic_map_is_empty(ctx, map->p[i]);
2522 int isl_set_is_empty(struct isl_ctx *ctx, struct isl_set *set)
2524 return isl_map_is_empty(ctx, (struct isl_map *)set);
2527 int isl_map_is_subset(struct isl_ctx *ctx, struct isl_map *map1,
2528 struct isl_map *map2)
2532 struct isl_map *diff;
2537 if (isl_map_is_empty(ctx, map1))
2540 if (isl_map_is_empty(ctx, map2))
2543 diff = isl_map_subtract(ctx, isl_map_copy(ctx, map1),
2544 isl_map_copy(ctx, map2));
2548 is_subset = isl_map_is_empty(ctx, diff);
2549 isl_map_free(ctx, diff);
2554 int isl_map_is_equal(struct isl_ctx *ctx,
2555 struct isl_map *map1, struct isl_map *map2)
2561 is_subset = isl_map_is_subset(ctx, map1, map2);
2564 is_subset = isl_map_is_subset(ctx, map2, map1);
2568 int isl_basic_map_is_strict_subset(struct isl_ctx *ctx,
2569 struct isl_basic_map *bmap1,
2570 struct isl_basic_map *bmap2)
2574 if (!bmap1 || !bmap2)
2576 is_subset = isl_basic_map_is_subset(ctx, bmap1, bmap2);
2579 is_subset = isl_basic_map_is_subset(ctx, bmap2, bmap1);
2580 if (is_subset == -1)
2585 int isl_basic_map_is_empty(struct isl_ctx *ctx,
2586 struct isl_basic_map *bmap)
2588 struct isl_basic_set *bset = NULL;
2589 struct isl_vec *sample = NULL;
2595 if (F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
2598 bset = isl_basic_map_underlying_set(ctx,
2599 isl_basic_map_copy(ctx, bmap));
2602 sample = isl_basic_set_sample(ctx, bset);
2605 empty = sample->size == 0;
2606 isl_vec_free(ctx, sample);
2611 struct isl_map *isl_basic_map_union(
2612 struct isl_ctx *ctx, struct isl_basic_map *bmap1,
2613 struct isl_basic_map *bmap2)
2615 struct isl_map *map;
2616 if (!bmap1 || !bmap2)
2619 isl_assert(ctx, bmap1->nparam == bmap2->nparam, goto error);
2620 isl_assert(ctx, bmap1->n_in == bmap2->n_in, goto error);
2621 isl_assert(ctx, bmap1->n_out == bmap2->n_out, goto error);
2623 map = isl_map_alloc(ctx, bmap1->nparam,
2624 bmap1->n_in, bmap1->n_out, 2, 0);
2627 map = isl_map_add(ctx, map, bmap1);
2628 map = isl_map_add(ctx, map, bmap2);
2631 isl_basic_map_free(ctx, bmap1);
2632 isl_basic_map_free(ctx, bmap2);
2636 struct isl_set *isl_basic_set_union(
2637 struct isl_ctx *ctx, struct isl_basic_set *bset1,
2638 struct isl_basic_set *bset2)
2640 return (struct isl_set *)isl_basic_map_union(ctx,
2641 (struct isl_basic_map *)bset1,
2642 (struct isl_basic_map *)bset2);
2645 /* Order divs such that any div only depends on previous divs */
2646 static struct isl_basic_map *order_divs(struct isl_ctx *ctx,
2647 struct isl_basic_map *bmap)
2650 unsigned off = bmap->nparam + bmap->n_in + bmap->n_out;
2652 for (i = 0; i < bmap->n_div; ++i) {
2654 pos = isl_seq_first_non_zero(bmap->div[i]+1+1+off+i,
2658 swap_div(bmap, i, pos);
2664 static int find_div(struct isl_basic_map *dst,
2665 struct isl_basic_map *src, unsigned div)
2669 unsigned total = src->nparam + src->n_in + src->n_out + src->n_div;
2671 for (i = 0; i < dst->n_div; ++i)
2672 if (isl_seq_eq(dst->div[i], src->div[div], 1+1+total) &&
2673 isl_seq_first_non_zero(dst->div[i]+1+1+total,
2674 dst->n_div - src->n_div) == -1)
2679 /* For a div d = floor(f/m), add the constraints
2682 * -(f-(n-1)) + m d >= 0
2684 * Note that the second constraint is the negation of
2688 static int add_div_constraints(struct isl_ctx *ctx,
2689 struct isl_basic_map *bmap, unsigned div)
2692 unsigned div_pos = 1 + bmap->nparam + bmap->n_in + bmap->n_out + div;
2693 unsigned total = bmap->nparam + bmap->n_in + bmap->n_out + bmap->n_div;
2695 i = isl_basic_map_alloc_inequality(ctx, bmap);
2698 isl_seq_cpy(bmap->ineq[i], bmap->div[div]+1, 1+total);
2699 isl_int_neg(bmap->ineq[i][div_pos], bmap->div[div][0]);
2701 j = isl_basic_map_alloc_inequality(ctx, bmap);
2704 isl_seq_neg(bmap->ineq[j], bmap->ineq[i], 1 + total);
2705 isl_int_add(bmap->ineq[j][0], bmap->ineq[j][0], bmap->ineq[j][div_pos]);
2706 isl_int_sub_ui(bmap->ineq[j][0], bmap->ineq[j][0], 1);
2710 struct isl_basic_map *isl_basic_map_align_divs(struct isl_ctx *ctx,
2711 struct isl_basic_map *dst, struct isl_basic_map *src)
2714 unsigned total = src->nparam + src->n_in + src->n_out + src->n_div;
2716 if (src->n_div == 0)
2719 src = order_divs(ctx, src);
2720 dst = isl_basic_map_extend(ctx, dst, dst->nparam, dst->n_in,
2721 dst->n_out, src->n_div, 0, 2 * src->n_div);
2724 for (i = 0; i < src->n_div; ++i) {
2725 int j = find_div(dst, src, i);
2727 j = isl_basic_map_alloc_div(ctx, dst);
2730 isl_seq_cpy(dst->div[j], src->div[i], 1+1+total);
2731 if (add_div_constraints(ctx, dst, j) < 0)
2735 swap_div(dst, i, j);
2739 isl_basic_map_free(ctx, dst);
2743 static struct isl_map *add_cut_constraint(struct isl_ctx *ctx,
2744 struct isl_map *dst,
2745 struct isl_basic_map *src, isl_int *c,
2746 unsigned len, unsigned extra, int oppose)
2748 struct isl_basic_map *copy = NULL;
2752 copy = isl_basic_map_copy(ctx, src);
2753 copy = isl_basic_map_cow(ctx, copy);
2756 copy = isl_basic_map_extend(ctx, copy,
2757 copy->nparam, copy->n_in, copy->n_out, 0, 0, 1);
2758 k = isl_basic_map_alloc_inequality(ctx, copy);
2762 isl_seq_neg(copy->ineq[k], c, len);
2764 isl_seq_cpy(copy->ineq[k], c, len);
2765 isl_seq_clr(copy->ineq[k]+len, extra);
2766 isl_inequality_negate(ctx, copy, k);
2767 copy = isl_basic_map_simplify(ctx, copy);
2768 copy = isl_basic_map_finalize(ctx, copy);
2769 is_empty = isl_basic_map_is_empty(ctx, copy);
2773 dst = isl_map_add(ctx, dst, copy);
2775 isl_basic_map_free(ctx, copy);
2778 isl_basic_map_free(ctx, copy);
2779 isl_map_free(ctx, dst);
2783 static struct isl_map *subtract(struct isl_ctx *ctx, struct isl_map *map,
2784 struct isl_basic_map *bmap)
2788 struct isl_map *rest = NULL;
2790 unsigned total = bmap->nparam + bmap->n_in + bmap->n_out + bmap->n_div;
2797 if (F_ISSET(map, ISL_MAP_DISJOINT))
2798 FL_SET(flags, ISL_MAP_DISJOINT);
2800 max = map->n * (2 * bmap->n_eq + bmap->n_ineq);
2801 rest = isl_map_alloc(ctx, map->nparam, map->n_in, map->n_out,
2806 for (i = 0; i < map->n; ++i) {
2807 map->p[i] = isl_basic_map_align_divs(ctx, map->p[i], bmap);
2812 for (j = 0; j < map->n; ++j)
2813 map->p[j] = isl_basic_map_cow(ctx, map->p[j]);
2815 for (i = 0; i < bmap->n_eq; ++i) {
2816 for (j = 0; j < map->n; ++j) {
2817 rest = add_cut_constraint(ctx, rest,
2818 map->p[j], bmap->eq[i],
2819 1+total, map->p[j]->n_div - bmap->n_div, 0);
2823 rest = add_cut_constraint(ctx, rest,
2824 map->p[j], bmap->eq[i],
2825 1+total, map->p[j]->n_div - bmap->n_div, 1);
2829 map->p[j] = isl_basic_map_extend(ctx, map->p[j],
2830 map->p[j]->nparam, map->p[j]->n_in,
2831 map->p[j]->n_out, 0, 1, 0);
2834 k = isl_basic_map_alloc_equality(ctx, map->p[j]);
2837 isl_seq_cpy(map->p[j]->eq[k], bmap->eq[i], 1+total);
2838 isl_seq_clr(map->p[j]->eq[k]+1+total,
2839 map->p[j]->n_div - bmap->n_div);
2843 for (i = 0; i < bmap->n_ineq; ++i) {
2844 for (j = 0; j < map->n; ++j) {
2845 rest = add_cut_constraint(ctx, rest,
2846 map->p[j], bmap->ineq[i],
2847 1+total, map->p[j]->n_div - bmap->n_div, 0);
2851 map->p[j] = isl_basic_map_extend(ctx, map->p[j],
2852 map->p[j]->nparam, map->p[j]->n_in,
2853 map->p[j]->n_out, 0, 0, 1);
2856 k = isl_basic_map_alloc_inequality(ctx, map->p[j]);
2859 isl_seq_cpy(map->p[j]->ineq[k], bmap->ineq[i], 1+total);
2860 isl_seq_clr(map->p[j]->ineq[k]+1+total,
2861 map->p[j]->n_div - bmap->n_div);
2865 isl_map_free(ctx, map);
2868 isl_map_free(ctx, map);
2869 isl_map_free(ctx, rest);
2873 struct isl_map *isl_map_subtract(struct isl_ctx *ctx, struct isl_map *map1,
2874 struct isl_map *map2)
2880 isl_assert(ctx, map1->nparam == map2->nparam, goto error);
2881 isl_assert(ctx, map1->n_in == map2->n_in, goto error);
2882 isl_assert(ctx, map1->n_out == map2->n_out, goto error);
2884 if (isl_map_is_empty(ctx, map2)) {
2885 isl_map_free(ctx, map2);
2889 map1 = isl_map_compute_divs(ctx, map1);
2890 map2 = isl_map_compute_divs(ctx, map2);
2894 for (i = 0; map1 && i < map2->n; ++i)
2895 map1 = subtract(ctx, map1, map2->p[i]);
2897 isl_map_free(ctx, map2);
2900 isl_map_free(ctx, map1);
2901 isl_map_free(ctx, map2);
2905 struct isl_set *isl_set_subtract(struct isl_ctx *ctx, struct isl_set *set1,
2906 struct isl_set *set2)
2908 return (struct isl_set *)
2909 isl_map_subtract(ctx,
2910 (struct isl_map *)set1, (struct isl_map *)set2);
2913 struct isl_set *isl_set_apply(struct isl_ctx *ctx, struct isl_set *set,
2914 struct isl_map *map)
2916 isl_assert(ctx, set->dim == map->n_in, goto error);
2917 map = isl_map_intersect_domain(ctx, map, set);
2918 set = isl_map_range(ctx, map);
2921 isl_set_free(ctx, set);
2922 isl_map_free(ctx, map);