From 3482bf1f4da8c70be2a8eae2554c6fadbd274b53 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 9 Mar 2011 20:46:12 +0100 Subject: [PATCH] add isl_union_map_zip Signed-off-by: Sven Verdoolaege --- doc/user.pod | 23 ++++++++++++++ include/isl/dim.h | 3 ++ include/isl/map.h | 5 +++ include/isl/union_map.h | 2 ++ isl_dim.c | 36 ++++++++++++++++++++++ isl_map.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++ isl_union_map.c | 18 +++++++++++ 7 files changed, 168 insertions(+) diff --git a/doc/user.pod b/doc/user.pod index b08896f7..be81874c 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -536,6 +536,7 @@ specifications using the following functions. enum isl_dim_type type, unsigned first, unsigned n); __isl_give isl_dim *isl_dim_map_from_set( __isl_take isl_dim *dim); + __isl_give isl_dim *isl_dim_zip(__isl_take isl_dim *dim); Note that if dimensions are added or removed from a space, then the name and the internal structure are lost. @@ -1179,6 +1180,16 @@ The followning functions check whether the domain of the given __isl_keep isl_basic_set *bset); int isl_set_is_wrapping(__isl_keep isl_set *set); +=item * Internal Product + + int isl_basic_map_can_zip( + __isl_keep isl_basic_map *bmap); + int isl_map_can_zip(__isl_keep isl_map *map); + +Check whether the product of domain and range of the given relation +can be computed, +i.e., whether both domain and range are nested relations. + =back =head3 Binary Properties @@ -1503,6 +1514,18 @@ then the name of the space is also removed. The function above constructs a relation that maps the input set to a flattened version of the set. +=item * Internal Product + + __isl_give isl_basic_map *isl_basic_map_zip( + __isl_take isl_basic_map *bmap); + __isl_give isl_map *isl_map_zip( + __isl_take isl_map *map); + __isl_give isl_union_map *isl_union_map_zip( + __isl_take isl_union_map *umap); + +Given a relation with nested relations for domain and range, +interchange the range of the domain with the domain of the range. + =item * Dimension manipulation __isl_give isl_set *isl_set_add_dims( diff --git a/include/isl/dim.h b/include/isl/dim.h index dbbc0256..b7eae910 100644 --- a/include/isl/dim.h +++ b/include/isl/dim.h @@ -81,6 +81,9 @@ int isl_dim_is_wrapping(__isl_keep isl_dim *dim); __isl_give isl_dim *isl_dim_wrap(__isl_take isl_dim *dim); __isl_give isl_dim *isl_dim_unwrap(__isl_take isl_dim *dim); +int isl_dim_can_zip(__isl_keep isl_dim *dim); +__isl_give isl_dim *isl_dim_zip(__isl_take isl_dim *dim); + int isl_dim_equal(struct isl_dim *dim1, struct isl_dim *dim2); int isl_dim_match(struct isl_dim *dim1, enum isl_dim_type dim1_type, struct isl_dim *dim2, enum isl_dim_type dim2_type); diff --git a/include/isl/map.h b/include/isl/map.h index f01dc30c..d73f0aa8 100644 --- a/include/isl/map.h +++ b/include/isl/map.h @@ -375,6 +375,11 @@ int isl_map_is_bijective(__isl_keep isl_map *map); int isl_map_is_translation(__isl_keep isl_map *map); int isl_map_has_equal_dim(__isl_keep isl_map *map1, __isl_keep isl_map *map2); +int isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap); +int isl_map_can_zip(__isl_keep isl_map *map); +__isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap); +__isl_give isl_map *isl_map_zip(__isl_take isl_map *map); + __isl_give isl_map *isl_map_make_disjoint(__isl_take isl_map *map); __isl_give isl_map *isl_basic_map_compute_divs(__isl_take isl_basic_map *bmap); __isl_give isl_map *isl_map_compute_divs(__isl_take isl_map *map); diff --git a/include/isl/union_map.h b/include/isl/union_map.h index 47bf4e18..1ac18faa 100644 --- a/include/isl/union_map.h +++ b/include/isl/union_map.h @@ -123,6 +123,8 @@ void isl_union_map_dump(__isl_keep isl_union_map *umap); __isl_give isl_union_set *isl_union_map_wrap(__isl_take isl_union_map *umap); __isl_give isl_union_map *isl_union_set_unwrap(__isl_take isl_union_set *uset); +__isl_give isl_union_map *isl_union_map_zip(__isl_take isl_union_map *umap); + __isl_give isl_union_map *isl_union_map_align_params( __isl_take isl_union_map *umap, __isl_take isl_dim *model); __isl_give isl_union_set *isl_union_set_align_params( diff --git a/isl_dim.c b/isl_dim.c index a9ae54eb..841b2912 100644 --- a/isl_dim.c +++ b/isl_dim.c @@ -1213,3 +1213,39 @@ __isl_give isl_dim *isl_dim_lift(__isl_take isl_dim *dim, unsigned n_local) return dim; } + +int isl_dim_can_zip(__isl_keep isl_dim *dim) +{ + if (!dim) + return -1; + + return dim->nested[0] && dim->nested[1]; +} + +__isl_give isl_dim *isl_dim_zip(__isl_take isl_dim *dim) +{ + isl_dim *dom, *ran; + isl_dim *dom_dom, *dom_ran, *ran_dom, *ran_ran; + + if (!isl_dim_can_zip(dim)) + isl_die(dim->ctx, isl_error_invalid, "dim cannot be zipped", + goto error); + + if (!dim) + return 0; + dom = isl_dim_unwrap(isl_dim_domain(isl_dim_copy(dim))); + ran = isl_dim_unwrap(isl_dim_range(dim)); + dom_dom = isl_dim_domain(isl_dim_copy(dom)); + dom_ran = isl_dim_range(dom); + ran_dom = isl_dim_domain(isl_dim_copy(ran)); + ran_ran = isl_dim_range(ran); + dom = isl_dim_join(isl_dim_from_domain(dom_dom), + isl_dim_from_range(ran_dom)); + ran = isl_dim_join(isl_dim_from_domain(dom_ran), + isl_dim_from_range(ran_ran)); + return isl_dim_join(isl_dim_from_domain(isl_dim_wrap(dom)), + isl_dim_from_range(isl_dim_wrap(ran))); +error: + isl_dim_free(dim); + return NULL; +} diff --git a/isl_map.c b/isl_map.c index e9a6f88c..03e29cc6 100644 --- a/isl_map.c +++ b/isl_map.c @@ -8450,3 +8450,84 @@ __isl_give isl_basic_set *isl_basic_set_from_constraint_matrices( isl_basic_map_from_constraint_matrices(dim, eq, ineq, c1, c2, c3, c4, isl_dim_in); } + +int isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap) +{ + if (!bmap) + return -1; + + return isl_dim_can_zip(bmap->dim); +} + +int isl_map_can_zip(__isl_keep isl_map *map) +{ + if (!map) + return -1; + + return isl_dim_can_zip(map->dim); +} + +/* Given a basic map (A -> B) -> (C -> D), return the corresponding basic map + * (A -> C) -> (B -> D). + */ +__isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap) +{ + unsigned pos; + unsigned n1; + unsigned n2; + + if (!bmap) + return NULL; + + if (!isl_basic_map_can_zip(bmap)) + isl_die(bmap->ctx, isl_error_invalid, + "basic map cannot be zipped", goto error); + pos = isl_basic_map_offset(bmap, isl_dim_in) + + isl_dim_size(bmap->dim->nested[0], isl_dim_in); + n1 = isl_dim_size(bmap->dim->nested[0], isl_dim_out); + n2 = isl_dim_size(bmap->dim->nested[1], isl_dim_in); + bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2); + if (!bmap) + return NULL; + bmap->dim = isl_dim_zip(bmap->dim); + if (!bmap->dim) + goto error; + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +/* Given a map (A -> B) -> (C -> D), return the corresponding map + * (A -> C) -> (B -> D). + */ +__isl_give isl_map *isl_map_zip(__isl_take isl_map *map) +{ + int i; + + if (!map) + return NULL; + + if (!isl_map_can_zip(map)) + isl_die(map->ctx, isl_error_invalid, "map cannot be zipped", + goto error); + + map = isl_map_cow(map); + if (!map) + return NULL; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_zip(map->p[i]); + if (!map->p[i]) + goto error; + } + + map->dim = isl_dim_zip(map->dim); + if (!map->dim) + goto error; + + return map; +error: + isl_map_free(map); + return NULL; +} diff --git a/isl_union_map.c b/isl_union_map.c index fa1bc126..c2ba9751 100644 --- a/isl_union_map.c +++ b/isl_union_map.c @@ -1466,3 +1466,21 @@ int isl_union_set_is_empty(__isl_keep isl_union_set *uset) { return isl_union_map_is_empty(uset); } + +static int zip_entry(void **entry, void *user) +{ + isl_map *map = *entry; + isl_union_map **res = user; + + if (!isl_map_can_zip(map)) + return 0; + + *res = isl_union_map_add_map(*res, isl_map_zip(isl_map_copy(map))); + + return 0; +} + +__isl_give isl_union_map *isl_union_map_zip(__isl_take isl_union_map *umap) +{ + return cond_un_op(umap, &zip_entry); +} -- 2.11.4.GIT