6 #include "isl_equalities.h"
12 #include "isl_map_private.h"
13 #include "isl_map_piplib.h"
14 #include "isl_sample.h"
17 /* Maps dst positions to src positions */
23 static struct isl_dim_map *isl_dim_map_alloc(struct isl_ctx *ctx, unsigned len)
26 struct isl_dim_map *dim_map;
27 dim_map = isl_alloc(ctx, struct isl_dim_map,
28 sizeof(struct isl_dim_map) + len * sizeof(int));
31 dim_map->len = 1 + len;
33 for (i = 0; i < len; ++i)
34 dim_map->pos[1 + i] = -1;
38 static unsigned n(struct isl_dim *dim, enum isl_dim_type type)
41 case isl_dim_param: return dim->nparam;
42 case isl_dim_in: return dim->n_in;
43 case isl_dim_out: return dim->n_out;
47 static unsigned pos(struct isl_dim *dim, enum isl_dim_type type)
50 case isl_dim_param: return 1;
51 case isl_dim_in: return 1 + dim->nparam;
52 case isl_dim_out: return 1 + dim->nparam + dim->n_in;
56 static void isl_dim_map_dim(struct isl_dim_map *dim_map, struct isl_dim *dim,
57 enum isl_dim_type type, unsigned dst_pos)
65 src_pos = pos(dim, type);
66 for (i = 0; i < n(dim, type); ++i)
67 dim_map->pos[1 + dst_pos + i] = src_pos + i;
70 static void isl_dim_map_div(struct isl_dim_map *dim_map,
71 struct isl_basic_map *bmap, unsigned dst_pos)
76 if (!dim_map || !bmap)
79 src_pos = 1 + isl_dim_total(bmap->dim);
80 for (i = 0; i < bmap->n_div; ++i)
81 dim_map->pos[1 + dst_pos + i] = src_pos + i;
84 static void isl_dim_map_dump(struct isl_dim_map *dim_map)
88 for (i = 0; i < dim_map->len; ++i)
89 fprintf(stderr, "%d -> %d; ", i, dim_map->pos[i]);
90 fprintf(stderr, "\n");
93 unsigned isl_basic_map_dim(const struct isl_basic_map *bmap,
94 enum isl_dim_type type)
96 struct isl_dim *dim = bmap->dim;
98 case isl_dim_param: return dim->nparam;
99 case isl_dim_in: return dim->n_in;
100 case isl_dim_out: return dim->n_out;
101 case isl_dim_div: return bmap->n_div;
102 case isl_dim_all: return isl_basic_map_total_dim(bmap);
106 unsigned isl_basic_set_dim(const struct isl_basic_set *bset,
107 enum isl_dim_type type)
109 return isl_basic_map_dim((const struct isl_basic_map*)bset, type);
112 unsigned isl_basic_set_n_dim(const struct isl_basic_set *bset)
114 return bset->dim->n_out;
117 unsigned isl_basic_set_n_param(const struct isl_basic_set *bset)
119 return bset->dim->nparam;
122 unsigned isl_basic_set_total_dim(const struct isl_basic_set *bset)
124 return isl_dim_total(bset->dim) + bset->n_div;
127 unsigned isl_set_n_dim(const struct isl_set *set)
129 return set->dim->n_out;
132 unsigned isl_set_n_param(const struct isl_set *set)
134 return set->dim->nparam;
137 unsigned isl_basic_map_n_in(const struct isl_basic_map *bmap)
139 return bmap->dim->n_in;
142 unsigned isl_basic_map_n_out(const struct isl_basic_map *bmap)
144 return bmap->dim->n_out;
147 unsigned isl_basic_map_n_param(const struct isl_basic_map *bmap)
149 return bmap->dim->nparam;
152 unsigned isl_basic_map_n_div(const struct isl_basic_map *bmap)
157 unsigned isl_basic_map_total_dim(const struct isl_basic_map *bmap)
159 return isl_dim_total(bmap->dim) + bmap->n_div;
162 unsigned isl_map_n_in(const struct isl_map *map)
164 return map->dim->n_in;
167 unsigned isl_map_n_out(const struct isl_map *map)
169 return map->dim->n_out;
172 unsigned isl_map_n_param(const struct isl_map *map)
174 return map->dim->nparam;
177 int isl_map_compatible_domain(struct isl_map *map, struct isl_set *set)
179 return map->dim->n_in == set->dim->n_out &&
180 map->dim->nparam == set->dim->nparam;
183 int isl_basic_map_compatible_domain(struct isl_basic_map *bmap,
184 struct isl_basic_set *bset)
186 return bmap->dim->n_in == bset->dim->n_out &&
187 bmap->dim->nparam == bset->dim->nparam;
190 int isl_basic_map_compatible_range(struct isl_basic_map *bmap,
191 struct isl_basic_set *bset)
193 return bmap->dim->n_out == bset->dim->n_out &&
194 bmap->dim->nparam == bset->dim->nparam;
197 static struct isl_basic_map *basic_map_init(struct isl_ctx *ctx,
198 struct isl_basic_map *bmap, unsigned extra,
199 unsigned n_eq, unsigned n_ineq)
202 size_t row_size = 1 + isl_dim_total(bmap->dim) + extra;
204 bmap->block = isl_blk_alloc(ctx, (n_eq + n_ineq) * row_size);
205 if (isl_blk_is_error(bmap->block)) {
210 bmap->eq = isl_alloc_array(ctx, isl_int *, n_eq + n_ineq);
212 isl_blk_free(ctx, bmap->block);
218 bmap->block2 = isl_blk_empty();
221 bmap->block2 = isl_blk_alloc(ctx, extra * (1 + row_size));
222 if (isl_blk_is_error(bmap->block2)) {
224 isl_blk_free(ctx, bmap->block);
229 bmap->div = isl_alloc_array(ctx, isl_int *, extra);
231 isl_blk_free(ctx, bmap->block2);
233 isl_blk_free(ctx, bmap->block);
239 for (i = 0; i < n_eq + n_ineq; ++i)
240 bmap->eq[i] = bmap->block.data + i * row_size;
242 for (i = 0; i < extra; ++i)
243 bmap->div[i] = bmap->block2.data + i * (1 + row_size);
249 bmap->c_size = n_eq + n_ineq;
250 bmap->ineq = bmap->eq + n_eq;
259 isl_basic_map_free(bmap);
263 struct isl_basic_set *isl_basic_set_alloc(struct isl_ctx *ctx,
264 unsigned nparam, unsigned dim, unsigned extra,
265 unsigned n_eq, unsigned n_ineq)
267 struct isl_basic_map *bmap;
268 bmap = isl_basic_map_alloc(ctx, nparam, 0, dim, extra, n_eq, n_ineq);
269 return (struct isl_basic_set *)bmap;
272 struct isl_basic_set *isl_basic_set_alloc_dim(struct isl_dim *dim,
273 unsigned extra, unsigned n_eq, unsigned n_ineq)
275 struct isl_basic_map *bmap;
278 isl_assert(dim->ctx, dim->n_in == 0, return NULL);
279 bmap = isl_basic_map_alloc_dim(dim, extra, n_eq, n_ineq);
280 return (struct isl_basic_set *)bmap;
283 struct isl_basic_map *isl_basic_map_alloc_dim(struct isl_dim *dim,
284 unsigned extra, unsigned n_eq, unsigned n_ineq)
286 struct isl_basic_map *bmap;
290 bmap = isl_alloc_type(dim->ctx, struct isl_basic_map);
295 return basic_map_init(dim->ctx, bmap, extra, n_eq, n_ineq);
301 struct isl_basic_map *isl_basic_map_alloc(struct isl_ctx *ctx,
302 unsigned nparam, unsigned in, unsigned out, unsigned extra,
303 unsigned n_eq, unsigned n_ineq)
305 struct isl_basic_map *bmap;
308 dim = isl_dim_alloc(ctx, nparam, in, out);
312 bmap = isl_basic_map_alloc_dim(dim, extra, n_eq, n_ineq);
316 static void dup_constraints(
317 struct isl_basic_map *dst, struct isl_basic_map *src)
320 unsigned total = isl_basic_map_total_dim(src);
322 for (i = 0; i < src->n_eq; ++i) {
323 int j = isl_basic_map_alloc_equality(dst);
324 isl_seq_cpy(dst->eq[j], src->eq[i], 1+total);
327 for (i = 0; i < src->n_ineq; ++i) {
328 int j = isl_basic_map_alloc_inequality(dst);
329 isl_seq_cpy(dst->ineq[j], src->ineq[i], 1+total);
332 for (i = 0; i < src->n_div; ++i) {
333 int j = isl_basic_map_alloc_div(dst);
334 isl_seq_cpy(dst->div[j], src->div[i], 1+1+total);
336 F_SET(dst, ISL_BASIC_SET_FINAL);
339 struct isl_basic_map *isl_basic_map_dup(struct isl_basic_map *bmap)
341 struct isl_basic_map *dup;
345 dup = isl_basic_map_alloc_dim(isl_dim_copy(bmap->dim),
346 bmap->n_div, bmap->n_eq, bmap->n_ineq);
349 dup->flags = bmap->flags;
350 dup_constraints(dup, bmap);
351 dup->sample = isl_vec_copy(bmap->ctx, bmap->sample);
355 struct isl_basic_set *isl_basic_set_dup(struct isl_basic_set *bset)
357 struct isl_basic_map *dup;
359 dup = isl_basic_map_dup((struct isl_basic_map *)bset);
360 return (struct isl_basic_set *)dup;
363 struct isl_basic_set *isl_basic_set_copy(struct isl_basic_set *bset)
368 if (F_ISSET(bset, ISL_BASIC_SET_FINAL)) {
372 return isl_basic_set_dup(bset);
375 struct isl_set *isl_set_copy(struct isl_set *set)
384 struct isl_basic_map *isl_basic_map_copy(struct isl_basic_map *bmap)
389 if (F_ISSET(bmap, ISL_BASIC_SET_FINAL)) {
393 return isl_basic_map_dup(bmap);
396 struct isl_map *isl_map_copy(struct isl_map *map)
405 void isl_basic_map_free(struct isl_basic_map *bmap)
413 isl_ctx_deref(bmap->ctx);
415 isl_blk_free(bmap->ctx, bmap->block2);
417 isl_blk_free(bmap->ctx, bmap->block);
418 isl_vec_free(bmap->ctx, bmap->sample);
419 isl_dim_free(bmap->dim);
423 void isl_basic_set_free(struct isl_basic_set *bset)
425 isl_basic_map_free((struct isl_basic_map *)bset);
428 int isl_basic_map_alloc_equality(struct isl_basic_map *bmap)
434 isl_assert(ctx, bmap->n_eq + bmap->n_ineq < bmap->c_size, return -1);
435 isl_assert(ctx, bmap->eq + bmap->n_eq <= bmap->ineq, return -1);
436 if (bmap->eq + bmap->n_eq == bmap->ineq) {
438 int j = isl_basic_map_alloc_inequality(bmap);
442 bmap->ineq[0] = bmap->ineq[j];
447 isl_seq_clr(bmap->eq[bmap->n_eq] +
448 1 + isl_basic_map_total_dim(bmap),
449 bmap->extra - bmap->n_div);
453 int isl_basic_set_alloc_equality(struct isl_basic_set *bset)
455 return isl_basic_map_alloc_equality((struct isl_basic_map *)bset);
458 int isl_basic_map_free_equality(struct isl_basic_map *bmap, unsigned n)
462 isl_assert(bmap->ctx, n <= bmap->n_eq, return -1);
467 int isl_basic_map_drop_equality(struct isl_basic_map *bmap, unsigned pos)
472 isl_assert(bmap->ctx, pos < bmap->n_eq, return -1);
474 if (pos != bmap->n_eq - 1) {
476 bmap->eq[pos] = bmap->eq[bmap->n_eq - 1];
477 bmap->eq[bmap->n_eq - 1] = t;
483 int isl_basic_set_drop_equality(struct isl_basic_set *bset, unsigned pos)
485 return isl_basic_map_drop_equality((struct isl_basic_map *)bset, pos);
488 void isl_basic_map_inequality_to_equality(
489 struct isl_basic_map *bmap, unsigned pos)
494 bmap->ineq[pos] = bmap->ineq[0];
495 bmap->ineq[0] = bmap->eq[bmap->n_eq];
496 bmap->eq[bmap->n_eq] = t;
500 F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
503 int isl_basic_map_alloc_inequality(struct isl_basic_map *bmap)
509 isl_assert(ctx, (bmap->ineq - bmap->eq) + bmap->n_ineq < bmap->c_size,
511 F_CLR(bmap, ISL_BASIC_MAP_NO_IMPLICIT);
512 F_CLR(bmap, ISL_BASIC_MAP_NO_REDUNDANT);
513 F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
514 isl_seq_clr(bmap->ineq[bmap->n_ineq] +
515 1 + isl_basic_map_total_dim(bmap),
516 bmap->extra - bmap->n_div);
517 return bmap->n_ineq++;
520 int isl_basic_set_alloc_inequality(struct isl_basic_set *bset)
522 return isl_basic_map_alloc_inequality((struct isl_basic_map *)bset);
525 int isl_basic_map_free_inequality(struct isl_basic_map *bmap, unsigned n)
529 isl_assert(bmap->ctx, n <= bmap->n_ineq, return -1);
534 int isl_basic_set_free_inequality(struct isl_basic_set *bset, unsigned n)
536 return isl_basic_map_free_inequality((struct isl_basic_map *)bset, n);
539 int isl_basic_map_drop_inequality(struct isl_basic_map *bmap, unsigned pos)
544 isl_assert(bmap->ctx, pos < bmap->n_ineq, return -1);
546 if (pos != bmap->n_ineq - 1) {
548 bmap->ineq[pos] = bmap->ineq[bmap->n_ineq - 1];
549 bmap->ineq[bmap->n_ineq - 1] = t;
550 F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
556 int isl_basic_set_drop_inequality(struct isl_basic_set *bset, unsigned pos)
558 return isl_basic_map_drop_inequality((struct isl_basic_map *)bset, pos);
561 int isl_basic_map_alloc_div(struct isl_basic_map *bmap)
565 isl_assert(bmap->ctx, bmap->n_div < bmap->extra, return -1);
566 isl_seq_clr(bmap->div[bmap->n_div] +
567 1 + 1 + isl_basic_map_total_dim(bmap),
568 bmap->extra - bmap->n_div);
569 return bmap->n_div++;
572 int isl_basic_map_free_div(struct isl_basic_map *bmap, unsigned n)
576 isl_assert(bmap->ctx, n <= bmap->n_div, return -1);
581 /* Copy constraint from src to dst, putting the vars of src at offset
582 * dim_off in dst and the divs of src at offset div_off in dst.
583 * If both sets are actually map, then dim_off applies to the input
586 static void copy_constraint(struct isl_basic_map *dst_map, isl_int *dst,
587 struct isl_basic_map *src_map, isl_int *src,
588 unsigned in_off, unsigned out_off, unsigned div_off)
590 unsigned src_nparam = isl_basic_map_n_param(src_map);
591 unsigned dst_nparam = isl_basic_map_n_param(dst_map);
592 unsigned src_in = isl_basic_map_n_in(src_map);
593 unsigned dst_in = isl_basic_map_n_in(dst_map);
594 unsigned src_out = isl_basic_map_n_out(src_map);
595 unsigned dst_out = isl_basic_map_n_out(dst_map);
596 isl_int_set(dst[0], src[0]);
597 isl_seq_cpy(dst+1, src+1, isl_min(dst_nparam, src_nparam));
598 if (dst_nparam > src_nparam)
599 isl_seq_clr(dst+1+src_nparam,
600 dst_nparam - src_nparam);
601 isl_seq_clr(dst+1+dst_nparam, in_off);
602 isl_seq_cpy(dst+1+dst_nparam+in_off,
604 isl_min(dst_in-in_off, src_in));
605 if (dst_in-in_off > src_in)
606 isl_seq_clr(dst+1+dst_nparam+in_off+src_in,
607 dst_in - in_off - src_in);
608 isl_seq_clr(dst+1+dst_nparam+dst_in, out_off);
609 isl_seq_cpy(dst+1+dst_nparam+dst_in+out_off,
610 src+1+src_nparam+src_in,
611 isl_min(dst_out-out_off, src_out));
612 if (dst_out-out_off > src_out)
613 isl_seq_clr(dst+1+dst_nparam+dst_in+out_off+src_out,
614 dst_out - out_off - src_out);
615 isl_seq_clr(dst+1+dst_nparam+dst_in+dst_out, div_off);
616 isl_seq_cpy(dst+1+dst_nparam+dst_in+dst_out+div_off,
617 src+1+src_nparam+src_in+src_out,
618 isl_min(dst_map->extra-div_off, src_map->n_div));
619 if (dst_map->n_div-div_off > src_map->n_div)
620 isl_seq_clr(dst+1+dst_nparam+dst_in+dst_out+
621 div_off+src_map->n_div,
622 dst_map->n_div - div_off - src_map->n_div);
625 static void copy_div(struct isl_basic_map *dst_map, isl_int *dst,
626 struct isl_basic_map *src_map, isl_int *src,
627 unsigned in_off, unsigned out_off, unsigned div_off)
629 isl_int_set(dst[0], src[0]);
630 copy_constraint(dst_map, dst+1, src_map, src+1, in_off, out_off, div_off);
633 static struct isl_basic_map *add_constraints(struct isl_basic_map *bmap1,
634 struct isl_basic_map *bmap2, unsigned i_pos, unsigned o_pos)
639 if (!bmap1 || !bmap2)
642 div_off = bmap1->n_div;
644 for (i = 0; i < bmap2->n_eq; ++i) {
645 int i1 = isl_basic_map_alloc_equality(bmap1);
648 copy_constraint(bmap1, bmap1->eq[i1], bmap2, bmap2->eq[i],
649 i_pos, o_pos, div_off);
652 for (i = 0; i < bmap2->n_ineq; ++i) {
653 int i1 = isl_basic_map_alloc_inequality(bmap1);
656 copy_constraint(bmap1, bmap1->ineq[i1], bmap2, bmap2->ineq[i],
657 i_pos, o_pos, div_off);
660 for (i = 0; i < bmap2->n_div; ++i) {
661 int i1 = isl_basic_map_alloc_div(bmap1);
664 copy_div(bmap1, bmap1->div[i1], bmap2, bmap2->div[i],
665 i_pos, o_pos, div_off);
668 isl_basic_map_free(bmap2);
673 isl_basic_map_free(bmap1);
674 isl_basic_map_free(bmap2);
678 static void copy_constraint_dim_map(isl_int *dst, isl_int *src,
679 struct isl_dim_map *dim_map)
683 for (i = 0; i < dim_map->len; ++i) {
684 if (dim_map->pos[i] < 0)
685 isl_int_set_si(dst[i], 0);
687 isl_int_set(dst[i], src[dim_map->pos[i]]);
691 static void copy_div_dim_map(isl_int *dst, isl_int *src,
692 struct isl_dim_map *dim_map)
694 isl_int_set(dst[0], src[0]);
695 copy_constraint_dim_map(dst+1, src+1, dim_map);
698 static struct isl_basic_map *add_constraints_dim_map(struct isl_basic_map *dst,
699 struct isl_basic_map *src, struct isl_dim_map *dim_map)
703 if (!src || !dst || !dim_map)
706 for (i = 0; i < src->n_eq; ++i) {
707 int i1 = isl_basic_map_alloc_equality(dst);
710 copy_constraint_dim_map(dst->eq[i1], src->eq[i], dim_map);
713 for (i = 0; i < src->n_ineq; ++i) {
714 int i1 = isl_basic_map_alloc_inequality(dst);
717 copy_constraint_dim_map(dst->ineq[i1], src->ineq[i], dim_map);
720 for (i = 0; i < src->n_div; ++i) {
721 int i1 = isl_basic_map_alloc_div(dst);
724 copy_div_dim_map(dst->div[i1], src->div[i], dim_map);
728 isl_basic_map_free(src);
733 isl_basic_map_free(src);
734 isl_basic_map_free(dst);
738 static struct isl_basic_set *set_add_constraints(struct isl_basic_set *bset1,
739 struct isl_basic_set *bset2, unsigned pos)
741 return (struct isl_basic_set *)
742 add_constraints((struct isl_basic_map *)bset1,
743 (struct isl_basic_map *)bset2, 0, pos);
746 struct isl_basic_map *isl_basic_map_extend_dim(struct isl_basic_map *base,
747 struct isl_dim *dim, unsigned extra,
748 unsigned n_eq, unsigned n_ineq)
750 struct isl_basic_map *ext;
757 base = isl_basic_map_cow(base);
761 dims_ok = isl_dim_equal(base->dim, dim) &&
762 base->extra >= base->n_div + extra;
764 if (dims_ok && n_eq == 0 && n_ineq == 0) {
769 isl_assert(base->ctx, base->dim->nparam <= dim->nparam, goto error);
770 isl_assert(base->ctx, base->dim->n_in <= dim->n_in, goto error);
771 isl_assert(base->ctx, base->dim->n_out <= dim->n_out, goto error);
772 extra += base->extra;
774 n_ineq += base->n_ineq;
776 ext = isl_basic_map_alloc_dim(dim, extra, n_eq, n_ineq);
782 ext = add_constraints(ext, base, 0, 0);
785 F_CLR(ext, ISL_BASIC_SET_FINAL);
792 isl_basic_map_free(base);
796 struct isl_basic_map *isl_basic_map_extend_constraints(
797 struct isl_basic_map *base, unsigned n_eq, unsigned n_ineq)
801 return isl_basic_map_extend_dim(base, isl_dim_copy(base->dim),
805 struct isl_basic_map *isl_basic_map_extend(struct isl_basic_map *base,
806 unsigned nparam, unsigned n_in, unsigned n_out, unsigned extra,
807 unsigned n_eq, unsigned n_ineq)
809 struct isl_basic_map *bmap;
814 dim = isl_dim_alloc(base->ctx, nparam, n_in, n_out);
818 bmap = isl_basic_map_extend_dim(base, dim, extra, n_eq, n_ineq);
822 struct isl_basic_set *isl_basic_set_extend(struct isl_basic_set *base,
823 unsigned nparam, unsigned dim, unsigned extra,
824 unsigned n_eq, unsigned n_ineq)
826 return (struct isl_basic_set *)
827 isl_basic_map_extend((struct isl_basic_map *)base,
828 nparam, 0, dim, extra, n_eq, n_ineq);
831 struct isl_basic_set *isl_basic_set_extend_constraints(
832 struct isl_basic_set *base, unsigned n_eq, unsigned n_ineq)
834 return (struct isl_basic_set *)
835 isl_basic_map_extend_constraints((struct isl_basic_map *)base,
839 struct isl_basic_set *isl_basic_set_cow(struct isl_basic_set *bset)
841 return (struct isl_basic_set *)
842 isl_basic_map_cow((struct isl_basic_map *)bset);
845 struct isl_basic_map *isl_basic_map_cow(struct isl_basic_map *bmap)
852 bmap = isl_basic_map_dup(bmap);
854 F_CLR(bmap, ISL_BASIC_SET_FINAL);
858 struct isl_set *isl_set_cow(struct isl_set *set)
866 return isl_set_dup(set);
869 struct isl_map *isl_map_cow(struct isl_map *map)
877 return isl_map_dup(map);
880 static void swap_vars(struct isl_blk blk, isl_int *a,
881 unsigned a_len, unsigned b_len)
883 isl_seq_cpy(blk.data, a+a_len, b_len);
884 isl_seq_cpy(blk.data+b_len, a, a_len);
885 isl_seq_cpy(a, blk.data, b_len+a_len);
888 struct isl_basic_set *isl_basic_set_swap_vars(
889 struct isl_basic_set *bset, unsigned n)
899 nparam = isl_basic_set_n_param(bset);
900 dim = isl_basic_set_n_dim(bset);
901 isl_assert(bset->ctx, n <= dim, goto error);
906 bset = isl_basic_set_cow(bset);
910 blk = isl_blk_alloc(bset->ctx, dim);
911 if (isl_blk_is_error(blk))
914 for (i = 0; i < bset->n_eq; ++i)
916 bset->eq[i]+1+nparam, n, dim - n);
918 for (i = 0; i < bset->n_ineq; ++i)
920 bset->ineq[i]+1+nparam, n, dim - n);
922 for (i = 0; i < bset->n_div; ++i)
924 bset->div[i]+1+1+nparam, n, dim - n);
926 isl_blk_free(bset->ctx, blk);
928 F_CLR(bset, ISL_BASIC_SET_NORMALIZED);
932 isl_basic_set_free(bset);
936 struct isl_set *isl_set_swap_vars(struct isl_set *set, unsigned n)
939 set = isl_set_cow(set);
943 for (i = 0; i < set->n; ++i) {
944 set->p[i] = isl_basic_set_swap_vars(set->p[i], n);
950 F_CLR(set, ISL_SET_NORMALIZED);
954 static void constraint_drop_vars(isl_int *c, unsigned n, unsigned rem)
956 isl_seq_cpy(c, c + n, rem);
957 isl_seq_clr(c + rem, n);
960 /* Drop n dimensions starting at first.
962 * In principle, this frees up some extra variables as the number
963 * of columns remains constant, but we would have to extend
964 * the div array too as the number of rows in this array is assumed
965 * to be equal to extra.
967 struct isl_basic_set *isl_basic_set_drop_dims(
968 struct isl_basic_set *bset, unsigned first, unsigned n)
975 isl_assert(bset->ctx, first + n <= bset->dim->n_out, goto error);
980 bset = isl_basic_set_cow(bset);
984 for (i = 0; i < bset->n_eq; ++i)
985 constraint_drop_vars(bset->eq[i]+1+bset->dim->nparam+first, n,
986 (bset->dim->n_out-first-n)+bset->extra);
988 for (i = 0; i < bset->n_ineq; ++i)
989 constraint_drop_vars(bset->ineq[i]+1+bset->dim->nparam+first, n,
990 (bset->dim->n_out-first-n)+bset->extra);
992 for (i = 0; i < bset->n_div; ++i)
993 constraint_drop_vars(bset->div[i]+1+1+bset->dim->nparam+first, n,
994 (bset->dim->n_out-first-n)+bset->extra);
996 bset->dim = isl_dim_drop_outputs(bset->dim, first, n);
1000 F_CLR(bset, ISL_BASIC_SET_NORMALIZED);
1001 bset = isl_basic_set_simplify(bset);
1002 return isl_basic_set_finalize(bset);
1004 isl_basic_set_free(bset);
1008 static struct isl_set *isl_set_drop_dims(
1009 struct isl_set *set, unsigned first, unsigned n)
1016 isl_assert(set->ctx, first + n <= set->dim->n_out, goto error);
1020 set = isl_set_cow(set);
1023 set->dim = isl_dim_drop_outputs(set->dim, first, n);
1027 for (i = 0; i < set->n; ++i) {
1028 set->p[i] = isl_basic_set_drop_dims(set->p[i], first, n);
1033 F_CLR(set, ISL_SET_NORMALIZED);
1040 /* Drop n input dimensions starting at first.
1042 * In principle, this frees up some extra variables as the number
1043 * of columns remains constant, but we would have to extend
1044 * the div array too as the number of rows in this array is assumed
1045 * to be equal to extra.
1047 struct isl_basic_map *isl_basic_map_drop_inputs(
1048 struct isl_basic_map *bmap, unsigned first, unsigned n)
1058 nparam = isl_basic_map_n_param(bmap);
1059 n_in = isl_basic_map_n_in(bmap);
1060 n_out = isl_basic_map_n_out(bmap);
1061 isl_assert(bmap->ctx, first + n <= n_in, goto error);
1066 bmap = isl_basic_map_cow(bmap);
1070 for (i = 0; i < bmap->n_eq; ++i)
1071 constraint_drop_vars(bmap->eq[i]+1+nparam+first, n,
1072 (n_in-first-n)+n_out+bmap->extra);
1074 for (i = 0; i < bmap->n_ineq; ++i)
1075 constraint_drop_vars(bmap->ineq[i]+1+nparam+first, n,
1076 (n_in-first-n)+n_out+bmap->extra);
1078 for (i = 0; i < bmap->n_div; ++i)
1079 constraint_drop_vars(bmap->div[i]+1+1+nparam+first, n,
1080 (n_in-first-n)+n_out+bmap->extra);
1082 bmap->dim = isl_dim_drop_inputs(bmap->dim, first, n);
1086 F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
1087 bmap = isl_basic_map_simplify(bmap);
1088 return isl_basic_map_finalize(bmap);
1090 isl_basic_map_free(bmap);
1094 static struct isl_map *isl_map_drop_inputs(
1095 struct isl_map *map, unsigned first, unsigned n)
1102 isl_assert(map->ctx, first + n <= map->dim->n_in, goto error);
1106 map = isl_map_cow(map);
1109 map->dim = isl_dim_drop_inputs(map->dim, first, n);
1113 for (i = 0; i < map->n; ++i) {
1114 map->p[i] = isl_basic_map_drop_inputs(map->p[i], first, n);
1118 F_CLR(map, ISL_MAP_NORMALIZED);
1127 * We don't cow, as the div is assumed to be redundant.
1129 static struct isl_basic_map *isl_basic_map_drop_div(
1130 struct isl_basic_map *bmap, unsigned div)
1138 pos = 1 + isl_dim_total(bmap->dim) + div;
1140 isl_assert(bmap->ctx, div < bmap->n_div, goto error);
1142 for (i = 0; i < bmap->n_eq; ++i)
1143 constraint_drop_vars(bmap->eq[i]+pos, 1, bmap->extra-div-1);
1145 for (i = 0; i < bmap->n_ineq; ++i) {
1146 if (!isl_int_is_zero(bmap->ineq[i][pos])) {
1147 isl_basic_map_drop_inequality(bmap, i);
1151 constraint_drop_vars(bmap->ineq[i]+pos, 1, bmap->extra-div-1);
1154 for (i = 0; i < bmap->n_div; ++i)
1155 constraint_drop_vars(bmap->div[i]+1+pos, 1, bmap->extra-div-1);
1157 if (div != bmap->n_div - 1) {
1159 isl_int *t = bmap->div[div];
1161 for (j = div; j < bmap->n_div - 1; ++j)
1162 bmap->div[j] = bmap->div[j+1];
1164 bmap->div[bmap->n_div - 1] = t;
1166 F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
1167 isl_basic_map_free_div(bmap, 1);
1171 isl_basic_map_free(bmap);
1175 static void eliminate_div(struct isl_basic_map *bmap, isl_int *eq, unsigned div)
1178 unsigned pos = 1 + isl_dim_total(bmap->dim) + div;
1180 len = 1 + isl_basic_map_total_dim(bmap);
1182 for (i = 0; i < bmap->n_eq; ++i)
1183 if (bmap->eq[i] != eq)
1184 isl_seq_elim(bmap->eq[i], eq, pos, len, NULL);
1186 for (i = 0; i < bmap->n_ineq; ++i)
1187 isl_seq_elim(bmap->ineq[i], eq, pos, len, NULL);
1189 /* We need to be careful about circular definitions,
1190 * so for now we just remove the definitions of other divs that
1191 * depend on this div and (possibly) recompute them later.
1193 for (i = 0; i < bmap->n_div; ++i)
1194 if (!isl_int_is_zero(bmap->div[i][0]) &&
1195 !isl_int_is_zero(bmap->div[i][1 + pos]))
1196 isl_seq_clr(bmap->div[i], 1 + len);
1198 isl_basic_map_drop_div(bmap, div);
1201 struct isl_basic_map *isl_basic_map_set_to_empty(struct isl_basic_map *bmap)
1207 total = isl_basic_map_total_dim(bmap);
1208 isl_basic_map_free_div(bmap, bmap->n_div);
1209 isl_basic_map_free_inequality(bmap, bmap->n_ineq);
1211 isl_basic_map_free_equality(bmap, bmap->n_eq-1);
1213 isl_basic_map_alloc_equality(bmap);
1217 isl_int_set_si(bmap->eq[i][0], 1);
1218 isl_seq_clr(bmap->eq[i]+1, total);
1219 F_SET(bmap, ISL_BASIC_MAP_EMPTY);
1220 return isl_basic_map_finalize(bmap);
1222 isl_basic_map_free(bmap);
1226 struct isl_basic_set *isl_basic_set_set_to_empty(struct isl_basic_set *bset)
1228 return (struct isl_basic_set *)
1229 isl_basic_map_set_to_empty((struct isl_basic_map *)bset);
1232 static void swap_equality(struct isl_basic_map *bmap, int a, int b)
1234 isl_int *t = bmap->eq[a];
1235 bmap->eq[a] = bmap->eq[b];
1239 static void swap_inequality(struct isl_basic_map *bmap, int a, int b)
1242 isl_int *t = bmap->ineq[a];
1243 bmap->ineq[a] = bmap->ineq[b];
1248 static void set_swap_inequality(struct isl_basic_set *bset, int a, int b)
1250 swap_inequality((struct isl_basic_map *)bset, a, b);
1253 static void swap_div(struct isl_basic_map *bmap, int a, int b)
1256 unsigned off = isl_dim_total(bmap->dim);
1257 isl_int *t = bmap->div[a];
1258 bmap->div[a] = bmap->div[b];
1261 for (i = 0; i < bmap->n_eq; ++i)
1262 isl_int_swap(bmap->eq[i][1+off+a], bmap->eq[i][1+off+b]);
1264 for (i = 0; i < bmap->n_ineq; ++i)
1265 isl_int_swap(bmap->ineq[i][1+off+a], bmap->ineq[i][1+off+b]);
1267 for (i = 0; i < bmap->n_div; ++i)
1268 isl_int_swap(bmap->div[i][1+1+off+a], bmap->div[i][1+1+off+b]);
1269 F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
1272 static void eliminate_var_using_equality(struct isl_basic_map *bmap,
1273 unsigned pos, isl_int *eq, int *progress)
1278 total = isl_basic_map_total_dim(bmap);
1279 for (k = 0; k < bmap->n_eq; ++k) {
1280 if (bmap->eq[k] == eq)
1282 if (isl_int_is_zero(bmap->eq[k][1+pos]))
1286 isl_seq_elim(bmap->eq[k], eq, 1+pos, 1+total, NULL);
1289 for (k = 0; k < bmap->n_ineq; ++k) {
1290 if (isl_int_is_zero(bmap->ineq[k][1+pos]))
1294 isl_seq_elim(bmap->ineq[k], eq, 1+pos, 1+total, NULL);
1295 F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
1298 for (k = 0; k < bmap->n_div; ++k) {
1299 if (isl_int_is_zero(bmap->div[k][0]))
1301 if (isl_int_is_zero(bmap->div[k][1+1+pos]))
1305 isl_seq_elim(bmap->div[k]+1, eq,
1306 1+pos, 1+total, &bmap->div[k][0]);
1307 F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
1312 struct isl_basic_map *isl_basic_map_gauss(
1313 struct isl_basic_map *bmap, int *progress)
1324 total = isl_basic_map_total_dim(bmap);
1325 total_var = total - bmap->n_div;
1327 last_var = total - 1;
1328 for (done = 0; done < bmap->n_eq; ++done) {
1329 for (; last_var >= 0; --last_var) {
1330 for (k = done; k < bmap->n_eq; ++k)
1331 if (!isl_int_is_zero(bmap->eq[k][1+last_var]))
1339 swap_equality(bmap, k, done);
1340 if (isl_int_is_neg(bmap->eq[done][1+last_var]))
1341 isl_seq_neg(bmap->eq[done], bmap->eq[done], 1+total);
1343 eliminate_var_using_equality(bmap, last_var, bmap->eq[done],
1346 if (last_var >= total_var &&
1347 isl_int_is_zero(bmap->div[last_var - total_var][0])) {
1348 unsigned div = last_var - total_var;
1349 isl_seq_neg(bmap->div[div]+1, bmap->eq[done], 1+total);
1350 isl_int_set_si(bmap->div[div][1+1+last_var], 0);
1351 isl_int_set(bmap->div[div][0],
1352 bmap->eq[done][1+last_var]);
1353 F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
1356 if (done == bmap->n_eq)
1358 for (k = done; k < bmap->n_eq; ++k) {
1359 if (isl_int_is_zero(bmap->eq[k][0]))
1361 return isl_basic_map_set_to_empty(bmap);
1363 isl_basic_map_free_equality(bmap, bmap->n_eq-done);
1367 struct isl_basic_set *isl_basic_set_gauss(
1368 struct isl_basic_set *bset, int *progress)
1370 return (struct isl_basic_set*)isl_basic_map_gauss(
1371 (struct isl_basic_map *)bset, progress);
1374 static unsigned int round_up(unsigned int v)
1385 static int hash_index(isl_int ***index, unsigned int size, int bits,
1386 struct isl_basic_map *bmap, int k)
1389 unsigned total = isl_basic_map_total_dim(bmap);
1390 uint32_t hash = isl_seq_get_hash_bits(bmap->ineq[k]+1, total, bits);
1391 for (h = hash; index[h]; h = (h+1) % size)
1392 if (&bmap->ineq[k] != index[h] &&
1393 isl_seq_eq(bmap->ineq[k]+1, index[h][0]+1, total))
1398 static int set_hash_index(isl_int ***index, unsigned int size, int bits,
1399 struct isl_basic_set *bset, int k)
1401 return hash_index(index, size, bits, (struct isl_basic_map *)bset, k);
1404 static struct isl_basic_map *remove_duplicate_constraints(
1405 struct isl_basic_map *bmap, int *progress)
1411 unsigned total = isl_basic_map_total_dim(bmap);
1414 if (bmap->n_ineq <= 1)
1417 size = round_up(4 * (bmap->n_ineq+1) / 3 - 1);
1418 bits = ffs(size) - 1;
1419 index = isl_calloc_array(ctx, isl_int **, size);
1423 index[isl_seq_get_hash_bits(bmap->ineq[0]+1, total, bits)] = &bmap->ineq[0];
1424 for (k = 1; k < bmap->n_ineq; ++k) {
1425 h = hash_index(index, size, bits, bmap, k);
1427 index[h] = &bmap->ineq[k];
1432 l = index[h] - &bmap->ineq[0];
1433 if (isl_int_lt(bmap->ineq[k][0], bmap->ineq[l][0]))
1434 swap_inequality(bmap, k, l);
1435 isl_basic_map_drop_inequality(bmap, k);
1439 for (k = 0; k < bmap->n_ineq-1; ++k) {
1440 isl_seq_neg(bmap->ineq[k]+1, bmap->ineq[k]+1, total);
1441 h = hash_index(index, size, bits, bmap, k);
1442 isl_seq_neg(bmap->ineq[k]+1, bmap->ineq[k]+1, total);
1445 l = index[h] - &bmap->ineq[0];
1446 isl_int_add(sum, bmap->ineq[k][0], bmap->ineq[l][0]);
1447 if (isl_int_is_pos(sum))
1449 if (isl_int_is_zero(sum)) {
1450 /* We need to break out of the loop after these
1451 * changes since the contents of the hash
1452 * will no longer be valid.
1453 * Plus, we probably we want to regauss first.
1455 isl_basic_map_drop_inequality(bmap, l);
1456 isl_basic_map_inequality_to_equality(bmap, k);
1458 bmap = isl_basic_map_set_to_empty(bmap);
1467 static void compute_elimination_index(struct isl_basic_map *bmap, int *elim)
1472 total = isl_dim_total(bmap->dim);
1473 for (d = 0; d < total; ++d)
1475 for (d = total - 1, i = 0; d >= 0 && i < bmap->n_eq; ++i) {
1476 for (; d >= 0; --d) {
1477 if (isl_int_is_zero(bmap->eq[i][1+d]))
1485 static void set_compute_elimination_index(struct isl_basic_set *bset, int *elim)
1487 return compute_elimination_index((struct isl_basic_map *)bset, elim);
1490 static int reduced_using_equalities(isl_int *dst, isl_int *src,
1491 struct isl_basic_map *bmap, int *elim)
1497 total = isl_dim_total(bmap->dim);
1498 for (d = total - 1; d >= 0; --d) {
1499 if (isl_int_is_zero(src[1+d]))
1504 isl_seq_cpy(dst, src, 1 + total);
1507 isl_seq_elim(dst, bmap->eq[elim[d]], 1 + d, 1 + total, NULL);
1512 static int set_reduced_using_equalities(isl_int *dst, isl_int *src,
1513 struct isl_basic_set *bset, int *elim)
1515 return reduced_using_equalities(dst, src,
1516 (struct isl_basic_map *)bset, elim);
1519 /* Quick check to see if two basic maps are disjoint.
1520 * In particular, we reduce the equalities and inequalities of
1521 * one basic map in the context of the equalities of the other
1522 * basic map and check if we get a contradiction.
1524 int isl_basic_map_fast_is_disjoint(struct isl_basic_map *bmap1,
1525 struct isl_basic_map *bmap2)
1527 struct isl_vec *v = NULL;
1532 if (!bmap1 || !bmap2)
1534 isl_assert(bmap1->ctx, isl_dim_equal(bmap1->dim, bmap2->dim),
1536 if (bmap1->n_div || bmap2->n_div)
1538 if (!bmap1->n_eq && !bmap2->n_eq)
1541 total = isl_dim_total(bmap1->dim);
1544 v = isl_vec_alloc(bmap1->ctx, 1 + total);
1547 elim = isl_alloc_array(bmap1->ctx, int, total);
1550 compute_elimination_index(bmap1, elim);
1551 for (i = 0; i < bmap2->n_eq; ++i) {
1553 reduced = reduced_using_equalities(v->block.data, bmap2->eq[i],
1555 if (reduced && !isl_int_is_zero(v->block.data[0]) &&
1556 isl_seq_first_non_zero(v->block.data + 1, total) == -1)
1559 for (i = 0; i < bmap2->n_ineq; ++i) {
1561 reduced = reduced_using_equalities(v->block.data,
1562 bmap2->ineq[i], bmap1, elim);
1563 if (reduced && isl_int_is_neg(v->block.data[0]) &&
1564 isl_seq_first_non_zero(v->block.data + 1, total) == -1)
1567 compute_elimination_index(bmap2, elim);
1568 for (i = 0; i < bmap1->n_ineq; ++i) {
1570 reduced = reduced_using_equalities(v->block.data,
1571 bmap1->ineq[i], bmap2, elim);
1572 if (reduced && isl_int_is_neg(v->block.data[0]) &&
1573 isl_seq_first_non_zero(v->block.data + 1, total) == -1)
1576 isl_vec_free(bmap1->ctx, v);
1580 isl_vec_free(bmap1->ctx, v);
1584 isl_vec_free(bmap1->ctx, v);
1589 int isl_basic_set_fast_is_disjoint(struct isl_basic_set *bset1,
1590 struct isl_basic_set *bset2)
1592 return isl_basic_map_fast_is_disjoint((struct isl_basic_map *)bset1,
1593 (struct isl_basic_map *)bset2);
1596 int isl_map_fast_is_disjoint(struct isl_map *map1, struct isl_map *map2)
1603 if (isl_map_fast_is_equal(map1, map2))
1606 for (i = 0; i < map1->n; ++i) {
1607 for (j = 0; j < map2->n; ++j) {
1608 int d = isl_basic_map_fast_is_disjoint(map1->p[i],
1617 int isl_set_fast_is_disjoint(struct isl_set *set1, struct isl_set *set2)
1619 return isl_map_fast_is_disjoint((struct isl_map *)set1,
1620 (struct isl_map *)set2);
1623 static struct isl_basic_map *remove_duplicate_divs(
1624 struct isl_basic_map *bmap, int *progress)
1631 unsigned total_var = isl_dim_total(bmap->dim);
1632 unsigned total = total_var + bmap->n_div;
1633 struct isl_ctx *ctx;
1635 if (bmap->n_div <= 1)
1639 for (k = bmap->n_div - 1; k >= 0; --k)
1640 if (!isl_int_is_zero(bmap->div[k][0]))
1645 size = round_up(4 * bmap->n_div / 3 - 1);
1646 bits = ffs(size) - 1;
1647 index = isl_calloc_array(ctx, int, size);
1650 eq = isl_blk_alloc(ctx, 1+total);
1651 if (isl_blk_is_error(eq))
1654 isl_seq_clr(eq.data, 1+total);
1655 index[isl_seq_get_hash_bits(bmap->div[k], 2+total, bits)] = k + 1;
1656 for (--k; k >= 0; --k) {
1659 if (isl_int_is_zero(bmap->div[k][0]))
1662 hash = isl_seq_get_hash_bits(bmap->div[k], 2+total, bits);
1663 for (h = hash; index[h]; h = (h+1) % size)
1664 if (isl_seq_eq(bmap->div[k],
1665 bmap->div[index[h]-1], 2+total))
1670 isl_int_set_si(eq.data[1+total_var+k], -1);
1671 isl_int_set_si(eq.data[1+total_var+l], 1);
1672 eliminate_div(bmap, eq.data, l);
1673 isl_int_set_si(eq.data[1+total_var+k], 0);
1674 isl_int_set_si(eq.data[1+total_var+l], 0);
1679 isl_blk_free(ctx, eq);
1685 /* Elimininate divs based on equalities
1687 static struct isl_basic_map *eliminate_divs_eq(
1688 struct isl_basic_map *bmap, int *progress)
1698 off = 1 + isl_dim_total(bmap->dim);
1700 for (d = bmap->n_div - 1; d >= 0 ; --d) {
1701 for (i = 0; i < bmap->n_eq; ++i) {
1702 if (!isl_int_is_one(bmap->eq[i][off + d]) &&
1703 !isl_int_is_negone(bmap->eq[i][off + d]))
1707 eliminate_div(bmap, bmap->eq[i], d);
1708 isl_basic_map_drop_equality(bmap, i);
1713 return eliminate_divs_eq(bmap, progress);
1717 static struct isl_basic_map *normalize_constraints(struct isl_basic_map *bmap)
1721 unsigned total = isl_basic_map_total_dim(bmap);
1724 for (i = bmap->n_eq - 1; i >= 0; --i) {
1725 isl_seq_gcd(bmap->eq[i]+1, total, &gcd);
1726 if (isl_int_is_zero(gcd)) {
1727 if (!isl_int_is_zero(bmap->eq[i][0])) {
1728 bmap = isl_basic_map_set_to_empty(bmap);
1731 isl_basic_map_drop_equality(bmap, i);
1734 if (F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL))
1735 isl_int_gcd(gcd, gcd, bmap->eq[i][0]);
1736 if (isl_int_is_one(gcd))
1738 if (!isl_int_is_divisible_by(bmap->eq[i][0], gcd)) {
1739 bmap = isl_basic_map_set_to_empty(bmap);
1742 isl_seq_scale_down(bmap->eq[i], bmap->eq[i], gcd, 1+total);
1745 for (i = bmap->n_ineq - 1; i >= 0; --i) {
1746 isl_seq_gcd(bmap->ineq[i]+1, total, &gcd);
1747 if (isl_int_is_zero(gcd)) {
1748 if (isl_int_is_neg(bmap->ineq[i][0])) {
1749 bmap = isl_basic_map_set_to_empty(bmap);
1752 isl_basic_map_drop_inequality(bmap, i);
1755 if (F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL))
1756 isl_int_gcd(gcd, gcd, bmap->ineq[i][0]);
1757 if (isl_int_is_one(gcd))
1759 isl_int_fdiv_q(bmap->ineq[i][0], bmap->ineq[i][0], gcd);
1760 isl_seq_scale_down(bmap->ineq[i]+1, bmap->ineq[i]+1, gcd, total);
1768 /* Remove any div that is defined in terms of the given variable.
1770 static struct isl_basic_map *remove_dependent_vars(struct isl_basic_map *bmap,
1774 unsigned dim = isl_dim_total(bmap->dim);
1776 for (i = 0; i < bmap->n_div; ++i) {
1777 if (isl_int_is_zero(bmap->div[i][0]))
1779 if (isl_int_is_zero(bmap->div[i][1+1+pos]))
1781 bmap = isl_basic_map_eliminate_vars(bmap, dim + i, 1);
1789 /* Eliminate the specified variables from the constraints using
1790 * Fourier-Motzkin. The variables themselves are not removed.
1792 struct isl_basic_map *isl_basic_map_eliminate_vars(
1793 struct isl_basic_map *bmap, unsigned pos, unsigned n)
1803 total = isl_basic_map_total_dim(bmap);
1805 bmap = isl_basic_map_cow(bmap);
1806 for (d = pos + n - 1; d >= 0 && d >= pos; --d) {
1807 int n_lower, n_upper;
1808 bmap = remove_dependent_vars(bmap, d);
1811 if (d >= total - bmap->n_div)
1812 isl_seq_clr(bmap->div[d-(total-bmap->n_div)], 2+total);
1813 for (i = 0; i < bmap->n_eq; ++i) {
1814 if (isl_int_is_zero(bmap->eq[i][1+d]))
1816 eliminate_var_using_equality(bmap, d, bmap->eq[i], NULL);
1817 isl_basic_map_drop_equality(bmap, i);
1824 for (i = 0; i < bmap->n_ineq; ++i) {
1825 if (isl_int_is_pos(bmap->ineq[i][1+d]))
1827 else if (isl_int_is_neg(bmap->ineq[i][1+d]))
1830 bmap = isl_basic_map_extend_constraints(bmap,
1831 0, n_lower * n_upper);
1832 for (i = bmap->n_ineq - 1; i >= 0; --i) {
1834 if (isl_int_is_zero(bmap->ineq[i][1+d]))
1837 for (j = 0; j < i; ++j) {
1838 if (isl_int_is_zero(bmap->ineq[j][1+d]))
1841 if (isl_int_sgn(bmap->ineq[i][1+d]) ==
1842 isl_int_sgn(bmap->ineq[j][1+d]))
1844 k = isl_basic_map_alloc_inequality(bmap);
1847 isl_seq_cpy(bmap->ineq[k], bmap->ineq[i],
1849 isl_seq_elim(bmap->ineq[k], bmap->ineq[j],
1850 1+d, 1+total, NULL);
1852 isl_basic_map_drop_inequality(bmap, i);
1855 if (n_lower > 0 && n_upper > 0) {
1856 bmap = normalize_constraints(bmap);
1857 bmap = remove_duplicate_constraints(bmap, NULL);
1858 bmap = isl_basic_map_gauss(bmap, NULL);
1859 bmap = isl_basic_map_convex_hull(bmap);
1862 if (F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
1866 F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
1869 isl_basic_map_free(bmap);
1873 struct isl_basic_set *isl_basic_set_eliminate_vars(
1874 struct isl_basic_set *bset, unsigned pos, unsigned n)
1876 return (struct isl_basic_set *)isl_basic_map_eliminate_vars(
1877 (struct isl_basic_map *)bset, pos, n);
1880 /* Eliminate the specified n dimensions starting at first from the
1881 * constraints using Fourier-Motzkin, The dimensions themselves
1884 struct isl_set *isl_set_eliminate_dims(struct isl_set *set,
1885 unsigned first, unsigned n)
1895 set = isl_set_cow(set);
1898 isl_assert(set->ctx, first+n <= isl_set_n_dim(set), goto error);
1899 nparam = isl_set_n_param(set);
1901 for (i = 0; i < set->n; ++i) {
1902 set->p[i] = isl_basic_set_eliminate_vars(set->p[i],
1913 /* Project out n dimensions starting at first using Fourier-Motzkin */
1914 struct isl_set *isl_set_remove_dims(struct isl_set *set,
1915 unsigned first, unsigned n)
1917 set = isl_set_eliminate_dims(set, first, n);
1918 set = isl_set_drop_dims(set, first, n);
1922 struct isl_basic_set *isl_basic_set_remove_divs(struct isl_basic_set *bset)
1924 bset = isl_basic_set_eliminate_vars(bset, isl_dim_total(bset->dim),
1932 struct isl_set *isl_set_remove_divs(struct isl_set *set)
1941 set = isl_set_cow(set);
1945 for (i = 0; i < set->n; ++i) {
1946 set->p[i] = isl_basic_set_remove_divs(set->p[i]);
1956 /* Project out n inputs starting at first using Fourier-Motzkin */
1957 struct isl_map *isl_map_remove_inputs(struct isl_map *map,
1958 unsigned first, unsigned n)
1966 map = isl_map_cow(map);
1969 nparam = isl_map_n_param(map);
1970 isl_assert(map->ctx, first+n <= isl_map_n_in(map), goto error);
1972 for (i = 0; i < map->n; ++i) {
1973 map->p[i] = isl_basic_map_eliminate_vars(map->p[i],
1978 map = isl_map_drop_inputs(map, first, n);
1985 /* Project out n dimensions starting at first using Fourier-Motzkin */
1986 struct isl_basic_set *isl_basic_set_remove_dims(struct isl_basic_set *bset,
1987 unsigned first, unsigned n)
1989 unsigned nparam = isl_basic_set_n_param(bset);
1990 bset = isl_basic_set_eliminate_vars(bset, nparam + first, n);
1991 bset = isl_basic_set_drop_dims(bset, first, n);
1995 /* Elimininate divs based on inequalities
1997 static struct isl_basic_map *eliminate_divs_ineq(
1998 struct isl_basic_map *bmap, int *progress)
2003 struct isl_ctx *ctx;
2009 off = 1 + isl_dim_total(bmap->dim);
2011 for (d = bmap->n_div - 1; d >= 0 ; --d) {
2012 for (i = 0; i < bmap->n_eq; ++i)
2013 if (!isl_int_is_zero(bmap->eq[i][off + d]))
2017 for (i = 0; i < bmap->n_ineq; ++i)
2018 if (isl_int_abs_gt(bmap->ineq[i][off + d], ctx->one))
2020 if (i < bmap->n_ineq)
2023 bmap = isl_basic_map_eliminate_vars(bmap, (off-1)+d, 1);
2024 if (F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
2026 bmap = isl_basic_map_drop_div(bmap, d);
2033 struct isl_basic_map *isl_basic_map_simplify(struct isl_basic_map *bmap)
2040 bmap = normalize_constraints(bmap);
2041 bmap = eliminate_divs_eq(bmap, &progress);
2042 bmap = eliminate_divs_ineq(bmap, &progress);
2043 bmap = isl_basic_map_gauss(bmap, &progress);
2044 bmap = remove_duplicate_divs(bmap, &progress);
2045 bmap = remove_duplicate_constraints(bmap, &progress);
2050 struct isl_basic_set *isl_basic_set_simplify(struct isl_basic_set *bset)
2052 return (struct isl_basic_set *)
2053 isl_basic_map_simplify((struct isl_basic_map *)bset);
2056 static void dump_term(struct isl_basic_map *bmap,
2057 isl_int c, int pos, FILE *out)
2060 unsigned in = isl_basic_map_n_in(bmap);
2061 unsigned dim = in + isl_basic_map_n_out(bmap);
2062 unsigned nparam = isl_basic_map_n_param(bmap);
2064 isl_int_print(out, c, 0);
2066 if (!isl_int_is_one(c))
2067 isl_int_print(out, c, 0);
2068 if (pos < 1 + nparam) {
2069 name = isl_dim_get_name(bmap->dim,
2070 isl_dim_param, pos - 1);
2072 fprintf(out, "%s", name);
2074 fprintf(out, "p%d", pos - 1);
2075 } else if (pos < 1 + nparam + in)
2076 fprintf(out, "i%d", pos - 1 - nparam);
2077 else if (pos < 1 + nparam + dim)
2078 fprintf(out, "o%d", pos - 1 - nparam - in);
2080 fprintf(out, "e%d", pos - 1 - nparam - dim);
2084 static void dump_constraint_sign(struct isl_basic_map *bmap, isl_int *c,
2085 int sign, FILE *out)
2089 unsigned len = 1 + isl_basic_map_total_dim(bmap);
2093 for (i = 0, first = 1; i < len; ++i) {
2094 if (isl_int_sgn(c[i]) * sign <= 0)
2097 fprintf(out, " + ");
2099 isl_int_abs(v, c[i]);
2100 dump_term(bmap, v, i, out);
2107 static void dump_constraint(struct isl_basic_map *bmap, isl_int *c,
2108 const char *op, FILE *out, int indent)
2112 fprintf(out, "%*s", indent, "");
2114 dump_constraint_sign(bmap, c, 1, out);
2115 fprintf(out, " %s ", op);
2116 dump_constraint_sign(bmap, c, -1, out);
2120 for (i = bmap->n_div; i < bmap->extra; ++i) {
2121 if (isl_int_is_zero(c[1+isl_dim_total(bmap->dim)+i]))
2123 fprintf(out, "%*s", indent, "");
2124 fprintf(out, "ERROR: unused div coefficient not zero\n");
2129 static void dump_constraints(struct isl_basic_map *bmap,
2130 isl_int **c, unsigned n,
2131 const char *op, FILE *out, int indent)
2135 for (i = 0; i < n; ++i)
2136 dump_constraint(bmap, c[i], op, out, indent);
2139 static void dump_affine(struct isl_basic_map *bmap, isl_int *exp, FILE *out)
2143 unsigned total = isl_basic_map_total_dim(bmap);
2145 for (j = 0; j < 1 + total; ++j) {
2146 if (isl_int_is_zero(exp[j]))
2148 if (!first && isl_int_is_pos(exp[j]))
2150 dump_term(bmap, exp[j], j, out);
2155 static void dump(struct isl_basic_map *bmap, FILE *out, int indent)
2159 dump_constraints(bmap, bmap->eq, bmap->n_eq, "=", out, indent);
2160 dump_constraints(bmap, bmap->ineq, bmap->n_ineq, ">=", out, indent);
2162 for (i = 0; i < bmap->n_div; ++i) {
2163 fprintf(out, "%*s", indent, "");
2164 fprintf(out, "e%d = [(", i);
2165 dump_affine(bmap, bmap->div[i]+1, out);
2167 isl_int_print(out, bmap->div[i][0], 0);
2168 fprintf(out, "]\n");
2172 void isl_basic_set_dump(struct isl_basic_set *bset, FILE *out, int indent)
2175 fprintf(out, "null basic set\n");
2179 fprintf(out, "%*s", indent, "");
2180 fprintf(out, "ref: %d, nparam: %d, dim: %d, extra: %d, flags: %x\n",
2181 bset->ref, bset->dim->nparam, bset->dim->n_out,
2182 bset->extra, bset->flags);
2183 dump((struct isl_basic_map *)bset, out, indent);
2186 void isl_basic_map_dump(struct isl_basic_map *bmap, FILE *out, int indent)
2189 fprintf(out, "null basic map\n");
2193 fprintf(out, "%*s", indent, "");
2194 fprintf(out, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, "
2195 "flags: %x, n_name: %d\n",
2197 bmap->dim->nparam, bmap->dim->n_in, bmap->dim->n_out,
2198 bmap->extra, bmap->flags, bmap->dim->n_name);
2199 dump(bmap, out, indent);
2202 int isl_inequality_negate(struct isl_basic_map *bmap, unsigned pos)
2207 total = isl_basic_map_total_dim(bmap);
2208 isl_assert(bmap->ctx, pos < bmap->n_ineq, return -1);
2209 isl_seq_neg(bmap->ineq[pos], bmap->ineq[pos], 1 + total);
2210 isl_int_sub_ui(bmap->ineq[pos][0], bmap->ineq[pos][0], 1);
2211 F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
2215 struct isl_set *isl_set_alloc_dim(struct isl_dim *dim, int n, unsigned flags)
2217 struct isl_set *set;
2221 isl_assert(dim->ctx, dim->n_in == 0, return NULL);
2222 isl_assert(dim->ctx, n >= 0, return NULL);
2223 set = isl_alloc(dim->ctx, struct isl_set,
2224 sizeof(struct isl_set) +
2225 n * sizeof(struct isl_basic_set *));
2229 set->ctx = dim->ctx;
2230 isl_ctx_ref(set->ctx);
2242 struct isl_set *isl_set_alloc(struct isl_ctx *ctx,
2243 unsigned nparam, unsigned dim, int n, unsigned flags)
2245 struct isl_set *set;
2246 struct isl_dim *dims;
2248 dims = isl_dim_alloc(ctx, nparam, 0, dim);
2252 set = isl_set_alloc_dim(dims, n, flags);
2256 struct isl_set *isl_set_dup(struct isl_set *set)
2259 struct isl_set *dup;
2264 dup = isl_set_alloc_dim(isl_dim_copy(set->dim), set->n, set->flags);
2267 for (i = 0; i < set->n; ++i)
2268 dup = isl_set_add(dup, isl_basic_set_copy(set->p[i]));
2272 struct isl_set *isl_set_from_basic_set(struct isl_basic_set *bset)
2274 struct isl_set *set;
2279 set = isl_set_alloc_dim(isl_dim_copy(bset->dim), 1, ISL_MAP_DISJOINT);
2281 isl_basic_set_free(bset);
2284 return isl_set_add(set, bset);
2287 struct isl_map *isl_map_from_basic_map(struct isl_basic_map *bmap)
2289 struct isl_map *map;
2294 map = isl_map_alloc_dim(isl_dim_copy(bmap->dim), 1, ISL_MAP_DISJOINT);
2296 isl_basic_map_free(bmap);
2299 return isl_map_add(map, bmap);
2302 struct isl_set *isl_set_add(struct isl_set *set, struct isl_basic_set *bset)
2306 isl_assert(set->ctx, isl_dim_equal(set->dim, bset->dim), goto error);
2307 isl_assert(set->ctx, set->n < set->size, goto error);
2308 set->p[set->n] = bset;
2315 isl_basic_set_free(bset);
2319 void isl_set_free(struct isl_set *set)
2329 isl_ctx_deref(set->ctx);
2330 for (i = 0; i < set->n; ++i)
2331 isl_basic_set_free(set->p[i]);
2332 isl_dim_free(set->dim);
2336 void isl_set_dump(struct isl_set *set, FILE *out, int indent)
2341 fprintf(out, "null set\n");
2345 fprintf(out, "%*s", indent, "");
2346 fprintf(out, "ref: %d, n: %d, nparam: %d, dim: %d, flags: %x\n",
2347 set->ref, set->n, set->dim->nparam, set->dim->n_out,
2349 for (i = 0; i < set->n; ++i) {
2350 fprintf(out, "%*s", indent, "");
2351 fprintf(out, "basic set %d:\n", i);
2352 isl_basic_set_dump(set->p[i], out, indent+4);
2356 void isl_map_dump(struct isl_map *map, FILE *out, int indent)
2361 fprintf(out, "null map\n");
2365 fprintf(out, "%*s", indent, "");
2366 fprintf(out, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, "
2367 "flags: %x, n_name: %d\n",
2368 map->ref, map->n, map->dim->nparam, map->dim->n_in,
2369 map->dim->n_out, map->flags, map->dim->n_name);
2370 for (i = 0; i < map->n; ++i) {
2371 fprintf(out, "%*s", indent, "");
2372 fprintf(out, "basic map %d:\n", i);
2373 isl_basic_map_dump(map->p[i], out, indent+4);
2377 struct isl_basic_map *isl_basic_map_intersect_domain(
2378 struct isl_basic_map *bmap, struct isl_basic_set *bset)
2380 struct isl_basic_map *bmap_domain;
2381 struct isl_dim *dim;
2386 isl_assert(set->ctx, isl_basic_map_compatible_domain(bmap, bset),
2389 bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim),
2390 bset->n_div, bset->n_eq, bset->n_ineq);
2393 dim = isl_dim_reverse(isl_dim_copy(bset->dim));
2394 bmap_domain = isl_basic_map_from_basic_set(bset, dim);
2395 bmap = add_constraints(bmap, bmap_domain, 0, 0);
2397 bmap = isl_basic_map_simplify(bmap);
2398 return isl_basic_map_finalize(bmap);
2400 isl_basic_map_free(bmap);
2401 isl_basic_set_free(bset);
2405 struct isl_basic_map *isl_basic_map_intersect_range(
2406 struct isl_basic_map *bmap, struct isl_basic_set *bset)
2408 struct isl_basic_map *bmap_range;
2413 isl_assert(bset->ctx, isl_basic_map_compatible_range(bmap, bset),
2416 bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim),
2417 bset->n_div, bset->n_eq, bset->n_ineq);
2420 bmap_range = isl_basic_map_from_basic_set(bset, isl_dim_copy(bset->dim));
2421 bmap = add_constraints(bmap, bmap_range, 0, 0);
2423 bmap = isl_basic_map_simplify(bmap);
2424 return isl_basic_map_finalize(bmap);
2426 isl_basic_map_free(bmap);
2427 isl_basic_set_free(bset);
2431 struct isl_basic_map *isl_basic_map_intersect(
2432 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
2434 if (!bmap1 || !bmap2)
2437 isl_assert(map1->ctx, isl_dim_equal(bmap1->dim, bmap2->dim), goto error);
2439 bmap1 = isl_basic_map_extend_dim(bmap1, isl_dim_copy(bmap1->dim),
2440 bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
2443 bmap1 = add_constraints(bmap1, bmap2, 0, 0);
2445 bmap1 = isl_basic_map_simplify(bmap1);
2446 return isl_basic_map_finalize(bmap1);
2448 isl_basic_map_free(bmap1);
2449 isl_basic_map_free(bmap2);
2453 struct isl_basic_set *isl_basic_set_intersect(
2454 struct isl_basic_set *bset1, struct isl_basic_set *bset2)
2456 return (struct isl_basic_set *)
2457 isl_basic_map_intersect(
2458 (struct isl_basic_map *)bset1,
2459 (struct isl_basic_map *)bset2);
2462 struct isl_map *isl_map_intersect(struct isl_map *map1, struct isl_map *map2)
2465 struct isl_map *result;
2471 if (F_ISSET(map1, ISL_MAP_DISJOINT) &&
2472 F_ISSET(map2, ISL_MAP_DISJOINT))
2473 FL_SET(flags, ISL_MAP_DISJOINT);
2475 result = isl_map_alloc_dim(isl_dim_copy(map1->dim),
2476 map1->n * map2->n, flags);
2479 for (i = 0; i < map1->n; ++i)
2480 for (j = 0; j < map2->n; ++j) {
2481 struct isl_basic_map *part;
2482 part = isl_basic_map_intersect(
2483 isl_basic_map_copy(map1->p[i]),
2484 isl_basic_map_copy(map2->p[j]));
2485 if (isl_basic_map_is_empty(part))
2486 isl_basic_map_free(part);
2488 result = isl_map_add(result, part);
2501 struct isl_set *isl_set_intersect(struct isl_set *set1, struct isl_set *set2)
2503 return (struct isl_set *)
2504 isl_map_intersect((struct isl_map *)set1,
2505 (struct isl_map *)set2);
2508 struct isl_basic_map *isl_basic_map_reverse(struct isl_basic_map *bmap)
2510 struct isl_dim *dim;
2511 struct isl_basic_set *bset;
2516 bmap = isl_basic_map_cow(bmap);
2519 dim = isl_dim_reverse(isl_dim_copy(bmap->dim));
2520 in = isl_basic_map_n_in(bmap);
2521 bset = isl_basic_set_from_basic_map(bmap);
2522 bset = isl_basic_set_swap_vars(bset, in);
2523 return isl_basic_map_from_basic_set(bset, dim);
2526 /* Turn final n dimensions into existentially quantified variables.
2528 struct isl_basic_set *isl_basic_set_project_out(
2529 struct isl_basic_set *bset, unsigned n, unsigned flags)
2539 isl_assert(bset->ctx, n <= isl_basic_set_n_dim(bset), goto error);
2544 bset = isl_basic_set_cow(bset);
2546 row_size = 1 + isl_dim_total(bset->dim) + bset->extra;
2547 old = bset->block2.data;
2548 bset->block2 = isl_blk_extend(bset->ctx, bset->block2,
2549 (bset->extra + n) * (1 + row_size));
2550 if (!bset->block2.data)
2552 new_div = isl_alloc_array(ctx, isl_int *, bset->extra + n);
2555 for (i = 0; i < n; ++i) {
2556 new_div[i] = bset->block2.data +
2557 (bset->extra + i) * (1 + row_size);
2558 isl_seq_clr(new_div[i], 1 + row_size);
2560 for (i = 0; i < bset->extra; ++i)
2561 new_div[n + i] = bset->block2.data + (bset->div[i] - old);
2563 bset->div = new_div;
2566 bset->dim = isl_dim_drop_outputs(bset->dim,
2567 isl_basic_set_n_dim(bset) - n, n);
2570 bset = isl_basic_set_simplify(bset);
2571 return isl_basic_set_finalize(bset);
2573 isl_basic_set_free(bset);
2577 struct isl_basic_map *add_divs(struct isl_basic_map *bmap, unsigned n)
2581 for (i = 0; i < n; ++i) {
2582 j = isl_basic_map_alloc_div(bmap);
2585 isl_seq_clr(bmap->div[j], 1+1+isl_basic_map_total_dim(bmap));
2589 isl_basic_map_free(bmap);
2593 struct isl_basic_map *isl_basic_map_apply_range(
2594 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
2596 struct isl_dim *dim_result = NULL;
2597 struct isl_basic_map *bmap;
2598 unsigned n_in, n_out, n, nparam, total, pos;
2599 struct isl_dim_map *dim_map1, *dim_map2;
2601 if (!bmap1 || !bmap2)
2604 dim_result = isl_dim_join(isl_dim_copy(bmap1->dim),
2605 isl_dim_copy(bmap2->dim));
2607 n_in = isl_basic_map_n_in(bmap1);
2608 n_out = isl_basic_map_n_out(bmap2);
2609 n = isl_basic_map_n_out(bmap1);
2610 nparam = isl_basic_map_n_param(bmap1);
2612 total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + n;
2613 dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
2614 dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
2615 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
2616 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
2617 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
2618 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_in);
2619 isl_dim_map_div(dim_map1, bmap1, pos += n_out);
2620 isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
2621 isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
2622 isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
2624 bmap = isl_basic_map_alloc_dim(dim_result,
2625 bmap1->n_div + bmap2->n_div + n,
2626 bmap1->n_eq + bmap2->n_eq,
2627 bmap1->n_ineq + bmap2->n_ineq);
2628 bmap = add_constraints_dim_map(bmap, bmap1, dim_map1);
2629 bmap = add_constraints_dim_map(bmap, bmap2, dim_map2);
2630 bmap = add_divs(bmap, n);
2631 bmap = isl_basic_map_simplify(bmap);
2632 return isl_basic_map_finalize(bmap);
2634 isl_basic_map_free(bmap1);
2635 isl_basic_map_free(bmap2);
2639 struct isl_basic_set *isl_basic_set_apply(
2640 struct isl_basic_set *bset, struct isl_basic_map *bmap)
2645 isl_assert(set->ctx, isl_basic_map_compatible_domain(bmap, bset),
2648 return (struct isl_basic_set *)
2649 isl_basic_map_apply_range((struct isl_basic_map *)bset, bmap);
2651 isl_basic_set_free(bset);
2652 isl_basic_map_free(bmap);
2656 struct isl_basic_map *isl_basic_map_apply_domain(
2657 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
2659 if (!bmap1 || !bmap2)
2663 isl_basic_map_n_in(bmap1) == isl_basic_map_n_in(bmap2), goto error);
2665 isl_basic_map_n_param(bmap1) == isl_basic_map_n_param(bmap2),
2668 bmap1 = isl_basic_map_reverse(bmap1);
2669 bmap1 = isl_basic_map_apply_range(bmap1, bmap2);
2670 return isl_basic_map_reverse(bmap1);
2672 isl_basic_map_free(bmap1);
2673 isl_basic_map_free(bmap2);
2677 static struct isl_basic_map *var_equal(struct isl_ctx *ctx,
2678 struct isl_basic_map *bmap, unsigned pos)
2684 i = isl_basic_map_alloc_equality(bmap);
2687 nparam = isl_basic_map_n_param(bmap);
2688 n_in = isl_basic_map_n_in(bmap);
2689 isl_seq_clr(bmap->eq[i], 1 + isl_basic_map_total_dim(bmap));
2690 isl_int_set_si(bmap->eq[i][1+nparam+pos], -1);
2691 isl_int_set_si(bmap->eq[i][1+nparam+n_in+pos], 1);
2692 return isl_basic_map_finalize(bmap);
2694 isl_basic_map_free(bmap);
2698 static struct isl_basic_map *var_more(struct isl_ctx *ctx,
2699 struct isl_basic_map *bmap, unsigned pos)
2705 i = isl_basic_map_alloc_inequality(bmap);
2708 nparam = isl_basic_map_n_param(bmap);
2709 n_in = isl_basic_map_n_in(bmap);
2710 isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
2711 isl_int_set_si(bmap->ineq[i][0], -1);
2712 isl_int_set_si(bmap->ineq[i][1+nparam+pos], -1);
2713 isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], 1);
2714 return isl_basic_map_finalize(bmap);
2716 isl_basic_map_free(bmap);
2720 static struct isl_basic_map *var_less(struct isl_ctx *ctx,
2721 struct isl_basic_map *bmap, unsigned pos)
2727 i = isl_basic_map_alloc_inequality(bmap);
2730 nparam = isl_basic_map_n_param(bmap);
2731 n_in = isl_basic_map_n_in(bmap);
2732 isl_seq_clr(bmap->ineq[i], 1 + isl_basic_map_total_dim(bmap));
2733 isl_int_set_si(bmap->ineq[i][0], -1);
2734 isl_int_set_si(bmap->ineq[i][1+nparam+pos], 1);
2735 isl_int_set_si(bmap->ineq[i][1+nparam+n_in+pos], -1);
2736 return isl_basic_map_finalize(bmap);
2738 isl_basic_map_free(bmap);
2742 struct isl_basic_map *isl_basic_map_equal(struct isl_ctx *ctx,
2743 unsigned nparam, unsigned in, unsigned out, unsigned n_equal)
2746 struct isl_basic_map *bmap;
2747 bmap = isl_basic_map_alloc(ctx, nparam, in, out, 0, n_equal, 0);
2750 for (i = 0; i < n_equal && bmap; ++i)
2751 bmap = var_equal(ctx, bmap, i);
2752 return isl_basic_map_finalize(bmap);
2755 struct isl_basic_map *isl_basic_map_less_at(struct isl_ctx *ctx,
2756 unsigned nparam, unsigned in, unsigned out, unsigned pos)
2759 struct isl_basic_map *bmap;
2760 bmap = isl_basic_map_alloc(ctx, nparam, in, out, 0, pos, 1);
2763 for (i = 0; i < pos && bmap; ++i)
2764 bmap = var_equal(ctx, bmap, i);
2766 bmap = var_less(ctx, bmap, pos);
2767 return isl_basic_map_finalize(bmap);
2770 struct isl_basic_map *isl_basic_map_more_at(struct isl_ctx *ctx,
2771 unsigned nparam, unsigned in, unsigned out, unsigned pos)
2774 struct isl_basic_map *bmap;
2775 bmap = isl_basic_map_alloc(ctx, nparam, in, out, 0, pos, 1);
2778 for (i = 0; i < pos && bmap; ++i)
2779 bmap = var_equal(ctx, bmap, i);
2781 bmap = var_more(ctx, bmap, pos);
2782 return isl_basic_map_finalize(bmap);
2785 struct isl_basic_map *isl_basic_map_from_basic_set(
2786 struct isl_basic_set *bset, struct isl_dim *dim)
2788 struct isl_basic_map *bmap;
2790 bset = isl_basic_set_cow(bset);
2794 isl_assert(bset->ctx, isl_dim_compatible(bset->dim, dim), goto error);
2795 isl_dim_free(bset->dim);
2796 bmap = (struct isl_basic_map *) bset;
2798 return isl_basic_map_finalize(bmap);
2800 isl_basic_set_free(bset);
2805 struct isl_basic_set *isl_basic_set_from_basic_map(struct isl_basic_map *bmap)
2809 if (bmap->dim->n_in == 0)
2810 return (struct isl_basic_set *)bmap;
2811 bmap = isl_basic_map_cow(bmap);
2814 bmap->dim = isl_dim_cow(bmap->dim);
2817 bmap->dim->n_out += bmap->dim->n_in;
2818 bmap->dim->n_in = 0;
2819 bmap = isl_basic_map_finalize(bmap);
2820 return (struct isl_basic_set *)bmap;
2822 isl_basic_map_free(bmap);
2826 /* For a div d = floor(f/m), add the constraints
2829 * -(f-(n-1)) + m d >= 0
2831 * Note that the second constraint is the negation of
2835 static int add_div_constraints(struct isl_basic_map *bmap, unsigned div)
2838 unsigned total = isl_basic_map_total_dim(bmap);
2839 unsigned div_pos = 1 + total - bmap->n_div + div;
2841 i = isl_basic_map_alloc_inequality(bmap);
2844 isl_seq_cpy(bmap->ineq[i], bmap->div[div]+1, 1+total);
2845 isl_int_neg(bmap->ineq[i][div_pos], bmap->div[div][0]);
2847 j = isl_basic_map_alloc_inequality(bmap);
2850 isl_seq_neg(bmap->ineq[j], bmap->ineq[i], 1 + total);
2851 isl_int_add(bmap->ineq[j][0], bmap->ineq[j][0], bmap->ineq[j][div_pos]);
2852 isl_int_sub_ui(bmap->ineq[j][0], bmap->ineq[j][0], 1);
2856 struct isl_basic_set *isl_basic_map_underlying_set(
2857 struct isl_basic_map *bmap)
2861 if (bmap->dim->nparam == 0 && bmap->dim->n_in == 0 && bmap->n_div == 0)
2862 return (struct isl_basic_set *)bmap;
2863 bmap = isl_basic_map_cow(bmap);
2866 bmap->dim = isl_dim_cow(bmap->dim);
2869 bmap->dim->n_out += bmap->dim->nparam + bmap->dim->n_in + bmap->n_div;
2870 bmap->dim->nparam = 0;
2871 bmap->dim->n_in = 0;
2872 bmap->extra -= bmap->n_div;
2874 bmap = isl_basic_map_finalize(bmap);
2875 return (struct isl_basic_set *)bmap;
2880 struct isl_basic_map *isl_basic_map_overlying_set(
2881 struct isl_basic_set *bset, struct isl_basic_map *like)
2883 struct isl_basic_map *bmap;
2884 struct isl_ctx *ctx;
2891 isl_assert(ctx, bset->n_div == 0, goto error);
2892 isl_assert(ctx, isl_basic_set_n_param(bset) == 0, goto error);
2893 isl_assert(ctx, bset->dim->n_out == isl_basic_map_total_dim(like),
2895 if (isl_dim_equal(bset->dim, like->dim) && like->n_div == 0) {
2896 isl_basic_map_free(like);
2897 return (struct isl_basic_map *)bset;
2899 bset = isl_basic_set_cow(bset);
2902 total = bset->dim->n_out + bset->extra;
2903 bmap = (struct isl_basic_map *)bset;
2904 isl_dim_free(bmap->dim);
2905 bmap->dim = isl_dim_copy(like->dim);
2908 bmap->n_div = like->n_div;
2909 bmap->extra += like->n_div;
2912 ltotal = total - bmap->extra + like->extra;
2915 bmap->block2 = isl_blk_extend(ctx, bmap->block2,
2916 bmap->extra * (1 + 1 + total));
2917 if (isl_blk_is_error(bmap->block2))
2919 bmap->div = isl_realloc_array(ctx, bmap->div, isl_int *,
2923 for (i = 0; i < bmap->extra; ++i)
2924 bmap->div[i] = bmap->block2.data + i * (1 + 1 + total);
2925 for (i = 0; i < like->n_div; ++i) {
2926 isl_seq_cpy(bmap->div[i], like->div[i], 1 + 1 + ltotal);
2927 isl_seq_clr(bmap->div[i]+1+1+ltotal, total - ltotal);
2929 bmap = isl_basic_map_extend_constraints(bmap,
2930 0, 2 * like->n_div);
2931 for (i = 0; i < like->n_div; ++i)
2932 if (add_div_constraints(bmap, i) < 0)
2935 isl_basic_map_free(like);
2936 bmap = isl_basic_map_simplify(bmap);
2937 bmap = isl_basic_map_finalize(bmap);
2940 isl_basic_map_free(like);
2941 isl_basic_set_free(bset);
2945 struct isl_basic_set *isl_basic_set_from_underlying_set(
2946 struct isl_basic_set *bset, struct isl_basic_set *like)
2948 return (struct isl_basic_set *)
2949 isl_basic_map_overlying_set(bset, (struct isl_basic_map *)like);
2952 struct isl_set *isl_set_from_underlying_set(
2953 struct isl_set *set, struct isl_basic_set *like)
2959 isl_assert(set->ctx, set->dim->n_out == isl_basic_set_total_dim(like),
2961 if (isl_dim_equal(set->dim, like->dim) && like->n_div == 0) {
2962 isl_basic_set_free(like);
2965 set = isl_set_cow(set);
2968 for (i = 0; i < set->n; ++i) {
2969 set->p[i] = isl_basic_set_from_underlying_set(set->p[i],
2970 isl_basic_set_copy(like));
2974 isl_dim_free(set->dim);
2975 set->dim = isl_dim_copy(like->dim);
2978 isl_basic_set_free(like);
2981 isl_basic_set_free(like);
2986 struct isl_set *isl_map_underlying_set(struct isl_map *map)
2990 map = isl_map_cow(map);
2993 map->dim = isl_dim_cow(map->dim);
2997 for (i = 1; i < map->n; ++i)
2998 isl_assert(map->ctx, map->p[0]->n_div == map->p[i]->n_div,
3000 for (i = 0; i < map->n; ++i) {
3001 map->p[i] = (struct isl_basic_map *)
3002 isl_basic_map_underlying_set(map->p[i]);
3007 map->dim->n_out += map->dim->nparam + map->dim->n_in;
3009 map->dim->n_out = map->p[0]->dim->n_out;
3010 map->dim->nparam = 0;
3012 return (struct isl_set *)map;
3018 struct isl_set *isl_set_to_underlying_set(struct isl_set *set)
3020 return (struct isl_set *)isl_map_underlying_set((struct isl_map *)set);
3023 struct isl_basic_set *isl_basic_map_domain(struct isl_basic_map *bmap)
3025 struct isl_basic_set *domain;
3029 n_out = isl_basic_map_n_out(bmap);
3030 domain = isl_basic_set_from_basic_map(bmap);
3031 return isl_basic_set_project_out(domain, n_out, 0);
3034 struct isl_basic_set *isl_basic_map_range(struct isl_basic_map *bmap)
3036 return isl_basic_map_domain(isl_basic_map_reverse(bmap));
3039 struct isl_set *isl_map_range(struct isl_map *map)
3042 struct isl_set *set;
3046 map = isl_map_cow(map);
3050 set = (struct isl_set *) map;
3051 if (set->dim->n_in != 0) {
3052 set->dim = isl_dim_drop_inputs(set->dim, 0, set->dim->n_in);
3056 for (i = 0; i < map->n; ++i) {
3057 set->p[i] = isl_basic_map_range(map->p[i]);
3061 F_CLR(set, ISL_MAP_DISJOINT);
3062 F_CLR(set, ISL_SET_NORMALIZED);
3069 struct isl_map *isl_map_from_set(struct isl_set *set, struct isl_dim *dim)
3072 struct isl_map *map = NULL;
3074 set = isl_set_cow(set);
3077 isl_assert(set->ctx, isl_dim_compatible(set->dim, dim), goto error);
3078 map = (struct isl_map *)set;
3079 for (i = 0; i < set->n; ++i) {
3080 map->p[i] = isl_basic_map_from_basic_set(
3081 set->p[i], isl_dim_copy(dim));
3085 isl_dim_free(map->dim);
3094 struct isl_set *isl_set_from_map(struct isl_map *map)
3097 struct isl_set *set = NULL;
3101 map = isl_map_cow(map);
3104 map->dim = isl_dim_cow(map->dim);
3107 map->dim->n_out += map->dim->n_in;
3109 set = (struct isl_set *)map;
3110 for (i = 0; i < map->n; ++i) {
3111 set->p[i] = isl_basic_set_from_basic_map(map->p[i]);
3121 struct isl_map *isl_map_alloc_dim(struct isl_dim *dim, int n, unsigned flags)
3123 struct isl_map *map;
3127 isl_assert(dim->ctx, n >= 0, return NULL);
3128 map = isl_alloc(dim->ctx, struct isl_map,
3129 sizeof(struct isl_map) +
3130 n * sizeof(struct isl_basic_map *));
3134 map->ctx = dim->ctx;
3135 isl_ctx_ref(map->ctx);
3147 struct isl_map *isl_map_alloc(struct isl_ctx *ctx,
3148 unsigned nparam, unsigned in, unsigned out, int n,
3151 struct isl_map *map;
3152 struct isl_dim *dims;
3154 dims = isl_dim_alloc(ctx, nparam, in, out);
3158 map = isl_map_alloc_dim(dims, n, flags);
3162 struct isl_basic_map *isl_basic_map_empty(struct isl_ctx *ctx,
3163 unsigned nparam, unsigned in, unsigned out)
3165 struct isl_basic_map *bmap;
3166 bmap = isl_basic_map_alloc(ctx, nparam, in, out, 0, 1, 0);
3167 bmap = isl_basic_map_set_to_empty(bmap);
3171 struct isl_basic_set *isl_basic_set_empty(struct isl_dim *dim)
3173 struct isl_basic_set *bset;
3174 bset = isl_basic_set_alloc_dim(dim, 0, 1, 0);
3175 bset = isl_basic_set_set_to_empty(bset);
3179 struct isl_basic_map *isl_basic_map_empty_like(struct isl_basic_map *model)
3181 struct isl_basic_map *bmap;
3184 bmap = isl_basic_map_alloc_dim(isl_dim_copy(model->dim), 0, 1, 0);
3185 bmap = isl_basic_map_set_to_empty(bmap);
3189 struct isl_basic_map *isl_basic_map_empty_like_map(struct isl_map *model)
3191 struct isl_basic_map *bmap;
3194 bmap = isl_basic_map_alloc_dim(isl_dim_copy(model->dim), 0, 1, 0);
3195 bmap = isl_basic_map_set_to_empty(bmap);
3199 struct isl_basic_set *isl_basic_set_empty_like(struct isl_basic_set *model)
3201 struct isl_basic_set *bset;
3204 bset = isl_basic_set_alloc_dim(isl_dim_copy(model->dim), 0, 1, 0);
3205 bset = isl_basic_set_set_to_empty(bset);
3209 struct isl_basic_map *isl_basic_map_universe(struct isl_dim *dim)
3211 struct isl_basic_map *bmap;
3212 bmap = isl_basic_map_alloc_dim(dim, 0, 0, 0);
3216 struct isl_basic_set *isl_basic_set_universe(struct isl_dim *dim)
3218 struct isl_basic_set *bset;
3219 bset = isl_basic_set_alloc_dim(dim, 0, 0, 0);
3223 struct isl_basic_set *isl_basic_set_universe_like(struct isl_basic_set *model)
3227 return isl_basic_set_alloc_dim(isl_dim_copy(model->dim), 0, 0, 0);
3230 struct isl_map *isl_map_empty(struct isl_ctx *ctx,
3231 unsigned nparam, unsigned in, unsigned out)
3233 return isl_map_alloc(ctx, nparam, in, out, 0, ISL_MAP_DISJOINT);
3236 struct isl_map *isl_map_empty_like_basic_map(struct isl_basic_map *model)
3240 return isl_map_alloc_dim(isl_dim_copy(model->dim), 0, ISL_MAP_DISJOINT);
3243 struct isl_set *isl_set_empty(struct isl_dim *dim)
3245 return isl_set_alloc_dim(dim, 0, ISL_MAP_DISJOINT);
3248 struct isl_set *isl_set_empty_like(struct isl_set *model)
3252 return isl_set_empty(isl_dim_copy(model->dim));
3255 struct isl_set *isl_set_universe(struct isl_dim *dim)
3257 struct isl_set *set;
3260 set = isl_set_alloc_dim(isl_dim_copy(dim), 1, ISL_MAP_DISJOINT);
3261 set = isl_set_add(set, isl_basic_set_universe(dim));
3265 struct isl_map *isl_map_dup(struct isl_map *map)
3268 struct isl_map *dup;
3272 dup = isl_map_alloc_dim(isl_dim_copy(map->dim), map->n, map->flags);
3273 for (i = 0; i < map->n; ++i)
3274 dup = isl_map_add(dup, isl_basic_map_copy(map->p[i]));
3278 struct isl_map *isl_map_add(struct isl_map *map, struct isl_basic_map *bmap)
3282 isl_assert(map->ctx, isl_dim_equal(map->dim, bmap->dim), goto error);
3283 isl_assert(map->ctx, map->n < map->size, goto error);
3284 map->p[map->n] = bmap;
3286 F_CLR(map, ISL_MAP_NORMALIZED);
3292 isl_basic_map_free(bmap);
3296 void isl_map_free(struct isl_map *map)
3306 isl_ctx_deref(map->ctx);
3307 for (i = 0; i < map->n; ++i)
3308 isl_basic_map_free(map->p[i]);
3309 isl_dim_free(map->dim);
3313 struct isl_map *isl_map_extend(struct isl_map *base,
3314 unsigned nparam, unsigned n_in, unsigned n_out)
3318 base = isl_map_cow(base);
3322 base->dim = isl_dim_extend(base->dim, nparam, n_in, n_out);
3325 for (i = 0; i < base->n; ++i) {
3326 base->p[i] = isl_basic_map_extend_dim(base->p[i],
3327 isl_dim_copy(base->dim), 0, 0, 0);
3337 struct isl_set *isl_set_extend(struct isl_set *base,
3338 unsigned nparam, unsigned dim)
3340 return (struct isl_set *)isl_map_extend((struct isl_map *)base,
3344 static struct isl_basic_map *isl_basic_map_fix_var(struct isl_basic_map *bmap,
3345 unsigned var, int value)
3349 bmap = isl_basic_map_cow(bmap);
3350 bmap = isl_basic_map_extend_constraints(bmap, 1, 0);
3351 j = isl_basic_map_alloc_equality(bmap);
3354 isl_seq_clr(bmap->eq[j], 1 + isl_basic_map_total_dim(bmap));
3355 isl_int_set_si(bmap->eq[j][1 + var], -1);
3356 isl_int_set_si(bmap->eq[j][0], value);
3357 bmap = isl_basic_map_simplify(bmap);
3358 return isl_basic_map_finalize(bmap);
3360 isl_basic_map_free(bmap);
3364 struct isl_basic_map *isl_basic_map_fix_input_si(struct isl_basic_map *bmap,
3365 unsigned input, int value)
3369 isl_assert(bmap->ctx, input < isl_basic_map_n_in(bmap), goto error);
3370 return isl_basic_map_fix_var(bmap, isl_basic_map_n_param(bmap) + input,
3373 isl_basic_map_free(bmap);
3377 struct isl_basic_set *isl_basic_set_fix_dim_si(struct isl_basic_set *bset,
3378 unsigned dim, int value)
3382 isl_assert(bset->ctx, dim < isl_basic_set_n_dim(bset), goto error);
3383 return (struct isl_basic_set *)
3384 isl_basic_map_fix_var((struct isl_basic_map *)bset,
3385 isl_basic_set_n_param(bset) + dim, value);
3387 isl_basic_set_free(bset);
3391 struct isl_map *isl_map_fix_input_si(struct isl_map *map,
3392 unsigned input, int value)
3396 map = isl_map_cow(map);
3400 isl_assert(ctx, input < isl_map_n_in(map), goto error);
3401 for (i = 0; i < map->n; ++i) {
3402 map->p[i] = isl_basic_map_fix_input_si(map->p[i], input, value);
3406 F_CLR(map, ISL_MAP_NORMALIZED);
3413 struct isl_set *isl_set_fix_dim_si(struct isl_set *set, unsigned dim, int value)
3417 set = isl_set_cow(set);
3421 isl_assert(set->ctx, dim < isl_set_n_dim(set), goto error);
3422 for (i = 0; i < set->n; ++i) {
3423 set->p[i] = isl_basic_set_fix_dim_si(set->p[i], dim, value);
3433 struct isl_basic_set *isl_basic_set_lower_bound_dim(struct isl_basic_set *bset,
3434 unsigned dim, isl_int value)
3439 bset = isl_basic_set_cow(bset);
3440 bset = isl_basic_set_extend_constraints(bset, 0, 1);
3441 j = isl_basic_set_alloc_inequality(bset);
3444 isl_seq_clr(bset->ineq[j], 1 + isl_basic_set_total_dim(bset));
3445 isl_int_set_si(bset->ineq[j][1 + isl_basic_set_n_param(bset) + dim], 1);
3446 isl_int_neg(bset->ineq[j][0], value);
3447 bset = isl_basic_set_simplify(bset);
3448 return isl_basic_set_finalize(bset);
3450 isl_basic_set_free(bset);
3454 struct isl_set *isl_set_lower_bound_dim(struct isl_set *set, unsigned dim,
3459 set = isl_set_cow(set);
3463 isl_assert(set->ctx, dim < isl_set_n_dim(set), goto error);
3464 for (i = 0; i < set->n; ++i) {
3465 set->p[i] = isl_basic_set_lower_bound_dim(set->p[i], dim, value);
3475 struct isl_map *isl_map_reverse(struct isl_map *map)
3480 map = isl_map_cow(map);
3484 map->dim = isl_dim_reverse(map->dim);
3487 for (i = 0; i < map->n; ++i) {
3488 map->p[i] = isl_basic_map_reverse(map->p[i]);
3492 F_CLR(map, ISL_MAP_NORMALIZED);
3499 struct isl_map *isl_basic_map_lexmax(
3500 struct isl_basic_map *bmap, struct isl_basic_set *dom,
3501 struct isl_set **empty)
3503 return isl_pip_basic_map_lexmax(bmap, dom, empty);
3506 struct isl_map *isl_basic_map_lexmin(
3507 struct isl_basic_map *bmap, struct isl_basic_set *dom,
3508 struct isl_set **empty)
3510 return isl_pip_basic_map_lexmin(bmap, dom, empty);
3513 struct isl_set *isl_basic_set_lexmin(struct isl_basic_set *bset)
3515 struct isl_basic_map *bmap = NULL;
3516 struct isl_basic_set *dom = NULL;
3517 struct isl_map *min;
3518 struct isl_dim *param_dim;
3522 bmap = isl_basic_map_from_basic_set(bset, isl_dim_copy(bset->dim));
3525 param_dim = isl_dim_domain(isl_dim_copy(bmap->dim));
3526 dom = isl_basic_set_universe(param_dim);
3529 min = isl_basic_map_lexmin(bmap, dom, NULL);
3530 return isl_map_range(min);
3532 isl_basic_map_free(bmap);
3536 struct isl_map *isl_basic_map_compute_divs(struct isl_basic_map *bmap)
3543 off = isl_dim_total(bmap->dim);
3544 for (i = 0; i < bmap->n_div; ++i) {
3545 if (isl_int_is_zero(bmap->div[i][0]))
3546 return isl_pip_basic_map_compute_divs(bmap);
3547 isl_assert(bmap->ctx, isl_int_is_zero(bmap->div[i][1+1+off+i]),
3550 return isl_map_from_basic_map(bmap);
3552 isl_basic_map_free(bmap);
3556 struct isl_map *isl_map_compute_divs(struct isl_map *map)
3559 struct isl_map *res;
3565 res = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[0]));
3566 for (i = 1 ; i < map->n; ++i) {
3568 r2 = isl_basic_map_compute_divs(isl_basic_map_copy(map->p[i]));
3569 if (F_ISSET(map, ISL_MAP_DISJOINT))
3570 res = isl_map_union_disjoint(res, r2);
3572 res = isl_map_union(res, r2);
3579 struct isl_set *isl_basic_set_compute_divs(struct isl_basic_set *bset)
3581 return (struct isl_set *)
3582 isl_basic_map_compute_divs((struct isl_basic_map *)bset);
3585 struct isl_set *isl_set_compute_divs(struct isl_set *set)
3587 return (struct isl_set *)
3588 isl_map_compute_divs((struct isl_map *)set);
3591 struct isl_set *isl_map_domain(struct isl_map *map)
3594 struct isl_set *set;
3599 map = isl_map_cow(map);
3603 set = (struct isl_set *)map;
3604 set->dim = isl_dim_domain(set->dim);
3607 for (i = 0; i < map->n; ++i) {
3608 set->p[i] = isl_basic_map_domain(map->p[i]);
3612 F_CLR(set, ISL_MAP_DISJOINT);
3613 F_CLR(set, ISL_SET_NORMALIZED);
3620 struct isl_map *isl_map_union_disjoint(
3621 struct isl_map *map1, struct isl_map *map2)
3625 struct isl_map *map = NULL;
3639 isl_assert(map1->ctx, isl_dim_equal(map1->dim, map2->dim), goto error);
3641 if (F_ISSET(map1, ISL_MAP_DISJOINT) &&
3642 F_ISSET(map2, ISL_MAP_DISJOINT))
3643 FL_SET(flags, ISL_MAP_DISJOINT);
3645 map = isl_map_alloc_dim(isl_dim_copy(map1->dim),
3646 map1->n + map2->n, flags);
3649 for (i = 0; i < map1->n; ++i) {
3650 map = isl_map_add(map,
3651 isl_basic_map_copy(map1->p[i]));
3655 for (i = 0; i < map2->n; ++i) {
3656 map = isl_map_add(map,
3657 isl_basic_map_copy(map2->p[i]));
3671 struct isl_map *isl_map_union(struct isl_map *map1, struct isl_map *map2)
3673 map1 = isl_map_union_disjoint(map1, map2);
3677 F_CLR(map1, ISL_MAP_DISJOINT);
3681 struct isl_set *isl_set_union_disjoint(
3682 struct isl_set *set1, struct isl_set *set2)
3684 return (struct isl_set *)
3685 isl_map_union_disjoint(
3686 (struct isl_map *)set1, (struct isl_map *)set2);
3689 struct isl_set *isl_set_union(struct isl_set *set1, struct isl_set *set2)
3691 return (struct isl_set *)
3692 isl_map_union((struct isl_map *)set1, (struct isl_map *)set2);
3695 struct isl_map *isl_map_intersect_range(
3696 struct isl_map *map, struct isl_set *set)
3699 struct isl_map *result;
3705 if (F_ISSET(map, ISL_MAP_DISJOINT) &&
3706 F_ISSET(set, ISL_MAP_DISJOINT))
3707 FL_SET(flags, ISL_MAP_DISJOINT);
3709 result = isl_map_alloc_dim(isl_dim_copy(map->dim),
3710 map->n * set->n, flags);
3713 for (i = 0; i < map->n; ++i)
3714 for (j = 0; j < set->n; ++j) {
3715 result = isl_map_add(result,
3716 isl_basic_map_intersect_range(
3717 isl_basic_map_copy(map->p[i]),
3718 isl_basic_set_copy(set->p[j])));
3731 struct isl_map *isl_map_intersect_domain(
3732 struct isl_map *map, struct isl_set *set)
3734 return isl_map_reverse(
3735 isl_map_intersect_range(isl_map_reverse(map), set));
3738 struct isl_map *isl_map_apply_domain(
3739 struct isl_map *map1, struct isl_map *map2)
3743 map1 = isl_map_reverse(map1);
3744 map1 = isl_map_apply_range(map1, map2);
3745 return isl_map_reverse(map1);
3752 struct isl_map *isl_map_apply_range(
3753 struct isl_map *map1, struct isl_map *map2)
3755 struct isl_dim *dim_result;
3756 struct isl_map *result;
3765 dim_result = isl_dim_join(isl_dim_copy(map1->dim),
3766 isl_dim_copy(map2->dim));
3768 result = isl_map_alloc_dim(dim_result, map1->n * map2->n, 0);
3771 for (i = 0; i < map1->n; ++i)
3772 for (j = 0; j < map2->n; ++j) {
3773 result = isl_map_add(result,
3774 isl_basic_map_apply_range(
3775 isl_basic_map_copy(map1->p[i]),
3776 isl_basic_map_copy(map2->p[j])));
3782 if (result && result->n <= 1)
3783 F_SET(result, ISL_MAP_DISJOINT);
3792 * returns range - domain
3794 struct isl_basic_set *isl_basic_map_deltas(struct isl_basic_map *bmap)
3796 struct isl_basic_set *bset;
3803 dim = isl_basic_map_n_in(bmap);
3804 nparam = isl_basic_map_n_param(bmap);
3805 isl_assert(bmap->ctx, dim == isl_basic_map_n_out(bmap), goto error);
3806 bset = isl_basic_set_from_basic_map(bmap);
3807 bset = isl_basic_set_extend(bset, nparam, 3*dim, 0, dim, 0);
3808 bset = isl_basic_set_swap_vars(bset, 2*dim);
3809 for (i = 0; i < dim; ++i) {
3810 int j = isl_basic_map_alloc_equality(
3811 (struct isl_basic_map *)bset);
3814 isl_seq_clr(bset->eq[j], 1 + isl_basic_set_total_dim(bset));
3815 isl_int_set_si(bset->eq[j][1+nparam+i], 1);
3816 isl_int_set_si(bset->eq[j][1+nparam+dim+i], 1);
3817 isl_int_set_si(bset->eq[j][1+nparam+2*dim+i], -1);
3819 return isl_basic_set_project_out(bset, 2*dim, 0);
3821 isl_basic_map_free(bmap);
3826 * returns range - domain
3828 struct isl_set *isl_map_deltas(struct isl_map *map)
3831 struct isl_set *result;
3836 isl_assert(map->ctx, isl_map_n_in(map) == isl_map_n_out(map), goto error);
3837 result = isl_set_alloc(map->ctx, isl_map_n_param(map),
3838 isl_map_n_in(map), map->n, map->flags);
3841 for (i = 0; i < map->n; ++i)
3842 result = isl_set_add(result,
3843 isl_basic_map_deltas(isl_basic_map_copy(map->p[i])));
3851 /* If the only constraints a div d=floor(f/m)
3852 * appears in are its two defining constraints
3855 * -(f - (m - 1)) + m d >= 0
3857 * then it can safely be removed.
3859 static int div_is_redundant(struct isl_basic_map *bmap, int div)
3862 unsigned pos = 1 + isl_dim_total(bmap->dim) + div;
3864 for (i = 0; i < bmap->n_eq; ++i)
3865 if (!isl_int_is_zero(bmap->eq[i][pos]))
3868 for (i = 0; i < bmap->n_ineq; ++i) {
3869 if (isl_int_is_zero(bmap->ineq[i][pos]))
3871 if (isl_int_eq(bmap->ineq[i][pos], bmap->div[div][0])) {
3873 isl_int_sub(bmap->div[div][1],
3874 bmap->div[div][1], bmap->div[div][0]);
3875 isl_int_add_ui(bmap->div[div][1], bmap->div[div][1], 1);
3876 neg = isl_seq_is_neg(bmap->ineq[i], bmap->div[div]+1, pos);
3877 isl_int_sub_ui(bmap->div[div][1], bmap->div[div][1], 1);
3878 isl_int_add(bmap->div[div][1],
3879 bmap->div[div][1], bmap->div[div][0]);
3882 if (isl_seq_first_non_zero(bmap->ineq[i]+pos+1,
3883 bmap->n_div-div-1) != -1)
3885 } else if (isl_int_abs_eq(bmap->ineq[i][pos], bmap->div[div][0])) {
3886 if (!isl_seq_eq(bmap->ineq[i], bmap->div[div]+1, pos))
3888 if (isl_seq_first_non_zero(bmap->ineq[i]+pos+1,
3889 bmap->n_div-div-1) != -1)
3895 for (i = 0; i < bmap->n_div; ++i)
3896 if (!isl_int_is_zero(bmap->div[i][1+pos]))
3903 * Remove divs that don't occur in any of the constraints or other divs.
3904 * These can arise when dropping some of the variables in a quast
3905 * returned by piplib.
3907 static struct isl_basic_map *remove_redundant_divs(struct isl_basic_map *bmap)
3914 for (i = bmap->n_div-1; i >= 0; --i) {
3915 if (!div_is_redundant(bmap, i))
3917 bmap = isl_basic_map_drop_div(bmap, i);
3922 struct isl_basic_map *isl_basic_map_finalize(struct isl_basic_map *bmap)
3924 bmap = remove_redundant_divs(bmap);
3927 F_SET(bmap, ISL_BASIC_SET_FINAL);
3931 struct isl_basic_set *isl_basic_set_finalize(struct isl_basic_set *bset)
3933 return (struct isl_basic_set *)
3934 isl_basic_map_finalize((struct isl_basic_map *)bset);
3937 struct isl_set *isl_set_finalize(struct isl_set *set)
3943 for (i = 0; i < set->n; ++i) {
3944 set->p[i] = isl_basic_set_finalize(set->p[i]);
3954 struct isl_map *isl_map_finalize(struct isl_map *map)
3960 for (i = 0; i < map->n; ++i) {
3961 map->p[i] = isl_basic_map_finalize(map->p[i]);
3965 F_CLR(map, ISL_MAP_NORMALIZED);
3972 static struct isl_basic_map *basic_map_identity(struct isl_dim *dims)
3974 struct isl_basic_map *bmap;
3982 nparam = dims->nparam;
3984 bmap = isl_basic_map_alloc_dim(dims, 0, dim, 0);
3988 for (i = 0; i < dim; ++i) {
3989 int j = isl_basic_map_alloc_equality(bmap);
3992 isl_seq_clr(bmap->eq[j], 1 + isl_basic_map_total_dim(bmap));
3993 isl_int_set_si(bmap->eq[j][1+nparam+i], 1);
3994 isl_int_set_si(bmap->eq[j][1+nparam+dim+i], -1);
3996 return isl_basic_map_finalize(bmap);
3998 isl_basic_map_free(bmap);
4002 struct isl_basic_map *isl_basic_map_identity(struct isl_dim *set_dim)
4004 struct isl_dim *dim = isl_dim_map(set_dim);
4007 return basic_map_identity(dim);
4010 struct isl_basic_map *isl_basic_map_identity_like(struct isl_basic_map *model)
4012 if (!model || !model->dim)
4014 isl_assert(model->ctx,
4015 model->dim->n_in == model->dim->n_out, return NULL);
4016 return basic_map_identity(isl_dim_copy(model->dim));
4019 static struct isl_map *map_identity(struct isl_dim *dim)
4021 struct isl_map *map = isl_map_alloc_dim(dim, 1, ISL_MAP_DISJOINT);
4022 return isl_map_add(map, basic_map_identity(isl_dim_copy(dim)));
4025 struct isl_map *isl_map_identity(struct isl_dim *set_dim)
4027 struct isl_dim *dim = isl_dim_map(set_dim);
4030 return map_identity(dim);
4033 struct isl_map *isl_map_identity_like(struct isl_basic_map *model)
4035 if (!model || !model->dim)
4037 isl_assert(model->ctx,
4038 model->dim->n_in == model->dim->n_out, return NULL);
4039 return map_identity(isl_dim_copy(model->dim));
4042 int isl_set_is_equal(struct isl_set *set1, struct isl_set *set2)
4044 return isl_map_is_equal((struct isl_map *)set1, (struct isl_map *)set2);
4047 int isl_set_is_subset(struct isl_set *set1, struct isl_set *set2)
4049 return isl_map_is_subset(
4050 (struct isl_map *)set1, (struct isl_map *)set2);
4053 int isl_basic_map_is_subset(
4054 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
4057 struct isl_map *map1;
4058 struct isl_map *map2;
4060 if (!bmap1 || !bmap2)
4063 map1 = isl_map_from_basic_map(isl_basic_map_copy(bmap1));
4064 map2 = isl_map_from_basic_map(isl_basic_map_copy(bmap2));
4066 is_subset = isl_map_is_subset(map1, map2);
4074 int isl_basic_map_is_equal(
4075 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
4079 if (!bmap1 || !bmap2)
4081 is_subset = isl_basic_map_is_subset(bmap1, bmap2);
4084 is_subset = isl_basic_map_is_subset(bmap2, bmap1);
4088 int isl_basic_set_is_equal(
4089 struct isl_basic_set *bset1, struct isl_basic_set *bset2)
4091 return isl_basic_map_is_equal(
4092 (struct isl_basic_map *)bset1, (struct isl_basic_map *)bset2);
4095 int isl_map_is_empty(struct isl_map *map)
4102 for (i = 0; i < map->n; ++i) {
4103 is_empty = isl_basic_map_is_empty(map->p[i]);
4112 int isl_set_is_empty(struct isl_set *set)
4114 return isl_map_is_empty((struct isl_map *)set);
4117 int isl_map_is_subset(struct isl_map *map1, struct isl_map *map2)
4121 struct isl_map *diff;
4126 if (isl_map_is_empty(map1))
4129 if (isl_map_is_empty(map2))
4132 diff = isl_map_subtract(isl_map_copy(map1), isl_map_copy(map2));
4136 is_subset = isl_map_is_empty(diff);
4142 int isl_map_is_equal(struct isl_map *map1, struct isl_map *map2)
4148 is_subset = isl_map_is_subset(map1, map2);
4151 is_subset = isl_map_is_subset(map2, map1);
4155 int isl_basic_map_is_strict_subset(
4156 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
4160 if (!bmap1 || !bmap2)
4162 is_subset = isl_basic_map_is_subset(bmap1, bmap2);
4165 is_subset = isl_basic_map_is_subset(bmap2, bmap1);
4166 if (is_subset == -1)
4171 static int basic_map_contains(struct isl_basic_map *bmap, struct isl_vec *vec)
4177 total = 1 + isl_basic_map_total_dim(bmap);
4178 if (total != vec->size)
4183 for (i = 0; i < bmap->n_eq; ++i) {
4184 isl_seq_inner_product(vec->block.data, bmap->eq[i], total, &s);
4185 if (!isl_int_is_zero(s)) {
4191 for (i = 0; i < bmap->n_ineq; ++i) {
4192 isl_seq_inner_product(vec->block.data, bmap->ineq[i], total, &s);
4193 if (isl_int_is_neg(s)) {
4204 int isl_basic_map_is_universe(struct isl_basic_map *bmap)
4208 return bmap->n_eq == 0 && bmap->n_ineq == 0;
4211 int isl_basic_map_is_empty(struct isl_basic_map *bmap)
4213 struct isl_basic_set *bset = NULL;
4214 struct isl_vec *sample = NULL;
4221 if (F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
4224 if (F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) {
4225 struct isl_basic_map *copy = isl_basic_map_copy(bmap);
4226 copy = isl_basic_map_convex_hull(copy);
4227 empty = F_ISSET(copy, ISL_BASIC_MAP_EMPTY);
4228 isl_basic_map_free(copy);
4232 total = 1 + isl_basic_map_total_dim(bmap);
4233 if (bmap->sample && bmap->sample->size == total) {
4234 int contains = basic_map_contains(bmap, bmap->sample);
4240 bset = isl_basic_map_underlying_set(isl_basic_map_copy(bmap));
4243 sample = isl_basic_set_sample(bset);
4246 empty = sample->size == 0;
4248 isl_vec_free(bmap->ctx, bmap->sample);
4249 bmap->sample = sample;
4254 struct isl_map *isl_basic_map_union(
4255 struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
4257 struct isl_map *map;
4258 if (!bmap1 || !bmap2)
4261 isl_assert(map1->ctx, isl_dim_equal(bmap1->dim, bmap2->dim), goto error);
4263 map = isl_map_alloc_dim(isl_dim_copy(bmap1->dim), 2, 0);
4266 map = isl_map_add(map, bmap1);
4267 map = isl_map_add(map, bmap2);
4270 isl_basic_map_free(bmap1);
4271 isl_basic_map_free(bmap2);
4275 struct isl_set *isl_basic_set_union(
4276 struct isl_basic_set *bset1, struct isl_basic_set *bset2)
4278 return (struct isl_set *)isl_basic_map_union(
4279 (struct isl_basic_map *)bset1,
4280 (struct isl_basic_map *)bset2);
4283 /* Order divs such that any div only depends on previous divs */
4284 static struct isl_basic_map *order_divs(struct isl_basic_map *bmap)
4287 unsigned off = isl_dim_total(bmap->dim);
4289 for (i = 0; i < bmap->n_div; ++i) {
4291 pos = isl_seq_first_non_zero(bmap->div[i]+1+1+off+i,
4295 swap_div(bmap, i, pos);
4301 /* Look for a div in dst that corresponds to the div "div" in src.
4302 * The divs before "div" in src and dst are assumed to be the same.
4304 * Returns -1 if no corresponding div was found and the position
4305 * of the corresponding div in dst otherwise.
4307 static int find_div(struct isl_basic_map *dst,
4308 struct isl_basic_map *src, unsigned div)
4312 unsigned total = isl_dim_total(src->dim);
4314 isl_assert(dst->ctx, div <= dst->n_div, return -1);
4315 for (i = div; i < dst->n_div; ++i)
4316 if (isl_seq_eq(dst->div[i], src->div[div], 1+1+total+div) &&
4317 isl_seq_first_non_zero(dst->div[i]+1+1+total+div,
4318 dst->n_div - div) == -1)
4323 struct isl_basic_map *isl_basic_map_align_divs(
4324 struct isl_basic_map *dst, struct isl_basic_map *src)
4327 unsigned total = isl_dim_total(src->dim);
4332 if (src->n_div == 0)
4335 for (i = 0; i < src->n_div; ++i)
4336 isl_assert(src->ctx, !isl_int_is_zero(src->div[i][0]), goto error);
4338 src = order_divs(src);
4339 dst = isl_basic_map_extend_dim(dst, isl_dim_copy(dst->dim),
4340 src->n_div, 0, 2 * src->n_div);
4343 for (i = 0; i < src->n_div; ++i) {
4344 int j = find_div(dst, src, i);
4346 j = isl_basic_map_alloc_div(dst);
4349 isl_seq_cpy(dst->div[j], src->div[i], 1+1+total+i);
4350 isl_seq_clr(dst->div[j]+1+1+total+i, dst->n_div - i);
4351 if (add_div_constraints(dst, j) < 0)
4355 swap_div(dst, i, j);
4359 isl_basic_map_free(dst);
4363 struct isl_basic_set *isl_basic_set_align_divs(
4364 struct isl_basic_set *dst, struct isl_basic_set *src)
4366 return (struct isl_basic_set *)isl_basic_map_align_divs(
4367 (struct isl_basic_map *)dst, (struct isl_basic_map *)src);
4370 struct isl_map *isl_map_align_divs(struct isl_map *map)
4374 map = isl_map_compute_divs(map);
4375 map = isl_map_cow(map);
4379 for (i = 1; i < map->n; ++i)
4380 map->p[0] = isl_basic_map_align_divs(map->p[0], map->p[i]);
4381 for (i = 1; i < map->n; ++i)
4382 map->p[i] = isl_basic_map_align_divs(map->p[i], map->p[0]);
4384 F_CLR(map, ISL_MAP_NORMALIZED);
4388 static struct isl_map *add_cut_constraint(struct isl_map *dst,
4389 struct isl_basic_map *src, isl_int *c,
4390 unsigned len, int oppose)
4392 struct isl_basic_map *copy = NULL;
4397 copy = isl_basic_map_copy(src);
4398 copy = isl_basic_map_cow(copy);
4401 copy = isl_basic_map_extend_constraints(copy, 0, 1);
4402 k = isl_basic_map_alloc_inequality(copy);
4406 isl_seq_neg(copy->ineq[k], c, len);
4408 isl_seq_cpy(copy->ineq[k], c, len);
4409 total = 1 + isl_basic_map_total_dim(copy);
4410 isl_seq_clr(copy->ineq[k]+len, total - len);
4411 isl_inequality_negate(copy, k);
4412 copy = isl_basic_map_simplify(copy);
4413 copy = isl_basic_map_finalize(copy);
4414 is_empty = isl_basic_map_is_empty(copy);
4418 dst = isl_map_add(dst, copy);
4420 isl_basic_map_free(copy);
4423 isl_basic_map_free(copy);
4428 static struct isl_map *subtract(struct isl_map *map, struct isl_basic_map *bmap)
4432 struct isl_map *rest = NULL;
4434 unsigned total = isl_basic_map_total_dim(bmap);
4441 if (F_ISSET(map, ISL_MAP_DISJOINT))
4442 FL_SET(flags, ISL_MAP_DISJOINT);
4444 max = map->n * (2 * bmap->n_eq + bmap->n_ineq);
4445 rest = isl_map_alloc_dim(isl_dim_copy(map->dim), max, flags);
4449 for (i = 0; i < map->n; ++i) {
4450 map->p[i] = isl_basic_map_align_divs(map->p[i], bmap);
4455 for (j = 0; j < map->n; ++j)
4456 map->p[j] = isl_basic_map_cow(map->p[j]);
4458 for (i = 0; i < bmap->n_eq; ++i) {
4459 for (j = 0; j < map->n; ++j) {
4460 rest = add_cut_constraint(rest,
4461 map->p[j], bmap->eq[i], 1+total, 0);
4465 rest = add_cut_constraint(rest,
4466 map->p[j], bmap->eq[i], 1+total, 1);
4470 map->p[j] = isl_basic_map_extend_constraints(map->p[j],
4474 k = isl_basic_map_alloc_equality(map->p[j]);
4477 isl_seq_cpy(map->p[j]->eq[k], bmap->eq[i], 1+total);
4478 isl_seq_clr(map->p[j]->eq[k]+1+total,
4479 map->p[j]->n_div - bmap->n_div);
4483 for (i = 0; i < bmap->n_ineq; ++i) {
4484 for (j = 0; j < map->n; ++j) {
4485 rest = add_cut_constraint(rest,
4486 map->p[j], bmap->ineq[i], 1+total, 0);
4490 map->p[j] = isl_basic_map_extend_constraints(map->p[j],
4494 k = isl_basic_map_alloc_inequality(map->p[j]);
4497 isl_seq_cpy(map->p[j]->ineq[k], bmap->ineq[i], 1+total);
4498 isl_seq_clr(map->p[j]->ineq[k]+1+total,
4499 map->p[j]->n_div - bmap->n_div);
4511 struct isl_map *isl_map_subtract(struct isl_map *map1, struct isl_map *map2)
4517 isl_assert(map1->ctx, isl_dim_equal(map1->dim, map2->dim), goto error);
4519 if (isl_map_is_empty(map2)) {
4524 map1 = isl_map_compute_divs(map1);
4525 map2 = isl_map_compute_divs(map2);
4529 for (i = 0; map1 && i < map2->n; ++i)
4530 map1 = subtract(map1, map2->p[i]);
4540 struct isl_set *isl_set_subtract(struct isl_set *set1, struct isl_set *set2)
4542 return (struct isl_set *)
4544 (struct isl_map *)set1, (struct isl_map *)set2);
4547 struct isl_set *isl_set_apply(struct isl_set *set, struct isl_map *map)
4551 isl_assert(set->ctx, isl_map_compatible_domain(map, set), goto error);
4552 map = isl_map_intersect_domain(map, set);
4553 set = isl_map_range(map);
4561 /* There is no need to cow as removing empty parts doesn't change
4562 * the meaning of the set.
4564 struct isl_map *isl_map_remove_empty_parts(struct isl_map *map)
4571 for (i = map->n-1; i >= 0; --i) {
4572 if (!F_ISSET(map->p[i], ISL_BASIC_MAP_EMPTY))
4574 isl_basic_map_free(map->p[i]);
4575 if (i != map->n-1) {
4576 F_CLR(map, ISL_MAP_NORMALIZED);
4577 map->p[i] = map->p[map->n-1];
4585 struct isl_set *isl_set_remove_empty_parts(struct isl_set *set)
4587 return (struct isl_set *)
4588 isl_map_remove_empty_parts((struct isl_map *)set);
4591 struct isl_basic_set *isl_set_copy_basic_set(struct isl_set *set)
4593 struct isl_basic_set *bset;
4594 if (!set || set->n == 0)
4596 bset = set->p[set->n-1];
4597 isl_assert(set->ctx, F_ISSET(bset, ISL_BASIC_SET_FINAL), return NULL);
4598 return isl_basic_set_copy(bset);
4601 struct isl_set *isl_set_drop_basic_set(struct isl_set *set,
4602 struct isl_basic_set *bset)
4608 for (i = set->n-1; i >= 0; --i) {
4609 if (set->p[i] != bset)
4611 set = isl_set_cow(set);
4614 isl_basic_set_free(set->p[i]);
4615 if (i != set->n-1) {
4616 F_CLR(set, ISL_SET_NORMALIZED);
4617 set->p[i] = set->p[set->n-1];
4622 isl_basic_set_free(bset);
4626 isl_basic_set_free(bset);
4630 /* Given two _disjoint_ basic sets bset1 and bset2, check whether
4631 * for any common value of the parameters and dimensions preceding dim
4632 * in both basic sets, the values of dimension pos in bset1 are
4633 * smaller or larger than those in bset2.
4636 * 1 if bset1 follows bset2
4637 * -1 if bset1 precedes bset2
4638 * 0 if bset1 and bset2 are incomparable
4639 * -2 if some error occurred.
4641 int isl_basic_set_compare_at(struct isl_basic_set *bset1,
4642 struct isl_basic_set *bset2, int pos)
4644 struct isl_dim *dims;
4645 struct isl_basic_map *bmap1 = NULL;
4646 struct isl_basic_map *bmap2 = NULL;
4647 struct isl_ctx *ctx;
4648 struct isl_vec *obj;
4651 unsigned dim1, dim2;
4653 enum isl_lp_result res;
4656 if (!bset1 || !bset2)
4659 nparam = isl_basic_set_n_param(bset1);
4660 dim1 = isl_basic_set_n_dim(bset1);
4661 dim2 = isl_basic_set_n_dim(bset2);
4662 dims = isl_dim_alloc(bset1->ctx, nparam, pos, dim1 - pos);
4663 bmap1 = isl_basic_map_from_basic_set(isl_basic_set_copy(bset1), dims);
4664 dims = isl_dim_alloc(bset2->ctx, nparam, pos, dim2 - pos);
4665 bmap2 = isl_basic_map_from_basic_set(isl_basic_set_copy(bset2), dims);
4666 if (!bmap1 || !bmap2)
4668 bmap1 = isl_basic_map_extend(bmap1, nparam,
4669 pos, (dim1 - pos) + (dim2 - pos),
4670 bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
4671 bmap1 = add_constraints(bmap1, bmap2, 0, dim1 - pos);
4674 total = isl_basic_map_total_dim(bmap1);
4676 obj = isl_vec_alloc(ctx, total);
4677 isl_seq_clr(obj->block.data, total);
4678 isl_int_set_si(obj->block.data[nparam+pos], 1);
4679 isl_int_set_si(obj->block.data[nparam+pos+(dim1-pos)], -1);
4684 res = isl_solve_lp(bmap1, 0, obj->block.data, ctx->one, &num, &den);
4685 if (res == isl_lp_empty)
4687 else if (res == isl_lp_ok && isl_int_is_pos(num))
4689 else if ((res == isl_lp_ok && isl_int_is_neg(num)) ||
4690 res == isl_lp_unbounded)
4696 isl_basic_map_free(bmap1);
4697 isl_vec_free(ctx, obj);
4700 isl_basic_map_free(bmap1);
4701 isl_basic_map_free(bmap2);
4705 static int isl_basic_map_fast_has_fixed_var(struct isl_basic_map *bmap,
4706 unsigned pos, isl_int *val)
4714 total = isl_basic_map_total_dim(bmap);
4715 for (i = 0, d = total-1; i < bmap->n_eq && d+1 > pos; ++i) {
4716 for (; d+1 > pos; --d)
4717 if (!isl_int_is_zero(bmap->eq[i][1+d]))
4721 if (isl_seq_first_non_zero(bmap->eq[i]+1, d) != -1)
4723 if (isl_seq_first_non_zero(bmap->eq[i]+1+d+1, total-d-1) != -1)
4725 if (!isl_int_is_one(bmap->eq[i][1+d]))
4728 isl_int_neg(*val, bmap->eq[i][0]);
4734 static int isl_map_fast_has_fixed_var(struct isl_map *map,
4735 unsigned pos, isl_int *val)
4747 return isl_basic_map_fast_has_fixed_var(map->p[0], pos, val);
4750 fixed = isl_basic_map_fast_has_fixed_var(map->p[0], pos, &v);
4751 for (i = 1; fixed == 1 && i < map->n; ++i) {
4752 fixed = isl_basic_map_fast_has_fixed_var(map->p[i], pos, &tmp);
4753 if (fixed == 1 && isl_int_ne(tmp, v))
4757 isl_int_set(*val, v);
4763 static int isl_set_fast_has_fixed_var(struct isl_set *set, unsigned pos,
4766 return isl_map_fast_has_fixed_var((struct isl_map *)set, pos, val);
4769 /* Check if dimension dim has fixed value and if so and if val is not NULL,
4770 * then return this fixed value in *val.
4772 int isl_set_fast_dim_is_fixed(struct isl_set *set, unsigned dim, isl_int *val)
4774 return isl_set_fast_has_fixed_var(set, isl_set_n_param(set) + dim, val);
4777 /* Check if input variable in has fixed value and if so and if val is not NULL,
4778 * then return this fixed value in *val.
4780 int isl_map_fast_input_is_fixed(struct isl_map *map, unsigned in, isl_int *val)
4782 return isl_map_fast_has_fixed_var(map, isl_map_n_param(map) + in, val);
4785 /* Check if dimension dim has an (obvious) fixed lower bound and if so
4786 * and if val is not NULL, then return this lower bound in *val.
4788 int isl_basic_set_fast_dim_has_fixed_lower_bound(struct isl_basic_set *bset,
4789 unsigned dim, isl_int *val)
4791 int i, i_eq = -1, i_ineq = -1;
4798 total = isl_basic_set_total_dim(bset);
4799 nparam = isl_basic_set_n_param(bset);
4800 for (i = 0; i < bset->n_eq; ++i) {
4801 if (isl_int_is_zero(bset->eq[i][1+nparam+dim]))
4807 for (i = 0; i < bset->n_ineq; ++i) {
4808 if (!isl_int_is_pos(bset->ineq[i][1+nparam+dim]))
4810 if (i_eq != -1 || i_ineq != -1)
4814 if (i_eq == -1 && i_ineq == -1)
4816 c = i_eq != -1 ? bset->eq[i_eq] : bset->ineq[i_ineq];
4817 /* The coefficient should always be one due to normalization. */
4818 if (!isl_int_is_one(c[1+nparam+dim]))
4820 if (isl_seq_first_non_zero(c+1, nparam+dim) != -1)
4822 if (isl_seq_first_non_zero(c+1+nparam+dim+1,
4823 total - nparam - dim - 1) != -1)
4826 isl_int_neg(*val, c[0]);
4830 int isl_set_fast_dim_has_fixed_lower_bound(struct isl_set *set,
4831 unsigned dim, isl_int *val)
4843 return isl_basic_set_fast_dim_has_fixed_lower_bound(set->p[0],
4847 fixed = isl_basic_set_fast_dim_has_fixed_lower_bound(set->p[0],
4849 for (i = 1; fixed == 1 && i < set->n; ++i) {
4850 fixed = isl_basic_set_fast_dim_has_fixed_lower_bound(set->p[i],
4852 if (fixed == 1 && isl_int_ne(tmp, v))
4856 isl_int_set(*val, v);
4862 static struct isl_basic_set *isl_basic_set_reduce_using_equalities(
4863 struct isl_basic_set *bset, struct isl_basic_set *context)
4868 if (!bset || !context)
4871 bset = isl_basic_set_cow(bset);
4875 elim = isl_alloc_array(ctx, int, isl_basic_set_n_dim(bset));
4878 set_compute_elimination_index(context, elim);
4879 for (i = 0; i < bset->n_eq; ++i)
4880 set_reduced_using_equalities(bset->eq[i], bset->eq[i],
4882 for (i = 0; i < bset->n_ineq; ++i)
4883 set_reduced_using_equalities(bset->ineq[i], bset->ineq[i],
4885 isl_basic_set_free(context);
4887 bset = isl_basic_set_simplify(bset);
4888 bset = isl_basic_set_finalize(bset);
4891 isl_basic_set_free(bset);
4892 isl_basic_set_free(context);
4896 static struct isl_basic_set *remove_shifted_constraints(
4897 struct isl_basic_set *bset, struct isl_basic_set *context)
4907 size = round_up(4 * (context->n_ineq+1) / 3 - 1);
4908 bits = ffs(size) - 1;
4909 index = isl_calloc_array(ctx, isl_int **, size);
4913 for (k = 0; k < context->n_ineq; ++k) {
4914 h = set_hash_index(index, size, bits, context, k);
4915 index[h] = &context->ineq[k];
4917 for (k = 0; k < bset->n_ineq; ++k) {
4918 h = set_hash_index(index, size, bits, bset, k);
4921 l = index[h] - &context->ineq[0];
4922 if (isl_int_lt(bset->ineq[k][0], context->ineq[l][0]))
4924 bset = isl_basic_set_cow(bset);
4927 isl_basic_set_drop_inequality(bset, k);
4937 static struct isl_basic_set *uset_gist(struct isl_basic_set *bset,
4938 struct isl_basic_set *context);
4940 static struct isl_basic_set *uset_gist_context_eq(struct isl_basic_set *bset,
4941 struct isl_basic_set *context)
4945 struct isl_ctx *ctx = context->ctx;
4946 struct isl_basic_set *reduced_context;
4947 reduced_context = isl_basic_set_remove_equalities(
4948 isl_basic_set_copy(context), &T, &T2);
4949 if (!reduced_context)
4951 bset = isl_basic_set_preimage(ctx, bset, T);
4952 bset = uset_gist(bset, reduced_context);
4953 bset = isl_basic_set_preimage(ctx, bset, T2);
4954 bset = isl_basic_set_reduce_using_equalities(bset, context);
4957 isl_basic_set_free(context);
4958 isl_basic_set_free(bset);
4962 static struct isl_basic_set *uset_gist_set_eq(struct isl_basic_set *bset,
4963 struct isl_basic_set *context)
4967 struct isl_ctx *ctx = context->ctx;
4968 struct isl_basic_set *affine_hull = NULL;
4970 affine_hull = isl_basic_set_copy(bset);
4971 affine_hull = isl_basic_set_cow(affine_hull);
4974 isl_basic_set_free_inequality(affine_hull, affine_hull->n_ineq);
4976 bset = isl_basic_set_remove_equalities(bset, &T, &T2);
4979 context = isl_basic_set_preimage(ctx, context, T);
4980 bset = uset_gist(bset, context);
4981 bset = isl_basic_set_preimage(ctx, bset, T2);
4982 bset = isl_basic_set_intersect(bset, affine_hull);
4985 isl_basic_set_free(affine_hull);
4986 isl_basic_set_free(context);
4987 isl_basic_set_free(bset);
4991 /* Remove all information from bset that is redundant in the context
4992 * of context. In particular, equalities that are linear combinations
4993 * of those in context are removed. Then the inequalities that are
4994 * redundant in the context of the equalities and inequalities of
4995 * context are removed.
4997 static struct isl_basic_set *uset_gist(struct isl_basic_set *bset,
4998 struct isl_basic_set *context)
5002 struct isl_basic_set *combined;
5003 struct isl_ctx *ctx;
5005 if (!bset || !context)
5008 if (context->n_eq > 0)
5009 return uset_gist_context_eq(bset, context);
5010 if (!context->n_ineq)
5013 return uset_gist_set_eq(bset, context);
5014 bset = remove_shifted_constraints(bset, context);
5015 combined = isl_basic_set_extend_constraints(isl_basic_set_copy(bset),
5016 context->n_eq, context->n_ineq);
5017 context = set_add_constraints(combined, context, 0);
5022 for (i = bset->n_ineq-1; i >= 0; --i) {
5024 set_swap_inequality(context, i, context->n_ineq-1);
5026 redundant = isl_basic_set_constraint_is_redundant(&context,
5027 context->ineq[context->n_ineq], &opt, NULL);
5028 if (redundant == -1) {
5032 if (F_ISSET(context, ISL_BASIC_MAP_EMPTY)) {
5033 bset = isl_basic_set_set_to_empty(bset);
5037 set_swap_inequality(context, i, context->n_ineq-1);
5039 isl_basic_set_drop_inequality(context, i);
5040 isl_basic_set_drop_inequality(bset, i);
5045 isl_basic_set_free(context);
5048 isl_basic_set_free(context);
5049 isl_basic_set_free(bset);
5053 struct isl_basic_map *isl_basic_map_gist(struct isl_basic_map *bmap,
5054 struct isl_basic_map *context)
5056 struct isl_basic_set *bset;
5058 if (!bmap || !context)
5061 context = isl_basic_map_align_divs(context, bmap);
5062 bmap = isl_basic_map_align_divs(bmap, context);
5064 bset = uset_gist(isl_basic_map_underlying_set(isl_basic_map_copy(bmap)),
5065 isl_basic_map_underlying_set(context));
5067 return isl_basic_map_overlying_set(bset, bmap);
5069 isl_basic_map_free(bmap);
5070 isl_basic_map_free(context);
5075 * Assumes context has no implicit divs.
5077 struct isl_map *isl_map_gist(struct isl_map *map, struct isl_basic_map *context)
5081 map = isl_map_cow(map);
5082 if (!map || !context)
5084 isl_assert(map->ctx, isl_dim_equal(map->dim, context->dim), goto error);
5085 map = isl_map_compute_divs(map);
5086 for (i = 0; i < map->n; ++i)
5087 context = isl_basic_map_align_divs(context, map->p[i]);
5088 for (i = 0; i < map->n; ++i) {
5089 map->p[i] = isl_basic_map_gist(map->p[i],
5090 isl_basic_map_copy(context));
5094 isl_basic_map_free(context);
5095 F_CLR(map, ISL_MAP_NORMALIZED);
5099 isl_basic_map_free(context);
5103 struct isl_basic_set *isl_basic_set_gist(struct isl_basic_set *bset,
5104 struct isl_basic_set *context)
5106 return (struct isl_basic_set *)isl_basic_map_gist(
5107 (struct isl_basic_map *)bset, (struct isl_basic_map *)context);
5110 struct isl_set *isl_set_gist(struct isl_set *set, struct isl_basic_set *context)
5112 return (struct isl_set *)isl_map_gist((struct isl_map *)set,
5113 (struct isl_basic_map *)context);
5121 static int qsort_constraint_cmp(const void *p1, const void *p2)
5123 const struct constraint *c1 = (const struct constraint *)p1;
5124 const struct constraint *c2 = (const struct constraint *)p2;
5125 unsigned size = isl_min(c1->size, c2->size);
5126 return isl_seq_cmp(c1->c, c2->c, size);
5129 static struct isl_basic_map *isl_basic_map_sort_constraints(
5130 struct isl_basic_map *bmap)
5133 struct constraint *c;
5138 total = isl_basic_map_total_dim(bmap);
5139 c = isl_alloc_array(bmap->ctx, struct constraint, bmap->n_ineq);
5142 for (i = 0; i < bmap->n_ineq; ++i) {
5144 c[i].c = bmap->ineq[i];
5146 qsort(c, bmap->n_ineq, sizeof(struct constraint), qsort_constraint_cmp);
5147 for (i = 0; i < bmap->n_ineq; ++i)
5148 bmap->ineq[i] = c[i].c;
5152 isl_basic_map_free(bmap);
5156 struct isl_basic_map *isl_basic_map_normalize(struct isl_basic_map *bmap)
5160 if (F_ISSET(bmap, ISL_BASIC_MAP_NORMALIZED))
5162 bmap = isl_basic_map_convex_hull(bmap);
5163 bmap = isl_basic_map_sort_constraints(bmap);
5164 F_SET(bmap, ISL_BASIC_MAP_NORMALIZED);
5168 struct isl_basic_set *isl_basic_set_normalize(struct isl_basic_set *bset)
5170 return (struct isl_basic_set *)isl_basic_map_normalize(
5171 (struct isl_basic_map *)bset);
5174 static int isl_basic_map_fast_cmp(const struct isl_basic_map *bmap1,
5175 const struct isl_basic_map *bmap2)
5182 if (isl_basic_map_n_param(bmap1) != isl_basic_map_n_param(bmap2))
5183 return isl_basic_map_n_param(bmap1) - isl_basic_map_n_param(bmap2);
5184 if (isl_basic_map_n_in(bmap1) != isl_basic_map_n_in(bmap2))
5185 return isl_basic_map_n_out(bmap1) - isl_basic_map_n_out(bmap2);
5186 if (isl_basic_map_n_out(bmap1) != isl_basic_map_n_out(bmap2))
5187 return isl_basic_map_n_out(bmap1) - isl_basic_map_n_out(bmap2);
5188 if (F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY) &&
5189 F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
5191 if (F_ISSET(bmap1, ISL_BASIC_MAP_EMPTY))
5193 if (F_ISSET(bmap2, ISL_BASIC_MAP_EMPTY))
5195 if (bmap1->n_eq != bmap2->n_eq)
5196 return bmap1->n_eq - bmap2->n_eq;
5197 if (bmap1->n_ineq != bmap2->n_ineq)
5198 return bmap1->n_ineq - bmap2->n_ineq;
5199 if (bmap1->n_div != bmap2->n_div)
5200 return bmap1->n_div - bmap2->n_div;
5201 total = isl_basic_map_total_dim(bmap1);
5202 for (i = 0; i < bmap1->n_eq; ++i) {
5203 cmp = isl_seq_cmp(bmap1->eq[i], bmap2->eq[i], 1+total);
5207 for (i = 0; i < bmap1->n_ineq; ++i) {
5208 cmp = isl_seq_cmp(bmap1->ineq[i], bmap2->ineq[i], 1+total);
5212 for (i = 0; i < bmap1->n_div; ++i) {
5213 cmp = isl_seq_cmp(bmap1->div[i], bmap2->div[i], 1+1+total);
5220 static int isl_basic_map_fast_is_equal(struct isl_basic_map *bmap1,
5221 struct isl_basic_map *bmap2)
5223 return isl_basic_map_fast_cmp(bmap1, bmap2) == 0;
5226 static int qsort_bmap_cmp(const void *p1, const void *p2)
5228 const struct isl_basic_map *bmap1 = *(const struct isl_basic_map **)p1;
5229 const struct isl_basic_map *bmap2 = *(const struct isl_basic_map **)p2;
5231 return isl_basic_map_fast_cmp(bmap1, bmap2);
5234 /* We normalize in place, but if anything goes wrong we need
5235 * to return NULL, so we need to make sure we don't change the
5236 * meaning of any possible other copies of map.
5238 struct isl_map *isl_map_normalize(struct isl_map *map)
5241 struct isl_basic_map *bmap;
5245 if (F_ISSET(map, ISL_MAP_NORMALIZED))
5247 for (i = 0; i < map->n; ++i) {
5248 bmap = isl_basic_map_normalize(isl_basic_map_copy(map->p[i]));
5251 isl_basic_map_free(map->p[i]);
5254 qsort(map->p, map->n, sizeof(struct isl_basic_map *), qsort_bmap_cmp);
5255 F_SET(map, ISL_MAP_NORMALIZED);
5256 map = isl_map_remove_empty_parts(map);
5259 for (i = map->n - 1; i >= 1; --i) {
5260 if (!isl_basic_map_fast_is_equal(map->p[i-1], map->p[i]))
5262 isl_basic_map_free(map->p[i-1]);
5263 for (j = i; j < map->n; ++j)
5264 map->p[j-1] = map->p[j];
5274 struct isl_set *isl_set_normalize(struct isl_set *set)
5276 return (struct isl_set *)isl_map_normalize((struct isl_map *)set);
5279 int isl_map_fast_is_equal(struct isl_map *map1, struct isl_map *map2)
5289 if (!isl_dim_equal(map1->dim, map2->dim))
5292 map1 = isl_map_copy(map1);
5293 map2 = isl_map_copy(map2);
5294 map1 = isl_map_normalize(map1);
5295 map2 = isl_map_normalize(map2);
5298 equal = map1->n == map2->n;
5299 for (i = 0; equal && i < map1->n; ++i) {
5300 equal = isl_basic_map_fast_is_equal(map1->p[i], map2->p[i]);
5313 int isl_set_fast_is_equal(struct isl_set *set1, struct isl_set *set2)
5315 return isl_map_fast_is_equal((struct isl_map *)set1,
5316 (struct isl_map *)set2);
5319 /* Return an interval that ranges from min to max (inclusive)
5321 struct isl_basic_set *isl_basic_set_interval(struct isl_ctx *ctx,
5322 isl_int min, isl_int max)
5325 struct isl_basic_set *bset = NULL;
5327 bset = isl_basic_set_alloc(ctx, 0, 1, 0, 0, 2);
5331 k = isl_basic_set_alloc_inequality(bset);
5334 isl_int_set_si(bset->ineq[k][1], 1);
5335 isl_int_neg(bset->ineq[k][0], min);
5337 k = isl_basic_set_alloc_inequality(bset);
5340 isl_int_set_si(bset->ineq[k][1], -1);
5341 isl_int_set(bset->ineq[k][0], max);
5345 isl_basic_set_free(bset);
5349 /* Return the Cartesian product of the basic sets in list (in the given order).
5351 struct isl_basic_set *isl_basic_set_product(struct isl_basic_set_list *list)
5359 struct isl_basic_set *product = NULL;
5363 isl_assert(list->ctx, list->n > 0, goto error);
5364 isl_assert(list->ctx, list->p[0], goto error);
5365 nparam = isl_basic_set_n_param(list->p[0]);
5366 dim = isl_basic_set_n_dim(list->p[0]);
5367 extra = list->p[0]->n_div;
5368 n_eq = list->p[0]->n_eq;
5369 n_ineq = list->p[0]->n_ineq;
5370 for (i = 1; i < list->n; ++i) {
5371 isl_assert(list->ctx, list->p[i], goto error);
5372 isl_assert(list->ctx,
5373 nparam == isl_basic_set_n_param(list->p[i]), goto error);
5374 dim += isl_basic_set_n_dim(list->p[i]);
5375 extra += list->p[i]->n_div;
5376 n_eq += list->p[i]->n_eq;
5377 n_ineq += list->p[i]->n_ineq;
5379 product = isl_basic_set_alloc(list->ctx, nparam, dim, extra,
5384 for (i = 0; i < list->n; ++i) {
5385 set_add_constraints(product,
5386 isl_basic_set_copy(list->p[i]), dim);
5387 dim += isl_basic_set_n_dim(list->p[i]);
5389 isl_basic_set_list_free(list);
5392 isl_basic_set_free(product);
5393 isl_basic_set_list_free(list);
5397 uint32_t isl_basic_set_get_hash(struct isl_basic_set *bset)
5405 bset = isl_basic_set_copy(bset);
5406 bset = isl_basic_set_normalize(bset);
5409 total = isl_basic_set_total_dim(bset);
5410 isl_hash_byte(hash, bset->n_eq & 0xFF);
5411 for (i = 0; i < bset->n_eq; ++i) {
5413 c_hash = isl_seq_get_hash(bset->eq[i], 1 + total);
5414 isl_hash_hash(hash, c_hash);
5416 isl_hash_byte(hash, bset->n_ineq & 0xFF);
5417 for (i = 0; i < bset->n_ineq; ++i) {
5419 c_hash = isl_seq_get_hash(bset->ineq[i], 1 + total);
5420 isl_hash_hash(hash, c_hash);
5422 isl_hash_byte(hash, bset->n_div & 0xFF);
5423 for (i = 0; i < bset->n_div; ++i) {
5425 if (isl_int_is_zero(bset->div[i][0]))
5427 isl_hash_byte(hash, i & 0xFF);
5428 c_hash = isl_seq_get_hash(bset->div[i], 1 + 1 + total);
5429 isl_hash_hash(hash, c_hash);
5431 isl_basic_set_free(bset);
5435 uint32_t isl_set_get_hash(struct isl_set *set)
5442 set = isl_set_copy(set);
5443 set = isl_set_normalize(set);
5447 hash = isl_hash_init();
5448 for (i = 0; i < set->n; ++i) {
5450 bset_hash = isl_basic_set_get_hash(set->p[i]);
5451 isl_hash_hash(hash, bset_hash);
5459 /* Check if the value for dimension dim is completely determined
5460 * by the values of the other parameters and variables.
5461 * That is, check if dimension dim is involved in an equality.
5463 int isl_basic_set_dim_is_unique(struct isl_basic_set *bset, unsigned dim)
5470 nparam = isl_basic_set_n_param(bset);
5471 for (i = 0; i < bset->n_eq; ++i)
5472 if (!isl_int_is_zero(bset->eq[i][1 + nparam + dim]))
5477 /* Check if the value for dimension dim is completely determined
5478 * by the values of the other parameters and variables.
5479 * That is, check if dimension dim is involved in an equality
5480 * for each of the subsets.
5482 int isl_set_dim_is_unique(struct isl_set *set, unsigned dim)
5488 for (i = 0; i < set->n; ++i) {
5490 unique = isl_basic_set_dim_is_unique(set->p[i], dim);