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,
11 #include <isl_map_private.h>
16 #include <isl_dim_private.h>
17 #include <isl_union_map_private.h>
18 #include <isl/union_set.h>
20 static __isl_give isl_union_map *isl_union_map_alloc(__isl_take isl_dim *dim,
28 umap = isl_calloc_type(dim->ctx, isl_union_map);
34 if (isl_hash_table_init(dim->ctx, &umap->table, size) < 0)
40 isl_union_map_free(umap);
44 __isl_give isl_union_map *isl_union_map_empty(__isl_take isl_dim *dim)
46 return isl_union_map_alloc(dim, 16);
49 __isl_give isl_union_set *isl_union_set_empty(__isl_take isl_dim *dim)
51 return isl_union_map_empty(dim);
54 isl_ctx *isl_union_map_get_ctx(__isl_keep isl_union_map *umap)
56 return umap ? umap->dim->ctx : NULL;
59 isl_ctx *isl_union_set_get_ctx(__isl_keep isl_union_set *uset)
61 return uset ? uset->dim->ctx : NULL;
64 __isl_give isl_dim *isl_union_map_get_dim(__isl_keep isl_union_map *umap)
68 return isl_dim_copy(umap->dim);
71 __isl_give isl_dim *isl_union_set_get_dim(__isl_keep isl_union_set *uset)
73 return isl_union_map_get_dim(uset);
76 static int free_umap_entry(void **entry, void *user)
78 isl_map *map = *entry;
83 static int add_map(__isl_take isl_map *map, void *user)
85 isl_union_map **umap = (isl_union_map **)user;
87 *umap = isl_union_map_add_map(*umap, map);
92 __isl_give isl_union_map *isl_union_map_dup(__isl_keep isl_union_map *umap)
99 dup = isl_union_map_empty(isl_dim_copy(umap->dim));
100 if (isl_union_map_foreach_map(umap, &add_map, &dup) < 0)
104 isl_union_map_free(dup);
108 __isl_give isl_union_map *isl_union_map_cow(__isl_take isl_union_map *umap)
116 return isl_union_map_dup(umap);
119 struct isl_union_align {
124 static int align_entry(void **entry, void *user)
126 isl_map *map = *entry;
128 struct isl_union_align *data = user;
130 exp = isl_reordering_extend_dim(isl_reordering_copy(data->exp),
131 isl_map_get_dim(map));
133 data->res = isl_union_map_add_map(data->res,
134 isl_map_realign(isl_map_copy(map), exp));
139 /* Align the parameters of umap along those of model.
140 * The result has the parameters of model first, in the same order
141 * as they appear in model, followed by any remaining parameters of
142 * umap that do not appear in model.
144 __isl_give isl_union_map *isl_union_map_align_params(
145 __isl_take isl_union_map *umap, __isl_take isl_dim *model)
147 struct isl_union_align data = { NULL, NULL };
152 if (isl_dim_match(umap->dim, isl_dim_param, model, isl_dim_param)) {
157 data.exp = isl_parameter_alignment_reordering(umap->dim, model);
161 data.res = isl_union_map_alloc(isl_dim_copy(data.exp->dim),
163 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
164 &align_entry, &data) < 0)
167 isl_reordering_free(data.exp);
168 isl_union_map_free(umap);
172 isl_reordering_free(data.exp);
173 isl_union_map_free(umap);
174 isl_union_map_free(data.res);
179 __isl_give isl_union_set *isl_union_set_align_params(
180 __isl_take isl_union_set *uset, __isl_take isl_dim *model)
182 return isl_union_map_align_params(uset, model);
185 __isl_give isl_union_map *isl_union_map_union(__isl_take isl_union_map *umap1,
186 __isl_take isl_union_map *umap2)
188 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_dim(umap2));
189 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_dim(umap1));
191 umap1 = isl_union_map_cow(umap1);
193 if (!umap1 || !umap2)
196 if (isl_union_map_foreach_map(umap2, &add_map, &umap1) < 0)
199 isl_union_map_free(umap2);
203 isl_union_map_free(umap1);
204 isl_union_map_free(umap2);
208 __isl_give isl_union_set *isl_union_set_union(__isl_take isl_union_set *uset1,
209 __isl_take isl_union_set *uset2)
211 return isl_union_map_union(uset1, uset2);
214 __isl_give isl_union_map *isl_union_map_copy(__isl_keep isl_union_map *umap)
223 __isl_give isl_union_set *isl_union_set_copy(__isl_keep isl_union_set *uset)
225 return isl_union_map_copy(uset);
228 void *isl_union_map_free(__isl_take isl_union_map *umap)
236 isl_hash_table_foreach(umap->dim->ctx, &umap->table,
237 &free_umap_entry, NULL);
238 isl_hash_table_clear(&umap->table);
239 isl_dim_free(umap->dim);
244 void *isl_union_set_free(__isl_take isl_union_set *uset)
246 return isl_union_map_free(uset);
249 static int has_dim(const void *entry, const void *val)
251 isl_map *map = (isl_map *)entry;
252 isl_dim *dim = (isl_dim *)val;
254 return isl_dim_equal(map->dim, dim);
257 __isl_give isl_union_map *isl_union_map_add_map(__isl_take isl_union_map *umap,
258 __isl_take isl_map *map)
261 struct isl_hash_table_entry *entry;
263 if (isl_map_plain_is_empty(map)) {
268 umap = isl_union_map_cow(umap);
273 isl_assert(map->ctx, isl_dim_match(map->dim, isl_dim_param, umap->dim,
274 isl_dim_param), goto error);
276 hash = isl_dim_get_hash(map->dim);
277 entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
278 &has_dim, map->dim, 1);
285 entry->data = isl_map_union(entry->data, isl_map_copy(map));
294 isl_union_map_free(umap);
298 __isl_give isl_union_set *isl_union_set_add_set(__isl_take isl_union_set *uset,
299 __isl_take isl_set *set)
301 return isl_union_map_add_map(uset, (isl_map *)set);
304 __isl_give isl_union_map *isl_union_map_from_map(__isl_take isl_map *map)
312 dim = isl_map_get_dim(map);
313 dim = isl_dim_drop(dim, isl_dim_in, 0, isl_dim_size(dim, isl_dim_in));
314 dim = isl_dim_drop(dim, isl_dim_out, 0, isl_dim_size(dim, isl_dim_out));
315 umap = isl_union_map_empty(dim);
316 umap = isl_union_map_add_map(umap, map);
321 __isl_give isl_union_set *isl_union_set_from_set(__isl_take isl_set *set)
323 return isl_union_map_from_map((isl_map *)set);
326 struct isl_union_map_foreach_data
328 int (*fn)(__isl_take isl_map *map, void *user);
332 static int call_on_copy(void **entry, void *user)
334 isl_map *map = *entry;
335 struct isl_union_map_foreach_data *data;
336 data = (struct isl_union_map_foreach_data *)user;
338 return data->fn(isl_map_copy(map), data->user);
341 int isl_union_map_n_map(__isl_keep isl_union_map *umap)
343 return umap ? umap->table.n : 0;
346 int isl_union_set_n_set(__isl_keep isl_union_set *uset)
348 return uset ? uset->table.n : 0;
351 int isl_union_map_foreach_map(__isl_keep isl_union_map *umap,
352 int (*fn)(__isl_take isl_map *map, void *user), void *user)
354 struct isl_union_map_foreach_data data = { fn, user };
359 return isl_hash_table_foreach(umap->dim->ctx, &umap->table,
360 &call_on_copy, &data);
363 static int copy_map(void **entry, void *user)
365 isl_map *map = *entry;
366 isl_map **map_p = user;
368 *map_p = isl_map_copy(map);
373 __isl_give isl_map *isl_union_map_copy_map(__isl_keep isl_union_map *umap)
377 if (!umap || umap->table.n == 0)
380 isl_hash_table_foreach(umap->dim->ctx, &umap->table, ©_map, &map);
385 __isl_give isl_set *isl_union_set_copy_set(__isl_keep isl_union_set *uset)
387 return isl_union_map_copy_map(uset);
390 __isl_give isl_map *isl_map_from_union_map(__isl_take isl_union_map *umap)
397 ctx = isl_union_map_get_ctx(umap);
398 if (umap->table.n != 1)
399 isl_die(ctx, isl_error_invalid,
400 "union map needs to contain elements in exactly "
401 "one space", return isl_union_map_free(umap));
403 isl_hash_table_foreach(ctx, &umap->table, ©_map, &map);
405 isl_union_map_free(umap);
410 __isl_give isl_set *isl_set_from_union_set(__isl_take isl_union_set *uset)
412 return isl_map_from_union_map(uset);
415 __isl_give isl_map *isl_union_map_extract_map(__isl_keep isl_union_map *umap,
416 __isl_take isl_dim *dim)
419 struct isl_hash_table_entry *entry;
424 hash = isl_dim_get_hash(dim);
425 entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
428 return isl_map_empty(dim);
430 return isl_map_copy(entry->data);
436 __isl_give isl_set *isl_union_set_extract_set(__isl_keep isl_union_set *uset,
437 __isl_take isl_dim *dim)
439 return (isl_set *)isl_union_map_extract_map(uset, dim);
442 /* Check if umap contains a map in the given space.
444 __isl_give int isl_union_map_contains(__isl_keep isl_union_map *umap,
445 __isl_keep isl_dim *dim)
448 struct isl_hash_table_entry *entry;
453 hash = isl_dim_get_hash(dim);
454 entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
459 __isl_give int isl_union_set_contains(__isl_keep isl_union_set *uset,
460 __isl_keep isl_dim *dim)
462 return isl_union_map_contains(uset, dim);
465 int isl_union_set_foreach_set(__isl_keep isl_union_set *uset,
466 int (*fn)(__isl_take isl_set *set, void *user), void *user)
468 return isl_union_map_foreach_map(uset,
469 (int(*)(__isl_take isl_map *, void*))fn, user);
472 struct isl_union_set_foreach_point_data {
473 int (*fn)(__isl_take isl_point *pnt, void *user);
477 static int foreach_point(__isl_take isl_set *set, void *user)
479 struct isl_union_set_foreach_point_data *data = user;
482 r = isl_set_foreach_point(set, data->fn, data->user);
488 int isl_union_set_foreach_point(__isl_keep isl_union_set *uset,
489 int (*fn)(__isl_take isl_point *pnt, void *user), void *user)
491 struct isl_union_set_foreach_point_data data = { fn, user };
492 return isl_union_set_foreach_set(uset, &foreach_point, &data);
495 struct isl_union_map_gen_bin_data {
496 isl_union_map *umap2;
500 static int subtract_entry(void **entry, void *user)
502 struct isl_union_map_gen_bin_data *data = user;
504 struct isl_hash_table_entry *entry2;
505 isl_map *map = *entry;
507 hash = isl_dim_get_hash(map->dim);
508 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
509 hash, &has_dim, map->dim, 0);
510 map = isl_map_copy(map);
513 map = isl_map_subtract(map, isl_map_copy(entry2->data));
515 empty = isl_map_is_empty(map);
525 data->res = isl_union_map_add_map(data->res, map);
530 static __isl_give isl_union_map *gen_bin_op(__isl_take isl_union_map *umap1,
531 __isl_take isl_union_map *umap2, int (*fn)(void **, void *))
533 struct isl_union_map_gen_bin_data data = { NULL, NULL };
535 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_dim(umap2));
536 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_dim(umap1));
538 if (!umap1 || !umap2)
542 data.res = isl_union_map_alloc(isl_dim_copy(umap1->dim),
544 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
548 isl_union_map_free(umap1);
549 isl_union_map_free(umap2);
552 isl_union_map_free(umap1);
553 isl_union_map_free(umap2);
554 isl_union_map_free(data.res);
558 __isl_give isl_union_map *isl_union_map_subtract(
559 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
561 return gen_bin_op(umap1, umap2, &subtract_entry);
564 __isl_give isl_union_set *isl_union_set_subtract(
565 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
567 return isl_union_map_subtract(uset1, uset2);
570 struct isl_union_map_match_bin_data {
571 isl_union_map *umap2;
573 __isl_give isl_map *(*fn)(__isl_take isl_map*, __isl_take isl_map*);
576 static int match_bin_entry(void **entry, void *user)
578 struct isl_union_map_match_bin_data *data = user;
580 struct isl_hash_table_entry *entry2;
581 isl_map *map = *entry;
584 hash = isl_dim_get_hash(map->dim);
585 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
586 hash, &has_dim, map->dim, 0);
590 map = isl_map_copy(map);
591 map = data->fn(map, isl_map_copy(entry2->data));
593 empty = isl_map_is_empty(map);
603 data->res = isl_union_map_add_map(data->res, map);
608 static __isl_give isl_union_map *match_bin_op(__isl_take isl_union_map *umap1,
609 __isl_take isl_union_map *umap2,
610 __isl_give isl_map *(*fn)(__isl_take isl_map*, __isl_take isl_map*))
612 struct isl_union_map_match_bin_data data = { NULL, NULL, fn };
614 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_dim(umap2));
615 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_dim(umap1));
617 if (!umap1 || !umap2)
621 data.res = isl_union_map_alloc(isl_dim_copy(umap1->dim),
623 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
624 &match_bin_entry, &data) < 0)
627 isl_union_map_free(umap1);
628 isl_union_map_free(umap2);
631 isl_union_map_free(umap1);
632 isl_union_map_free(umap2);
633 isl_union_map_free(data.res);
637 __isl_give isl_union_map *isl_union_map_intersect(
638 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
640 return match_bin_op(umap1, umap2, &isl_map_intersect);
643 __isl_give isl_union_set *isl_union_set_intersect(
644 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
646 return isl_union_map_intersect(uset1, uset2);
649 __isl_give isl_union_map *isl_union_map_gist(__isl_take isl_union_map *umap,
650 __isl_take isl_union_map *context)
652 return match_bin_op(umap, context, &isl_map_gist);
655 __isl_give isl_union_set *isl_union_set_gist(__isl_take isl_union_set *uset,
656 __isl_take isl_union_set *context)
658 return isl_union_map_gist(uset, context);
661 static __isl_give isl_map *lex_le_set(__isl_take isl_map *set1,
662 __isl_take isl_map *set2)
664 return isl_set_lex_le_set((isl_set *)set1, (isl_set *)set2);
667 static __isl_give isl_map *lex_lt_set(__isl_take isl_map *set1,
668 __isl_take isl_map *set2)
670 return isl_set_lex_lt_set((isl_set *)set1, (isl_set *)set2);
673 __isl_give isl_union_map *isl_union_set_lex_lt_union_set(
674 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
676 return match_bin_op(uset1, uset2, &lex_lt_set);
679 __isl_give isl_union_map *isl_union_set_lex_le_union_set(
680 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
682 return match_bin_op(uset1, uset2, &lex_le_set);
685 __isl_give isl_union_map *isl_union_set_lex_gt_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_lt_union_set(uset2, uset1));
691 __isl_give isl_union_map *isl_union_set_lex_ge_union_set(
692 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
694 return isl_union_map_reverse(isl_union_set_lex_le_union_set(uset2, uset1));
697 __isl_give isl_union_map *isl_union_map_lex_gt_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_lt_union_map(umap2, umap1));
703 __isl_give isl_union_map *isl_union_map_lex_ge_union_map(
704 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
706 return isl_union_map_reverse(isl_union_map_lex_le_union_map(umap2, umap1));
709 static int intersect_domain_entry(void **entry, void *user)
711 struct isl_union_map_gen_bin_data *data = user;
713 struct isl_hash_table_entry *entry2;
715 isl_map *map = *entry;
718 dim = isl_map_get_dim(map);
719 dim = isl_dim_domain(dim);
720 hash = isl_dim_get_hash(dim);
721 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
722 hash, &has_dim, dim, 0);
727 map = isl_map_copy(map);
728 map = isl_map_intersect_domain(map, isl_set_copy(entry2->data));
730 empty = isl_map_is_empty(map);
740 data->res = isl_union_map_add_map(data->res, map);
745 __isl_give isl_union_map *isl_union_map_intersect_domain(
746 __isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
748 return gen_bin_op(umap, uset, &intersect_domain_entry);
751 static int intersect_range_entry(void **entry, void *user)
753 struct isl_union_map_gen_bin_data *data = user;
755 struct isl_hash_table_entry *entry2;
757 isl_map *map = *entry;
760 dim = isl_map_get_dim(map);
761 dim = isl_dim_range(dim);
762 hash = isl_dim_get_hash(dim);
763 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
764 hash, &has_dim, dim, 0);
769 map = isl_map_copy(map);
770 map = isl_map_intersect_range(map, isl_set_copy(entry2->data));
772 empty = isl_map_is_empty(map);
782 data->res = isl_union_map_add_map(data->res, map);
787 __isl_give isl_union_map *isl_union_map_intersect_range(
788 __isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
790 return gen_bin_op(umap, uset, &intersect_range_entry);
793 struct isl_union_map_bin_data {
794 isl_union_map *umap2;
797 int (*fn)(void **entry, void *user);
800 static int apply_range_entry(void **entry, void *user)
802 struct isl_union_map_bin_data *data = user;
803 isl_map *map2 = *entry;
806 if (!isl_dim_tuple_match(data->map->dim, isl_dim_out,
807 map2->dim, isl_dim_in))
810 map2 = isl_map_apply_range(isl_map_copy(data->map), isl_map_copy(map2));
812 empty = isl_map_is_empty(map2);
822 data->res = isl_union_map_add_map(data->res, map2);
827 static int bin_entry(void **entry, void *user)
829 struct isl_union_map_bin_data *data = user;
830 isl_map *map = *entry;
833 if (isl_hash_table_foreach(data->umap2->dim->ctx, &data->umap2->table,
840 static __isl_give isl_union_map *bin_op(__isl_take isl_union_map *umap1,
841 __isl_take isl_union_map *umap2, int (*fn)(void **entry, void *user))
843 struct isl_union_map_bin_data data = { NULL, NULL, NULL, fn };
845 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_dim(umap2));
846 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_dim(umap1));
848 if (!umap1 || !umap2)
852 data.res = isl_union_map_alloc(isl_dim_copy(umap1->dim),
854 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
855 &bin_entry, &data) < 0)
858 isl_union_map_free(umap1);
859 isl_union_map_free(umap2);
862 isl_union_map_free(umap1);
863 isl_union_map_free(umap2);
864 isl_union_map_free(data.res);
868 __isl_give isl_union_map *isl_union_map_apply_range(
869 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
871 return bin_op(umap1, umap2, &apply_range_entry);
874 __isl_give isl_union_map *isl_union_map_apply_domain(
875 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
877 umap1 = isl_union_map_reverse(umap1);
878 umap1 = isl_union_map_apply_range(umap1, umap2);
879 return isl_union_map_reverse(umap1);
882 __isl_give isl_union_set *isl_union_set_apply(
883 __isl_take isl_union_set *uset, __isl_take isl_union_map *umap)
885 return isl_union_map_apply_range(uset, umap);
888 static int map_lex_lt_entry(void **entry, void *user)
890 struct isl_union_map_bin_data *data = user;
891 isl_map *map2 = *entry;
893 if (!isl_dim_tuple_match(data->map->dim, isl_dim_out,
894 map2->dim, isl_dim_out))
897 map2 = isl_map_lex_lt_map(isl_map_copy(data->map), isl_map_copy(map2));
899 data->res = isl_union_map_add_map(data->res, map2);
904 __isl_give isl_union_map *isl_union_map_lex_lt_union_map(
905 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
907 return bin_op(umap1, umap2, &map_lex_lt_entry);
910 static int map_lex_le_entry(void **entry, void *user)
912 struct isl_union_map_bin_data *data = user;
913 isl_map *map2 = *entry;
915 if (!isl_dim_tuple_match(data->map->dim, isl_dim_out,
916 map2->dim, isl_dim_out))
919 map2 = isl_map_lex_le_map(isl_map_copy(data->map), isl_map_copy(map2));
921 data->res = isl_union_map_add_map(data->res, map2);
926 __isl_give isl_union_map *isl_union_map_lex_le_union_map(
927 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
929 return bin_op(umap1, umap2, &map_lex_le_entry);
932 static int product_entry(void **entry, void *user)
934 struct isl_union_map_bin_data *data = user;
935 isl_map *map2 = *entry;
937 map2 = isl_map_product(isl_map_copy(data->map), isl_map_copy(map2));
939 data->res = isl_union_map_add_map(data->res, map2);
944 __isl_give isl_union_map *isl_union_map_product(__isl_take isl_union_map *umap1,
945 __isl_take isl_union_map *umap2)
947 return bin_op(umap1, umap2, &product_entry);
950 __isl_give isl_union_set *isl_union_set_product(__isl_take isl_union_set *uset1,
951 __isl_take isl_union_set *uset2)
953 return isl_union_map_product(uset1, uset2);
956 static int range_product_entry(void **entry, void *user)
958 struct isl_union_map_bin_data *data = user;
959 isl_map *map2 = *entry;
961 if (!isl_dim_tuple_match(data->map->dim, isl_dim_in,
962 map2->dim, isl_dim_in))
965 map2 = isl_map_range_product(isl_map_copy(data->map),
968 data->res = isl_union_map_add_map(data->res, map2);
973 __isl_give isl_union_map *isl_union_map_range_product(
974 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
976 return bin_op(umap1, umap2, &range_product_entry);
979 static int flat_range_product_entry(void **entry, void *user)
981 struct isl_union_map_bin_data *data = user;
982 isl_map *map2 = *entry;
984 if (!isl_dim_tuple_match(data->map->dim, isl_dim_in,
985 map2->dim, isl_dim_in))
988 map2 = isl_map_flat_range_product(isl_map_copy(data->map),
991 data->res = isl_union_map_add_map(data->res, map2);
996 __isl_give isl_union_map *isl_union_map_flat_range_product(
997 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
999 return bin_op(umap1, umap2, &flat_range_product_entry);
1002 __isl_give isl_union_map *isl_union_map_from_range(
1003 __isl_take isl_union_set *uset)
1008 __isl_give isl_union_map *isl_union_map_from_domain(
1009 __isl_take isl_union_set *uset)
1011 return isl_union_map_reverse(isl_union_map_from_range(uset));
1014 __isl_give isl_union_map *isl_union_map_from_domain_and_range(
1015 __isl_take isl_union_set *domain, __isl_take isl_union_set *range)
1017 return isl_union_map_apply_range(isl_union_map_from_domain(domain),
1018 isl_union_map_from_range(range));
1021 static __isl_give isl_union_map *un_op(__isl_take isl_union_map *umap,
1022 int (*fn)(void **, void *))
1024 umap = isl_union_map_cow(umap);
1028 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, fn, NULL) < 0)
1033 isl_union_map_free(umap);
1037 static int affine_entry(void **entry, void *user)
1039 isl_map **map = (isl_map **)entry;
1041 *map = isl_map_from_basic_map(isl_map_affine_hull(*map));
1043 return *map ? 0 : -1;
1046 __isl_give isl_union_map *isl_union_map_affine_hull(
1047 __isl_take isl_union_map *umap)
1049 return un_op(umap, &affine_entry);
1052 __isl_give isl_union_set *isl_union_set_affine_hull(
1053 __isl_take isl_union_set *uset)
1055 return isl_union_map_affine_hull(uset);
1058 static int polyhedral_entry(void **entry, void *user)
1060 isl_map **map = (isl_map **)entry;
1062 *map = isl_map_from_basic_map(isl_map_polyhedral_hull(*map));
1064 return *map ? 0 : -1;
1067 __isl_give isl_union_map *isl_union_map_polyhedral_hull(
1068 __isl_take isl_union_map *umap)
1070 return un_op(umap, &polyhedral_entry);
1073 __isl_give isl_union_set *isl_union_set_polyhedral_hull(
1074 __isl_take isl_union_set *uset)
1076 return isl_union_map_polyhedral_hull(uset);
1079 static int simple_entry(void **entry, void *user)
1081 isl_map **map = (isl_map **)entry;
1083 *map = isl_map_from_basic_map(isl_map_simple_hull(*map));
1085 return *map ? 0 : -1;
1088 __isl_give isl_union_map *isl_union_map_simple_hull(
1089 __isl_take isl_union_map *umap)
1091 return un_op(umap, &simple_entry);
1094 __isl_give isl_union_set *isl_union_set_simple_hull(
1095 __isl_take isl_union_set *uset)
1097 return isl_union_map_simple_hull(uset);
1100 static int inplace_entry(void **entry, void *user)
1102 __isl_give isl_map *(*fn)(__isl_take isl_map *);
1103 isl_map **map = (isl_map **)entry;
1106 fn = *(__isl_give isl_map *(**)(__isl_take isl_map *)) user;
1107 copy = fn(isl_map_copy(*map));
1117 static __isl_give isl_union_map *inplace(__isl_take isl_union_map *umap,
1118 __isl_give isl_map *(*fn)(__isl_take isl_map *))
1123 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
1124 &inplace_entry, &fn) < 0)
1129 isl_union_map_free(umap);
1133 __isl_give isl_union_map *isl_union_map_coalesce(
1134 __isl_take isl_union_map *umap)
1136 return inplace(umap, &isl_map_coalesce);
1139 __isl_give isl_union_set *isl_union_set_coalesce(
1140 __isl_take isl_union_set *uset)
1142 return isl_union_map_coalesce(uset);
1145 __isl_give isl_union_map *isl_union_map_detect_equalities(
1146 __isl_take isl_union_map *umap)
1148 return inplace(umap, &isl_map_detect_equalities);
1151 __isl_give isl_union_set *isl_union_set_detect_equalities(
1152 __isl_take isl_union_set *uset)
1154 return isl_union_map_detect_equalities(uset);
1157 __isl_give isl_union_map *isl_union_map_compute_divs(
1158 __isl_take isl_union_map *umap)
1160 return inplace(umap, &isl_map_compute_divs);
1163 __isl_give isl_union_set *isl_union_set_compute_divs(
1164 __isl_take isl_union_set *uset)
1166 return isl_union_map_compute_divs(uset);
1169 static int lexmin_entry(void **entry, void *user)
1171 isl_map **map = (isl_map **)entry;
1173 *map = isl_map_lexmin(*map);
1175 return *map ? 0 : -1;
1178 __isl_give isl_union_map *isl_union_map_lexmin(
1179 __isl_take isl_union_map *umap)
1181 return un_op(umap, &lexmin_entry);
1184 __isl_give isl_union_set *isl_union_set_lexmin(
1185 __isl_take isl_union_set *uset)
1187 return isl_union_map_lexmin(uset);
1190 static int lexmax_entry(void **entry, void *user)
1192 isl_map **map = (isl_map **)entry;
1194 *map = isl_map_lexmax(*map);
1196 return *map ? 0 : -1;
1199 __isl_give isl_union_map *isl_union_map_lexmax(
1200 __isl_take isl_union_map *umap)
1202 return un_op(umap, &lexmax_entry);
1205 __isl_give isl_union_set *isl_union_set_lexmax(
1206 __isl_take isl_union_set *uset)
1208 return isl_union_map_lexmax(uset);
1211 static __isl_give isl_union_set *cond_un_op(__isl_take isl_union_map *umap,
1212 int (*fn)(void **, void *))
1219 res = isl_union_map_alloc(isl_dim_copy(umap->dim), umap->table.n);
1220 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, fn, &res) < 0)
1223 isl_union_map_free(umap);
1226 isl_union_map_free(umap);
1227 isl_union_set_free(res);
1231 static int universe_entry(void **entry, void *user)
1233 isl_map *map = *entry;
1234 isl_union_map **res = user;
1236 map = isl_map_universe(isl_map_get_dim(map));
1237 *res = isl_union_map_add_map(*res, map);
1242 __isl_give isl_union_map *isl_union_map_universe(__isl_take isl_union_map *umap)
1244 return cond_un_op(umap, &universe_entry);
1247 __isl_give isl_union_set *isl_union_set_universe(__isl_take isl_union_set *uset)
1249 return isl_union_map_universe(uset);
1252 static int reverse_entry(void **entry, void *user)
1254 isl_map *map = *entry;
1255 isl_union_map **res = user;
1257 *res = isl_union_map_add_map(*res, isl_map_reverse(isl_map_copy(map)));
1262 __isl_give isl_union_map *isl_union_map_reverse(__isl_take isl_union_map *umap)
1264 return cond_un_op(umap, &reverse_entry);
1267 static int domain_entry(void **entry, void *user)
1269 isl_map *map = *entry;
1270 isl_union_set **res = user;
1272 *res = isl_union_set_add_set(*res, isl_map_domain(isl_map_copy(map)));
1277 __isl_give isl_union_set *isl_union_map_domain(__isl_take isl_union_map *umap)
1279 return cond_un_op(umap, &domain_entry);
1282 static int range_entry(void **entry, void *user)
1284 isl_map *map = *entry;
1285 isl_union_set **res = user;
1287 *res = isl_union_set_add_set(*res, isl_map_range(isl_map_copy(map)));
1292 __isl_give isl_union_set *isl_union_map_range(__isl_take isl_union_map *umap)
1294 return cond_un_op(umap, &range_entry);
1297 static int domain_map_entry(void **entry, void *user)
1299 isl_map *map = *entry;
1300 isl_union_set **res = user;
1302 *res = isl_union_map_add_map(*res,
1303 isl_map_domain_map(isl_map_copy(map)));
1308 __isl_give isl_union_map *isl_union_map_domain_map(
1309 __isl_take isl_union_map *umap)
1311 return cond_un_op(umap, &domain_map_entry);
1314 static int range_map_entry(void **entry, void *user)
1316 isl_map *map = *entry;
1317 isl_union_set **res = user;
1319 *res = isl_union_map_add_map(*res,
1320 isl_map_range_map(isl_map_copy(map)));
1325 __isl_give isl_union_map *isl_union_map_range_map(
1326 __isl_take isl_union_map *umap)
1328 return cond_un_op(umap, &range_map_entry);
1331 static int deltas_entry(void **entry, void *user)
1333 isl_map *map = *entry;
1334 isl_union_set **res = user;
1336 if (!isl_dim_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
1339 *res = isl_union_set_add_set(*res, isl_map_deltas(isl_map_copy(map)));
1344 __isl_give isl_union_set *isl_union_map_deltas(__isl_take isl_union_map *umap)
1346 return cond_un_op(umap, &deltas_entry);
1349 static int deltas_map_entry(void **entry, void *user)
1351 isl_map *map = *entry;
1352 isl_union_map **res = user;
1354 if (!isl_dim_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
1357 *res = isl_union_map_add_map(*res,
1358 isl_map_deltas_map(isl_map_copy(map)));
1363 __isl_give isl_union_map *isl_union_map_deltas_map(
1364 __isl_take isl_union_map *umap)
1366 return cond_un_op(umap, &deltas_map_entry);
1369 static int identity_entry(void **entry, void *user)
1371 isl_set *set = *entry;
1372 isl_union_map **res = user;
1374 *res = isl_union_map_add_map(*res, isl_set_identity(isl_set_copy(set)));
1379 __isl_give isl_union_map *isl_union_set_identity(__isl_take isl_union_set *uset)
1381 return cond_un_op(uset, &identity_entry);
1384 static int unwrap_entry(void **entry, void *user)
1386 isl_set *set = *entry;
1387 isl_union_set **res = user;
1389 if (!isl_set_is_wrapping(set))
1392 *res = isl_union_map_add_map(*res, isl_set_unwrap(isl_set_copy(set)));
1397 __isl_give isl_union_map *isl_union_set_unwrap(__isl_take isl_union_set *uset)
1399 return cond_un_op(uset, &unwrap_entry);
1402 static int wrap_entry(void **entry, void *user)
1404 isl_map *map = *entry;
1405 isl_union_set **res = user;
1407 *res = isl_union_set_add_set(*res, isl_map_wrap(isl_map_copy(map)));
1412 __isl_give isl_union_set *isl_union_map_wrap(__isl_take isl_union_map *umap)
1414 return cond_un_op(umap, &wrap_entry);
1417 struct isl_union_map_is_subset_data {
1418 isl_union_map *umap2;
1422 static int is_subset_entry(void **entry, void *user)
1424 struct isl_union_map_is_subset_data *data = user;
1426 struct isl_hash_table_entry *entry2;
1427 isl_map *map = *entry;
1429 hash = isl_dim_get_hash(map->dim);
1430 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
1431 hash, &has_dim, map->dim, 0);
1433 data->is_subset = 0;
1437 data->is_subset = isl_map_is_subset(map, entry2->data);
1438 if (data->is_subset < 0 || !data->is_subset)
1444 int isl_union_map_is_subset(__isl_keep isl_union_map *umap1,
1445 __isl_keep isl_union_map *umap2)
1447 struct isl_union_map_is_subset_data data = { NULL, 1 };
1449 umap1 = isl_union_map_copy(umap1);
1450 umap2 = isl_union_map_copy(umap2);
1451 umap1 = isl_union_map_align_params(umap1, isl_union_map_get_dim(umap2));
1452 umap2 = isl_union_map_align_params(umap2, isl_union_map_get_dim(umap1));
1454 if (!umap1 || !umap2)
1458 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
1459 &is_subset_entry, &data) < 0 &&
1463 isl_union_map_free(umap1);
1464 isl_union_map_free(umap2);
1466 return data.is_subset;
1468 isl_union_map_free(umap1);
1469 isl_union_map_free(umap2);
1473 int isl_union_set_is_subset(__isl_keep isl_union_set *uset1,
1474 __isl_keep isl_union_set *uset2)
1476 return isl_union_map_is_subset(uset1, uset2);
1479 int isl_union_map_is_equal(__isl_keep isl_union_map *umap1,
1480 __isl_keep isl_union_map *umap2)
1484 if (!umap1 || !umap2)
1486 is_subset = isl_union_map_is_subset(umap1, umap2);
1489 is_subset = isl_union_map_is_subset(umap2, umap1);
1493 int isl_union_set_is_equal(__isl_keep isl_union_set *uset1,
1494 __isl_keep isl_union_set *uset2)
1496 return isl_union_map_is_equal(uset1, uset2);
1499 int isl_union_map_is_strict_subset(__isl_keep isl_union_map *umap1,
1500 __isl_keep isl_union_map *umap2)
1504 if (!umap1 || !umap2)
1506 is_subset = isl_union_map_is_subset(umap1, umap2);
1509 is_subset = isl_union_map_is_subset(umap2, umap1);
1510 if (is_subset == -1)
1515 int isl_union_set_is_strict_subset(__isl_keep isl_union_set *uset1,
1516 __isl_keep isl_union_set *uset2)
1518 return isl_union_map_is_strict_subset(uset1, uset2);
1521 static int sample_entry(void **entry, void *user)
1523 isl_basic_map **sample = (isl_basic_map **)user;
1524 isl_map *map = *entry;
1526 *sample = isl_map_sample(isl_map_copy(map));
1529 if (!isl_basic_map_plain_is_empty(*sample))
1534 __isl_give isl_basic_map *isl_union_map_sample(__isl_take isl_union_map *umap)
1536 isl_basic_map *sample = NULL;
1541 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
1542 &sample_entry, &sample) < 0 &&
1547 sample = isl_basic_map_empty(isl_union_map_get_dim(umap));
1549 isl_union_map_free(umap);
1553 isl_union_map_free(umap);
1557 __isl_give isl_basic_set *isl_union_set_sample(__isl_take isl_union_set *uset)
1559 return (isl_basic_set *)isl_union_map_sample(uset);
1562 struct isl_forall_data {
1564 int (*fn)(__isl_keep isl_map *map);
1567 static int forall_entry(void **entry, void *user)
1569 struct isl_forall_data *data = user;
1570 isl_map *map = *entry;
1572 data->res = data->fn(map);
1582 static int union_map_forall(__isl_keep isl_union_map *umap,
1583 int (*fn)(__isl_keep isl_map *map))
1585 struct isl_forall_data data = { 1, fn };
1590 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
1591 &forall_entry, &data) < 0 && data.res)
1597 struct isl_forall_user_data {
1599 int (*fn)(__isl_keep isl_map *map, void *user);
1603 static int forall_user_entry(void **entry, void *user)
1605 struct isl_forall_user_data *data = user;
1606 isl_map *map = *entry;
1608 data->res = data->fn(map, data->user);
1618 /* Check if fn(map, user) returns true for all maps "map" in umap.
1620 static int union_map_forall_user(__isl_keep isl_union_map *umap,
1621 int (*fn)(__isl_keep isl_map *map, void *user), void *user)
1623 struct isl_forall_user_data data = { 1, fn, user };
1628 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
1629 &forall_user_entry, &data) < 0 && data.res)
1635 int isl_union_map_is_empty(__isl_keep isl_union_map *umap)
1637 return union_map_forall(umap, &isl_map_is_empty);
1640 int isl_union_set_is_empty(__isl_keep isl_union_set *uset)
1642 return isl_union_map_is_empty(uset);
1645 static int is_subset_of_identity(__isl_keep isl_map *map)
1654 if (!isl_dim_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
1657 dim = isl_map_get_dim(map);
1658 id = isl_map_identity(dim);
1660 is_subset = isl_map_is_subset(map, id);
1667 /* Check if the given map is single-valued.
1672 * and check if the result is a subset of the identity mapping.
1674 int isl_union_map_is_single_valued(__isl_keep isl_union_map *umap)
1676 isl_union_map *test;
1679 if (isl_union_map_n_map(umap) == 1) {
1680 isl_map *map = isl_union_map_copy_map(umap);
1681 sv = isl_map_is_single_valued(map);
1686 test = isl_union_map_reverse(isl_union_map_copy(umap));
1687 test = isl_union_map_apply_range(test, isl_union_map_copy(umap));
1689 sv = union_map_forall(test, &is_subset_of_identity);
1691 isl_union_map_free(test);
1696 int isl_union_map_is_injective(__isl_keep isl_union_map *umap)
1700 umap = isl_union_map_copy(umap);
1701 umap = isl_union_map_reverse(umap);
1702 in = isl_union_map_is_single_valued(umap);
1703 isl_union_map_free(umap);
1708 /* Represents a map that has a fixed value (v) for one of its
1710 * The map in this structure is not reference counted, so it
1711 * is only valid while the isl_union_map from which it was
1712 * obtained is still alive.
1714 struct isl_fixed_map {
1719 static struct isl_fixed_map *alloc_isl_fixed_map_array(isl_ctx *ctx,
1723 struct isl_fixed_map *v;
1725 v = isl_calloc_array(ctx, struct isl_fixed_map, n);
1728 for (i = 0; i < n; ++i)
1729 isl_int_init(v[i].v);
1733 static void free_isl_fixed_map_array(struct isl_fixed_map *v, int n)
1739 for (i = 0; i < n; ++i)
1740 isl_int_clear(v[i].v);
1744 /* Compare the "v" field of two isl_fixed_map structs.
1746 static int qsort_fixed_map_cmp(const void *p1, const void *p2)
1748 const struct isl_fixed_map *e1 = (const struct isl_fixed_map *) p1;
1749 const struct isl_fixed_map *e2 = (const struct isl_fixed_map *) p2;
1751 return isl_int_cmp(e1->v, e2->v);
1754 /* Internal data structure used while checking whether all maps
1755 * in a union_map have a fixed value for a given output dimension.
1756 * v is the list of maps, with the fixed value for the dimension
1757 * n is the number of maps considered so far
1758 * pos is the output dimension under investigation
1760 struct isl_fixed_dim_data {
1761 struct isl_fixed_map *v;
1766 static int fixed_at_pos(__isl_keep isl_map *map, void *user)
1768 struct isl_fixed_dim_data *data = user;
1770 data->v[data->n].map = map;
1771 return isl_map_plain_is_fixed(map, isl_dim_out, data->pos,
1772 &data->v[data->n++].v);
1775 static int plain_injective_on_range(__isl_take isl_union_map *umap,
1776 int first, int n_range);
1778 /* Given a list of the maps, with their fixed values at output dimension "pos",
1779 * check whether the ranges of the maps form an obvious partition.
1781 * We first sort the maps according to their fixed values.
1782 * If all maps have a different value, then we know the ranges form
1784 * Otherwise, we collect the maps with the same fixed value and
1785 * check whether each such collection is obviously injective
1786 * based on later dimensions.
1788 static int separates(struct isl_fixed_map *v, int n,
1789 __isl_take isl_dim *dim, int pos, int n_range)
1796 qsort(v, n, sizeof(*v), &qsort_fixed_map_cmp);
1798 for (i = 0; i + 1 < n; ++i) {
1800 isl_union_map *part;
1803 for (j = i + 1; j < n; ++j)
1804 if (isl_int_ne(v[i].v, v[j].v))
1810 part = isl_union_map_alloc(isl_dim_copy(dim), j - i);
1811 for (k = i; k < j; ++k)
1812 part = isl_union_map_add_map(part,
1813 isl_map_copy(v[k].map));
1815 injective = plain_injective_on_range(part, pos + 1, n_range);
1825 free_isl_fixed_map_array(v, n);
1829 free_isl_fixed_map_array(v, n);
1833 /* Check whether the maps in umap have obviously distinct ranges.
1834 * In particular, check for an output dimension in the range
1835 * [first,n_range) for which all maps have a fixed value
1836 * and then check if these values, possibly along with fixed values
1837 * at later dimensions, entail distinct ranges.
1839 static int plain_injective_on_range(__isl_take isl_union_map *umap,
1840 int first, int n_range)
1844 struct isl_fixed_dim_data data = { NULL };
1846 ctx = isl_union_map_get_ctx(umap);
1851 n = isl_union_map_n_map(umap);
1853 isl_union_map_free(umap);
1857 if (first >= n_range) {
1858 isl_union_map_free(umap);
1862 data.v = alloc_isl_fixed_map_array(ctx, n);
1866 for (data.pos = first; data.pos < n_range; ++data.pos) {
1872 fixed = union_map_forall_user(umap, &fixed_at_pos, &data);
1877 dim = isl_union_map_get_dim(umap);
1878 injective = separates(data.v, n, dim, data.pos, n_range);
1879 isl_union_map_free(umap);
1883 free_isl_fixed_map_array(data.v, n);
1884 isl_union_map_free(umap);
1888 free_isl_fixed_map_array(data.v, n);
1889 isl_union_map_free(umap);
1893 /* Check whether the maps in umap that map to subsets of "ran"
1894 * have obviously distinct ranges.
1896 static int plain_injective_on_range_wrap(__isl_keep isl_set *ran, void *user)
1898 isl_union_map *umap = user;
1900 umap = isl_union_map_copy(umap);
1901 umap = isl_union_map_intersect_range(umap,
1902 isl_union_set_from_set(isl_set_copy(ran)));
1903 return plain_injective_on_range(umap, 0, isl_set_dim(ran, isl_dim_set));
1906 /* Check if the given union_map is obviously injective.
1908 * In particular, we first check if all individual maps are obviously
1909 * injective and then check if all the ranges of these maps are
1910 * obviously disjoint.
1912 int isl_union_map_plain_is_injective(__isl_keep isl_union_map *umap)
1915 isl_union_map *univ;
1918 in = union_map_forall(umap, &isl_map_plain_is_injective);
1924 univ = isl_union_map_universe(isl_union_map_copy(umap));
1925 ran = isl_union_map_range(univ);
1927 in = union_map_forall_user(ran, &plain_injective_on_range_wrap, umap);
1929 isl_union_set_free(ran);
1934 int isl_union_map_is_bijective(__isl_keep isl_union_map *umap)
1938 sv = isl_union_map_is_single_valued(umap);
1942 return isl_union_map_is_injective(umap);
1945 static int zip_entry(void **entry, void *user)
1947 isl_map *map = *entry;
1948 isl_union_map **res = user;
1950 if (!isl_map_can_zip(map))
1953 *res = isl_union_map_add_map(*res, isl_map_zip(isl_map_copy(map)));
1958 __isl_give isl_union_map *isl_union_map_zip(__isl_take isl_union_map *umap)
1960 return cond_un_op(umap, &zip_entry);
1963 static int lift_entry(void **entry, void *user)
1965 isl_set *set = *entry;
1966 isl_union_set **res = user;
1968 *res = isl_union_set_add_set(*res, isl_set_lift(isl_set_copy(set)));
1973 __isl_give isl_union_set *isl_union_set_lift(__isl_take isl_union_set *uset)
1975 return cond_un_op(uset, &lift_entry);
1978 static int coefficients_entry(void **entry, void *user)
1980 isl_set *set = *entry;
1981 isl_union_set **res = user;
1983 set = isl_set_copy(set);
1984 set = isl_set_from_basic_set(isl_set_coefficients(set));
1985 *res = isl_union_set_add_set(*res, set);
1990 __isl_give isl_union_set *isl_union_set_coefficients(
1991 __isl_take isl_union_set *uset)
2000 ctx = isl_union_set_get_ctx(uset);
2001 dim = isl_dim_set_alloc(ctx, 0, 0);
2002 res = isl_union_map_alloc(dim, uset->table.n);
2003 if (isl_hash_table_foreach(uset->dim->ctx, &uset->table,
2004 &coefficients_entry, &res) < 0)
2007 isl_union_set_free(uset);
2010 isl_union_set_free(uset);
2011 isl_union_set_free(res);
2015 static int solutions_entry(void **entry, void *user)
2017 isl_set *set = *entry;
2018 isl_union_set **res = user;
2020 set = isl_set_copy(set);
2021 set = isl_set_from_basic_set(isl_set_solutions(set));
2023 *res = isl_union_set_from_set(set);
2025 *res = isl_union_set_add_set(*res, set);
2033 __isl_give isl_union_set *isl_union_set_solutions(
2034 __isl_take isl_union_set *uset)
2036 isl_union_set *res = NULL;
2041 if (uset->table.n == 0) {
2042 res = isl_union_set_empty(isl_union_set_get_dim(uset));
2043 isl_union_set_free(uset);
2047 if (isl_hash_table_foreach(uset->dim->ctx, &uset->table,
2048 &solutions_entry, &res) < 0)
2051 isl_union_set_free(uset);
2054 isl_union_set_free(uset);
2055 isl_union_set_free(res);