add isl_union_map_zip
authorSven Verdoolaege <skimo@kotnet.org>
Wed, 9 Mar 2011 19:46:12 +0000 (20:46 +0100)
committerSven Verdoolaege <skimo@kotnet.org>
Sat, 12 Mar 2011 09:42:36 +0000 (10:42 +0100)
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
doc/user.pod
include/isl/dim.h
include/isl/map.h
include/isl/union_map.h
isl_dim.c
isl_map.c
isl_union_map.c

index b08896f..be81874 100644 (file)
@@ -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(
index dbbc025..b7eae91 100644 (file)
@@ -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);
index f01dc30..d73f0aa 100644 (file)
@@ -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);
index 47bf4e1..1ac18fa 100644 (file)
@@ -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(
index a9ae54e..841b291 100644 (file)
--- 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;
+}
index e9a6f88..03e29cc 100644 (file)
--- 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;
+}
index fa1bc12..c2ba975 100644 (file)
@@ -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);
+}