2 * Copyright 2010-2011 INRIA Saclay
4 * Use of this software is governed by the GNU LGPLv2.1 license
6 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
7 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
12 #include <isl_map_private.h>
17 #include <isl_space_private.h>
18 #include <isl_union_map_private.h>
19 #include <isl/union_set.h>
21 static __isl_give isl_union_map *isl_union_map_alloc(__isl_take isl_space *dim,
29 umap = isl_calloc_type(dim->ctx, isl_union_map);
35 if (isl_hash_table_init(dim->ctx, &umap->table, size) < 0)
41 isl_union_map_free(umap);
45 __isl_give isl_union_map *isl_union_map_empty(__isl_take isl_space *dim)
47 return isl_union_map_alloc(dim, 16);
50 __isl_give isl_union_set *isl_union_set_empty(__isl_take isl_space *dim)
52 return isl_union_map_empty(dim);
55 isl_ctx *isl_union_map_get_ctx(__isl_keep isl_union_map *umap)
57 return umap ? umap->dim->ctx : NULL;
60 isl_ctx *isl_union_set_get_ctx(__isl_keep isl_union_set *uset)
62 return uset ? uset->dim->ctx : NULL;
65 __isl_give isl_space *isl_union_map_get_space(__isl_keep isl_union_map *umap)
69 return isl_space_copy(umap->dim);
72 __isl_give isl_space *isl_union_set_get_space(__isl_keep isl_union_set *uset)
74 return isl_union_map_get_space(uset);
77 static int free_umap_entry(void **entry, void *user)
79 isl_map *map = *entry;
84 static int add_map(__isl_take isl_map *map, void *user)
86 isl_union_map **umap = (isl_union_map **)user;
88 *umap = isl_union_map_add_map(*umap, map);
93 __isl_give isl_union_map *isl_union_map_dup(__isl_keep isl_union_map *umap)
100 dup = isl_union_map_empty(isl_space_copy(umap->dim));
101 if (isl_union_map_foreach_map(umap, &add_map, &dup) < 0)
105 isl_union_map_free(dup);
109 __isl_give isl_union_map *isl_union_map_cow(__isl_take isl_union_map *umap)
117 return isl_union_map_dup(umap);
120 struct isl_union_align {
125 static int align_entry(void **entry, void *user)
127 isl_map *map = *entry;
129 struct isl_union_align *data = user;
131 exp = isl_reordering_extend_space(isl_reordering_copy(data->exp),
132 isl_map_get_space(map));
134 data->res = isl_union_map_add_map(data->res,
135 isl_map_realign(isl_map_copy(map), exp));
140 /* Align the parameters of umap along those of model.
141 * The result has the parameters of model first, in the same order
142 * as they appear in model, followed by any remaining parameters of
143 * umap that do not appear in model.
145 __isl_give isl_union_map *isl_union_map_align_params(
146 __isl_take isl_union_map *umap, __isl_take isl_space *model)
148 struct isl_union_align data = { NULL, NULL };
153 if (isl_space_match(umap->dim, isl_dim_param, model, isl_dim_param)) {
154 isl_space_free(model);
158 model = isl_space_drop_dims(model, isl_dim_in,
159 0, isl_space_dim(model, isl_dim_in));
160 model = isl_space_drop_dims(model, isl_dim_out,
161 0, isl_space_dim(model, isl_dim_out));
163 data.exp = isl_parameter_alignment_reordering(umap->dim, model);
167 data.res = isl_union_map_alloc(isl_space_copy(data.exp->dim),
169 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
170 &align_entry, &data) < 0)
173 isl_reordering_free(data.exp);
174 isl_union_map_free(umap);
175 isl_space_free(model);
178 isl_reordering_free(data.exp);
179 isl_union_map_free(umap);
180 isl_union_map_free(data.res);
181 isl_space_free(model);
185 __isl_give isl_union_set *isl_union_set_align_params(
186 __isl_take isl_union_set *uset, __isl_take isl_space *model)
188 return isl_union_map_align_params(uset, model);
191 __isl_give isl_union_map *isl_union_map_union(__isl_take isl_union_map *umap1,
192 __isl_take isl_union_map *umap2)
194 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2));
195 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1));
197 umap1 = isl_union_map_cow(umap1);
199 if (!umap1 || !umap2)
202 if (isl_union_map_foreach_map(umap2, &add_map, &umap1) < 0)
205 isl_union_map_free(umap2);
209 isl_union_map_free(umap1);
210 isl_union_map_free(umap2);
214 __isl_give isl_union_set *isl_union_set_union(__isl_take isl_union_set *uset1,
215 __isl_take isl_union_set *uset2)
217 return isl_union_map_union(uset1, uset2);
220 __isl_give isl_union_map *isl_union_map_copy(__isl_keep isl_union_map *umap)
229 __isl_give isl_union_set *isl_union_set_copy(__isl_keep isl_union_set *uset)
231 return isl_union_map_copy(uset);
234 void *isl_union_map_free(__isl_take isl_union_map *umap)
242 isl_hash_table_foreach(umap->dim->ctx, &umap->table,
243 &free_umap_entry, NULL);
244 isl_hash_table_clear(&umap->table);
245 isl_space_free(umap->dim);
250 void *isl_union_set_free(__isl_take isl_union_set *uset)
252 return isl_union_map_free(uset);
255 static int has_dim(const void *entry, const void *val)
257 isl_map *map = (isl_map *)entry;
258 isl_space *dim = (isl_space *)val;
260 return isl_space_is_equal(map->dim, dim);
263 __isl_give isl_union_map *isl_union_map_add_map(__isl_take isl_union_map *umap,
264 __isl_take isl_map *map)
267 struct isl_hash_table_entry *entry;
272 if (isl_map_plain_is_empty(map)) {
277 if (!isl_space_match(map->dim, isl_dim_param, umap->dim, isl_dim_param)) {
278 umap = isl_union_map_align_params(umap, isl_map_get_space(map));
279 map = isl_map_align_params(map, isl_union_map_get_space(umap));
282 umap = isl_union_map_cow(umap);
287 hash = isl_space_get_hash(map->dim);
288 entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
289 &has_dim, map->dim, 1);
296 entry->data = isl_map_union(entry->data, isl_map_copy(map));
305 isl_union_map_free(umap);
309 __isl_give isl_union_set *isl_union_set_add_set(__isl_take isl_union_set *uset,
310 __isl_take isl_set *set)
312 return isl_union_map_add_map(uset, (isl_map *)set);
315 __isl_give isl_union_map *isl_union_map_from_map(__isl_take isl_map *map)
323 dim = isl_map_get_space(map);
324 dim = isl_space_drop_dims(dim, isl_dim_in, 0, isl_space_dim(dim, isl_dim_in));
325 dim = isl_space_drop_dims(dim, isl_dim_out, 0, isl_space_dim(dim, isl_dim_out));
326 umap = isl_union_map_empty(dim);
327 umap = isl_union_map_add_map(umap, map);
332 __isl_give isl_union_set *isl_union_set_from_set(__isl_take isl_set *set)
334 return isl_union_map_from_map((isl_map *)set);
337 struct isl_union_map_foreach_data
339 int (*fn)(__isl_take isl_map *map, void *user);
343 static int call_on_copy(void **entry, void *user)
345 isl_map *map = *entry;
346 struct isl_union_map_foreach_data *data;
347 data = (struct isl_union_map_foreach_data *)user;
349 return data->fn(isl_map_copy(map), data->user);
352 int isl_union_map_n_map(__isl_keep isl_union_map *umap)
354 return umap ? umap->table.n : 0;
357 int isl_union_set_n_set(__isl_keep isl_union_set *uset)
359 return uset ? uset->table.n : 0;
362 int isl_union_map_foreach_map(__isl_keep isl_union_map *umap,
363 int (*fn)(__isl_take isl_map *map, void *user), void *user)
365 struct isl_union_map_foreach_data data = { fn, user };
370 return isl_hash_table_foreach(umap->dim->ctx, &umap->table,
371 &call_on_copy, &data);
374 static int copy_map(void **entry, void *user)
376 isl_map *map = *entry;
377 isl_map **map_p = user;
379 *map_p = isl_map_copy(map);
384 __isl_give isl_map *isl_map_from_union_map(__isl_take isl_union_map *umap)
391 ctx = isl_union_map_get_ctx(umap);
392 if (umap->table.n != 1)
393 isl_die(ctx, isl_error_invalid,
394 "union map needs to contain elements in exactly "
395 "one space", return isl_union_map_free(umap));
397 isl_hash_table_foreach(ctx, &umap->table, ©_map, &map);
399 isl_union_map_free(umap);
404 __isl_give isl_set *isl_set_from_union_set(__isl_take isl_union_set *uset)
406 return isl_map_from_union_map(uset);
409 __isl_give isl_map *isl_union_map_extract_map(__isl_keep isl_union_map *umap,
410 __isl_take isl_space *dim)
413 struct isl_hash_table_entry *entry;
418 hash = isl_space_get_hash(dim);
419 entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
422 return isl_map_empty(dim);
424 return isl_map_copy(entry->data);
430 __isl_give isl_set *isl_union_set_extract_set(__isl_keep isl_union_set *uset,
431 __isl_take isl_space *dim)
433 return (isl_set *)isl_union_map_extract_map(uset, dim);
436 /* Check if umap contains a map in the given space.
438 __isl_give int isl_union_map_contains(__isl_keep isl_union_map *umap,
439 __isl_keep isl_space *dim)
442 struct isl_hash_table_entry *entry;
447 hash = isl_space_get_hash(dim);
448 entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
453 __isl_give int isl_union_set_contains(__isl_keep isl_union_set *uset,
454 __isl_keep isl_space *dim)
456 return isl_union_map_contains(uset, dim);
459 int isl_union_set_foreach_set(__isl_keep isl_union_set *uset,
460 int (*fn)(__isl_take isl_set *set, void *user), void *user)
462 return isl_union_map_foreach_map(uset,
463 (int(*)(__isl_take isl_map *, void*))fn, user);
466 struct isl_union_set_foreach_point_data {
467 int (*fn)(__isl_take isl_point *pnt, void *user);
471 static int foreach_point(__isl_take isl_set *set, void *user)
473 struct isl_union_set_foreach_point_data *data = user;
476 r = isl_set_foreach_point(set, data->fn, data->user);
482 int isl_union_set_foreach_point(__isl_keep isl_union_set *uset,
483 int (*fn)(__isl_take isl_point *pnt, void *user), void *user)
485 struct isl_union_set_foreach_point_data data = { fn, user };
486 return isl_union_set_foreach_set(uset, &foreach_point, &data);
489 struct isl_union_map_gen_bin_data {
490 isl_union_map *umap2;
494 static int subtract_entry(void **entry, void *user)
496 struct isl_union_map_gen_bin_data *data = user;
498 struct isl_hash_table_entry *entry2;
499 isl_map *map = *entry;
501 hash = isl_space_get_hash(map->dim);
502 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
503 hash, &has_dim, map->dim, 0);
504 map = isl_map_copy(map);
507 map = isl_map_subtract(map, isl_map_copy(entry2->data));
509 empty = isl_map_is_empty(map);
519 data->res = isl_union_map_add_map(data->res, map);
524 static __isl_give isl_union_map *gen_bin_op(__isl_take isl_union_map *umap1,
525 __isl_take isl_union_map *umap2, int (*fn)(void **, void *))
527 struct isl_union_map_gen_bin_data data = { NULL, NULL };
529 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2));
530 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1));
532 if (!umap1 || !umap2)
536 data.res = isl_union_map_alloc(isl_space_copy(umap1->dim),
538 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
542 isl_union_map_free(umap1);
543 isl_union_map_free(umap2);
546 isl_union_map_free(umap1);
547 isl_union_map_free(umap2);
548 isl_union_map_free(data.res);
552 __isl_give isl_union_map *isl_union_map_subtract(
553 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
555 return gen_bin_op(umap1, umap2, &subtract_entry);
558 __isl_give isl_union_set *isl_union_set_subtract(
559 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
561 return isl_union_map_subtract(uset1, uset2);
564 struct isl_union_map_match_bin_data {
565 isl_union_map *umap2;
567 __isl_give isl_map *(*fn)(__isl_take isl_map*, __isl_take isl_map*);
570 static int match_bin_entry(void **entry, void *user)
572 struct isl_union_map_match_bin_data *data = user;
574 struct isl_hash_table_entry *entry2;
575 isl_map *map = *entry;
578 hash = isl_space_get_hash(map->dim);
579 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
580 hash, &has_dim, map->dim, 0);
584 map = isl_map_copy(map);
585 map = data->fn(map, isl_map_copy(entry2->data));
587 empty = isl_map_is_empty(map);
597 data->res = isl_union_map_add_map(data->res, map);
602 static __isl_give isl_union_map *match_bin_op(__isl_take isl_union_map *umap1,
603 __isl_take isl_union_map *umap2,
604 __isl_give isl_map *(*fn)(__isl_take isl_map*, __isl_take isl_map*))
606 struct isl_union_map_match_bin_data data = { NULL, NULL, fn };
608 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2));
609 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1));
611 if (!umap1 || !umap2)
615 data.res = isl_union_map_alloc(isl_space_copy(umap1->dim),
617 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
618 &match_bin_entry, &data) < 0)
621 isl_union_map_free(umap1);
622 isl_union_map_free(umap2);
625 isl_union_map_free(umap1);
626 isl_union_map_free(umap2);
627 isl_union_map_free(data.res);
631 __isl_give isl_union_map *isl_union_map_intersect(
632 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
634 return match_bin_op(umap1, umap2, &isl_map_intersect);
637 __isl_give isl_union_set *isl_union_set_intersect(
638 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
640 return isl_union_map_intersect(uset1, uset2);
643 __isl_give isl_union_map *isl_union_map_gist(__isl_take isl_union_map *umap,
644 __isl_take isl_union_map *context)
646 return match_bin_op(umap, context, &isl_map_gist);
649 __isl_give isl_union_set *isl_union_set_gist(__isl_take isl_union_set *uset,
650 __isl_take isl_union_set *context)
652 return isl_union_map_gist(uset, context);
655 static __isl_give isl_map *lex_le_set(__isl_take isl_map *set1,
656 __isl_take isl_map *set2)
658 return isl_set_lex_le_set((isl_set *)set1, (isl_set *)set2);
661 static __isl_give isl_map *lex_lt_set(__isl_take isl_map *set1,
662 __isl_take isl_map *set2)
664 return isl_set_lex_lt_set((isl_set *)set1, (isl_set *)set2);
667 __isl_give isl_union_map *isl_union_set_lex_lt_union_set(
668 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
670 return match_bin_op(uset1, uset2, &lex_lt_set);
673 __isl_give isl_union_map *isl_union_set_lex_le_union_set(
674 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
676 return match_bin_op(uset1, uset2, &lex_le_set);
679 __isl_give isl_union_map *isl_union_set_lex_gt_union_set(
680 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
682 return isl_union_map_reverse(isl_union_set_lex_lt_union_set(uset2, uset1));
685 __isl_give isl_union_map *isl_union_set_lex_ge_union_set(
686 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
688 return isl_union_map_reverse(isl_union_set_lex_le_union_set(uset2, uset1));
691 __isl_give isl_union_map *isl_union_map_lex_gt_union_map(
692 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
694 return isl_union_map_reverse(isl_union_map_lex_lt_union_map(umap2, umap1));
697 __isl_give isl_union_map *isl_union_map_lex_ge_union_map(
698 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
700 return isl_union_map_reverse(isl_union_map_lex_le_union_map(umap2, umap1));
703 static int intersect_domain_entry(void **entry, void *user)
705 struct isl_union_map_gen_bin_data *data = user;
707 struct isl_hash_table_entry *entry2;
709 isl_map *map = *entry;
712 dim = isl_map_get_space(map);
713 dim = isl_space_domain(dim);
714 hash = isl_space_get_hash(dim);
715 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
716 hash, &has_dim, dim, 0);
721 map = isl_map_copy(map);
722 map = isl_map_intersect_domain(map, isl_set_copy(entry2->data));
724 empty = isl_map_is_empty(map);
734 data->res = isl_union_map_add_map(data->res, map);
739 __isl_give isl_union_map *isl_union_map_intersect_domain(
740 __isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
742 return gen_bin_op(umap, uset, &intersect_domain_entry);
745 static int intersect_range_entry(void **entry, void *user)
747 struct isl_union_map_gen_bin_data *data = user;
749 struct isl_hash_table_entry *entry2;
751 isl_map *map = *entry;
754 dim = isl_map_get_space(map);
755 dim = isl_space_range(dim);
756 hash = isl_space_get_hash(dim);
757 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
758 hash, &has_dim, dim, 0);
763 map = isl_map_copy(map);
764 map = isl_map_intersect_range(map, isl_set_copy(entry2->data));
766 empty = isl_map_is_empty(map);
776 data->res = isl_union_map_add_map(data->res, map);
781 __isl_give isl_union_map *isl_union_map_intersect_range(
782 __isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
784 return gen_bin_op(umap, uset, &intersect_range_entry);
787 struct isl_union_map_bin_data {
788 isl_union_map *umap2;
791 int (*fn)(void **entry, void *user);
794 static int apply_range_entry(void **entry, void *user)
796 struct isl_union_map_bin_data *data = user;
797 isl_map *map2 = *entry;
800 if (!isl_space_tuple_match(data->map->dim, isl_dim_out,
801 map2->dim, isl_dim_in))
804 map2 = isl_map_apply_range(isl_map_copy(data->map), isl_map_copy(map2));
806 empty = isl_map_is_empty(map2);
816 data->res = isl_union_map_add_map(data->res, map2);
821 static int bin_entry(void **entry, void *user)
823 struct isl_union_map_bin_data *data = user;
824 isl_map *map = *entry;
827 if (isl_hash_table_foreach(data->umap2->dim->ctx, &data->umap2->table,
834 static __isl_give isl_union_map *bin_op(__isl_take isl_union_map *umap1,
835 __isl_take isl_union_map *umap2, int (*fn)(void **entry, void *user))
837 struct isl_union_map_bin_data data = { NULL, NULL, NULL, fn };
839 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2));
840 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1));
842 if (!umap1 || !umap2)
846 data.res = isl_union_map_alloc(isl_space_copy(umap1->dim),
848 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
849 &bin_entry, &data) < 0)
852 isl_union_map_free(umap1);
853 isl_union_map_free(umap2);
856 isl_union_map_free(umap1);
857 isl_union_map_free(umap2);
858 isl_union_map_free(data.res);
862 __isl_give isl_union_map *isl_union_map_apply_range(
863 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
865 return bin_op(umap1, umap2, &apply_range_entry);
868 __isl_give isl_union_map *isl_union_map_apply_domain(
869 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
871 umap1 = isl_union_map_reverse(umap1);
872 umap1 = isl_union_map_apply_range(umap1, umap2);
873 return isl_union_map_reverse(umap1);
876 __isl_give isl_union_set *isl_union_set_apply(
877 __isl_take isl_union_set *uset, __isl_take isl_union_map *umap)
879 return isl_union_map_apply_range(uset, umap);
882 static int map_lex_lt_entry(void **entry, void *user)
884 struct isl_union_map_bin_data *data = user;
885 isl_map *map2 = *entry;
887 if (!isl_space_tuple_match(data->map->dim, isl_dim_out,
888 map2->dim, isl_dim_out))
891 map2 = isl_map_lex_lt_map(isl_map_copy(data->map), isl_map_copy(map2));
893 data->res = isl_union_map_add_map(data->res, map2);
898 __isl_give isl_union_map *isl_union_map_lex_lt_union_map(
899 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
901 return bin_op(umap1, umap2, &map_lex_lt_entry);
904 static int map_lex_le_entry(void **entry, void *user)
906 struct isl_union_map_bin_data *data = user;
907 isl_map *map2 = *entry;
909 if (!isl_space_tuple_match(data->map->dim, isl_dim_out,
910 map2->dim, isl_dim_out))
913 map2 = isl_map_lex_le_map(isl_map_copy(data->map), isl_map_copy(map2));
915 data->res = isl_union_map_add_map(data->res, map2);
920 __isl_give isl_union_map *isl_union_map_lex_le_union_map(
921 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
923 return bin_op(umap1, umap2, &map_lex_le_entry);
926 static int product_entry(void **entry, void *user)
928 struct isl_union_map_bin_data *data = user;
929 isl_map *map2 = *entry;
931 map2 = isl_map_product(isl_map_copy(data->map), isl_map_copy(map2));
933 data->res = isl_union_map_add_map(data->res, map2);
938 __isl_give isl_union_map *isl_union_map_product(__isl_take isl_union_map *umap1,
939 __isl_take isl_union_map *umap2)
941 return bin_op(umap1, umap2, &product_entry);
944 __isl_give isl_union_set *isl_union_set_product(__isl_take isl_union_set *uset1,
945 __isl_take isl_union_set *uset2)
947 return isl_union_map_product(uset1, uset2);
950 static int range_product_entry(void **entry, void *user)
952 struct isl_union_map_bin_data *data = user;
953 isl_map *map2 = *entry;
955 if (!isl_space_tuple_match(data->map->dim, isl_dim_in,
956 map2->dim, isl_dim_in))
959 map2 = isl_map_range_product(isl_map_copy(data->map),
962 data->res = isl_union_map_add_map(data->res, map2);
967 __isl_give isl_union_map *isl_union_map_range_product(
968 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
970 return bin_op(umap1, umap2, &range_product_entry);
973 static int flat_range_product_entry(void **entry, void *user)
975 struct isl_union_map_bin_data *data = user;
976 isl_map *map2 = *entry;
978 if (!isl_space_tuple_match(data->map->dim, isl_dim_in,
979 map2->dim, isl_dim_in))
982 map2 = isl_map_flat_range_product(isl_map_copy(data->map),
985 data->res = isl_union_map_add_map(data->res, map2);
990 __isl_give isl_union_map *isl_union_map_flat_range_product(
991 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
993 return bin_op(umap1, umap2, &flat_range_product_entry);
996 __isl_give isl_union_map *isl_union_map_from_range(
997 __isl_take isl_union_set *uset)
1002 __isl_give isl_union_map *isl_union_map_from_domain(
1003 __isl_take isl_union_set *uset)
1005 return isl_union_map_reverse(isl_union_map_from_range(uset));
1008 __isl_give isl_union_map *isl_union_map_from_domain_and_range(
1009 __isl_take isl_union_set *domain, __isl_take isl_union_set *range)
1011 return isl_union_map_apply_range(isl_union_map_from_domain(domain),
1012 isl_union_map_from_range(range));
1015 static __isl_give isl_union_map *un_op(__isl_take isl_union_map *umap,
1016 int (*fn)(void **, void *))
1018 umap = isl_union_map_cow(umap);
1022 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, fn, NULL) < 0)
1027 isl_union_map_free(umap);
1031 static int affine_entry(void **entry, void *user)
1033 isl_map **map = (isl_map **)entry;
1035 *map = isl_map_from_basic_map(isl_map_affine_hull(*map));
1037 return *map ? 0 : -1;
1040 __isl_give isl_union_map *isl_union_map_affine_hull(
1041 __isl_take isl_union_map *umap)
1043 return un_op(umap, &affine_entry);
1046 __isl_give isl_union_set *isl_union_set_affine_hull(
1047 __isl_take isl_union_set *uset)
1049 return isl_union_map_affine_hull(uset);
1052 static int polyhedral_entry(void **entry, void *user)
1054 isl_map **map = (isl_map **)entry;
1056 *map = isl_map_from_basic_map(isl_map_polyhedral_hull(*map));
1058 return *map ? 0 : -1;
1061 __isl_give isl_union_map *isl_union_map_polyhedral_hull(
1062 __isl_take isl_union_map *umap)
1064 return un_op(umap, &polyhedral_entry);
1067 __isl_give isl_union_set *isl_union_set_polyhedral_hull(
1068 __isl_take isl_union_set *uset)
1070 return isl_union_map_polyhedral_hull(uset);
1073 static int simple_entry(void **entry, void *user)
1075 isl_map **map = (isl_map **)entry;
1077 *map = isl_map_from_basic_map(isl_map_simple_hull(*map));
1079 return *map ? 0 : -1;
1082 __isl_give isl_union_map *isl_union_map_simple_hull(
1083 __isl_take isl_union_map *umap)
1085 return un_op(umap, &simple_entry);
1088 __isl_give isl_union_set *isl_union_set_simple_hull(
1089 __isl_take isl_union_set *uset)
1091 return isl_union_map_simple_hull(uset);
1094 static int inplace_entry(void **entry, void *user)
1096 __isl_give isl_map *(*fn)(__isl_take isl_map *);
1097 isl_map **map = (isl_map **)entry;
1100 fn = *(__isl_give isl_map *(**)(__isl_take isl_map *)) user;
1101 copy = fn(isl_map_copy(*map));
1111 static __isl_give isl_union_map *inplace(__isl_take isl_union_map *umap,
1112 __isl_give isl_map *(*fn)(__isl_take isl_map *))
1117 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
1118 &inplace_entry, &fn) < 0)
1123 isl_union_map_free(umap);
1127 __isl_give isl_union_map *isl_union_map_coalesce(
1128 __isl_take isl_union_map *umap)
1130 return inplace(umap, &isl_map_coalesce);
1133 __isl_give isl_union_set *isl_union_set_coalesce(
1134 __isl_take isl_union_set *uset)
1136 return isl_union_map_coalesce(uset);
1139 __isl_give isl_union_map *isl_union_map_detect_equalities(
1140 __isl_take isl_union_map *umap)
1142 return inplace(umap, &isl_map_detect_equalities);
1145 __isl_give isl_union_set *isl_union_set_detect_equalities(
1146 __isl_take isl_union_set *uset)
1148 return isl_union_map_detect_equalities(uset);
1151 __isl_give isl_union_map *isl_union_map_compute_divs(
1152 __isl_take isl_union_map *umap)
1154 return inplace(umap, &isl_map_compute_divs);
1157 __isl_give isl_union_set *isl_union_set_compute_divs(
1158 __isl_take isl_union_set *uset)
1160 return isl_union_map_compute_divs(uset);
1163 static int lexmin_entry(void **entry, void *user)
1165 isl_map **map = (isl_map **)entry;
1167 *map = isl_map_lexmin(*map);
1169 return *map ? 0 : -1;
1172 __isl_give isl_union_map *isl_union_map_lexmin(
1173 __isl_take isl_union_map *umap)
1175 return un_op(umap, &lexmin_entry);
1178 __isl_give isl_union_set *isl_union_set_lexmin(
1179 __isl_take isl_union_set *uset)
1181 return isl_union_map_lexmin(uset);
1184 static int lexmax_entry(void **entry, void *user)
1186 isl_map **map = (isl_map **)entry;
1188 *map = isl_map_lexmax(*map);
1190 return *map ? 0 : -1;
1193 __isl_give isl_union_map *isl_union_map_lexmax(
1194 __isl_take isl_union_map *umap)
1196 return un_op(umap, &lexmax_entry);
1199 __isl_give isl_union_set *isl_union_set_lexmax(
1200 __isl_take isl_union_set *uset)
1202 return isl_union_map_lexmax(uset);
1205 static __isl_give isl_union_set *cond_un_op(__isl_take isl_union_map *umap,
1206 int (*fn)(void **, void *))
1213 res = isl_union_map_alloc(isl_space_copy(umap->dim), umap->table.n);
1214 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, fn, &res) < 0)
1217 isl_union_map_free(umap);
1220 isl_union_map_free(umap);
1221 isl_union_set_free(res);
1225 static int universe_entry(void **entry, void *user)
1227 isl_map *map = *entry;
1228 isl_union_map **res = user;
1230 map = isl_map_universe(isl_map_get_space(map));
1231 *res = isl_union_map_add_map(*res, map);
1236 __isl_give isl_union_map *isl_union_map_universe(__isl_take isl_union_map *umap)
1238 return cond_un_op(umap, &universe_entry);
1241 __isl_give isl_union_set *isl_union_set_universe(__isl_take isl_union_set *uset)
1243 return isl_union_map_universe(uset);
1246 static int reverse_entry(void **entry, void *user)
1248 isl_map *map = *entry;
1249 isl_union_map **res = user;
1251 *res = isl_union_map_add_map(*res, isl_map_reverse(isl_map_copy(map)));
1256 __isl_give isl_union_map *isl_union_map_reverse(__isl_take isl_union_map *umap)
1258 return cond_un_op(umap, &reverse_entry);
1261 static int domain_entry(void **entry, void *user)
1263 isl_map *map = *entry;
1264 isl_union_set **res = user;
1266 *res = isl_union_set_add_set(*res, isl_map_domain(isl_map_copy(map)));
1271 __isl_give isl_union_set *isl_union_map_domain(__isl_take isl_union_map *umap)
1273 return cond_un_op(umap, &domain_entry);
1276 static int range_entry(void **entry, void *user)
1278 isl_map *map = *entry;
1279 isl_union_set **res = user;
1281 *res = isl_union_set_add_set(*res, isl_map_range(isl_map_copy(map)));
1286 __isl_give isl_union_set *isl_union_map_range(__isl_take isl_union_map *umap)
1288 return cond_un_op(umap, &range_entry);
1291 static int domain_map_entry(void **entry, void *user)
1293 isl_map *map = *entry;
1294 isl_union_set **res = user;
1296 *res = isl_union_map_add_map(*res,
1297 isl_map_domain_map(isl_map_copy(map)));
1302 __isl_give isl_union_map *isl_union_map_domain_map(
1303 __isl_take isl_union_map *umap)
1305 return cond_un_op(umap, &domain_map_entry);
1308 static int range_map_entry(void **entry, void *user)
1310 isl_map *map = *entry;
1311 isl_union_set **res = user;
1313 *res = isl_union_map_add_map(*res,
1314 isl_map_range_map(isl_map_copy(map)));
1319 __isl_give isl_union_map *isl_union_map_range_map(
1320 __isl_take isl_union_map *umap)
1322 return cond_un_op(umap, &range_map_entry);
1325 static int deltas_entry(void **entry, void *user)
1327 isl_map *map = *entry;
1328 isl_union_set **res = user;
1330 if (!isl_space_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
1333 *res = isl_union_set_add_set(*res, isl_map_deltas(isl_map_copy(map)));
1338 __isl_give isl_union_set *isl_union_map_deltas(__isl_take isl_union_map *umap)
1340 return cond_un_op(umap, &deltas_entry);
1343 static int deltas_map_entry(void **entry, void *user)
1345 isl_map *map = *entry;
1346 isl_union_map **res = user;
1348 if (!isl_space_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
1351 *res = isl_union_map_add_map(*res,
1352 isl_map_deltas_map(isl_map_copy(map)));
1357 __isl_give isl_union_map *isl_union_map_deltas_map(
1358 __isl_take isl_union_map *umap)
1360 return cond_un_op(umap, &deltas_map_entry);
1363 static int identity_entry(void **entry, void *user)
1365 isl_set *set = *entry;
1366 isl_union_map **res = user;
1368 *res = isl_union_map_add_map(*res, isl_set_identity(isl_set_copy(set)));
1373 __isl_give isl_union_map *isl_union_set_identity(__isl_take isl_union_set *uset)
1375 return cond_un_op(uset, &identity_entry);
1378 static int unwrap_entry(void **entry, void *user)
1380 isl_set *set = *entry;
1381 isl_union_set **res = user;
1383 if (!isl_set_is_wrapping(set))
1386 *res = isl_union_map_add_map(*res, isl_set_unwrap(isl_set_copy(set)));
1391 __isl_give isl_union_map *isl_union_set_unwrap(__isl_take isl_union_set *uset)
1393 return cond_un_op(uset, &unwrap_entry);
1396 static int wrap_entry(void **entry, void *user)
1398 isl_map *map = *entry;
1399 isl_union_set **res = user;
1401 *res = isl_union_set_add_set(*res, isl_map_wrap(isl_map_copy(map)));
1406 __isl_give isl_union_set *isl_union_map_wrap(__isl_take isl_union_map *umap)
1408 return cond_un_op(umap, &wrap_entry);
1411 struct isl_union_map_is_subset_data {
1412 isl_union_map *umap2;
1416 static int is_subset_entry(void **entry, void *user)
1418 struct isl_union_map_is_subset_data *data = user;
1420 struct isl_hash_table_entry *entry2;
1421 isl_map *map = *entry;
1423 hash = isl_space_get_hash(map->dim);
1424 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
1425 hash, &has_dim, map->dim, 0);
1427 data->is_subset = 0;
1431 data->is_subset = isl_map_is_subset(map, entry2->data);
1432 if (data->is_subset < 0 || !data->is_subset)
1438 int isl_union_map_is_subset(__isl_keep isl_union_map *umap1,
1439 __isl_keep isl_union_map *umap2)
1441 struct isl_union_map_is_subset_data data = { NULL, 1 };
1443 umap1 = isl_union_map_copy(umap1);
1444 umap2 = isl_union_map_copy(umap2);
1445 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_space(umap2));
1446 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_space(umap1));
1448 if (!umap1 || !umap2)
1452 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
1453 &is_subset_entry, &data) < 0 &&
1457 isl_union_map_free(umap1);
1458 isl_union_map_free(umap2);
1460 return data.is_subset;
1462 isl_union_map_free(umap1);
1463 isl_union_map_free(umap2);
1467 int isl_union_set_is_subset(__isl_keep isl_union_set *uset1,
1468 __isl_keep isl_union_set *uset2)
1470 return isl_union_map_is_subset(uset1, uset2);
1473 int isl_union_map_is_equal(__isl_keep isl_union_map *umap1,
1474 __isl_keep isl_union_map *umap2)
1478 if (!umap1 || !umap2)
1480 is_subset = isl_union_map_is_subset(umap1, umap2);
1483 is_subset = isl_union_map_is_subset(umap2, umap1);
1487 int isl_union_set_is_equal(__isl_keep isl_union_set *uset1,
1488 __isl_keep isl_union_set *uset2)
1490 return isl_union_map_is_equal(uset1, uset2);
1493 int isl_union_map_is_strict_subset(__isl_keep isl_union_map *umap1,
1494 __isl_keep isl_union_map *umap2)
1498 if (!umap1 || !umap2)
1500 is_subset = isl_union_map_is_subset(umap1, umap2);
1503 is_subset = isl_union_map_is_subset(umap2, umap1);
1504 if (is_subset == -1)
1509 int isl_union_set_is_strict_subset(__isl_keep isl_union_set *uset1,
1510 __isl_keep isl_union_set *uset2)
1512 return isl_union_map_is_strict_subset(uset1, uset2);
1515 static int sample_entry(void **entry, void *user)
1517 isl_basic_map **sample = (isl_basic_map **)user;
1518 isl_map *map = *entry;
1520 *sample = isl_map_sample(isl_map_copy(map));
1523 if (!isl_basic_map_plain_is_empty(*sample))
1528 __isl_give isl_basic_map *isl_union_map_sample(__isl_take isl_union_map *umap)
1530 isl_basic_map *sample = NULL;
1535 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
1536 &sample_entry, &sample) < 0 &&
1541 sample = isl_basic_map_empty(isl_union_map_get_space(umap));
1543 isl_union_map_free(umap);
1547 isl_union_map_free(umap);
1551 __isl_give isl_basic_set *isl_union_set_sample(__isl_take isl_union_set *uset)
1553 return (isl_basic_set *)isl_union_map_sample(uset);
1556 struct isl_forall_data {
1558 int (*fn)(__isl_keep isl_map *map);
1561 static int forall_entry(void **entry, void *user)
1563 struct isl_forall_data *data = user;
1564 isl_map *map = *entry;
1566 data->res = data->fn(map);
1576 static int union_map_forall(__isl_keep isl_union_map *umap,
1577 int (*fn)(__isl_keep isl_map *map))
1579 struct isl_forall_data data = { 1, fn };
1584 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
1585 &forall_entry, &data) < 0 && data.res)
1591 struct isl_forall_user_data {
1593 int (*fn)(__isl_keep isl_map *map, void *user);
1597 static int forall_user_entry(void **entry, void *user)
1599 struct isl_forall_user_data *data = user;
1600 isl_map *map = *entry;
1602 data->res = data->fn(map, data->user);
1612 /* Check if fn(map, user) returns true for all maps "map" in umap.
1614 static int union_map_forall_user(__isl_keep isl_union_map *umap,
1615 int (*fn)(__isl_keep isl_map *map, void *user), void *user)
1617 struct isl_forall_user_data data = { 1, fn, user };
1622 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
1623 &forall_user_entry, &data) < 0 && data.res)
1629 int isl_union_map_is_empty(__isl_keep isl_union_map *umap)
1631 return union_map_forall(umap, &isl_map_is_empty);
1634 int isl_union_set_is_empty(__isl_keep isl_union_set *uset)
1636 return isl_union_map_is_empty(uset);
1639 static int is_subset_of_identity(__isl_keep isl_map *map)
1648 if (!isl_space_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
1651 dim = isl_map_get_space(map);
1652 id = isl_map_identity(dim);
1654 is_subset = isl_map_is_subset(map, id);
1661 /* Check if the given map is single-valued.
1666 * and check if the result is a subset of the identity mapping.
1668 int isl_union_map_is_single_valued(__isl_keep isl_union_map *umap)
1670 isl_union_map *test;
1673 if (isl_union_map_n_map(umap) == 1) {
1675 umap = isl_union_map_copy(umap);
1676 map = isl_map_from_union_map(umap);
1677 sv = isl_map_is_single_valued(map);
1682 test = isl_union_map_reverse(isl_union_map_copy(umap));
1683 test = isl_union_map_apply_range(test, isl_union_map_copy(umap));
1685 sv = union_map_forall(test, &is_subset_of_identity);
1687 isl_union_map_free(test);
1692 int isl_union_map_is_injective(__isl_keep isl_union_map *umap)
1696 umap = isl_union_map_copy(umap);
1697 umap = isl_union_map_reverse(umap);
1698 in = isl_union_map_is_single_valued(umap);
1699 isl_union_map_free(umap);
1704 /* Represents a map that has a fixed value (v) for one of its
1706 * The map in this structure is not reference counted, so it
1707 * is only valid while the isl_union_map from which it was
1708 * obtained is still alive.
1710 struct isl_fixed_map {
1715 static struct isl_fixed_map *alloc_isl_fixed_map_array(isl_ctx *ctx,
1719 struct isl_fixed_map *v;
1721 v = isl_calloc_array(ctx, struct isl_fixed_map, n);
1724 for (i = 0; i < n; ++i)
1725 isl_int_init(v[i].v);
1729 static void free_isl_fixed_map_array(struct isl_fixed_map *v, int n)
1735 for (i = 0; i < n; ++i)
1736 isl_int_clear(v[i].v);
1740 /* Compare the "v" field of two isl_fixed_map structs.
1742 static int qsort_fixed_map_cmp(const void *p1, const void *p2)
1744 const struct isl_fixed_map *e1 = (const struct isl_fixed_map *) p1;
1745 const struct isl_fixed_map *e2 = (const struct isl_fixed_map *) p2;
1747 return isl_int_cmp(e1->v, e2->v);
1750 /* Internal data structure used while checking whether all maps
1751 * in a union_map have a fixed value for a given output dimension.
1752 * v is the list of maps, with the fixed value for the dimension
1753 * n is the number of maps considered so far
1754 * pos is the output dimension under investigation
1756 struct isl_fixed_dim_data {
1757 struct isl_fixed_map *v;
1762 static int fixed_at_pos(__isl_keep isl_map *map, void *user)
1764 struct isl_fixed_dim_data *data = user;
1766 data->v[data->n].map = map;
1767 return isl_map_plain_is_fixed(map, isl_dim_out, data->pos,
1768 &data->v[data->n++].v);
1771 static int plain_injective_on_range(__isl_take isl_union_map *umap,
1772 int first, int n_range);
1774 /* Given a list of the maps, with their fixed values at output dimension "pos",
1775 * check whether the ranges of the maps form an obvious partition.
1777 * We first sort the maps according to their fixed values.
1778 * If all maps have a different value, then we know the ranges form
1780 * Otherwise, we collect the maps with the same fixed value and
1781 * check whether each such collection is obviously injective
1782 * based on later dimensions.
1784 static int separates(struct isl_fixed_map *v, int n,
1785 __isl_take isl_space *dim, int pos, int n_range)
1792 qsort(v, n, sizeof(*v), &qsort_fixed_map_cmp);
1794 for (i = 0; i + 1 < n; ++i) {
1796 isl_union_map *part;
1799 for (j = i + 1; j < n; ++j)
1800 if (isl_int_ne(v[i].v, v[j].v))
1806 part = isl_union_map_alloc(isl_space_copy(dim), j - i);
1807 for (k = i; k < j; ++k)
1808 part = isl_union_map_add_map(part,
1809 isl_map_copy(v[k].map));
1811 injective = plain_injective_on_range(part, pos + 1, n_range);
1820 isl_space_free(dim);
1821 free_isl_fixed_map_array(v, n);
1824 isl_space_free(dim);
1825 free_isl_fixed_map_array(v, n);
1829 /* Check whether the maps in umap have obviously distinct ranges.
1830 * In particular, check for an output dimension in the range
1831 * [first,n_range) for which all maps have a fixed value
1832 * and then check if these values, possibly along with fixed values
1833 * at later dimensions, entail distinct ranges.
1835 static int plain_injective_on_range(__isl_take isl_union_map *umap,
1836 int first, int n_range)
1840 struct isl_fixed_dim_data data = { NULL };
1842 ctx = isl_union_map_get_ctx(umap);
1847 n = isl_union_map_n_map(umap);
1849 isl_union_map_free(umap);
1853 if (first >= n_range) {
1854 isl_union_map_free(umap);
1858 data.v = alloc_isl_fixed_map_array(ctx, n);
1862 for (data.pos = first; data.pos < n_range; ++data.pos) {
1868 fixed = union_map_forall_user(umap, &fixed_at_pos, &data);
1873 dim = isl_union_map_get_space(umap);
1874 injective = separates(data.v, n, dim, data.pos, n_range);
1875 isl_union_map_free(umap);
1879 free_isl_fixed_map_array(data.v, n);
1880 isl_union_map_free(umap);
1884 free_isl_fixed_map_array(data.v, n);
1885 isl_union_map_free(umap);
1889 /* Check whether the maps in umap that map to subsets of "ran"
1890 * have obviously distinct ranges.
1892 static int plain_injective_on_range_wrap(__isl_keep isl_set *ran, void *user)
1894 isl_union_map *umap = user;
1896 umap = isl_union_map_copy(umap);
1897 umap = isl_union_map_intersect_range(umap,
1898 isl_union_set_from_set(isl_set_copy(ran)));
1899 return plain_injective_on_range(umap, 0, isl_set_dim(ran, isl_dim_set));
1902 /* Check if the given union_map is obviously injective.
1904 * In particular, we first check if all individual maps are obviously
1905 * injective and then check if all the ranges of these maps are
1906 * obviously disjoint.
1908 int isl_union_map_plain_is_injective(__isl_keep isl_union_map *umap)
1911 isl_union_map *univ;
1914 in = union_map_forall(umap, &isl_map_plain_is_injective);
1920 univ = isl_union_map_universe(isl_union_map_copy(umap));
1921 ran = isl_union_map_range(univ);
1923 in = union_map_forall_user(ran, &plain_injective_on_range_wrap, umap);
1925 isl_union_set_free(ran);
1930 int isl_union_map_is_bijective(__isl_keep isl_union_map *umap)
1934 sv = isl_union_map_is_single_valued(umap);
1938 return isl_union_map_is_injective(umap);
1941 static int zip_entry(void **entry, void *user)
1943 isl_map *map = *entry;
1944 isl_union_map **res = user;
1946 if (!isl_map_can_zip(map))
1949 *res = isl_union_map_add_map(*res, isl_map_zip(isl_map_copy(map)));
1954 __isl_give isl_union_map *isl_union_map_zip(__isl_take isl_union_map *umap)
1956 return cond_un_op(umap, &zip_entry);
1959 static int lift_entry(void **entry, void *user)
1961 isl_set *set = *entry;
1962 isl_union_set **res = user;
1964 *res = isl_union_set_add_set(*res, isl_set_lift(isl_set_copy(set)));
1969 __isl_give isl_union_set *isl_union_set_lift(__isl_take isl_union_set *uset)
1971 return cond_un_op(uset, &lift_entry);
1974 static int coefficients_entry(void **entry, void *user)
1976 isl_set *set = *entry;
1977 isl_union_set **res = user;
1979 set = isl_set_copy(set);
1980 set = isl_set_from_basic_set(isl_set_coefficients(set));
1981 *res = isl_union_set_add_set(*res, set);
1986 __isl_give isl_union_set *isl_union_set_coefficients(
1987 __isl_take isl_union_set *uset)
1996 ctx = isl_union_set_get_ctx(uset);
1997 dim = isl_space_set_alloc(ctx, 0, 0);
1998 res = isl_union_map_alloc(dim, uset->table.n);
1999 if (isl_hash_table_foreach(uset->dim->ctx, &uset->table,
2000 &coefficients_entry, &res) < 0)
2003 isl_union_set_free(uset);
2006 isl_union_set_free(uset);
2007 isl_union_set_free(res);
2011 static int solutions_entry(void **entry, void *user)
2013 isl_set *set = *entry;
2014 isl_union_set **res = user;
2016 set = isl_set_copy(set);
2017 set = isl_set_from_basic_set(isl_set_solutions(set));
2019 *res = isl_union_set_from_set(set);
2021 *res = isl_union_set_add_set(*res, set);
2029 __isl_give isl_union_set *isl_union_set_solutions(
2030 __isl_take isl_union_set *uset)
2032 isl_union_set *res = NULL;
2037 if (uset->table.n == 0) {
2038 res = isl_union_set_empty(isl_union_set_get_space(uset));
2039 isl_union_set_free(uset);
2043 if (isl_hash_table_foreach(uset->dim->ctx, &uset->table,
2044 &solutions_entry, &res) < 0)
2047 isl_union_set_free(uset);
2050 isl_union_set_free(uset);
2051 isl_union_set_free(res);