2 * Copyright 2010-2011 INRIA Saclay
3 * Copyright 2013-2014 Ecole Normale Superieure
4 * Copyright 2014 INRIA Rocquencourt
5 * Copyright 2016 Sven Verdoolaege
7 * Use of this software is governed by the MIT license
9 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
10 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
12 * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
13 * B.P. 105 - 78153 Le Chesnay, France
17 #include <isl_map_private.h>
18 #include <isl_union_map_private.h>
24 #include <isl_space_private.h>
25 #include <isl/union_set.h>
26 #include <isl/deprecated/union_map_int.h>
28 #include <bset_from_bmap.c>
29 #include <set_to_map.c>
30 #include <set_from_map.c>
32 /* Return the number of parameters of "umap", where "type"
33 * is required to be set to isl_dim_param.
35 unsigned isl_union_map_dim(__isl_keep isl_union_map
*umap
,
36 enum isl_dim_type type
)
41 if (type
!= isl_dim_param
)
42 isl_die(isl_union_map_get_ctx(umap
), isl_error_invalid
,
43 "can only reference parameters", return 0);
45 return isl_space_dim(umap
->dim
, type
);
48 /* Return the number of parameters of "uset", where "type"
49 * is required to be set to isl_dim_param.
51 unsigned isl_union_set_dim(__isl_keep isl_union_set
*uset
,
52 enum isl_dim_type type
)
54 return isl_union_map_dim(uset
, type
);
57 /* Return the id of the specified dimension.
59 __isl_give isl_id
*isl_union_map_get_dim_id(__isl_keep isl_union_map
*umap
,
60 enum isl_dim_type type
, unsigned pos
)
65 if (type
!= isl_dim_param
)
66 isl_die(isl_union_map_get_ctx(umap
), isl_error_invalid
,
67 "can only reference parameters", return NULL
);
69 return isl_space_get_dim_id(umap
->dim
, type
, pos
);
72 /* Is this union set a parameter domain?
74 isl_bool
isl_union_set_is_params(__isl_keep isl_union_set
*uset
)
80 return isl_bool_error
;
81 if (uset
->table
.n
!= 1)
82 return isl_bool_false
;
84 set
= isl_set_from_union_set(isl_union_set_copy(uset
));
85 params
= isl_set_is_params(set
);
90 static __isl_give isl_union_map
*isl_union_map_alloc(
91 __isl_take isl_space
*space
, int size
)
95 space
= isl_space_params(space
);
99 umap
= isl_calloc_type(space
->ctx
, isl_union_map
);
101 isl_space_free(space
);
107 if (isl_hash_table_init(space
->ctx
, &umap
->table
, size
) < 0)
108 return isl_union_map_free(umap
);
113 __isl_give isl_union_map
*isl_union_map_empty(__isl_take isl_space
*dim
)
115 return isl_union_map_alloc(dim
, 16);
118 __isl_give isl_union_set
*isl_union_set_empty(__isl_take isl_space
*dim
)
120 return isl_union_map_empty(dim
);
123 isl_ctx
*isl_union_map_get_ctx(__isl_keep isl_union_map
*umap
)
125 return umap
? umap
->dim
->ctx
: NULL
;
128 isl_ctx
*isl_union_set_get_ctx(__isl_keep isl_union_set
*uset
)
130 return uset
? uset
->dim
->ctx
: NULL
;
133 /* Return the space of "umap".
135 __isl_keep isl_space
*isl_union_map_peek_space(__isl_keep isl_union_map
*umap
)
137 return umap
? umap
->dim
: NULL
;
140 __isl_give isl_space
*isl_union_map_get_space(__isl_keep isl_union_map
*umap
)
142 return isl_space_copy(isl_union_map_peek_space(umap
));
145 /* Return the position of the parameter with the given name
147 * Return -1 if no such dimension can be found.
149 int isl_union_map_find_dim_by_name(__isl_keep isl_union_map
*umap
,
150 enum isl_dim_type type
, const char *name
)
154 return isl_space_find_dim_by_name(umap
->dim
, type
, name
);
157 __isl_give isl_space
*isl_union_set_get_space(__isl_keep isl_union_set
*uset
)
159 return isl_union_map_get_space(uset
);
162 static isl_stat
free_umap_entry(void **entry
, void *user
)
164 isl_map
*map
= *entry
;
169 static isl_stat
add_map(__isl_take isl_map
*map
, void *user
)
171 isl_union_map
**umap
= (isl_union_map
**)user
;
173 *umap
= isl_union_map_add_map(*umap
, map
);
178 __isl_give isl_union_map
*isl_union_map_dup(__isl_keep isl_union_map
*umap
)
185 dup
= isl_union_map_empty(isl_space_copy(umap
->dim
));
186 if (isl_union_map_foreach_map(umap
, &add_map
, &dup
) < 0)
190 isl_union_map_free(dup
);
194 __isl_give isl_union_map
*isl_union_map_cow(__isl_take isl_union_map
*umap
)
202 return isl_union_map_dup(umap
);
205 struct isl_union_align
{
210 static isl_stat
align_entry(void **entry
, void *user
)
212 isl_map
*map
= *entry
;
214 struct isl_union_align
*data
= user
;
216 exp
= isl_reordering_extend_space(isl_reordering_copy(data
->exp
),
217 isl_map_get_space(map
));
219 data
->res
= isl_union_map_add_map(data
->res
,
220 isl_map_realign(isl_map_copy(map
), exp
));
225 /* Align the parameters of umap along those of model.
226 * The result has the parameters of model first, in the same order
227 * as they appear in model, followed by any remaining parameters of
228 * umap that do not appear in model.
230 __isl_give isl_union_map
*isl_union_map_align_params(
231 __isl_take isl_union_map
*umap
, __isl_take isl_space
*model
)
233 struct isl_union_align data
= { NULL
, NULL
};
234 isl_bool equal_params
;
239 equal_params
= isl_space_has_equal_params(umap
->dim
, model
);
240 if (equal_params
< 0)
243 isl_space_free(model
);
247 model
= isl_space_params(model
);
248 data
.exp
= isl_parameter_alignment_reordering(umap
->dim
, model
);
252 data
.res
= isl_union_map_alloc(isl_space_copy(data
.exp
->dim
),
254 if (isl_hash_table_foreach(umap
->dim
->ctx
, &umap
->table
,
255 &align_entry
, &data
) < 0)
258 isl_reordering_free(data
.exp
);
259 isl_union_map_free(umap
);
260 isl_space_free(model
);
263 isl_reordering_free(data
.exp
);
264 isl_union_map_free(umap
);
265 isl_union_map_free(data
.res
);
266 isl_space_free(model
);
270 __isl_give isl_union_set
*isl_union_set_align_params(
271 __isl_take isl_union_set
*uset
, __isl_take isl_space
*model
)
273 return isl_union_map_align_params(uset
, model
);
276 __isl_give isl_union_map
*isl_union_map_union(__isl_take isl_union_map
*umap1
,
277 __isl_take isl_union_map
*umap2
)
279 umap1
= isl_union_map_align_params(umap1
, isl_union_map_get_space(umap2
));
280 umap2
= isl_union_map_align_params(umap2
, isl_union_map_get_space(umap1
));
282 umap1
= isl_union_map_cow(umap1
);
284 if (!umap1
|| !umap2
)
287 if (isl_union_map_foreach_map(umap2
, &add_map
, &umap1
) < 0)
290 isl_union_map_free(umap2
);
294 isl_union_map_free(umap1
);
295 isl_union_map_free(umap2
);
299 __isl_give isl_union_set
*isl_union_set_union(__isl_take isl_union_set
*uset1
,
300 __isl_take isl_union_set
*uset2
)
302 return isl_union_map_union(uset1
, uset2
);
305 __isl_give isl_union_map
*isl_union_map_copy(__isl_keep isl_union_map
*umap
)
314 __isl_give isl_union_set
*isl_union_set_copy(__isl_keep isl_union_set
*uset
)
316 return isl_union_map_copy(uset
);
319 __isl_null isl_union_map
*isl_union_map_free(__isl_take isl_union_map
*umap
)
327 isl_hash_table_foreach(umap
->dim
->ctx
, &umap
->table
,
328 &free_umap_entry
, NULL
);
329 isl_hash_table_clear(&umap
->table
);
330 isl_space_free(umap
->dim
);
335 __isl_null isl_union_set
*isl_union_set_free(__isl_take isl_union_set
*uset
)
337 return isl_union_map_free(uset
);
340 /* Do "umap" and "space" have the same parameters?
342 isl_bool
isl_union_map_space_has_equal_params(__isl_keep isl_union_map
*umap
,
343 __isl_keep isl_space
*space
)
345 isl_space
*umap_space
;
347 umap_space
= isl_union_map_peek_space(umap
);
348 return isl_space_has_equal_params(umap_space
, space
);
351 static int has_dim(const void *entry
, const void *val
)
353 isl_map
*map
= (isl_map
*)entry
;
354 isl_space
*dim
= (isl_space
*)val
;
356 return isl_space_is_equal(map
->dim
, dim
);
359 __isl_give isl_union_map
*isl_union_map_add_map(__isl_take isl_union_map
*umap
,
360 __isl_take isl_map
*map
)
363 struct isl_hash_table_entry
*entry
;
369 if (isl_map_plain_is_empty(map
)) {
374 aligned
= isl_map_space_has_equal_params(map
, umap
->dim
);
378 umap
= isl_union_map_align_params(umap
, isl_map_get_space(map
));
379 map
= isl_map_align_params(map
, isl_union_map_get_space(umap
));
382 umap
= isl_union_map_cow(umap
);
387 hash
= isl_space_get_hash(map
->dim
);
388 entry
= isl_hash_table_find(umap
->dim
->ctx
, &umap
->table
, hash
,
389 &has_dim
, map
->dim
, 1);
396 entry
->data
= isl_map_union(entry
->data
, isl_map_copy(map
));
405 isl_union_map_free(umap
);
409 __isl_give isl_union_set
*isl_union_set_add_set(__isl_take isl_union_set
*uset
,
410 __isl_take isl_set
*set
)
412 return isl_union_map_add_map(uset
, set_to_map(set
));
415 __isl_give isl_union_map
*isl_union_map_from_map(__isl_take isl_map
*map
)
423 dim
= isl_map_get_space(map
);
424 dim
= isl_space_params(dim
);
425 umap
= isl_union_map_empty(dim
);
426 umap
= isl_union_map_add_map(umap
, map
);
431 __isl_give isl_union_set
*isl_union_set_from_set(__isl_take isl_set
*set
)
433 return isl_union_map_from_map(set_to_map(set
));
436 __isl_give isl_union_map
*isl_union_map_from_basic_map(
437 __isl_take isl_basic_map
*bmap
)
439 return isl_union_map_from_map(isl_map_from_basic_map(bmap
));
442 __isl_give isl_union_set
*isl_union_set_from_basic_set(
443 __isl_take isl_basic_set
*bset
)
445 return isl_union_map_from_basic_map(bset
);
448 struct isl_union_map_foreach_data
450 isl_stat (*fn
)(__isl_take isl_map
*map
, void *user
);
454 static isl_stat
call_on_copy(void **entry
, void *user
)
456 isl_map
*map
= *entry
;
457 struct isl_union_map_foreach_data
*data
;
458 data
= (struct isl_union_map_foreach_data
*)user
;
460 return data
->fn(isl_map_copy(map
), data
->user
);
463 int isl_union_map_n_map(__isl_keep isl_union_map
*umap
)
465 return umap
? umap
->table
.n
: 0;
468 int isl_union_set_n_set(__isl_keep isl_union_set
*uset
)
470 return uset
? uset
->table
.n
: 0;
473 isl_stat
isl_union_map_foreach_map(__isl_keep isl_union_map
*umap
,
474 isl_stat (*fn
)(__isl_take isl_map
*map
, void *user
), void *user
)
476 struct isl_union_map_foreach_data data
= { fn
, user
};
479 return isl_stat_error
;
481 return isl_hash_table_foreach(umap
->dim
->ctx
, &umap
->table
,
482 &call_on_copy
, &data
);
485 static isl_stat
copy_map(void **entry
, void *user
)
487 isl_map
*map
= *entry
;
488 isl_map
**map_p
= user
;
490 *map_p
= isl_map_copy(map
);
492 return isl_stat_error
;
495 __isl_give isl_map
*isl_map_from_union_map(__isl_take isl_union_map
*umap
)
502 ctx
= isl_union_map_get_ctx(umap
);
503 if (umap
->table
.n
!= 1)
504 isl_die(ctx
, isl_error_invalid
,
505 "union map needs to contain elements in exactly "
506 "one space", goto error
);
508 isl_hash_table_foreach(ctx
, &umap
->table
, ©_map
, &map
);
510 isl_union_map_free(umap
);
514 isl_union_map_free(umap
);
518 __isl_give isl_set
*isl_set_from_union_set(__isl_take isl_union_set
*uset
)
520 return isl_map_from_union_map(uset
);
523 /* Extract the map in "umap" that lives in the given space (ignoring
526 __isl_give isl_map
*isl_union_map_extract_map(__isl_keep isl_union_map
*umap
,
527 __isl_take isl_space
*space
)
530 struct isl_hash_table_entry
*entry
;
532 space
= isl_space_drop_dims(space
, isl_dim_param
,
533 0, isl_space_dim(space
, isl_dim_param
));
534 space
= isl_space_align_params(space
, isl_union_map_get_space(umap
));
538 hash
= isl_space_get_hash(space
);
539 entry
= isl_hash_table_find(umap
->dim
->ctx
, &umap
->table
, hash
,
542 return isl_map_empty(space
);
543 isl_space_free(space
);
544 return isl_map_copy(entry
->data
);
546 isl_space_free(space
);
550 __isl_give isl_set
*isl_union_set_extract_set(__isl_keep isl_union_set
*uset
,
551 __isl_take isl_space
*dim
)
553 return set_from_map(isl_union_map_extract_map(uset
, dim
));
556 /* Check if umap contains a map in the given space.
558 isl_bool
isl_union_map_contains(__isl_keep isl_union_map
*umap
,
559 __isl_keep isl_space
*space
)
562 struct isl_hash_table_entry
*entry
;
565 return isl_bool_error
;
567 hash
= isl_space_get_hash(space
);
568 entry
= isl_hash_table_find(umap
->dim
->ctx
, &umap
->table
, hash
,
573 isl_bool
isl_union_set_contains(__isl_keep isl_union_set
*uset
,
574 __isl_keep isl_space
*space
)
576 return isl_union_map_contains(uset
, space
);
579 isl_stat
isl_union_set_foreach_set(__isl_keep isl_union_set
*uset
,
580 isl_stat (*fn
)(__isl_take isl_set
*set
, void *user
), void *user
)
582 return isl_union_map_foreach_map(uset
,
583 (isl_stat(*)(__isl_take isl_map
*, void*))fn
, user
);
586 struct isl_union_set_foreach_point_data
{
587 isl_stat (*fn
)(__isl_take isl_point
*pnt
, void *user
);
591 static isl_stat
foreach_point(__isl_take isl_set
*set
, void *user
)
593 struct isl_union_set_foreach_point_data
*data
= user
;
596 r
= isl_set_foreach_point(set
, data
->fn
, data
->user
);
602 isl_stat
isl_union_set_foreach_point(__isl_keep isl_union_set
*uset
,
603 isl_stat (*fn
)(__isl_take isl_point
*pnt
, void *user
), void *user
)
605 struct isl_union_set_foreach_point_data data
= { fn
, user
};
606 return isl_union_set_foreach_set(uset
, &foreach_point
, &data
);
609 struct isl_union_map_gen_bin_data
{
610 isl_union_map
*umap2
;
614 static isl_stat
subtract_entry(void **entry
, void *user
)
616 struct isl_union_map_gen_bin_data
*data
= user
;
618 struct isl_hash_table_entry
*entry2
;
619 isl_map
*map
= *entry
;
621 hash
= isl_space_get_hash(map
->dim
);
622 entry2
= isl_hash_table_find(data
->umap2
->dim
->ctx
, &data
->umap2
->table
,
623 hash
, &has_dim
, map
->dim
, 0);
624 map
= isl_map_copy(map
);
627 map
= isl_map_subtract(map
, isl_map_copy(entry2
->data
));
629 empty
= isl_map_is_empty(map
);
632 return isl_stat_error
;
639 data
->res
= isl_union_map_add_map(data
->res
, map
);
644 static __isl_give isl_union_map
*gen_bin_op(__isl_take isl_union_map
*umap1
,
645 __isl_take isl_union_map
*umap2
, isl_stat (*fn
)(void **, void *))
647 struct isl_union_map_gen_bin_data data
= { NULL
, NULL
};
649 umap1
= isl_union_map_align_params(umap1
, isl_union_map_get_space(umap2
));
650 umap2
= isl_union_map_align_params(umap2
, isl_union_map_get_space(umap1
));
652 if (!umap1
|| !umap2
)
656 data
.res
= isl_union_map_alloc(isl_space_copy(umap1
->dim
),
658 if (isl_hash_table_foreach(umap1
->dim
->ctx
, &umap1
->table
,
662 isl_union_map_free(umap1
);
663 isl_union_map_free(umap2
);
666 isl_union_map_free(umap1
);
667 isl_union_map_free(umap2
);
668 isl_union_map_free(data
.res
);
672 __isl_give isl_union_map
*isl_union_map_subtract(
673 __isl_take isl_union_map
*umap1
, __isl_take isl_union_map
*umap2
)
675 return gen_bin_op(umap1
, umap2
, &subtract_entry
);
678 __isl_give isl_union_set
*isl_union_set_subtract(
679 __isl_take isl_union_set
*uset1
, __isl_take isl_union_set
*uset2
)
681 return isl_union_map_subtract(uset1
, uset2
);
684 struct isl_union_map_gen_bin_set_data
{
689 static isl_stat
intersect_params_entry(void **entry
, void *user
)
691 struct isl_union_map_gen_bin_set_data
*data
= user
;
692 isl_map
*map
= *entry
;
695 map
= isl_map_copy(map
);
696 map
= isl_map_intersect_params(map
, isl_set_copy(data
->set
));
698 empty
= isl_map_is_empty(map
);
701 return isl_stat_error
;
704 data
->res
= isl_union_map_add_map(data
->res
, map
);
709 static __isl_give isl_union_map
*gen_bin_set_op(__isl_take isl_union_map
*umap
,
710 __isl_take isl_set
*set
, isl_stat (*fn
)(void **, void *))
712 struct isl_union_map_gen_bin_set_data data
= { NULL
, NULL
};
714 umap
= isl_union_map_align_params(umap
, isl_set_get_space(set
));
715 set
= isl_set_align_params(set
, isl_union_map_get_space(umap
));
721 data
.res
= isl_union_map_alloc(isl_space_copy(umap
->dim
),
723 if (isl_hash_table_foreach(umap
->dim
->ctx
, &umap
->table
,
727 isl_union_map_free(umap
);
731 isl_union_map_free(umap
);
733 isl_union_map_free(data
.res
);
737 /* Intersect "umap" with the parameter domain "set".
739 * If "set" does not have any constraints, then we can return immediately.
741 __isl_give isl_union_map
*isl_union_map_intersect_params(
742 __isl_take isl_union_map
*umap
, __isl_take isl_set
*set
)
746 is_universe
= isl_set_plain_is_universe(set
);
754 return gen_bin_set_op(umap
, set
, &intersect_params_entry
);
756 isl_union_map_free(umap
);
761 __isl_give isl_union_set
*isl_union_set_intersect_params(
762 __isl_take isl_union_set
*uset
, __isl_take isl_set
*set
)
764 return isl_union_map_intersect_params(uset
, set
);
767 static __isl_give isl_union_map
*union_map_intersect_params(
768 __isl_take isl_union_map
*umap
, __isl_take isl_union_set
*uset
)
770 return isl_union_map_intersect_params(umap
,
771 isl_set_from_union_set(uset
));
774 static __isl_give isl_union_map
*union_map_gist_params(
775 __isl_take isl_union_map
*umap
, __isl_take isl_union_set
*uset
)
777 return isl_union_map_gist_params(umap
, isl_set_from_union_set(uset
));
780 struct isl_union_map_match_bin_data
{
781 isl_union_map
*umap2
;
783 __isl_give isl_map
*(*fn
)(__isl_take isl_map
*, __isl_take isl_map
*);
786 static isl_stat
match_bin_entry(void **entry
, void *user
)
788 struct isl_union_map_match_bin_data
*data
= user
;
790 struct isl_hash_table_entry
*entry2
;
791 isl_map
*map
= *entry
;
794 hash
= isl_space_get_hash(map
->dim
);
795 entry2
= isl_hash_table_find(data
->umap2
->dim
->ctx
, &data
->umap2
->table
,
796 hash
, &has_dim
, map
->dim
, 0);
800 map
= isl_map_copy(map
);
801 map
= data
->fn(map
, isl_map_copy(entry2
->data
));
803 empty
= isl_map_is_empty(map
);
806 return isl_stat_error
;
813 data
->res
= isl_union_map_add_map(data
->res
, map
);
818 static __isl_give isl_union_map
*match_bin_op(__isl_take isl_union_map
*umap1
,
819 __isl_take isl_union_map
*umap2
,
820 __isl_give isl_map
*(*fn
)(__isl_take isl_map
*, __isl_take isl_map
*))
822 struct isl_union_map_match_bin_data data
= { NULL
, NULL
, fn
};
824 umap1
= isl_union_map_align_params(umap1
, isl_union_map_get_space(umap2
));
825 umap2
= isl_union_map_align_params(umap2
, isl_union_map_get_space(umap1
));
827 if (!umap1
|| !umap2
)
831 data
.res
= isl_union_map_alloc(isl_space_copy(umap1
->dim
),
833 if (isl_hash_table_foreach(umap1
->dim
->ctx
, &umap1
->table
,
834 &match_bin_entry
, &data
) < 0)
837 isl_union_map_free(umap1
);
838 isl_union_map_free(umap2
);
841 isl_union_map_free(umap1
);
842 isl_union_map_free(umap2
);
843 isl_union_map_free(data
.res
);
847 __isl_give isl_union_map
*isl_union_map_intersect(
848 __isl_take isl_union_map
*umap1
, __isl_take isl_union_map
*umap2
)
850 return match_bin_op(umap1
, umap2
, &isl_map_intersect
);
853 /* Compute the intersection of the two union_sets.
854 * As a special case, if exactly one of the two union_sets
855 * is a parameter domain, then intersect the parameter domain
856 * of the other one with this set.
858 __isl_give isl_union_set
*isl_union_set_intersect(
859 __isl_take isl_union_set
*uset1
, __isl_take isl_union_set
*uset2
)
863 p1
= isl_union_set_is_params(uset1
);
864 p2
= isl_union_set_is_params(uset2
);
865 if (p1
< 0 || p2
< 0)
868 return union_map_intersect_params(uset1
, uset2
);
870 return union_map_intersect_params(uset2
, uset1
);
871 return isl_union_map_intersect(uset1
, uset2
);
873 isl_union_set_free(uset1
);
874 isl_union_set_free(uset2
);
878 static isl_stat
gist_params_entry(void **entry
, void *user
)
880 struct isl_union_map_gen_bin_set_data
*data
= user
;
881 isl_map
*map
= *entry
;
884 map
= isl_map_copy(map
);
885 map
= isl_map_gist_params(map
, isl_set_copy(data
->set
));
887 empty
= isl_map_is_empty(map
);
890 return isl_stat_error
;
893 data
->res
= isl_union_map_add_map(data
->res
, map
);
898 __isl_give isl_union_map
*isl_union_map_gist_params(
899 __isl_take isl_union_map
*umap
, __isl_take isl_set
*set
)
901 return gen_bin_set_op(umap
, set
, &gist_params_entry
);
904 __isl_give isl_union_set
*isl_union_set_gist_params(
905 __isl_take isl_union_set
*uset
, __isl_take isl_set
*set
)
907 return isl_union_map_gist_params(uset
, set
);
910 __isl_give isl_union_map
*isl_union_map_gist(__isl_take isl_union_map
*umap
,
911 __isl_take isl_union_map
*context
)
913 return match_bin_op(umap
, context
, &isl_map_gist
);
916 __isl_give isl_union_set
*isl_union_set_gist(__isl_take isl_union_set
*uset
,
917 __isl_take isl_union_set
*context
)
919 if (isl_union_set_is_params(context
))
920 return union_map_gist_params(uset
, context
);
921 return isl_union_map_gist(uset
, context
);
924 static __isl_give isl_map
*lex_le_set(__isl_take isl_map
*set1
,
925 __isl_take isl_map
*set2
)
927 return isl_set_lex_le_set(set_from_map(set1
), set_from_map(set2
));
930 static __isl_give isl_map
*lex_lt_set(__isl_take isl_map
*set1
,
931 __isl_take isl_map
*set2
)
933 return isl_set_lex_lt_set(set_from_map(set1
), set_from_map(set2
));
936 __isl_give isl_union_map
*isl_union_set_lex_lt_union_set(
937 __isl_take isl_union_set
*uset1
, __isl_take isl_union_set
*uset2
)
939 return match_bin_op(uset1
, uset2
, &lex_lt_set
);
942 __isl_give isl_union_map
*isl_union_set_lex_le_union_set(
943 __isl_take isl_union_set
*uset1
, __isl_take isl_union_set
*uset2
)
945 return match_bin_op(uset1
, uset2
, &lex_le_set
);
948 __isl_give isl_union_map
*isl_union_set_lex_gt_union_set(
949 __isl_take isl_union_set
*uset1
, __isl_take isl_union_set
*uset2
)
951 return isl_union_map_reverse(isl_union_set_lex_lt_union_set(uset2
, uset1
));
954 __isl_give isl_union_map
*isl_union_set_lex_ge_union_set(
955 __isl_take isl_union_set
*uset1
, __isl_take isl_union_set
*uset2
)
957 return isl_union_map_reverse(isl_union_set_lex_le_union_set(uset2
, uset1
));
960 __isl_give isl_union_map
*isl_union_map_lex_gt_union_map(
961 __isl_take isl_union_map
*umap1
, __isl_take isl_union_map
*umap2
)
963 return isl_union_map_reverse(isl_union_map_lex_lt_union_map(umap2
, umap1
));
966 __isl_give isl_union_map
*isl_union_map_lex_ge_union_map(
967 __isl_take isl_union_map
*umap1
, __isl_take isl_union_map
*umap2
)
969 return isl_union_map_reverse(isl_union_map_lex_le_union_map(umap2
, umap1
));
972 static isl_stat
intersect_domain_entry(void **entry
, void *user
)
974 struct isl_union_map_gen_bin_data
*data
= user
;
976 struct isl_hash_table_entry
*entry2
;
978 isl_map
*map
= *entry
;
981 dim
= isl_map_get_space(map
);
982 dim
= isl_space_domain(dim
);
983 hash
= isl_space_get_hash(dim
);
984 entry2
= isl_hash_table_find(data
->umap2
->dim
->ctx
, &data
->umap2
->table
,
985 hash
, &has_dim
, dim
, 0);
990 map
= isl_map_copy(map
);
991 map
= isl_map_intersect_domain(map
, isl_set_copy(entry2
->data
));
993 empty
= isl_map_is_empty(map
);
996 return isl_stat_error
;
1003 data
->res
= isl_union_map_add_map(data
->res
, map
);
1008 /* Intersect the domain of "umap" with "uset".
1009 * If "uset" is a parameters domain, then intersect the parameter
1010 * domain of "umap" with this set.
1012 __isl_give isl_union_map
*isl_union_map_intersect_domain(
1013 __isl_take isl_union_map
*umap
, __isl_take isl_union_set
*uset
)
1015 if (isl_union_set_is_params(uset
))
1016 return union_map_intersect_params(umap
, uset
);
1017 return gen_bin_op(umap
, uset
, &intersect_domain_entry
);
1020 /* Remove the elements of data->umap2 from the domain of *entry
1021 * and add the result to data->res.
1023 static isl_stat
subtract_domain_entry(void **entry
, void *user
)
1025 struct isl_union_map_gen_bin_data
*data
= user
;
1027 struct isl_hash_table_entry
*entry2
;
1029 isl_map
*map
= *entry
;
1032 dim
= isl_map_get_space(map
);
1033 dim
= isl_space_domain(dim
);
1034 hash
= isl_space_get_hash(dim
);
1035 entry2
= isl_hash_table_find(data
->umap2
->dim
->ctx
, &data
->umap2
->table
,
1036 hash
, &has_dim
, dim
, 0);
1037 isl_space_free(dim
);
1039 map
= isl_map_copy(map
);
1042 data
->res
= isl_union_map_add_map(data
->res
, map
);
1046 map
= isl_map_subtract_domain(map
, isl_set_copy(entry2
->data
));
1048 empty
= isl_map_is_empty(map
);
1051 return isl_stat_error
;
1058 data
->res
= isl_union_map_add_map(data
->res
, map
);
1063 /* Remove the elements of "uset" from the domain of "umap".
1065 __isl_give isl_union_map
*isl_union_map_subtract_domain(
1066 __isl_take isl_union_map
*umap
, __isl_take isl_union_set
*dom
)
1068 return gen_bin_op(umap
, dom
, &subtract_domain_entry
);
1071 /* Remove the elements of data->umap2 from the range of *entry
1072 * and add the result to data->res.
1074 static isl_stat
subtract_range_entry(void **entry
, void *user
)
1076 struct isl_union_map_gen_bin_data
*data
= user
;
1078 struct isl_hash_table_entry
*entry2
;
1080 isl_map
*map
= *entry
;
1083 space
= isl_map_get_space(map
);
1084 space
= isl_space_range(space
);
1085 hash
= isl_space_get_hash(space
);
1086 entry2
= isl_hash_table_find(data
->umap2
->dim
->ctx
, &data
->umap2
->table
,
1087 hash
, &has_dim
, space
, 0);
1088 isl_space_free(space
);
1090 map
= isl_map_copy(map
);
1093 data
->res
= isl_union_map_add_map(data
->res
, map
);
1097 map
= isl_map_subtract_range(map
, isl_set_copy(entry2
->data
));
1099 empty
= isl_map_is_empty(map
);
1102 return isl_stat_error
;
1109 data
->res
= isl_union_map_add_map(data
->res
, map
);
1114 /* Remove the elements of "uset" from the range of "umap".
1116 __isl_give isl_union_map
*isl_union_map_subtract_range(
1117 __isl_take isl_union_map
*umap
, __isl_take isl_union_set
*dom
)
1119 return gen_bin_op(umap
, dom
, &subtract_range_entry
);
1122 static isl_stat
gist_domain_entry(void **entry
, void *user
)
1124 struct isl_union_map_gen_bin_data
*data
= user
;
1126 struct isl_hash_table_entry
*entry2
;
1128 isl_map
*map
= *entry
;
1131 dim
= isl_map_get_space(map
);
1132 dim
= isl_space_domain(dim
);
1133 hash
= isl_space_get_hash(dim
);
1134 entry2
= isl_hash_table_find(data
->umap2
->dim
->ctx
, &data
->umap2
->table
,
1135 hash
, &has_dim
, dim
, 0);
1136 isl_space_free(dim
);
1140 map
= isl_map_copy(map
);
1141 map
= isl_map_gist_domain(map
, isl_set_copy(entry2
->data
));
1143 empty
= isl_map_is_empty(map
);
1146 return isl_stat_error
;
1149 data
->res
= isl_union_map_add_map(data
->res
, map
);
1154 /* Compute the gist of "umap" with respect to the domain "uset".
1155 * If "uset" is a parameters domain, then compute the gist
1156 * with respect to this parameter domain.
1158 __isl_give isl_union_map
*isl_union_map_gist_domain(
1159 __isl_take isl_union_map
*umap
, __isl_take isl_union_set
*uset
)
1161 if (isl_union_set_is_params(uset
))
1162 return union_map_gist_params(umap
, uset
);
1163 return gen_bin_op(umap
, uset
, &gist_domain_entry
);
1166 static isl_stat
gist_range_entry(void **entry
, void *user
)
1168 struct isl_union_map_gen_bin_data
*data
= user
;
1170 struct isl_hash_table_entry
*entry2
;
1172 isl_map
*map
= *entry
;
1175 space
= isl_map_get_space(map
);
1176 space
= isl_space_range(space
);
1177 hash
= isl_space_get_hash(space
);
1178 entry2
= isl_hash_table_find(data
->umap2
->dim
->ctx
, &data
->umap2
->table
,
1179 hash
, &has_dim
, space
, 0);
1180 isl_space_free(space
);
1184 map
= isl_map_copy(map
);
1185 map
= isl_map_gist_range(map
, isl_set_copy(entry2
->data
));
1187 empty
= isl_map_is_empty(map
);
1190 return isl_stat_error
;
1193 data
->res
= isl_union_map_add_map(data
->res
, map
);
1198 /* Compute the gist of "umap" with respect to the range "uset".
1200 __isl_give isl_union_map
*isl_union_map_gist_range(
1201 __isl_take isl_union_map
*umap
, __isl_take isl_union_set
*uset
)
1203 return gen_bin_op(umap
, uset
, &gist_range_entry
);
1206 static isl_stat
intersect_range_entry(void **entry
, void *user
)
1208 struct isl_union_map_gen_bin_data
*data
= user
;
1210 struct isl_hash_table_entry
*entry2
;
1212 isl_map
*map
= *entry
;
1215 dim
= isl_map_get_space(map
);
1216 dim
= isl_space_range(dim
);
1217 hash
= isl_space_get_hash(dim
);
1218 entry2
= isl_hash_table_find(data
->umap2
->dim
->ctx
, &data
->umap2
->table
,
1219 hash
, &has_dim
, dim
, 0);
1220 isl_space_free(dim
);
1224 map
= isl_map_copy(map
);
1225 map
= isl_map_intersect_range(map
, isl_set_copy(entry2
->data
));
1227 empty
= isl_map_is_empty(map
);
1230 return isl_stat_error
;
1237 data
->res
= isl_union_map_add_map(data
->res
, map
);
1242 __isl_give isl_union_map
*isl_union_map_intersect_range(
1243 __isl_take isl_union_map
*umap
, __isl_take isl_union_set
*uset
)
1245 return gen_bin_op(umap
, uset
, &intersect_range_entry
);
1248 struct isl_union_map_bin_data
{
1249 isl_union_map
*umap2
;
1252 isl_stat (*fn
)(void **entry
, void *user
);
1255 static isl_stat
apply_range_entry(void **entry
, void *user
)
1257 struct isl_union_map_bin_data
*data
= user
;
1258 isl_map
*map2
= *entry
;
1261 if (!isl_space_tuple_is_equal(data
->map
->dim
, isl_dim_out
,
1262 map2
->dim
, isl_dim_in
))
1265 map2
= isl_map_apply_range(isl_map_copy(data
->map
), isl_map_copy(map2
));
1267 empty
= isl_map_is_empty(map2
);
1270 return isl_stat_error
;
1277 data
->res
= isl_union_map_add_map(data
->res
, map2
);
1282 static isl_stat
bin_entry(void **entry
, void *user
)
1284 struct isl_union_map_bin_data
*data
= user
;
1285 isl_map
*map
= *entry
;
1288 if (isl_hash_table_foreach(data
->umap2
->dim
->ctx
, &data
->umap2
->table
,
1289 data
->fn
, data
) < 0)
1290 return isl_stat_error
;
1295 static __isl_give isl_union_map
*bin_op(__isl_take isl_union_map
*umap1
,
1296 __isl_take isl_union_map
*umap2
,
1297 isl_stat (*fn
)(void **entry
, void *user
))
1299 struct isl_union_map_bin_data data
= { NULL
, NULL
, NULL
, fn
};
1301 umap1
= isl_union_map_align_params(umap1
, isl_union_map_get_space(umap2
));
1302 umap2
= isl_union_map_align_params(umap2
, isl_union_map_get_space(umap1
));
1304 if (!umap1
|| !umap2
)
1308 data
.res
= isl_union_map_alloc(isl_space_copy(umap1
->dim
),
1310 if (isl_hash_table_foreach(umap1
->dim
->ctx
, &umap1
->table
,
1311 &bin_entry
, &data
) < 0)
1314 isl_union_map_free(umap1
);
1315 isl_union_map_free(umap2
);
1318 isl_union_map_free(umap1
);
1319 isl_union_map_free(umap2
);
1320 isl_union_map_free(data
.res
);
1324 __isl_give isl_union_map
*isl_union_map_apply_range(
1325 __isl_take isl_union_map
*umap1
, __isl_take isl_union_map
*umap2
)
1327 return bin_op(umap1
, umap2
, &apply_range_entry
);
1330 __isl_give isl_union_map
*isl_union_map_apply_domain(
1331 __isl_take isl_union_map
*umap1
, __isl_take isl_union_map
*umap2
)
1333 umap1
= isl_union_map_reverse(umap1
);
1334 umap1
= isl_union_map_apply_range(umap1
, umap2
);
1335 return isl_union_map_reverse(umap1
);
1338 __isl_give isl_union_set
*isl_union_set_apply(
1339 __isl_take isl_union_set
*uset
, __isl_take isl_union_map
*umap
)
1341 return isl_union_map_apply_range(uset
, umap
);
1344 static isl_stat
map_lex_lt_entry(void **entry
, void *user
)
1346 struct isl_union_map_bin_data
*data
= user
;
1347 isl_map
*map2
= *entry
;
1349 if (!isl_space_tuple_is_equal(data
->map
->dim
, isl_dim_out
,
1350 map2
->dim
, isl_dim_out
))
1353 map2
= isl_map_lex_lt_map(isl_map_copy(data
->map
), isl_map_copy(map2
));
1355 data
->res
= isl_union_map_add_map(data
->res
, map2
);
1360 __isl_give isl_union_map
*isl_union_map_lex_lt_union_map(
1361 __isl_take isl_union_map
*umap1
, __isl_take isl_union_map
*umap2
)
1363 return bin_op(umap1
, umap2
, &map_lex_lt_entry
);
1366 static isl_stat
map_lex_le_entry(void **entry
, void *user
)
1368 struct isl_union_map_bin_data
*data
= user
;
1369 isl_map
*map2
= *entry
;
1371 if (!isl_space_tuple_is_equal(data
->map
->dim
, isl_dim_out
,
1372 map2
->dim
, isl_dim_out
))
1375 map2
= isl_map_lex_le_map(isl_map_copy(data
->map
), isl_map_copy(map2
));
1377 data
->res
= isl_union_map_add_map(data
->res
, map2
);
1382 __isl_give isl_union_map
*isl_union_map_lex_le_union_map(
1383 __isl_take isl_union_map
*umap1
, __isl_take isl_union_map
*umap2
)
1385 return bin_op(umap1
, umap2
, &map_lex_le_entry
);
1388 static isl_stat
product_entry(void **entry
, void *user
)
1390 struct isl_union_map_bin_data
*data
= user
;
1391 isl_map
*map2
= *entry
;
1393 map2
= isl_map_product(isl_map_copy(data
->map
), isl_map_copy(map2
));
1395 data
->res
= isl_union_map_add_map(data
->res
, map2
);
1400 __isl_give isl_union_map
*isl_union_map_product(__isl_take isl_union_map
*umap1
,
1401 __isl_take isl_union_map
*umap2
)
1403 return bin_op(umap1
, umap2
, &product_entry
);
1406 static isl_stat
set_product_entry(void **entry
, void *user
)
1408 struct isl_union_map_bin_data
*data
= user
;
1409 isl_set
*set2
= *entry
;
1411 set2
= isl_set_product(isl_set_copy(data
->map
), isl_set_copy(set2
));
1413 data
->res
= isl_union_set_add_set(data
->res
, set2
);
1418 __isl_give isl_union_set
*isl_union_set_product(__isl_take isl_union_set
*uset1
,
1419 __isl_take isl_union_set
*uset2
)
1421 return bin_op(uset1
, uset2
, &set_product_entry
);
1424 static isl_stat
domain_product_entry(void **entry
, void *user
)
1426 struct isl_union_map_bin_data
*data
= user
;
1427 isl_map
*map2
= *entry
;
1429 if (!isl_space_tuple_is_equal(data
->map
->dim
, isl_dim_out
,
1430 map2
->dim
, isl_dim_out
))
1433 map2
= isl_map_domain_product(isl_map_copy(data
->map
),
1434 isl_map_copy(map2
));
1436 data
->res
= isl_union_map_add_map(data
->res
, map2
);
1441 /* Given two maps A -> B and C -> D, construct a map [A -> C] -> (B * D)
1443 __isl_give isl_union_map
*isl_union_map_domain_product(
1444 __isl_take isl_union_map
*umap1
, __isl_take isl_union_map
*umap2
)
1446 return bin_op(umap1
, umap2
, &domain_product_entry
);
1449 static isl_stat
range_product_entry(void **entry
, void *user
)
1451 struct isl_union_map_bin_data
*data
= user
;
1452 isl_map
*map2
= *entry
;
1454 if (!isl_space_tuple_is_equal(data
->map
->dim
, isl_dim_in
,
1455 map2
->dim
, isl_dim_in
))
1458 map2
= isl_map_range_product(isl_map_copy(data
->map
),
1459 isl_map_copy(map2
));
1461 data
->res
= isl_union_map_add_map(data
->res
, map2
);
1466 __isl_give isl_union_map
*isl_union_map_range_product(
1467 __isl_take isl_union_map
*umap1
, __isl_take isl_union_map
*umap2
)
1469 return bin_op(umap1
, umap2
, &range_product_entry
);
1472 /* If data->map A -> B and "map2" C -> D have the same range space,
1473 * then add (A, C) -> (B * D) to data->res.
1475 static isl_stat
flat_domain_product_entry(void **entry
, void *user
)
1477 struct isl_union_map_bin_data
*data
= user
;
1478 isl_map
*map2
= *entry
;
1480 if (!isl_space_tuple_is_equal(data
->map
->dim
, isl_dim_out
,
1481 map2
->dim
, isl_dim_out
))
1484 map2
= isl_map_flat_domain_product(isl_map_copy(data
->map
),
1485 isl_map_copy(map2
));
1487 data
->res
= isl_union_map_add_map(data
->res
, map2
);
1492 /* Given two maps A -> B and C -> D, construct a map (A, C) -> (B * D).
1494 __isl_give isl_union_map
*isl_union_map_flat_domain_product(
1495 __isl_take isl_union_map
*umap1
, __isl_take isl_union_map
*umap2
)
1497 return bin_op(umap1
, umap2
, &flat_domain_product_entry
);
1500 static isl_stat
flat_range_product_entry(void **entry
, void *user
)
1502 struct isl_union_map_bin_data
*data
= user
;
1503 isl_map
*map2
= *entry
;
1505 if (!isl_space_tuple_is_equal(data
->map
->dim
, isl_dim_in
,
1506 map2
->dim
, isl_dim_in
))
1509 map2
= isl_map_flat_range_product(isl_map_copy(data
->map
),
1510 isl_map_copy(map2
));
1512 data
->res
= isl_union_map_add_map(data
->res
, map2
);
1517 __isl_give isl_union_map
*isl_union_map_flat_range_product(
1518 __isl_take isl_union_map
*umap1
, __isl_take isl_union_map
*umap2
)
1520 return bin_op(umap1
, umap2
, &flat_range_product_entry
);
1523 static __isl_give isl_union_set
*cond_un_op(__isl_take isl_union_map
*umap
,
1524 isl_stat (*fn
)(void **, void *))
1531 res
= isl_union_map_alloc(isl_space_copy(umap
->dim
), umap
->table
.n
);
1532 if (isl_hash_table_foreach(umap
->dim
->ctx
, &umap
->table
, fn
, &res
) < 0)
1535 isl_union_map_free(umap
);
1538 isl_union_map_free(umap
);
1539 isl_union_set_free(res
);
1543 static isl_stat
from_range_entry(void **entry
, void *user
)
1545 isl_map
*set
= *entry
;
1546 isl_union_set
**res
= user
;
1548 *res
= isl_union_map_add_map(*res
,
1549 isl_map_from_range(isl_set_copy(set
)));
1554 __isl_give isl_union_map
*isl_union_map_from_range(
1555 __isl_take isl_union_set
*uset
)
1557 return cond_un_op(uset
, &from_range_entry
);
1560 __isl_give isl_union_map
*isl_union_map_from_domain(
1561 __isl_take isl_union_set
*uset
)
1563 return isl_union_map_reverse(isl_union_map_from_range(uset
));
1566 __isl_give isl_union_map
*isl_union_map_from_domain_and_range(
1567 __isl_take isl_union_set
*domain
, __isl_take isl_union_set
*range
)
1569 return isl_union_map_apply_range(isl_union_map_from_domain(domain
),
1570 isl_union_map_from_range(range
));
1573 static __isl_give isl_union_map
*un_op(__isl_take isl_union_map
*umap
,
1574 isl_stat (*fn
)(void **, void *))
1576 umap
= isl_union_map_cow(umap
);
1580 if (isl_hash_table_foreach(umap
->dim
->ctx
, &umap
->table
, fn
, NULL
) < 0)
1585 isl_union_map_free(umap
);
1589 static isl_stat
affine_entry(void **entry
, void *user
)
1591 isl_map
**map
= (isl_map
**)entry
;
1593 *map
= isl_map_from_basic_map(isl_map_affine_hull(*map
));
1595 return *map
? isl_stat_ok
: isl_stat_error
;
1598 __isl_give isl_union_map
*isl_union_map_affine_hull(
1599 __isl_take isl_union_map
*umap
)
1601 return un_op(umap
, &affine_entry
);
1604 __isl_give isl_union_set
*isl_union_set_affine_hull(
1605 __isl_take isl_union_set
*uset
)
1607 return isl_union_map_affine_hull(uset
);
1610 static isl_stat
polyhedral_entry(void **entry
, void *user
)
1612 isl_map
**map
= (isl_map
**)entry
;
1614 *map
= isl_map_from_basic_map(isl_map_polyhedral_hull(*map
));
1616 return *map
? isl_stat_ok
: isl_stat_error
;
1619 __isl_give isl_union_map
*isl_union_map_polyhedral_hull(
1620 __isl_take isl_union_map
*umap
)
1622 return un_op(umap
, &polyhedral_entry
);
1625 __isl_give isl_union_set
*isl_union_set_polyhedral_hull(
1626 __isl_take isl_union_set
*uset
)
1628 return isl_union_map_polyhedral_hull(uset
);
1631 static isl_stat
simple_entry(void **entry
, void *user
)
1633 isl_map
**map
= (isl_map
**)entry
;
1635 *map
= isl_map_from_basic_map(isl_map_simple_hull(*map
));
1637 return *map
? isl_stat_ok
: isl_stat_error
;
1640 __isl_give isl_union_map
*isl_union_map_simple_hull(
1641 __isl_take isl_union_map
*umap
)
1643 return un_op(umap
, &simple_entry
);
1646 __isl_give isl_union_set
*isl_union_set_simple_hull(
1647 __isl_take isl_union_set
*uset
)
1649 return isl_union_map_simple_hull(uset
);
1652 static isl_stat
inplace_entry(void **entry
, void *user
)
1654 __isl_give isl_map
*(*fn
)(__isl_take isl_map
*);
1655 isl_map
**map
= (isl_map
**)entry
;
1658 fn
= *(__isl_give isl_map
*(**)(__isl_take isl_map
*)) user
;
1659 copy
= fn(isl_map_copy(*map
));
1661 return isl_stat_error
;
1669 static __isl_give isl_union_map
*inplace(__isl_take isl_union_map
*umap
,
1670 __isl_give isl_map
*(*fn
)(__isl_take isl_map
*))
1675 if (isl_hash_table_foreach(umap
->dim
->ctx
, &umap
->table
,
1676 &inplace_entry
, &fn
) < 0)
1681 isl_union_map_free(umap
);
1685 /* Remove redundant constraints in each of the basic maps of "umap".
1686 * Since removing redundant constraints does not change the meaning
1687 * or the space, the operation can be performed in-place.
1689 __isl_give isl_union_map
*isl_union_map_remove_redundancies(
1690 __isl_take isl_union_map
*umap
)
1692 return inplace(umap
, &isl_map_remove_redundancies
);
1695 /* Remove redundant constraints in each of the basic sets of "uset".
1697 __isl_give isl_union_set
*isl_union_set_remove_redundancies(
1698 __isl_take isl_union_set
*uset
)
1700 return isl_union_map_remove_redundancies(uset
);
1703 __isl_give isl_union_map
*isl_union_map_coalesce(
1704 __isl_take isl_union_map
*umap
)
1706 return inplace(umap
, &isl_map_coalesce
);
1709 __isl_give isl_union_set
*isl_union_set_coalesce(
1710 __isl_take isl_union_set
*uset
)
1712 return isl_union_map_coalesce(uset
);
1715 __isl_give isl_union_map
*isl_union_map_detect_equalities(
1716 __isl_take isl_union_map
*umap
)
1718 return inplace(umap
, &isl_map_detect_equalities
);
1721 __isl_give isl_union_set
*isl_union_set_detect_equalities(
1722 __isl_take isl_union_set
*uset
)
1724 return isl_union_map_detect_equalities(uset
);
1727 __isl_give isl_union_map
*isl_union_map_compute_divs(
1728 __isl_take isl_union_map
*umap
)
1730 return inplace(umap
, &isl_map_compute_divs
);
1733 __isl_give isl_union_set
*isl_union_set_compute_divs(
1734 __isl_take isl_union_set
*uset
)
1736 return isl_union_map_compute_divs(uset
);
1739 static isl_stat
lexmin_entry(void **entry
, void *user
)
1741 isl_map
**map
= (isl_map
**)entry
;
1743 *map
= isl_map_lexmin(*map
);
1745 return *map
? isl_stat_ok
: isl_stat_error
;
1748 __isl_give isl_union_map
*isl_union_map_lexmin(
1749 __isl_take isl_union_map
*umap
)
1751 return un_op(umap
, &lexmin_entry
);
1754 __isl_give isl_union_set
*isl_union_set_lexmin(
1755 __isl_take isl_union_set
*uset
)
1757 return isl_union_map_lexmin(uset
);
1760 static isl_stat
lexmax_entry(void **entry
, void *user
)
1762 isl_map
**map
= (isl_map
**)entry
;
1764 *map
= isl_map_lexmax(*map
);
1766 return *map
? isl_stat_ok
: isl_stat_error
;
1769 __isl_give isl_union_map
*isl_union_map_lexmax(
1770 __isl_take isl_union_map
*umap
)
1772 return un_op(umap
, &lexmax_entry
);
1775 __isl_give isl_union_set
*isl_union_set_lexmax(
1776 __isl_take isl_union_set
*uset
)
1778 return isl_union_map_lexmax(uset
);
1781 static isl_stat
universe_entry(void **entry
, void *user
)
1783 isl_map
*map
= *entry
;
1784 isl_union_map
**res
= user
;
1786 map
= isl_map_universe(isl_map_get_space(map
));
1787 *res
= isl_union_map_add_map(*res
, map
);
1792 __isl_give isl_union_map
*isl_union_map_universe(__isl_take isl_union_map
*umap
)
1794 return cond_un_op(umap
, &universe_entry
);
1797 __isl_give isl_union_set
*isl_union_set_universe(__isl_take isl_union_set
*uset
)
1799 return isl_union_map_universe(uset
);
1802 static isl_stat
reverse_entry(void **entry
, void *user
)
1804 isl_map
*map
= *entry
;
1805 isl_union_map
**res
= user
;
1807 *res
= isl_union_map_add_map(*res
, isl_map_reverse(isl_map_copy(map
)));
1812 __isl_give isl_union_map
*isl_union_map_reverse(__isl_take isl_union_map
*umap
)
1814 return cond_un_op(umap
, &reverse_entry
);
1817 static isl_stat
params_entry(void **entry
, void *user
)
1819 isl_map
*map
= *entry
;
1820 isl_union_set
**res
= user
;
1822 *res
= isl_union_set_add_set(*res
, isl_map_params(isl_map_copy(map
)));
1827 /* Compute the parameter domain of the given union map.
1829 __isl_give isl_set
*isl_union_map_params(__isl_take isl_union_map
*umap
)
1833 empty
= isl_union_map_is_empty(umap
);
1838 space
= isl_union_map_get_space(umap
);
1839 isl_union_map_free(umap
);
1840 return isl_set_empty(space
);
1842 return isl_set_from_union_set(cond_un_op(umap
, ¶ms_entry
));
1844 isl_union_map_free(umap
);
1848 /* Compute the parameter domain of the given union set.
1850 __isl_give isl_set
*isl_union_set_params(__isl_take isl_union_set
*uset
)
1852 return isl_union_map_params(uset
);
1855 static isl_stat
domain_entry(void **entry
, void *user
)
1857 isl_map
*map
= *entry
;
1858 isl_union_set
**res
= user
;
1860 *res
= isl_union_set_add_set(*res
, isl_map_domain(isl_map_copy(map
)));
1865 __isl_give isl_union_set
*isl_union_map_domain(__isl_take isl_union_map
*umap
)
1867 return cond_un_op(umap
, &domain_entry
);
1870 static isl_stat
range_entry(void **entry
, void *user
)
1872 isl_map
*map
= *entry
;
1873 isl_union_set
**res
= user
;
1875 *res
= isl_union_set_add_set(*res
, isl_map_range(isl_map_copy(map
)));
1880 __isl_give isl_union_set
*isl_union_map_range(__isl_take isl_union_map
*umap
)
1882 return cond_un_op(umap
, &range_entry
);
1885 static isl_stat
domain_map_entry(void **entry
, void *user
)
1887 isl_map
*map
= *entry
;
1888 isl_union_set
**res
= user
;
1890 *res
= isl_union_map_add_map(*res
,
1891 isl_map_domain_map(isl_map_copy(map
)));
1896 __isl_give isl_union_map
*isl_union_map_domain_map(
1897 __isl_take isl_union_map
*umap
)
1899 return cond_un_op(umap
, &domain_map_entry
);
1902 /* Construct an isl_pw_multi_aff that maps "map" to its domain and
1903 * add the result to "res".
1905 static isl_stat
domain_map_upma(__isl_take isl_map
*map
, void *user
)
1907 isl_union_pw_multi_aff
**res
= user
;
1909 isl_pw_multi_aff
*pma
;
1911 ma
= isl_multi_aff_domain_map(isl_map_get_space(map
));
1912 pma
= isl_pw_multi_aff_alloc(isl_map_wrap(map
), ma
);
1913 *res
= isl_union_pw_multi_aff_add_pw_multi_aff(*res
, pma
);
1915 return *res
? isl_stat_ok
: isl_stat_error
;
1919 /* Return an isl_union_pw_multi_aff that maps a wrapped copy of "umap"
1922 __isl_give isl_union_pw_multi_aff
*isl_union_map_domain_map_union_pw_multi_aff(
1923 __isl_take isl_union_map
*umap
)
1925 isl_union_pw_multi_aff
*res
;
1927 res
= isl_union_pw_multi_aff_empty(isl_union_map_get_space(umap
));
1928 if (isl_union_map_foreach_map(umap
, &domain_map_upma
, &res
) < 0)
1929 res
= isl_union_pw_multi_aff_free(res
);
1931 isl_union_map_free(umap
);
1935 static isl_stat
range_map_entry(void **entry
, void *user
)
1937 isl_map
*map
= *entry
;
1938 isl_union_set
**res
= user
;
1940 *res
= isl_union_map_add_map(*res
,
1941 isl_map_range_map(isl_map_copy(map
)));
1946 __isl_give isl_union_map
*isl_union_map_range_map(
1947 __isl_take isl_union_map
*umap
)
1949 return cond_un_op(umap
, &range_map_entry
);
1952 /* Check if "set" is of the form A[B -> C].
1953 * If so, add A[B -> C] -> B to "res".
1955 static isl_stat
wrapped_domain_map_entry(void **entry
, void *user
)
1957 isl_set
*set
= *entry
;
1958 isl_union_set
**res
= user
;
1961 wrapping
= isl_set_is_wrapping(set
);
1963 return isl_stat_error
;
1967 *res
= isl_union_map_add_map(*res
,
1968 isl_set_wrapped_domain_map(isl_set_copy(set
)));
1973 /* Given a collection of wrapped maps of the form A[B -> C],
1974 * return the collection of maps A[B -> C] -> B.
1976 __isl_give isl_union_map
*isl_union_set_wrapped_domain_map(
1977 __isl_take isl_union_set
*uset
)
1979 return cond_un_op(uset
, &wrapped_domain_map_entry
);
1982 static isl_stat
deltas_entry(void **entry
, void *user
)
1984 isl_map
*map
= *entry
;
1985 isl_union_set
**res
= user
;
1987 if (!isl_space_tuple_is_equal(map
->dim
, isl_dim_in
,
1988 map
->dim
, isl_dim_out
))
1991 *res
= isl_union_set_add_set(*res
, isl_map_deltas(isl_map_copy(map
)));
1996 __isl_give isl_union_set
*isl_union_map_deltas(__isl_take isl_union_map
*umap
)
1998 return cond_un_op(umap
, &deltas_entry
);
2001 static isl_stat
deltas_map_entry(void **entry
, void *user
)
2003 isl_map
*map
= *entry
;
2004 isl_union_map
**res
= user
;
2006 if (!isl_space_tuple_is_equal(map
->dim
, isl_dim_in
,
2007 map
->dim
, isl_dim_out
))
2010 *res
= isl_union_map_add_map(*res
,
2011 isl_map_deltas_map(isl_map_copy(map
)));
2016 __isl_give isl_union_map
*isl_union_map_deltas_map(
2017 __isl_take isl_union_map
*umap
)
2019 return cond_un_op(umap
, &deltas_map_entry
);
2022 static isl_stat
identity_entry(void **entry
, void *user
)
2024 isl_set
*set
= *entry
;
2025 isl_union_map
**res
= user
;
2027 *res
= isl_union_map_add_map(*res
, isl_set_identity(isl_set_copy(set
)));
2032 __isl_give isl_union_map
*isl_union_set_identity(__isl_take isl_union_set
*uset
)
2034 return cond_un_op(uset
, &identity_entry
);
2037 /* Construct an identity isl_pw_multi_aff on "set" and add it to *res.
2039 static isl_stat
identity_upma(__isl_take isl_set
*set
, void *user
)
2041 isl_union_pw_multi_aff
**res
= user
;
2043 isl_pw_multi_aff
*pma
;
2045 space
= isl_space_map_from_set(isl_set_get_space(set
));
2046 pma
= isl_pw_multi_aff_identity(space
);
2047 pma
= isl_pw_multi_aff_intersect_domain(pma
, set
);
2048 *res
= isl_union_pw_multi_aff_add_pw_multi_aff(*res
, pma
);
2050 return *res
? isl_stat_ok
: isl_stat_error
;
2053 /* Return an identity function on "uset" in the form
2054 * of an isl_union_pw_multi_aff.
2056 __isl_give isl_union_pw_multi_aff
*isl_union_set_identity_union_pw_multi_aff(
2057 __isl_take isl_union_set
*uset
)
2059 isl_union_pw_multi_aff
*res
;
2061 res
= isl_union_pw_multi_aff_empty(isl_union_set_get_space(uset
));
2062 if (isl_union_set_foreach_set(uset
, &identity_upma
, &res
) < 0)
2063 res
= isl_union_pw_multi_aff_free(res
);
2065 isl_union_set_free(uset
);
2069 /* If "map" is of the form [A -> B] -> C, then add A -> C to "res".
2071 static isl_stat
domain_factor_domain_entry(void **entry
, void *user
)
2073 isl_map
*map
= *entry
;
2074 isl_union_map
**res
= user
;
2076 if (!isl_map_domain_is_wrapping(map
))
2079 *res
= isl_union_map_add_map(*res
,
2080 isl_map_domain_factor_domain(isl_map_copy(map
)));
2082 return *res
? isl_stat_ok
: isl_stat_error
;
2085 /* For each map in "umap" of the form [A -> B] -> C,
2086 * construct the map A -> C and collect the results.
2088 __isl_give isl_union_map
*isl_union_map_domain_factor_domain(
2089 __isl_take isl_union_map
*umap
)
2091 return cond_un_op(umap
, &domain_factor_domain_entry
);
2094 /* If "map" is of the form [A -> B] -> C, then add B -> C to "res".
2096 static isl_stat
domain_factor_range_entry(void **entry
, void *user
)
2098 isl_map
*map
= *entry
;
2099 isl_union_map
**res
= user
;
2101 if (!isl_map_domain_is_wrapping(map
))
2104 *res
= isl_union_map_add_map(*res
,
2105 isl_map_domain_factor_range(isl_map_copy(map
)));
2107 return *res
? isl_stat_ok
: isl_stat_error
;
2110 /* For each map in "umap" of the form [A -> B] -> C,
2111 * construct the map B -> C and collect the results.
2113 __isl_give isl_union_map
*isl_union_map_domain_factor_range(
2114 __isl_take isl_union_map
*umap
)
2116 return cond_un_op(umap
, &domain_factor_range_entry
);
2119 /* If "map" is of the form A -> [B -> C], then add A -> B to "res".
2121 static isl_stat
range_factor_domain_entry(void **entry
, void *user
)
2123 isl_map
*map
= *entry
;
2124 isl_union_map
**res
= user
;
2126 if (!isl_map_range_is_wrapping(map
))
2129 *res
= isl_union_map_add_map(*res
,
2130 isl_map_range_factor_domain(isl_map_copy(map
)));
2132 return *res
? isl_stat_ok
: isl_stat_error
;
2135 /* For each map in "umap" of the form A -> [B -> C],
2136 * construct the map A -> B and collect the results.
2138 __isl_give isl_union_map
*isl_union_map_range_factor_domain(
2139 __isl_take isl_union_map
*umap
)
2141 return cond_un_op(umap
, &range_factor_domain_entry
);
2144 /* If "map" is of the form A -> [B -> C], then add A -> C to "res".
2146 static isl_stat
range_factor_range_entry(void **entry
, void *user
)
2148 isl_map
*map
= *entry
;
2149 isl_union_map
**res
= user
;
2151 if (!isl_map_range_is_wrapping(map
))
2154 *res
= isl_union_map_add_map(*res
,
2155 isl_map_range_factor_range(isl_map_copy(map
)));
2157 return *res
? isl_stat_ok
: isl_stat_error
;
2160 /* For each map in "umap" of the form A -> [B -> C],
2161 * construct the map A -> C and collect the results.
2163 __isl_give isl_union_map
*isl_union_map_range_factor_range(
2164 __isl_take isl_union_map
*umap
)
2166 return cond_un_op(umap
, &range_factor_range_entry
);
2169 /* If "map" is of the form [A -> B] -> [C -> D], then add A -> C to "res".
2171 static isl_stat
factor_domain_entry(void **entry
, void *user
)
2173 isl_map
*map
= *entry
;
2174 isl_union_map
**res
= user
;
2176 if (!isl_map_domain_is_wrapping(map
) || !isl_map_range_is_wrapping(map
))
2179 *res
= isl_union_map_add_map(*res
,
2180 isl_map_factor_domain(isl_map_copy(map
)));
2182 return *res
? isl_stat_ok
: isl_stat_error
;
2185 /* For each map in "umap" of the form [A -> B] -> [C -> D],
2186 * construct the map A -> C and collect the results.
2188 __isl_give isl_union_map
*isl_union_map_factor_domain(
2189 __isl_take isl_union_map
*umap
)
2191 return cond_un_op(umap
, &factor_domain_entry
);
2194 /* If "map" is of the form [A -> B] -> [C -> D], then add B -> D to "res".
2196 static isl_stat
factor_range_entry(void **entry
, void *user
)
2198 isl_map
*map
= *entry
;
2199 isl_union_map
**res
= user
;
2201 if (!isl_map_domain_is_wrapping(map
) || !isl_map_range_is_wrapping(map
))
2204 *res
= isl_union_map_add_map(*res
,
2205 isl_map_factor_range(isl_map_copy(map
)));
2207 return *res
? isl_stat_ok
: isl_stat_error
;
2210 /* For each map in "umap" of the form [A -> B] -> [C -> D],
2211 * construct the map B -> D and collect the results.
2213 __isl_give isl_union_map
*isl_union_map_factor_range(
2214 __isl_take isl_union_map
*umap
)
2216 return cond_un_op(umap
, &factor_range_entry
);
2219 static isl_stat
unwrap_entry(void **entry
, void *user
)
2221 isl_set
*set
= *entry
;
2222 isl_union_set
**res
= user
;
2224 if (!isl_set_is_wrapping(set
))
2227 *res
= isl_union_map_add_map(*res
, isl_set_unwrap(isl_set_copy(set
)));
2232 __isl_give isl_union_map
*isl_union_set_unwrap(__isl_take isl_union_set
*uset
)
2234 return cond_un_op(uset
, &unwrap_entry
);
2237 static isl_stat
wrap_entry(void **entry
, void *user
)
2239 isl_map
*map
= *entry
;
2240 isl_union_set
**res
= user
;
2242 *res
= isl_union_set_add_set(*res
, isl_map_wrap(isl_map_copy(map
)));
2247 __isl_give isl_union_set
*isl_union_map_wrap(__isl_take isl_union_map
*umap
)
2249 return cond_un_op(umap
, &wrap_entry
);
2252 struct isl_union_map_is_subset_data
{
2253 isl_union_map
*umap2
;
2257 static isl_stat
is_subset_entry(void **entry
, void *user
)
2259 struct isl_union_map_is_subset_data
*data
= user
;
2261 struct isl_hash_table_entry
*entry2
;
2262 isl_map
*map
= *entry
;
2264 hash
= isl_space_get_hash(map
->dim
);
2265 entry2
= isl_hash_table_find(data
->umap2
->dim
->ctx
, &data
->umap2
->table
,
2266 hash
, &has_dim
, map
->dim
, 0);
2268 int empty
= isl_map_is_empty(map
);
2270 return isl_stat_error
;
2273 data
->is_subset
= 0;
2274 return isl_stat_error
;
2277 data
->is_subset
= isl_map_is_subset(map
, entry2
->data
);
2278 if (data
->is_subset
< 0 || !data
->is_subset
)
2279 return isl_stat_error
;
2284 isl_bool
isl_union_map_is_subset(__isl_keep isl_union_map
*umap1
,
2285 __isl_keep isl_union_map
*umap2
)
2287 struct isl_union_map_is_subset_data data
= { NULL
, isl_bool_true
};
2289 umap1
= isl_union_map_copy(umap1
);
2290 umap2
= isl_union_map_copy(umap2
);
2291 umap1
= isl_union_map_align_params(umap1
, isl_union_map_get_space(umap2
));
2292 umap2
= isl_union_map_align_params(umap2
, isl_union_map_get_space(umap1
));
2294 if (!umap1
|| !umap2
)
2298 if (isl_hash_table_foreach(umap1
->dim
->ctx
, &umap1
->table
,
2299 &is_subset_entry
, &data
) < 0 &&
2303 isl_union_map_free(umap1
);
2304 isl_union_map_free(umap2
);
2306 return data
.is_subset
;
2308 isl_union_map_free(umap1
);
2309 isl_union_map_free(umap2
);
2310 return isl_bool_error
;
2313 isl_bool
isl_union_set_is_subset(__isl_keep isl_union_set
*uset1
,
2314 __isl_keep isl_union_set
*uset2
)
2316 return isl_union_map_is_subset(uset1
, uset2
);
2319 isl_bool
isl_union_map_is_equal(__isl_keep isl_union_map
*umap1
,
2320 __isl_keep isl_union_map
*umap2
)
2324 if (!umap1
|| !umap2
)
2325 return isl_bool_error
;
2326 is_subset
= isl_union_map_is_subset(umap1
, umap2
);
2327 if (is_subset
!= isl_bool_true
)
2329 is_subset
= isl_union_map_is_subset(umap2
, umap1
);
2333 isl_bool
isl_union_set_is_equal(__isl_keep isl_union_set
*uset1
,
2334 __isl_keep isl_union_set
*uset2
)
2336 return isl_union_map_is_equal(uset1
, uset2
);
2339 isl_bool
isl_union_map_is_strict_subset(__isl_keep isl_union_map
*umap1
,
2340 __isl_keep isl_union_map
*umap2
)
2344 if (!umap1
|| !umap2
)
2345 return isl_bool_error
;
2346 is_subset
= isl_union_map_is_subset(umap1
, umap2
);
2347 if (is_subset
!= isl_bool_true
)
2349 is_subset
= isl_union_map_is_subset(umap2
, umap1
);
2350 if (is_subset
== isl_bool_error
)
2355 isl_bool
isl_union_set_is_strict_subset(__isl_keep isl_union_set
*uset1
,
2356 __isl_keep isl_union_set
*uset2
)
2358 return isl_union_map_is_strict_subset(uset1
, uset2
);
2361 /* Internal data structure for isl_union_map_is_disjoint.
2362 * umap2 is the union map with which we are comparing.
2363 * is_disjoint is initialized to 1 and is set to 0 as soon
2364 * as the union maps turn out not to be disjoint.
2366 struct isl_union_map_is_disjoint_data
{
2367 isl_union_map
*umap2
;
2368 isl_bool is_disjoint
;
2371 /* Check if "map" is disjoint from data->umap2 and abort
2372 * the search if it is not.
2374 static isl_stat
is_disjoint_entry(void **entry
, void *user
)
2376 struct isl_union_map_is_disjoint_data
*data
= user
;
2378 struct isl_hash_table_entry
*entry2
;
2379 isl_map
*map
= *entry
;
2381 hash
= isl_space_get_hash(map
->dim
);
2382 entry2
= isl_hash_table_find(data
->umap2
->dim
->ctx
, &data
->umap2
->table
,
2383 hash
, &has_dim
, map
->dim
, 0);
2387 data
->is_disjoint
= isl_map_is_disjoint(map
, entry2
->data
);
2388 if (data
->is_disjoint
< 0 || !data
->is_disjoint
)
2389 return isl_stat_error
;
2394 /* Are "umap1" and "umap2" disjoint?
2396 isl_bool
isl_union_map_is_disjoint(__isl_keep isl_union_map
*umap1
,
2397 __isl_keep isl_union_map
*umap2
)
2399 struct isl_union_map_is_disjoint_data data
= { NULL
, isl_bool_true
};
2401 umap1
= isl_union_map_copy(umap1
);
2402 umap2
= isl_union_map_copy(umap2
);
2403 umap1
= isl_union_map_align_params(umap1
,
2404 isl_union_map_get_space(umap2
));
2405 umap2
= isl_union_map_align_params(umap2
,
2406 isl_union_map_get_space(umap1
));
2408 if (!umap1
|| !umap2
)
2412 if (isl_hash_table_foreach(umap1
->dim
->ctx
, &umap1
->table
,
2413 &is_disjoint_entry
, &data
) < 0 &&
2417 isl_union_map_free(umap1
);
2418 isl_union_map_free(umap2
);
2420 return data
.is_disjoint
;
2422 isl_union_map_free(umap1
);
2423 isl_union_map_free(umap2
);
2424 return isl_bool_error
;
2427 /* Are "uset1" and "uset2" disjoint?
2429 isl_bool
isl_union_set_is_disjoint(__isl_keep isl_union_set
*uset1
,
2430 __isl_keep isl_union_set
*uset2
)
2432 return isl_union_map_is_disjoint(uset1
, uset2
);
2435 static isl_stat
sample_entry(void **entry
, void *user
)
2437 isl_basic_map
**sample
= (isl_basic_map
**)user
;
2438 isl_map
*map
= *entry
;
2440 *sample
= isl_map_sample(isl_map_copy(map
));
2442 return isl_stat_error
;
2443 if (!isl_basic_map_plain_is_empty(*sample
))
2444 return isl_stat_error
;
2448 __isl_give isl_basic_map
*isl_union_map_sample(__isl_take isl_union_map
*umap
)
2450 isl_basic_map
*sample
= NULL
;
2455 if (isl_hash_table_foreach(umap
->dim
->ctx
, &umap
->table
,
2456 &sample_entry
, &sample
) < 0 &&
2461 sample
= isl_basic_map_empty(isl_union_map_get_space(umap
));
2463 isl_union_map_free(umap
);
2467 isl_union_map_free(umap
);
2471 __isl_give isl_basic_set
*isl_union_set_sample(__isl_take isl_union_set
*uset
)
2473 return bset_from_bmap(isl_union_map_sample(uset
));
2476 /* Return an element in "uset" in the form of an isl_point.
2477 * Return a void isl_point if "uset" is empty.
2479 __isl_give isl_point
*isl_union_set_sample_point(__isl_take isl_union_set
*uset
)
2481 return isl_basic_set_sample_point(isl_union_set_sample(uset
));
2484 struct isl_forall_data
{
2486 isl_bool (*fn
)(__isl_keep isl_map
*map
);
2489 static isl_stat
forall_entry(void **entry
, void *user
)
2491 struct isl_forall_data
*data
= user
;
2492 isl_map
*map
= *entry
;
2494 data
->res
= data
->fn(map
);
2496 return isl_stat_error
;
2499 return isl_stat_error
;
2504 static isl_bool
union_map_forall(__isl_keep isl_union_map
*umap
,
2505 isl_bool (*fn
)(__isl_keep isl_map
*map
))
2507 struct isl_forall_data data
= { isl_bool_true
, fn
};
2510 return isl_bool_error
;
2512 if (isl_hash_table_foreach(umap
->dim
->ctx
, &umap
->table
,
2513 &forall_entry
, &data
) < 0 && data
.res
)
2514 return isl_bool_error
;
2519 struct isl_forall_user_data
{
2521 isl_bool (*fn
)(__isl_keep isl_map
*map
, void *user
);
2525 static isl_stat
forall_user_entry(void **entry
, void *user
)
2527 struct isl_forall_user_data
*data
= user
;
2528 isl_map
*map
= *entry
;
2530 data
->res
= data
->fn(map
, data
->user
);
2532 return isl_stat_error
;
2535 return isl_stat_error
;
2540 /* Check if fn(map, user) returns true for all maps "map" in umap.
2542 static isl_bool
union_map_forall_user(__isl_keep isl_union_map
*umap
,
2543 isl_bool (*fn
)(__isl_keep isl_map
*map
, void *user
), void *user
)
2545 struct isl_forall_user_data data
= { isl_bool_true
, fn
, user
};
2548 return isl_bool_error
;
2550 if (isl_hash_table_foreach(umap
->dim
->ctx
, &umap
->table
,
2551 &forall_user_entry
, &data
) < 0 && data
.res
)
2552 return isl_bool_error
;
2557 isl_bool
isl_union_map_is_empty(__isl_keep isl_union_map
*umap
)
2559 return union_map_forall(umap
, &isl_map_is_empty
);
2562 isl_bool
isl_union_set_is_empty(__isl_keep isl_union_set
*uset
)
2564 return isl_union_map_is_empty(uset
);
2567 static isl_bool
is_subset_of_identity(__isl_keep isl_map
*map
)
2574 return isl_bool_error
;
2576 if (!isl_space_tuple_is_equal(map
->dim
, isl_dim_in
,
2577 map
->dim
, isl_dim_out
))
2578 return isl_bool_false
;
2580 dim
= isl_map_get_space(map
);
2581 id
= isl_map_identity(dim
);
2583 is_subset
= isl_map_is_subset(map
, id
);
2590 /* Given an isl_union_map that consists of a single map, check
2591 * if it is single-valued.
2593 static isl_bool
single_map_is_single_valued(__isl_keep isl_union_map
*umap
)
2598 umap
= isl_union_map_copy(umap
);
2599 map
= isl_map_from_union_map(umap
);
2600 sv
= isl_map_is_single_valued(map
);
2606 /* Internal data structure for single_valued_on_domain.
2608 * "umap" is the union map to be tested.
2609 * "sv" is set to 1 as long as "umap" may still be single-valued.
2611 struct isl_union_map_is_sv_data
{
2612 isl_union_map
*umap
;
2616 /* Check if the data->umap is single-valued on "set".
2618 * If data->umap consists of a single map on "set", then test it
2621 * Otherwise, compute
2625 * check if the result is a subset of the identity mapping and
2626 * store the result in data->sv.
2628 * Terminate as soon as data->umap has been determined not to
2631 static isl_stat
single_valued_on_domain(__isl_take isl_set
*set
, void *user
)
2633 struct isl_union_map_is_sv_data
*data
= user
;
2634 isl_union_map
*umap
, *test
;
2636 umap
= isl_union_map_copy(data
->umap
);
2637 umap
= isl_union_map_intersect_domain(umap
,
2638 isl_union_set_from_set(set
));
2640 if (isl_union_map_n_map(umap
) == 1) {
2641 data
->sv
= single_map_is_single_valued(umap
);
2642 isl_union_map_free(umap
);
2644 test
= isl_union_map_reverse(isl_union_map_copy(umap
));
2645 test
= isl_union_map_apply_range(test
, umap
);
2647 data
->sv
= union_map_forall(test
, &is_subset_of_identity
);
2649 isl_union_map_free(test
);
2652 if (data
->sv
< 0 || !data
->sv
)
2653 return isl_stat_error
;
2657 /* Check if the given map is single-valued.
2659 * If the union map consists of a single map, then test it as an isl_map.
2660 * Otherwise, check if the union map is single-valued on each of its
2663 isl_bool
isl_union_map_is_single_valued(__isl_keep isl_union_map
*umap
)
2665 isl_union_map
*universe
;
2666 isl_union_set
*domain
;
2667 struct isl_union_map_is_sv_data data
;
2669 if (isl_union_map_n_map(umap
) == 1)
2670 return single_map_is_single_valued(umap
);
2672 universe
= isl_union_map_universe(isl_union_map_copy(umap
));
2673 domain
= isl_union_map_domain(universe
);
2675 data
.sv
= isl_bool_true
;
2677 if (isl_union_set_foreach_set(domain
,
2678 &single_valued_on_domain
, &data
) < 0 && data
.sv
)
2679 data
.sv
= isl_bool_error
;
2680 isl_union_set_free(domain
);
2685 isl_bool
isl_union_map_is_injective(__isl_keep isl_union_map
*umap
)
2689 umap
= isl_union_map_copy(umap
);
2690 umap
= isl_union_map_reverse(umap
);
2691 in
= isl_union_map_is_single_valued(umap
);
2692 isl_union_map_free(umap
);
2697 /* Is "map" obviously not an identity relation because
2698 * it maps elements from one space to another space?
2699 * Update *non_identity accordingly.
2701 * In particular, if the domain and range spaces are the same,
2702 * then the map is not considered to obviously not be an identity relation.
2703 * Otherwise, the map is considered to obviously not be an identity relation
2704 * if it is is non-empty.
2706 * If "map" is determined to obviously not be an identity relation,
2707 * then the search is aborted.
2709 static isl_stat
map_plain_is_not_identity(__isl_take isl_map
*map
, void *user
)
2711 isl_bool
*non_identity
= user
;
2715 space
= isl_map_get_space(map
);
2716 equal
= isl_space_tuple_is_equal(space
, isl_dim_in
, space
, isl_dim_out
);
2717 if (equal
>= 0 && !equal
)
2718 *non_identity
= isl_bool_not(isl_map_is_empty(map
));
2720 *non_identity
= isl_bool_not(equal
);
2721 isl_space_free(space
);
2724 if (*non_identity
< 0 || *non_identity
)
2725 return isl_stat_error
;
2730 /* Is "umap" obviously not an identity relation because
2731 * it maps elements from one space to another space?
2733 * As soon as a map has been found that maps elements to a different space,
2734 * non_identity is changed and the search is aborted.
2736 static isl_bool
isl_union_map_plain_is_not_identity(
2737 __isl_keep isl_union_map
*umap
)
2739 isl_bool non_identity
;
2741 non_identity
= isl_bool_false
;
2742 if (isl_union_map_foreach_map(umap
, &map_plain_is_not_identity
,
2743 &non_identity
) < 0 &&
2744 non_identity
== isl_bool_false
)
2745 return isl_bool_error
;
2747 return non_identity
;
2750 /* Does "map" only map elements to themselves?
2751 * Update *identity accordingly.
2753 * If "map" is determined not to be an identity relation,
2754 * then the search is aborted.
2756 static isl_stat
map_is_identity(__isl_take isl_map
*map
, void *user
)
2758 isl_bool
*identity
= user
;
2760 *identity
= isl_map_is_identity(map
);
2763 if (*identity
< 0 || !*identity
)
2764 return isl_stat_error
;
2769 /* Does "umap" only map elements to themselves?
2771 * First check if there are any maps that map elements to different spaces.
2772 * If not, then check that all the maps (between identical spaces)
2773 * are identity relations.
2775 isl_bool
isl_union_map_is_identity(__isl_keep isl_union_map
*umap
)
2777 isl_bool non_identity
;
2780 non_identity
= isl_union_map_plain_is_not_identity(umap
);
2781 if (non_identity
< 0 || non_identity
)
2782 return isl_bool_not(non_identity
);
2784 identity
= isl_bool_true
;
2785 if (isl_union_map_foreach_map(umap
, &map_is_identity
, &identity
) < 0 &&
2786 identity
== isl_bool_true
)
2787 return isl_bool_error
;
2792 /* Represents a map that has a fixed value (v) for one of its
2794 * The map in this structure is not reference counted, so it
2795 * is only valid while the isl_union_map from which it was
2796 * obtained is still alive.
2798 struct isl_fixed_map
{
2803 static struct isl_fixed_map
*alloc_isl_fixed_map_array(isl_ctx
*ctx
,
2807 struct isl_fixed_map
*v
;
2809 v
= isl_calloc_array(ctx
, struct isl_fixed_map
, n
);
2812 for (i
= 0; i
< n
; ++i
)
2813 isl_int_init(v
[i
].v
);
2817 static void free_isl_fixed_map_array(struct isl_fixed_map
*v
, int n
)
2823 for (i
= 0; i
< n
; ++i
)
2824 isl_int_clear(v
[i
].v
);
2828 /* Compare the "v" field of two isl_fixed_map structs.
2830 static int qsort_fixed_map_cmp(const void *p1
, const void *p2
)
2832 const struct isl_fixed_map
*e1
= (const struct isl_fixed_map
*) p1
;
2833 const struct isl_fixed_map
*e2
= (const struct isl_fixed_map
*) p2
;
2835 return isl_int_cmp(e1
->v
, e2
->v
);
2838 /* Internal data structure used while checking whether all maps
2839 * in a union_map have a fixed value for a given output dimension.
2840 * v is the list of maps, with the fixed value for the dimension
2841 * n is the number of maps considered so far
2842 * pos is the output dimension under investigation
2844 struct isl_fixed_dim_data
{
2845 struct isl_fixed_map
*v
;
2850 static isl_bool
fixed_at_pos(__isl_keep isl_map
*map
, void *user
)
2852 struct isl_fixed_dim_data
*data
= user
;
2854 data
->v
[data
->n
].map
= map
;
2855 return isl_map_plain_is_fixed(map
, isl_dim_out
, data
->pos
,
2856 &data
->v
[data
->n
++].v
);
2859 static isl_bool
plain_injective_on_range(__isl_take isl_union_map
*umap
,
2860 int first
, int n_range
);
2862 /* Given a list of the maps, with their fixed values at output dimension "pos",
2863 * check whether the ranges of the maps form an obvious partition.
2865 * We first sort the maps according to their fixed values.
2866 * If all maps have a different value, then we know the ranges form
2868 * Otherwise, we collect the maps with the same fixed value and
2869 * check whether each such collection is obviously injective
2870 * based on later dimensions.
2872 static int separates(struct isl_fixed_map
*v
, int n
,
2873 __isl_take isl_space
*dim
, int pos
, int n_range
)
2880 qsort(v
, n
, sizeof(*v
), &qsort_fixed_map_cmp
);
2882 for (i
= 0; i
+ 1 < n
; ++i
) {
2884 isl_union_map
*part
;
2887 for (j
= i
+ 1; j
< n
; ++j
)
2888 if (isl_int_ne(v
[i
].v
, v
[j
].v
))
2894 part
= isl_union_map_alloc(isl_space_copy(dim
), j
- i
);
2895 for (k
= i
; k
< j
; ++k
)
2896 part
= isl_union_map_add_map(part
,
2897 isl_map_copy(v
[k
].map
));
2899 injective
= plain_injective_on_range(part
, pos
+ 1, n_range
);
2908 isl_space_free(dim
);
2909 free_isl_fixed_map_array(v
, n
);
2912 isl_space_free(dim
);
2913 free_isl_fixed_map_array(v
, n
);
2917 /* Check whether the maps in umap have obviously distinct ranges.
2918 * In particular, check for an output dimension in the range
2919 * [first,n_range) for which all maps have a fixed value
2920 * and then check if these values, possibly along with fixed values
2921 * at later dimensions, entail distinct ranges.
2923 static isl_bool
plain_injective_on_range(__isl_take isl_union_map
*umap
,
2924 int first
, int n_range
)
2928 struct isl_fixed_dim_data data
= { NULL
};
2930 ctx
= isl_union_map_get_ctx(umap
);
2932 n
= isl_union_map_n_map(umap
);
2937 isl_union_map_free(umap
);
2938 return isl_bool_true
;
2941 if (first
>= n_range
) {
2942 isl_union_map_free(umap
);
2943 return isl_bool_false
;
2946 data
.v
= alloc_isl_fixed_map_array(ctx
, n
);
2950 for (data
.pos
= first
; data
.pos
< n_range
; ++data
.pos
) {
2956 fixed
= union_map_forall_user(umap
, &fixed_at_pos
, &data
);
2961 dim
= isl_union_map_get_space(umap
);
2962 injective
= separates(data
.v
, n
, dim
, data
.pos
, n_range
);
2963 isl_union_map_free(umap
);
2967 free_isl_fixed_map_array(data
.v
, n
);
2968 isl_union_map_free(umap
);
2970 return isl_bool_false
;
2972 free_isl_fixed_map_array(data
.v
, n
);
2973 isl_union_map_free(umap
);
2974 return isl_bool_error
;
2977 /* Check whether the maps in umap that map to subsets of "ran"
2978 * have obviously distinct ranges.
2980 static isl_bool
plain_injective_on_range_wrap(__isl_keep isl_set
*ran
,
2983 isl_union_map
*umap
= user
;
2985 umap
= isl_union_map_copy(umap
);
2986 umap
= isl_union_map_intersect_range(umap
,
2987 isl_union_set_from_set(isl_set_copy(ran
)));
2988 return plain_injective_on_range(umap
, 0, isl_set_dim(ran
, isl_dim_set
));
2991 /* Check if the given union_map is obviously injective.
2993 * In particular, we first check if all individual maps are obviously
2994 * injective and then check if all the ranges of these maps are
2995 * obviously disjoint.
2997 isl_bool
isl_union_map_plain_is_injective(__isl_keep isl_union_map
*umap
)
3000 isl_union_map
*univ
;
3003 in
= union_map_forall(umap
, &isl_map_plain_is_injective
);
3005 return isl_bool_error
;
3007 return isl_bool_false
;
3009 univ
= isl_union_map_universe(isl_union_map_copy(umap
));
3010 ran
= isl_union_map_range(univ
);
3012 in
= union_map_forall_user(ran
, &plain_injective_on_range_wrap
, umap
);
3014 isl_union_set_free(ran
);
3019 isl_bool
isl_union_map_is_bijective(__isl_keep isl_union_map
*umap
)
3023 sv
= isl_union_map_is_single_valued(umap
);
3027 return isl_union_map_is_injective(umap
);
3030 static isl_stat
zip_entry(void **entry
, void *user
)
3032 isl_map
*map
= *entry
;
3033 isl_union_map
**res
= user
;
3035 if (!isl_map_can_zip(map
))
3038 *res
= isl_union_map_add_map(*res
, isl_map_zip(isl_map_copy(map
)));
3043 __isl_give isl_union_map
*isl_union_map_zip(__isl_take isl_union_map
*umap
)
3045 return cond_un_op(umap
, &zip_entry
);
3048 static isl_stat
uncurry_entry(void **entry
, void *user
)
3050 isl_map
*map
= *entry
;
3051 isl_union_map
**res
= user
;
3053 if (!isl_map_can_uncurry(map
))
3056 *res
= isl_union_map_add_map(*res
, isl_map_uncurry(isl_map_copy(map
)));
3061 /* Given a union map, take the maps of the form A -> (B -> C) and
3062 * return the union of the corresponding maps (A -> B) -> C.
3064 __isl_give isl_union_map
*isl_union_map_uncurry(__isl_take isl_union_map
*umap
)
3066 return cond_un_op(umap
, &uncurry_entry
);
3069 static isl_stat
curry_entry(void **entry
, void *user
)
3071 isl_map
*map
= *entry
;
3072 isl_union_map
**res
= user
;
3074 if (!isl_map_can_curry(map
))
3077 *res
= isl_union_map_add_map(*res
, isl_map_curry(isl_map_copy(map
)));
3082 /* Given a union map, take the maps of the form (A -> B) -> C and
3083 * return the union of the corresponding maps A -> (B -> C).
3085 __isl_give isl_union_map
*isl_union_map_curry(__isl_take isl_union_map
*umap
)
3087 return cond_un_op(umap
, &curry_entry
);
3090 /* If *entry is of the form A -> ((B -> C) -> D), then apply
3091 * isl_map_range_curry to it and add the result to *res.
3093 static isl_stat
range_curry_entry(void **entry
, void *user
)
3095 isl_map
*map
= *entry
;
3096 isl_union_map
**res
= user
;
3098 if (!isl_map_can_range_curry(map
))
3101 map
= isl_map_range_curry(isl_map_copy(map
));
3102 *res
= isl_union_map_add_map(*res
, map
);
3107 /* Given a union map, take the maps of the form A -> ((B -> C) -> D) and
3108 * return the union of the corresponding maps A -> (B -> (C -> D)).
3110 __isl_give isl_union_map
*isl_union_map_range_curry(
3111 __isl_take isl_union_map
*umap
)
3113 return cond_un_op(umap
, &range_curry_entry
);
3116 static isl_stat
lift_entry(void **entry
, void *user
)
3118 isl_set
*set
= *entry
;
3119 isl_union_set
**res
= user
;
3121 *res
= isl_union_set_add_set(*res
, isl_set_lift(isl_set_copy(set
)));
3126 __isl_give isl_union_set
*isl_union_set_lift(__isl_take isl_union_set
*uset
)
3128 return cond_un_op(uset
, &lift_entry
);
3131 static isl_stat
coefficients_entry(void **entry
, void *user
)
3133 isl_set
*set
= *entry
;
3134 isl_union_set
**res
= user
;
3136 set
= isl_set_copy(set
);
3137 set
= isl_set_from_basic_set(isl_set_coefficients(set
));
3138 *res
= isl_union_set_add_set(*res
, set
);
3143 __isl_give isl_union_set
*isl_union_set_coefficients(
3144 __isl_take isl_union_set
*uset
)
3153 ctx
= isl_union_set_get_ctx(uset
);
3154 dim
= isl_space_set_alloc(ctx
, 0, 0);
3155 res
= isl_union_map_alloc(dim
, uset
->table
.n
);
3156 if (isl_hash_table_foreach(uset
->dim
->ctx
, &uset
->table
,
3157 &coefficients_entry
, &res
) < 0)
3160 isl_union_set_free(uset
);
3163 isl_union_set_free(uset
);
3164 isl_union_set_free(res
);
3168 static isl_stat
solutions_entry(void **entry
, void *user
)
3170 isl_set
*set
= *entry
;
3171 isl_union_set
**res
= user
;
3173 set
= isl_set_copy(set
);
3174 set
= isl_set_from_basic_set(isl_set_solutions(set
));
3176 *res
= isl_union_set_from_set(set
);
3178 *res
= isl_union_set_add_set(*res
, set
);
3181 return isl_stat_error
;
3186 __isl_give isl_union_set
*isl_union_set_solutions(
3187 __isl_take isl_union_set
*uset
)
3189 isl_union_set
*res
= NULL
;
3194 if (uset
->table
.n
== 0) {
3195 res
= isl_union_set_empty(isl_union_set_get_space(uset
));
3196 isl_union_set_free(uset
);
3200 if (isl_hash_table_foreach(uset
->dim
->ctx
, &uset
->table
,
3201 &solutions_entry
, &res
) < 0)
3204 isl_union_set_free(uset
);
3207 isl_union_set_free(uset
);
3208 isl_union_set_free(res
);
3212 /* Is the domain space of "map" equal to "space"?
3214 static int domain_match(__isl_keep isl_map
*map
, __isl_keep isl_space
*space
)
3216 return isl_space_tuple_is_equal(map
->dim
, isl_dim_in
,
3217 space
, isl_dim_out
);
3220 /* Is the range space of "map" equal to "space"?
3222 static int range_match(__isl_keep isl_map
*map
, __isl_keep isl_space
*space
)
3224 return isl_space_tuple_is_equal(map
->dim
, isl_dim_out
,
3225 space
, isl_dim_out
);
3228 /* Is the set space of "map" equal to "space"?
3230 static int set_match(__isl_keep isl_map
*map
, __isl_keep isl_space
*space
)
3232 return isl_space_tuple_is_equal(map
->dim
, isl_dim_set
,
3233 space
, isl_dim_out
);
3236 /* Internal data structure for preimage_pw_multi_aff.
3238 * "pma" is the function under which the preimage should be taken.
3239 * "space" is the space of "pma".
3240 * "res" collects the results.
3241 * "fn" computes the preimage for a given map.
3242 * "match" returns true if "fn" can be called.
3244 struct isl_union_map_preimage_data
{
3246 isl_pw_multi_aff
*pma
;
3248 int (*match
)(__isl_keep isl_map
*map
, __isl_keep isl_space
*space
);
3249 __isl_give isl_map
*(*fn
)(__isl_take isl_map
*map
,
3250 __isl_take isl_pw_multi_aff
*pma
);
3253 /* Call data->fn to compute the preimage of the domain or range of *entry
3254 * under the function represented by data->pma, provided the domain/range
3255 * space of *entry matches the target space of data->pma
3256 * (as given by data->match), and add the result to data->res.
3258 static isl_stat
preimage_entry(void **entry
, void *user
)
3261 isl_map
*map
= *entry
;
3262 struct isl_union_map_preimage_data
*data
= user
;
3265 m
= data
->match(map
, data
->space
);
3267 return isl_stat_error
;
3271 map
= isl_map_copy(map
);
3272 map
= data
->fn(map
, isl_pw_multi_aff_copy(data
->pma
));
3274 empty
= isl_map_is_empty(map
);
3275 if (empty
< 0 || empty
) {
3277 return empty
< 0 ? isl_stat_error
: isl_stat_ok
;
3280 data
->res
= isl_union_map_add_map(data
->res
, map
);
3285 /* Compute the preimage of the domain or range of "umap" under the function
3286 * represented by "pma".
3287 * In other words, plug in "pma" in the domain or range of "umap".
3288 * The function "fn" performs the actual preimage computation on a map,
3289 * while "match" determines to which maps the function should be applied.
3291 static __isl_give isl_union_map
*preimage_pw_multi_aff(
3292 __isl_take isl_union_map
*umap
, __isl_take isl_pw_multi_aff
*pma
,
3293 int (*match
)(__isl_keep isl_map
*map
, __isl_keep isl_space
*space
),
3294 __isl_give isl_map
*(*fn
)(__isl_take isl_map
*map
,
3295 __isl_take isl_pw_multi_aff
*pma
))
3299 struct isl_union_map_preimage_data data
;
3301 umap
= isl_union_map_align_params(umap
,
3302 isl_pw_multi_aff_get_space(pma
));
3303 pma
= isl_pw_multi_aff_align_params(pma
, isl_union_map_get_space(umap
));
3308 ctx
= isl_union_map_get_ctx(umap
);
3309 space
= isl_union_map_get_space(umap
);
3310 data
.space
= isl_pw_multi_aff_get_space(pma
);
3312 data
.res
= isl_union_map_alloc(space
, umap
->table
.n
);
3315 if (isl_hash_table_foreach(ctx
, &umap
->table
, &preimage_entry
,
3317 data
.res
= isl_union_map_free(data
.res
);
3319 isl_space_free(data
.space
);
3320 isl_union_map_free(umap
);
3321 isl_pw_multi_aff_free(pma
);
3324 isl_union_map_free(umap
);
3325 isl_pw_multi_aff_free(pma
);
3329 /* Compute the preimage of the domain of "umap" under the function
3330 * represented by "pma".
3331 * In other words, plug in "pma" in the domain of "umap".
3332 * The result contains maps that live in the same spaces as the maps of "umap"
3333 * with domain space equal to the target space of "pma",
3334 * except that the domain has been replaced by the domain space of "pma".
3336 __isl_give isl_union_map
*isl_union_map_preimage_domain_pw_multi_aff(
3337 __isl_take isl_union_map
*umap
, __isl_take isl_pw_multi_aff
*pma
)
3339 return preimage_pw_multi_aff(umap
, pma
, &domain_match
,
3340 &isl_map_preimage_domain_pw_multi_aff
);
3343 /* Compute the preimage of the range of "umap" under the function
3344 * represented by "pma".
3345 * In other words, plug in "pma" in the range of "umap".
3346 * The result contains maps that live in the same spaces as the maps of "umap"
3347 * with range space equal to the target space of "pma",
3348 * except that the range has been replaced by the domain space of "pma".
3350 __isl_give isl_union_map
*isl_union_map_preimage_range_pw_multi_aff(
3351 __isl_take isl_union_map
*umap
, __isl_take isl_pw_multi_aff
*pma
)
3353 return preimage_pw_multi_aff(umap
, pma
, &range_match
,
3354 &isl_map_preimage_range_pw_multi_aff
);
3357 /* Compute the preimage of "uset" under the function represented by "pma".
3358 * In other words, plug in "pma" in "uset".
3359 * The result contains sets that live in the same spaces as the sets of "uset"
3360 * with space equal to the target space of "pma",
3361 * except that the space has been replaced by the domain space of "pma".
3363 __isl_give isl_union_set
*isl_union_set_preimage_pw_multi_aff(
3364 __isl_take isl_union_set
*uset
, __isl_take isl_pw_multi_aff
*pma
)
3366 return preimage_pw_multi_aff(uset
, pma
, &set_match
,
3367 &isl_set_preimage_pw_multi_aff
);
3370 /* Compute the preimage of the domain of "umap" under the function
3371 * represented by "ma".
3372 * In other words, plug in "ma" in the domain of "umap".
3373 * The result contains maps that live in the same spaces as the maps of "umap"
3374 * with domain space equal to the target space of "ma",
3375 * except that the domain has been replaced by the domain space of "ma".
3377 __isl_give isl_union_map
*isl_union_map_preimage_domain_multi_aff(
3378 __isl_take isl_union_map
*umap
, __isl_take isl_multi_aff
*ma
)
3380 return isl_union_map_preimage_domain_pw_multi_aff(umap
,
3381 isl_pw_multi_aff_from_multi_aff(ma
));
3384 /* Compute the preimage of the range of "umap" under the function
3385 * represented by "ma".
3386 * In other words, plug in "ma" in the range of "umap".
3387 * The result contains maps that live in the same spaces as the maps of "umap"
3388 * with range space equal to the target space of "ma",
3389 * except that the range has been replaced by the domain space of "ma".
3391 __isl_give isl_union_map
*isl_union_map_preimage_range_multi_aff(
3392 __isl_take isl_union_map
*umap
, __isl_take isl_multi_aff
*ma
)
3394 return isl_union_map_preimage_range_pw_multi_aff(umap
,
3395 isl_pw_multi_aff_from_multi_aff(ma
));
3398 /* Compute the preimage of "uset" under the function represented by "ma".
3399 * In other words, plug in "ma" in "uset".
3400 * The result contains sets that live in the same spaces as the sets of "uset"
3401 * with space equal to the target space of "ma",
3402 * except that the space has been replaced by the domain space of "ma".
3404 __isl_give isl_union_map
*isl_union_set_preimage_multi_aff(
3405 __isl_take isl_union_set
*uset
, __isl_take isl_multi_aff
*ma
)
3407 return isl_union_set_preimage_pw_multi_aff(uset
,
3408 isl_pw_multi_aff_from_multi_aff(ma
));
3411 /* Internal data structure for preimage_multi_pw_aff.
3413 * "mpa" is the function under which the preimage should be taken.
3414 * "space" is the space of "mpa".
3415 * "res" collects the results.
3416 * "fn" computes the preimage for a given map.
3417 * "match" returns true if "fn" can be called.
3419 struct isl_union_map_preimage_mpa_data
{
3421 isl_multi_pw_aff
*mpa
;
3423 int (*match
)(__isl_keep isl_map
*map
, __isl_keep isl_space
*space
);
3424 __isl_give isl_map
*(*fn
)(__isl_take isl_map
*map
,
3425 __isl_take isl_multi_pw_aff
*mpa
);
3428 /* Call data->fn to compute the preimage of the domain or range of *entry
3429 * under the function represented by data->mpa, provided the domain/range
3430 * space of *entry matches the target space of data->mpa
3431 * (as given by data->match), and add the result to data->res.
3433 static isl_stat
preimage_mpa_entry(void **entry
, void *user
)
3436 isl_map
*map
= *entry
;
3437 struct isl_union_map_preimage_mpa_data
*data
= user
;
3440 m
= data
->match(map
, data
->space
);
3442 return isl_stat_error
;
3446 map
= isl_map_copy(map
);
3447 map
= data
->fn(map
, isl_multi_pw_aff_copy(data
->mpa
));
3449 empty
= isl_map_is_empty(map
);
3450 if (empty
< 0 || empty
) {
3452 return empty
< 0 ? isl_stat_error
: isl_stat_ok
;
3455 data
->res
= isl_union_map_add_map(data
->res
, map
);
3460 /* Compute the preimage of the domain or range of "umap" under the function
3461 * represented by "mpa".
3462 * In other words, plug in "mpa" in the domain or range of "umap".
3463 * The function "fn" performs the actual preimage computation on a map,
3464 * while "match" determines to which maps the function should be applied.
3466 static __isl_give isl_union_map
*preimage_multi_pw_aff(
3467 __isl_take isl_union_map
*umap
, __isl_take isl_multi_pw_aff
*mpa
,
3468 int (*match
)(__isl_keep isl_map
*map
, __isl_keep isl_space
*space
),
3469 __isl_give isl_map
*(*fn
)(__isl_take isl_map
*map
,
3470 __isl_take isl_multi_pw_aff
*mpa
))
3474 struct isl_union_map_preimage_mpa_data data
;
3476 umap
= isl_union_map_align_params(umap
,
3477 isl_multi_pw_aff_get_space(mpa
));
3478 mpa
= isl_multi_pw_aff_align_params(mpa
, isl_union_map_get_space(umap
));
3483 ctx
= isl_union_map_get_ctx(umap
);
3484 space
= isl_union_map_get_space(umap
);
3485 data
.space
= isl_multi_pw_aff_get_space(mpa
);
3487 data
.res
= isl_union_map_alloc(space
, umap
->table
.n
);
3490 if (isl_hash_table_foreach(ctx
, &umap
->table
, &preimage_mpa_entry
,
3492 data
.res
= isl_union_map_free(data
.res
);
3494 isl_space_free(data
.space
);
3495 isl_union_map_free(umap
);
3496 isl_multi_pw_aff_free(mpa
);
3499 isl_union_map_free(umap
);
3500 isl_multi_pw_aff_free(mpa
);
3504 /* Compute the preimage of the domain of "umap" under the function
3505 * represented by "mpa".
3506 * In other words, plug in "mpa" in the domain of "umap".
3507 * The result contains maps that live in the same spaces as the maps of "umap"
3508 * with domain space equal to the target space of "mpa",
3509 * except that the domain has been replaced by the domain space of "mpa".
3511 __isl_give isl_union_map
*isl_union_map_preimage_domain_multi_pw_aff(
3512 __isl_take isl_union_map
*umap
, __isl_take isl_multi_pw_aff
*mpa
)
3514 return preimage_multi_pw_aff(umap
, mpa
, &domain_match
,
3515 &isl_map_preimage_domain_multi_pw_aff
);
3518 /* Internal data structure for preimage_upma.
3520 * "umap" is the map of which the preimage should be computed.
3521 * "res" collects the results.
3522 * "fn" computes the preimage for a given piecewise multi-affine function.
3524 struct isl_union_map_preimage_upma_data
{
3525 isl_union_map
*umap
;
3527 __isl_give isl_union_map
*(*fn
)(__isl_take isl_union_map
*umap
,
3528 __isl_take isl_pw_multi_aff
*pma
);
3531 /* Call data->fn to compute the preimage of the domain or range of data->umap
3532 * under the function represented by pma and add the result to data->res.
3534 static isl_stat
preimage_upma(__isl_take isl_pw_multi_aff
*pma
, void *user
)
3536 struct isl_union_map_preimage_upma_data
*data
= user
;
3537 isl_union_map
*umap
;
3539 umap
= isl_union_map_copy(data
->umap
);
3540 umap
= data
->fn(umap
, pma
);
3541 data
->res
= isl_union_map_union(data
->res
, umap
);
3543 return data
->res
? isl_stat_ok
: isl_stat_error
;
3546 /* Compute the preimage of the domain or range of "umap" under the function
3547 * represented by "upma".
3548 * In other words, plug in "upma" in the domain or range of "umap".
3549 * The function "fn" performs the actual preimage computation
3550 * on a piecewise multi-affine function.
3552 static __isl_give isl_union_map
*preimage_union_pw_multi_aff(
3553 __isl_take isl_union_map
*umap
,
3554 __isl_take isl_union_pw_multi_aff
*upma
,
3555 __isl_give isl_union_map
*(*fn
)(__isl_take isl_union_map
*umap
,
3556 __isl_take isl_pw_multi_aff
*pma
))
3558 struct isl_union_map_preimage_upma_data data
;
3561 data
.res
= isl_union_map_empty(isl_union_map_get_space(umap
));
3563 if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma
,
3564 &preimage_upma
, &data
) < 0)
3565 data
.res
= isl_union_map_free(data
.res
);
3567 isl_union_map_free(umap
);
3568 isl_union_pw_multi_aff_free(upma
);
3573 /* Compute the preimage of the domain of "umap" under the function
3574 * represented by "upma".
3575 * In other words, plug in "upma" in the domain of "umap".
3576 * The result contains maps that live in the same spaces as the maps of "umap"
3577 * with domain space equal to one of the target spaces of "upma",
3578 * except that the domain has been replaced by one of the the domain spaces that
3579 * corresponds to that target space of "upma".
3581 __isl_give isl_union_map
*isl_union_map_preimage_domain_union_pw_multi_aff(
3582 __isl_take isl_union_map
*umap
,
3583 __isl_take isl_union_pw_multi_aff
*upma
)
3585 return preimage_union_pw_multi_aff(umap
, upma
,
3586 &isl_union_map_preimage_domain_pw_multi_aff
);
3589 /* Compute the preimage of the range of "umap" under the function
3590 * represented by "upma".
3591 * In other words, plug in "upma" in the range of "umap".
3592 * The result contains maps that live in the same spaces as the maps of "umap"
3593 * with range space equal to one of the target spaces of "upma",
3594 * except that the range has been replaced by one of the the domain spaces that
3595 * corresponds to that target space of "upma".
3597 __isl_give isl_union_map
*isl_union_map_preimage_range_union_pw_multi_aff(
3598 __isl_take isl_union_map
*umap
,
3599 __isl_take isl_union_pw_multi_aff
*upma
)
3601 return preimage_union_pw_multi_aff(umap
, upma
,
3602 &isl_union_map_preimage_range_pw_multi_aff
);
3605 /* Compute the preimage of "uset" under the function represented by "upma".
3606 * In other words, plug in "upma" in the range of "uset".
3607 * The result contains sets that live in the same spaces as the sets of "uset"
3608 * with space equal to one of the target spaces of "upma",
3609 * except that the space has been replaced by one of the the domain spaces that
3610 * corresponds to that target space of "upma".
3612 __isl_give isl_union_set
*isl_union_set_preimage_union_pw_multi_aff(
3613 __isl_take isl_union_set
*uset
,
3614 __isl_take isl_union_pw_multi_aff
*upma
)
3616 return preimage_union_pw_multi_aff(uset
, upma
,
3617 &isl_union_set_preimage_pw_multi_aff
);
3620 /* Reset the user pointer on all identifiers of parameters and tuples
3621 * of the space of *entry.
3623 static isl_stat
reset_user(void **entry
, void *user
)
3625 isl_map
**map
= (isl_map
**)entry
;
3627 *map
= isl_map_reset_user(*map
);
3629 return *map
? isl_stat_ok
: isl_stat_error
;
3632 /* Reset the user pointer on all identifiers of parameters and tuples
3633 * of the spaces of "umap".
3635 __isl_give isl_union_map
*isl_union_map_reset_user(
3636 __isl_take isl_union_map
*umap
)
3638 umap
= isl_union_map_cow(umap
);
3641 umap
->dim
= isl_space_reset_user(umap
->dim
);
3643 return isl_union_map_free(umap
);
3644 umap
= un_op(umap
, &reset_user
);
3649 /* Reset the user pointer on all identifiers of parameters and tuples
3650 * of the spaces of "uset".
3652 __isl_give isl_union_set
*isl_union_set_reset_user(
3653 __isl_take isl_union_set
*uset
)
3655 return isl_union_map_reset_user(uset
);
3658 /* Internal data structure for isl_union_map_project_out.
3659 * "type", "first" and "n" are the arguments for the isl_map_project_out
3661 * "res" collects the results.
3663 struct isl_union_map_project_out_data
{
3664 enum isl_dim_type type
;
3671 /* Turn the data->n dimensions of type data->type, starting at data->first
3672 * into existentially quantified variables and add the result to data->res.
3674 static isl_stat
project_out(__isl_take isl_map
*map
, void *user
)
3676 struct isl_union_map_project_out_data
*data
= user
;
3678 map
= isl_map_project_out(map
, data
->type
, data
->first
, data
->n
);
3679 data
->res
= isl_union_map_add_map(data
->res
, map
);
3684 /* Turn the "n" dimensions of type "type", starting at "first"
3685 * into existentially quantified variables.
3686 * Since the space of an isl_union_map only contains parameters,
3687 * type is required to be equal to isl_dim_param.
3689 __isl_give isl_union_map
*isl_union_map_project_out(
3690 __isl_take isl_union_map
*umap
,
3691 enum isl_dim_type type
, unsigned first
, unsigned n
)
3694 struct isl_union_map_project_out_data data
= { type
, first
, n
};
3699 if (type
!= isl_dim_param
)
3700 isl_die(isl_union_map_get_ctx(umap
), isl_error_invalid
,
3701 "can only project out parameters",
3702 return isl_union_map_free(umap
));
3704 space
= isl_union_map_get_space(umap
);
3705 space
= isl_space_drop_dims(space
, type
, first
, n
);
3706 data
.res
= isl_union_map_empty(space
);
3707 if (isl_union_map_foreach_map(umap
, &project_out
, &data
) < 0)
3708 data
.res
= isl_union_map_free(data
.res
);
3710 isl_union_map_free(umap
);
3715 /* Turn the "n" dimensions of type "type", starting at "first"
3716 * into existentially quantified variables.
3717 * Since the space of an isl_union_set only contains parameters,
3718 * "type" is required to be equal to isl_dim_param.
3720 __isl_give isl_union_set
*isl_union_set_project_out(
3721 __isl_take isl_union_set
*uset
,
3722 enum isl_dim_type type
, unsigned first
, unsigned n
)
3724 return isl_union_map_project_out(uset
, type
, first
, n
);
3727 /* Internal data structure for isl_union_map_involves_dims.
3728 * "first" and "n" are the arguments for the isl_map_involves_dims calls.
3730 struct isl_union_map_involves_dims_data
{
3735 /* Does "map" _not_ involve the data->n parameters starting at data->first?
3737 static isl_bool
map_excludes(__isl_keep isl_map
*map
, void *user
)
3739 struct isl_union_map_involves_dims_data
*data
= user
;
3742 involves
= isl_map_involves_dims(map
,
3743 isl_dim_param
, data
->first
, data
->n
);
3745 return isl_bool_error
;
3749 /* Does "umap" involve any of the n parameters starting at first?
3750 * "type" is required to be set to isl_dim_param.
3752 * "umap" involves any of those parameters if any of its maps
3753 * involve the parameters. In other words, "umap" does not
3754 * involve any of the parameters if all its maps to not
3755 * involve the parameters.
3757 isl_bool
isl_union_map_involves_dims(__isl_keep isl_union_map
*umap
,
3758 enum isl_dim_type type
, unsigned first
, unsigned n
)
3760 struct isl_union_map_involves_dims_data data
= { first
, n
};
3763 if (type
!= isl_dim_param
)
3764 isl_die(isl_union_map_get_ctx(umap
), isl_error_invalid
,
3765 "can only reference parameters", return isl_bool_error
);
3767 excludes
= union_map_forall_user(umap
, &map_excludes
, &data
);
3770 return isl_bool_error
;
3775 /* Internal data structure for isl_union_map_reset_range_space.
3776 * "range" is the space from which to set the range space.
3777 * "res" collects the results.
3779 struct isl_union_map_reset_range_space_data
{
3784 /* Replace the range space of "map" by the range space of data->range and
3785 * add the result to data->res.
3787 static isl_stat
reset_range_space(__isl_take isl_map
*map
, void *user
)
3789 struct isl_union_map_reset_range_space_data
*data
= user
;
3792 space
= isl_map_get_space(map
);
3793 space
= isl_space_domain(space
);
3794 space
= isl_space_extend_domain_with_range(space
,
3795 isl_space_copy(data
->range
));
3796 map
= isl_map_reset_space(map
, space
);
3797 data
->res
= isl_union_map_add_map(data
->res
, map
);
3799 return data
->res
? isl_stat_ok
: isl_stat_error
;
3802 /* Replace the range space of all the maps in "umap" by
3803 * the range space of "space".
3805 * This assumes that all maps have the same output dimension.
3806 * This function should therefore not be made publicly available.
3808 * Since the spaces of the maps change, so do their hash value.
3809 * We therefore need to create a new isl_union_map.
3811 __isl_give isl_union_map
*isl_union_map_reset_range_space(
3812 __isl_take isl_union_map
*umap
, __isl_take isl_space
*space
)
3814 struct isl_union_map_reset_range_space_data data
= { space
};
3816 data
.res
= isl_union_map_empty(isl_union_map_get_space(umap
));
3817 if (isl_union_map_foreach_map(umap
, &reset_range_space
, &data
) < 0)
3818 data
.res
= isl_union_map_free(data
.res
);
3820 isl_space_free(space
);
3821 isl_union_map_free(umap
);
3825 /* Internal data structure for isl_union_map_order_at_multi_union_pw_aff.
3826 * "mupa" is the function from which the isl_multi_pw_affs are extracted.
3827 * "order" is applied to the extracted isl_multi_pw_affs that correspond
3828 * to the domain and the range of each map.
3829 * "res" collects the results.
3831 struct isl_union_order_at_data
{
3832 isl_multi_union_pw_aff
*mupa
;
3833 __isl_give isl_map
*(*order
)(__isl_take isl_multi_pw_aff
*mpa1
,
3834 __isl_take isl_multi_pw_aff
*mpa2
);
3838 /* Intersect "map" with the result of applying data->order to
3839 * the functions in data->mupa that apply to the domain and the range
3840 * of "map" and add the result to data->res.
3842 static isl_stat
order_at(__isl_take isl_map
*map
, void *user
)
3844 struct isl_union_order_at_data
*data
= user
;
3846 isl_multi_pw_aff
*mpa1
, *mpa2
;
3849 space
= isl_space_domain(isl_map_get_space(map
));
3850 mpa1
= isl_multi_union_pw_aff_extract_multi_pw_aff(data
->mupa
, space
);
3851 space
= isl_space_range(isl_map_get_space(map
));
3852 mpa2
= isl_multi_union_pw_aff_extract_multi_pw_aff(data
->mupa
, space
);
3853 order
= data
->order(mpa1
, mpa2
);
3854 map
= isl_map_intersect(map
, order
);
3855 data
->res
= isl_union_map_add_map(data
->res
, map
);
3857 return data
->res
? isl_stat_ok
: isl_stat_error
;
3860 /* Intersect each map in "umap" with the result of calling "order"
3861 * on the functions is "mupa" that apply to the domain and the range
3864 static __isl_give isl_union_map
*isl_union_map_order_at_multi_union_pw_aff(
3865 __isl_take isl_union_map
*umap
, __isl_take isl_multi_union_pw_aff
*mupa
,
3866 __isl_give isl_map
*(*order
)(__isl_take isl_multi_pw_aff
*mpa1
,
3867 __isl_take isl_multi_pw_aff
*mpa2
))
3869 struct isl_union_order_at_data data
;
3871 umap
= isl_union_map_align_params(umap
,
3872 isl_multi_union_pw_aff_get_space(mupa
));
3873 mupa
= isl_multi_union_pw_aff_align_params(mupa
,
3874 isl_union_map_get_space(umap
));
3877 data
.res
= isl_union_map_empty(isl_union_map_get_space(umap
));
3878 if (isl_union_map_foreach_map(umap
, &order_at
, &data
) < 0)
3879 data
.res
= isl_union_map_free(data
.res
);
3881 isl_multi_union_pw_aff_free(mupa
);
3882 isl_union_map_free(umap
);
3886 /* Return the subset of "umap" where the domain and the range
3887 * have equal "mupa" values.
3889 __isl_give isl_union_map
*isl_union_map_eq_at_multi_union_pw_aff(
3890 __isl_take isl_union_map
*umap
,
3891 __isl_take isl_multi_union_pw_aff
*mupa
)
3893 return isl_union_map_order_at_multi_union_pw_aff(umap
, mupa
,
3894 &isl_multi_pw_aff_eq_map
);
3897 /* Return the subset of "umap" where the domain has a lexicographically
3898 * smaller "mupa" value than the range.
3900 __isl_give isl_union_map
*isl_union_map_lex_lt_at_multi_union_pw_aff(
3901 __isl_take isl_union_map
*umap
,
3902 __isl_take isl_multi_union_pw_aff
*mupa
)
3904 return isl_union_map_order_at_multi_union_pw_aff(umap
, mupa
,
3905 &isl_multi_pw_aff_lex_lt_map
);
3908 /* Return the subset of "umap" where the domain has a lexicographically
3909 * greater "mupa" value than the range.
3911 __isl_give isl_union_map
*isl_union_map_lex_gt_at_multi_union_pw_aff(
3912 __isl_take isl_union_map
*umap
,
3913 __isl_take isl_multi_union_pw_aff
*mupa
)
3915 return isl_union_map_order_at_multi_union_pw_aff(umap
, mupa
,
3916 &isl_multi_pw_aff_lex_gt_map
);
3919 /* Return the union of the elements in the list "list".
3921 __isl_give isl_union_set
*isl_union_set_list_union(
3922 __isl_take isl_union_set_list
*list
)
3932 ctx
= isl_union_set_list_get_ctx(list
);
3933 space
= isl_space_params_alloc(ctx
, 0);
3934 res
= isl_union_set_empty(space
);
3936 n
= isl_union_set_list_n_union_set(list
);
3937 for (i
= 0; i
< n
; ++i
) {
3938 isl_union_set
*uset_i
;
3940 uset_i
= isl_union_set_list_get_union_set(list
, i
);
3941 res
= isl_union_set_union(res
, uset_i
);
3944 isl_union_set_list_free(list
);
3948 /* Update *hash with the hash value of "map".
3950 static isl_stat
add_hash(__isl_take isl_map
*map
, void *user
)
3952 uint32_t *hash
= user
;
3955 map_hash
= isl_map_get_hash(map
);
3956 isl_hash_hash(*hash
, map_hash
);
3962 /* Return a hash value that digests "umap".
3964 uint32_t isl_union_map_get_hash(__isl_keep isl_union_map
*umap
)
3971 hash
= isl_hash_init();
3972 if (isl_union_map_foreach_map(umap
, &add_hash
, &hash
) < 0)
3978 /* Return a hash value that digests "uset".
3980 uint32_t isl_union_set_get_hash(__isl_keep isl_union_set
*uset
)
3982 return isl_union_map_get_hash(uset
);