2 * Copyright 2010 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,
15 #include <isl_dim_private.h>
16 #include <isl_union_map_private.h>
17 #include <isl_union_set.h>
19 static __isl_give isl_union_map *isl_union_map_alloc(__isl_take isl_dim *dim,
27 umap = isl_calloc_type(dim->ctx, isl_union_map);
33 if (isl_hash_table_init(dim->ctx, &umap->table, size) < 0)
39 isl_union_map_free(umap);
43 __isl_give isl_union_map *isl_union_map_empty(__isl_take isl_dim *dim)
45 return isl_union_map_alloc(dim, 16);
48 __isl_give isl_union_set *isl_union_set_empty(__isl_take isl_dim *dim)
50 return isl_union_map_empty(dim);
53 isl_ctx *isl_union_map_get_ctx(__isl_keep isl_union_map *umap)
55 return umap ? umap->dim->ctx : NULL;
58 isl_ctx *isl_union_set_get_ctx(__isl_keep isl_union_set *uset)
60 return uset ? uset->dim->ctx : NULL;
63 __isl_give isl_dim *isl_union_map_get_dim(__isl_keep isl_union_map *umap)
67 return isl_dim_copy(umap->dim);
70 __isl_give isl_dim *isl_union_set_get_dim(__isl_keep isl_union_set *uset)
72 return isl_union_map_get_dim(uset);
75 static int free_umap_entry(void **entry, void *user)
77 isl_map *map = *entry;
82 static int add_map(__isl_take isl_map *map, void *user)
84 isl_union_map **umap = (isl_union_map **)user;
86 *umap = isl_union_map_add_map(*umap, map);
91 __isl_give isl_union_map *isl_union_map_dup(__isl_keep isl_union_map *umap)
98 dup = isl_union_map_empty(isl_dim_copy(umap->dim));
99 if (isl_union_map_foreach_map(umap, &add_map, &dup) < 0)
103 isl_union_map_free(dup);
107 __isl_give isl_union_map *isl_union_map_cow(__isl_take isl_union_map *umap)
115 return isl_union_map_dup(umap);
118 __isl_give isl_union_map *isl_union_map_union(__isl_take isl_union_map *umap1,
119 __isl_take isl_union_map *umap2)
121 umap1 = isl_union_map_cow(umap1);
123 if (!umap1 || !umap2)
126 if (isl_union_map_foreach_map(umap2, &add_map, &umap1) < 0)
129 isl_union_map_free(umap2);
133 isl_union_map_free(umap1);
134 isl_union_map_free(umap2);
138 __isl_give isl_union_set *isl_union_set_union(__isl_take isl_union_set *uset1,
139 __isl_take isl_union_set *uset2)
141 return isl_union_map_union(uset1, uset2);
144 __isl_give isl_union_map *isl_union_map_copy(__isl_keep isl_union_map *umap)
153 __isl_give isl_union_set *isl_union_set_copy(__isl_keep isl_union_set *uset)
155 return isl_union_map_copy(uset);
158 void isl_union_map_free(__isl_take isl_union_map *umap)
166 isl_hash_table_foreach(umap->dim->ctx, &umap->table,
167 &free_umap_entry, NULL);
168 isl_hash_table_clear(&umap->table);
169 isl_dim_free(umap->dim);
173 void isl_union_set_free(__isl_take isl_union_set *uset)
175 isl_union_map_free(uset);
178 static int has_dim(const void *entry, const void *val)
180 isl_map *map = (isl_map *)entry;
181 isl_dim *dim = (isl_dim *)val;
183 return isl_dim_equal(map->dim, dim);
186 __isl_give isl_union_map *isl_union_map_add_map(__isl_take isl_union_map *umap,
187 __isl_take isl_map *map)
190 struct isl_hash_table_entry *entry;
192 if (isl_map_fast_is_empty(map)) {
197 umap = isl_union_map_cow(umap);
202 isl_assert(map->ctx, isl_dim_match(map->dim, isl_dim_param, umap->dim,
203 isl_dim_param), goto error);
205 hash = isl_dim_get_hash(map->dim);
206 entry = isl_hash_table_find(umap->dim->ctx, &umap->table, hash,
207 &has_dim, map->dim, 1);
214 entry->data = isl_map_union(entry->data, isl_map_copy(map));
223 isl_union_map_free(umap);
227 __isl_give isl_union_set *isl_union_set_add_set(__isl_take isl_union_set *uset,
228 __isl_take isl_set *set)
230 return isl_union_map_add_map(uset, (isl_map *)set);
233 __isl_give isl_union_map *isl_union_map_from_map(__isl_take isl_map *map)
241 dim = isl_map_get_dim(map);
242 dim = isl_dim_drop(dim, isl_dim_in, 0, isl_dim_size(dim, isl_dim_in));
243 dim = isl_dim_drop(dim, isl_dim_out, 0, isl_dim_size(dim, isl_dim_out));
244 umap = isl_union_map_empty(dim);
245 umap = isl_union_map_add_map(umap, map);
250 __isl_give isl_union_set *isl_union_set_from_set(__isl_take isl_set *set)
252 return isl_union_map_from_map((isl_map *)set);
255 struct isl_union_map_foreach_data
257 int (*fn)(__isl_take isl_map *map, void *user);
261 static int call_on_copy(void **entry, void *user)
263 isl_map *map = *entry;
264 struct isl_union_map_foreach_data *data;
265 data = (struct isl_union_map_foreach_data *)user;
267 return data->fn(isl_map_copy(map), data->user);
270 int isl_union_map_foreach_map(__isl_keep isl_union_map *umap,
271 int (*fn)(__isl_take isl_map *map, void *user), void *user)
273 struct isl_union_map_foreach_data data = { fn, user };
278 return isl_hash_table_foreach(umap->dim->ctx, &umap->table,
279 &call_on_copy, &data);
282 int isl_union_set_foreach_set(__isl_keep isl_union_set *uset,
283 int (*fn)(__isl_take isl_set *set, void *user), void *user)
285 return isl_union_map_foreach_map(uset,
286 (int(*)(__isl_take isl_map *, void*))fn, user);
289 struct isl_union_set_foreach_point_data {
290 int (*fn)(__isl_take isl_point *pnt, void *user);
294 static int foreach_point(__isl_take isl_set *set, void *user)
296 struct isl_union_set_foreach_point_data *data = user;
299 r = isl_set_foreach_point(set, data->fn, data->user);
305 int isl_union_set_foreach_point(__isl_keep isl_union_set *uset,
306 int (*fn)(__isl_take isl_point *pnt, void *user), void *user)
308 struct isl_union_set_foreach_point_data data = { fn, user };
309 return isl_union_set_foreach_set(uset, &foreach_point, &data);
312 struct isl_union_map_gen_bin_data {
313 isl_union_map *umap2;
317 static int subtract_entry(void **entry, void *user)
319 struct isl_union_map_gen_bin_data *data = user;
321 struct isl_hash_table_entry *entry2;
322 isl_map *map = *entry;
324 hash = isl_dim_get_hash(map->dim);
325 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
326 hash, &has_dim, map->dim, 0);
327 map = isl_map_copy(map);
330 map = isl_map_subtract(map, isl_map_copy(entry2->data));
332 empty = isl_map_is_empty(map);
342 data->res = isl_union_map_add_map(data->res, map);
347 static __isl_give isl_union_map *gen_bin_op(__isl_take isl_union_map *umap1,
348 __isl_take isl_union_map *umap2, int (*fn)(void **, void *))
350 struct isl_union_map_gen_bin_data data = { umap2, NULL };
352 if (!umap1 || !umap2)
355 data.res = isl_union_map_alloc(isl_dim_copy(umap1->dim),
357 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
361 isl_union_map_free(umap1);
362 isl_union_map_free(umap2);
365 isl_union_map_free(umap1);
366 isl_union_map_free(umap2);
367 isl_union_map_free(data.res);
371 __isl_give isl_union_map *isl_union_map_subtract(
372 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
374 return gen_bin_op(umap1, umap2, &subtract_entry);
377 __isl_give isl_union_set *isl_union_set_subtract(
378 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
380 return isl_union_map_subtract(uset1, uset2);
383 struct isl_union_map_match_bin_data {
384 isl_union_map *umap2;
386 __isl_give isl_map *(*fn)(__isl_take isl_map*, __isl_take isl_map*);
389 static int match_bin_entry(void **entry, void *user)
391 struct isl_union_map_match_bin_data *data = user;
393 struct isl_hash_table_entry *entry2;
394 isl_map *map = *entry;
397 hash = isl_dim_get_hash(map->dim);
398 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
399 hash, &has_dim, map->dim, 0);
403 map = isl_map_copy(map);
404 map = data->fn(map, isl_map_copy(entry2->data));
406 empty = isl_map_is_empty(map);
416 data->res = isl_union_map_add_map(data->res, map);
421 static __isl_give isl_union_map *match_bin_op(__isl_take isl_union_map *umap1,
422 __isl_take isl_union_map *umap2,
423 __isl_give isl_map *(*fn)(__isl_take isl_map*, __isl_take isl_map*))
425 struct isl_union_map_match_bin_data data = { umap2, NULL, fn };
427 if (!umap1 || !umap2)
430 data.res = isl_union_map_alloc(isl_dim_copy(umap1->dim),
432 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
433 &match_bin_entry, &data) < 0)
436 isl_union_map_free(umap1);
437 isl_union_map_free(umap2);
440 isl_union_map_free(umap1);
441 isl_union_map_free(umap2);
442 isl_union_map_free(data.res);
446 __isl_give isl_union_map *isl_union_map_intersect(
447 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
449 return match_bin_op(umap1, umap2, &isl_map_intersect);
452 __isl_give isl_union_set *isl_union_set_intersect(
453 __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2)
455 return isl_union_map_intersect(uset1, uset2);
458 __isl_give isl_union_map *isl_union_map_gist(__isl_take isl_union_map *umap,
459 __isl_take isl_union_map *context)
461 return match_bin_op(umap, context, &isl_map_gist);
464 __isl_give isl_union_set *isl_union_set_gist(__isl_take isl_union_set *uset,
465 __isl_take isl_union_set *context)
467 return isl_union_map_gist(uset, context);
470 static int intersect_domain_entry(void **entry, void *user)
472 struct isl_union_map_gen_bin_data *data = user;
474 struct isl_hash_table_entry *entry2;
476 isl_map *map = *entry;
479 dim = isl_map_get_dim(map);
480 dim = isl_dim_domain(dim);
481 hash = isl_dim_get_hash(dim);
482 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
483 hash, &has_dim, dim, 0);
488 map = isl_map_copy(map);
489 map = isl_map_intersect_domain(map, isl_set_copy(entry2->data));
491 empty = isl_map_is_empty(map);
501 data->res = isl_union_map_add_map(data->res, map);
506 __isl_give isl_union_map *isl_union_map_intersect_domain(
507 __isl_take isl_union_map *umap, __isl_take isl_union_set *uset)
509 return gen_bin_op(umap, uset, &intersect_domain_entry);
512 struct isl_union_map_bin_data {
513 isl_union_map *umap2;
516 int (*fn)(void **entry, void *user);
519 static int apply_range_entry(void **entry, void *user)
521 struct isl_union_map_bin_data *data = user;
522 isl_map *map2 = *entry;
525 if (!isl_dim_tuple_match(data->map->dim, isl_dim_out,
526 map2->dim, isl_dim_in))
529 map2 = isl_map_apply_range(isl_map_copy(data->map), isl_map_copy(map2));
531 empty = isl_map_is_empty(map2);
541 data->res = isl_union_map_add_map(data->res, map2);
546 static int bin_entry(void **entry, void *user)
548 struct isl_union_map_bin_data *data = user;
549 isl_map *map = *entry;
552 if (isl_hash_table_foreach(data->umap2->dim->ctx, &data->umap2->table,
559 static __isl_give isl_union_map *bin_op(__isl_take isl_union_map *umap1,
560 __isl_take isl_union_map *umap2, int (*fn)(void **entry, void *user))
562 struct isl_union_map_bin_data data = { umap2, NULL, NULL, fn };
564 if (!umap1 || !umap2)
567 data.res = isl_union_map_alloc(isl_dim_copy(umap1->dim),
569 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
570 &bin_entry, &data) < 0)
573 isl_union_map_free(umap1);
574 isl_union_map_free(umap2);
577 isl_union_map_free(umap1);
578 isl_union_map_free(umap2);
579 isl_union_map_free(data.res);
583 __isl_give isl_union_map *isl_union_map_apply_range(
584 __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
586 return bin_op(umap1, umap2, &apply_range_entry);
589 __isl_give isl_union_set *isl_union_set_apply(
590 __isl_take isl_union_set *uset, __isl_take isl_union_map *umap)
592 return isl_union_map_apply_range(uset, umap);
595 static int product_entry(void **entry, void *user)
597 struct isl_union_map_bin_data *data = user;
598 isl_map *map2 = *entry;
600 map2 = isl_map_product(isl_map_copy(data->map), isl_map_copy(map2));
602 data->res = isl_union_map_add_map(data->res, map2);
607 __isl_give isl_union_map *isl_union_map_product(__isl_take isl_union_map *umap1,
608 __isl_take isl_union_map *umap2)
610 return bin_op(umap1, umap2, &product_entry);
613 __isl_give isl_union_set *isl_union_set_product(__isl_take isl_union_set *uset1,
614 __isl_take isl_union_set *uset2)
616 return isl_union_map_product(uset1, uset2);
619 __isl_give isl_union_map *isl_union_map_from_range(
620 __isl_take isl_union_set *uset)
625 __isl_give isl_union_map *isl_union_map_from_domain(
626 __isl_take isl_union_set *uset)
628 return isl_union_map_reverse(isl_union_map_from_range(uset));
631 __isl_give isl_union_map *isl_union_map_from_domain_and_range(
632 __isl_take isl_union_set *domain, __isl_take isl_union_set *range)
634 return isl_union_map_apply_range(isl_union_map_from_domain(domain),
635 isl_union_map_from_range(range));
638 static __isl_give isl_union_map *un_op(__isl_take isl_union_map *umap,
639 int (*fn)(void **, void *), int cow)
642 umap = isl_union_map_cow(umap);
646 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, fn, NULL) < 0)
651 isl_union_map_free(umap);
655 static int affine_entry(void **entry, void *user)
657 isl_map **map = (isl_map **)entry;
659 *map = isl_map_from_basic_map(isl_map_affine_hull(*map));
661 return *map ? 0 : -1;
664 __isl_give isl_union_map *isl_union_map_affine_hull(
665 __isl_take isl_union_map *umap)
667 return un_op(umap, &affine_entry, 1);
670 __isl_give isl_union_set *isl_union_set_affine_hull(
671 __isl_take isl_union_set *uset)
673 return isl_union_map_affine_hull(uset);
676 static int coalesce_entry(void **entry, void *user)
678 isl_map **map = (isl_map **)entry;
680 *map = isl_map_coalesce(*map);
682 return *map ? 0 : -1;
685 __isl_give isl_union_map *isl_union_map_coalesce(
686 __isl_take isl_union_map *umap)
688 return un_op(umap, &coalesce_entry, 0);
691 __isl_give isl_union_set *isl_union_set_coalesce(
692 __isl_take isl_union_set *uset)
694 return isl_union_map_coalesce(uset);
697 static int compute_divs_entry(void **entry, void *user)
699 isl_map **map = (isl_map **)entry;
701 *map = isl_map_compute_divs(*map);
703 return *map ? 0 : -1;
706 __isl_give isl_union_map *isl_union_map_compute_divs(
707 __isl_take isl_union_map *umap)
709 return un_op(umap, &compute_divs_entry, 0);
712 __isl_give isl_union_set *isl_union_set_compute_divs(
713 __isl_take isl_union_set *uset)
715 return isl_union_map_compute_divs(uset);
718 static int lexmin_entry(void **entry, void *user)
720 isl_map **map = (isl_map **)entry;
722 *map = isl_map_lexmin(*map);
724 return *map ? 0 : -1;
727 __isl_give isl_union_map *isl_union_map_lexmin(
728 __isl_take isl_union_map *umap)
730 return un_op(umap, &lexmin_entry, 1);
733 __isl_give isl_union_set *isl_union_set_lexmin(
734 __isl_take isl_union_set *uset)
736 return isl_union_map_lexmin(uset);
739 static int lexmax_entry(void **entry, void *user)
741 isl_map **map = (isl_map **)entry;
743 *map = isl_map_lexmax(*map);
745 return *map ? 0 : -1;
748 __isl_give isl_union_map *isl_union_map_lexmax(
749 __isl_take isl_union_map *umap)
751 return un_op(umap, &lexmax_entry, 1);
754 __isl_give isl_union_set *isl_union_set_lexmax(
755 __isl_take isl_union_set *uset)
757 return isl_union_map_lexmax(uset);
760 static __isl_give isl_union_set *cond_un_op(__isl_take isl_union_map *umap,
761 int (*fn)(void **, void *))
768 res = isl_union_map_alloc(isl_dim_copy(umap->dim), umap->table.n);
769 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, fn, &res) < 0)
772 isl_union_map_free(umap);
775 isl_union_map_free(umap);
776 isl_union_set_free(res);
780 static int reverse_entry(void **entry, void *user)
782 isl_map *map = *entry;
783 isl_union_map **res = user;
785 *res = isl_union_map_add_map(*res, isl_map_reverse(isl_map_copy(map)));
790 __isl_give isl_union_map *isl_union_map_reverse(__isl_take isl_union_map *umap)
792 return cond_un_op(umap, &reverse_entry);
795 static int domain_entry(void **entry, void *user)
797 isl_map *map = *entry;
798 isl_union_set **res = user;
800 *res = isl_union_set_add_set(*res, isl_map_domain(isl_map_copy(map)));
805 __isl_give isl_union_set *isl_union_map_domain(__isl_take isl_union_map *umap)
807 return cond_un_op(umap, &domain_entry);
810 static int range_entry(void **entry, void *user)
812 isl_map *map = *entry;
813 isl_union_set **res = user;
815 *res = isl_union_set_add_set(*res, isl_map_range(isl_map_copy(map)));
820 __isl_give isl_union_set *isl_union_map_range(__isl_take isl_union_map *umap)
822 return cond_un_op(umap, &range_entry);
825 static int deltas_entry(void **entry, void *user)
827 isl_map *map = *entry;
828 isl_union_set **res = user;
830 if (!isl_dim_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
833 *res = isl_union_set_add_set(*res, isl_map_deltas(isl_map_copy(map)));
838 __isl_give isl_union_set *isl_union_map_deltas(__isl_take isl_union_map *umap)
840 return cond_un_op(umap, &deltas_entry);
843 static int unwrap_entry(void **entry, void *user)
845 isl_set *set = *entry;
846 isl_union_set **res = user;
848 if (!isl_set_is_wrapping(set))
851 *res = isl_union_map_add_map(*res, isl_set_unwrap(isl_set_copy(set)));
856 __isl_give isl_union_map *isl_union_set_unwrap(__isl_take isl_union_set *uset)
858 return cond_un_op(uset, &unwrap_entry);
861 static int wrap_entry(void **entry, void *user)
863 isl_map *map = *entry;
864 isl_union_set **res = user;
866 *res = isl_union_set_add_set(*res, isl_map_wrap(isl_map_copy(map)));
871 __isl_give isl_union_set *isl_union_map_wrap(__isl_take isl_union_map *umap)
873 return cond_un_op(umap, &wrap_entry);
876 struct isl_union_map_is_subset_data {
877 isl_union_map *umap2;
881 static int is_subset_entry(void **entry, void *user)
883 struct isl_union_map_is_subset_data *data = user;
885 struct isl_hash_table_entry *entry2;
886 isl_map *map = *entry;
888 hash = isl_dim_get_hash(map->dim);
889 entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
890 hash, &has_dim, map->dim, 0);
896 data->is_subset = isl_map_is_subset(map, entry2->data);
897 if (data->is_subset < 0 || !data->is_subset)
903 int isl_union_map_is_subset(__isl_keep isl_union_map *umap1,
904 __isl_keep isl_union_map *umap2)
906 struct isl_union_map_is_subset_data data = { umap2, 1 };
908 if (!umap1 || !umap2)
911 if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
912 &is_subset_entry, &data) < 0 &&
916 return data.is_subset;
919 int isl_union_map_is_equal(__isl_keep isl_union_map *umap1,
920 __isl_keep isl_union_map *umap2)
924 if (!umap1 || !umap2)
926 is_subset = isl_union_map_is_subset(umap1, umap2);
929 is_subset = isl_union_map_is_subset(umap2, umap1);
933 int isl_union_map_is_strict_subset(__isl_keep isl_union_map *umap1,
934 __isl_keep isl_union_map *umap2)
938 if (!umap1 || !umap2)
940 is_subset = isl_union_map_is_subset(umap1, umap2);
943 is_subset = isl_union_map_is_subset(umap2, umap1);
949 static int sample_entry(void **entry, void *user)
951 isl_basic_map **sample = (isl_basic_map **)user;
952 isl_map *map = *entry;
954 *sample = isl_map_sample(isl_map_copy(map));
957 if (!isl_basic_map_fast_is_empty(*sample))
962 __isl_give isl_basic_map *isl_union_map_sample(__isl_take isl_union_map *umap)
964 isl_basic_map *sample = NULL;
969 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
970 &sample_entry, &sample) < 0 &&
974 isl_union_map_free(umap);
978 isl_union_map_free(umap);
982 __isl_give isl_basic_set *isl_union_set_sample(__isl_take isl_union_set *uset)
984 return (isl_basic_set *)isl_union_map_sample(uset);
987 static int empty_entry(void **entry, void *user)
990 isl_map *map = *entry;
992 if (isl_map_is_empty(map))
1000 __isl_give int isl_union_map_is_empty(__isl_keep isl_union_map *umap)
1007 if (isl_hash_table_foreach(umap->dim->ctx, &umap->table,
1008 &empty_entry, &empty) < 0 && empty)
1014 int isl_union_set_is_empty(__isl_keep isl_union_set *uset)
1016 return isl_union_map_is_empty(uset);