add isl_map_uncurry
authorSven Verdoolaege <skimo@kotnet.org>
Thu, 6 Sep 2012 13:42:24 +0000 (15:42 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Thu, 6 Sep 2012 13:46:55 +0000 (15:46 +0200)
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
doc/user.pod
include/isl/map.h
include/isl/space.h
isl_map.c
isl_space.c

index ad404c2..b637d82 100644 (file)
@@ -867,6 +867,8 @@ using the following functions.
        __isl_give isl_space *isl_space_zip(__isl_take isl_space *space);
        __isl_give isl_space *isl_space_curry(
                __isl_take isl_space *space);
+       __isl_give isl_space *isl_space_uncurry(
+               __isl_take isl_space *space);
 
 Note that if dimensions are added or removed from a space, then
 the name and the internal structure are lost.
@@ -1865,6 +1867,12 @@ i.e., whether both domain and range are nested relations.
 
 Check whether the domain of the (basic) relation is a wrapped relation.
 
+       int isl_basic_map_can_uncurry(
+               __isl_keep isl_basic_map *bmap);
+       int isl_map_can_uncurry(__isl_keep isl_map *map);
+
+Check whether the range of the (basic) relation is a wrapped relation.
+
 =back
 
 =head3 Binary Properties
@@ -2468,15 +2476,21 @@ interchange the range of the domain with the domain of the range.
 
        __isl_give isl_basic_map *isl_basic_map_curry(
                __isl_take isl_basic_map *bmap);
+       __isl_give isl_basic_map *isl_basic_map_uncurry(
+               __isl_take isl_basic_map *bmap);
        __isl_give isl_map *isl_map_curry(
                __isl_take isl_map *map);
+       __isl_give isl_map *isl_map_uncurry(
+               __isl_take isl_map *map);
        __isl_give isl_union_map *isl_union_map_curry(
                __isl_take isl_union_map *umap);
 
 Given a relation with a nested relation for domain,
+the C<curry> functions
 move the range of the nested relation out of the domain
 and use it as the domain of a nested relation in the range,
 with the original range as range of this nested relation.
+The C<uncurry> functions perform the inverse operation.
 
 =item * Aligning parameters
 
index b3e252d..5aee7b2 100644 (file)
@@ -537,6 +537,11 @@ int isl_map_can_curry(__isl_keep isl_map *map);
 __isl_give isl_basic_map *isl_basic_map_curry(__isl_take isl_basic_map *bmap);
 __isl_give isl_map *isl_map_curry(__isl_take isl_map *map);
 
+int isl_basic_map_can_uncurry(__isl_keep isl_basic_map *bmap);
+int isl_map_can_uncurry(__isl_keep isl_map *map);
+__isl_give isl_basic_map *isl_basic_map_uncurry(__isl_take isl_basic_map *bmap);
+__isl_give isl_map *isl_map_uncurry(__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 4f20f25..3ce4102 100644 (file)
@@ -125,6 +125,9 @@ __isl_give isl_space *isl_space_zip(__isl_take isl_space *dim);
 int isl_space_can_curry(__isl_keep isl_space *space);
 __isl_give isl_space *isl_space_curry(__isl_take isl_space *space);
 
+int isl_space_can_uncurry(__isl_keep isl_space *space);
+__isl_give isl_space *isl_space_uncurry(__isl_take isl_space *space);
+
 int isl_space_is_domain(__isl_keep isl_space *space1,
        __isl_keep isl_space *space2);
 int isl_space_is_range(__isl_keep isl_space *space1,
index 0b3af21..c42809c 100644 (file)
--- a/isl_map.c
+++ b/isl_map.c
@@ -10251,6 +10251,78 @@ error:
        return NULL;
 }
 
+/* Can we apply isl_basic_map_uncurry to "bmap"?
+ * That is, does it have a nested relation in its domain?
+ */
+int isl_basic_map_can_uncurry(__isl_keep isl_basic_map *bmap)
+{
+       if (!bmap)
+               return -1;
+
+       return isl_space_can_uncurry(bmap->dim);
+}
+
+/* Can we apply isl_map_uncurry to "map"?
+ * That is, does it have a nested relation in its domain?
+ */
+int isl_map_can_uncurry(__isl_keep isl_map *map)
+{
+       if (!map)
+               return -1;
+
+       return isl_space_can_uncurry(map->dim);
+}
+
+/* Given a basic map A -> (B -> C), return the corresponding basic map
+ * (A -> B) -> C.
+ */
+__isl_give isl_basic_map *isl_basic_map_uncurry(__isl_take isl_basic_map *bmap)
+{
+
+       if (!bmap)
+               return NULL;
+
+       if (!isl_basic_map_can_uncurry(bmap))
+               isl_die(bmap->ctx, isl_error_invalid,
+                       "basic map cannot be uncurried",
+                       return isl_basic_map_free(bmap));
+       bmap->dim = isl_space_uncurry(bmap->dim);
+       if (!bmap->dim)
+               return isl_basic_map_free(bmap);
+       return bmap;
+}
+
+/* Given a map A -> (B -> C), return the corresponding map
+ * (A -> B) -> C.
+ */
+__isl_give isl_map *isl_map_uncurry(__isl_take isl_map *map)
+{
+       int i;
+
+       if (!map)
+               return NULL;
+
+       if (!isl_map_can_uncurry(map))
+               isl_die(map->ctx, isl_error_invalid, "map cannot be uncurried",
+                       return isl_map_free(map));
+
+       map = isl_map_cow(map);
+       if (!map)
+               return NULL;
+
+       for (i = 0; i < map->n; ++i) {
+               map->p[i] = isl_basic_map_uncurry(map->p[i]);
+               if (!map->p[i])
+                       return isl_map_free(map);
+       }
+
+       map->dim = isl_space_uncurry(map->dim);
+       if (!map->dim)
+               return isl_map_free(map);
+
+       return map;
+}
+
 /* Construct a basic map mapping the domain of the affine expression
  * to a one-dimensional range prescribed by the affine expression.
  */
index 625ea36..eaad1a6 100644 (file)
@@ -1844,6 +1844,43 @@ error:
        return NULL;
 }
 
+/* Can we apply isl_space_uncurry to "space"?
+ * That is, does it have a nested relation in its range?
+ */
+int isl_space_can_uncurry(__isl_keep isl_space *space)
+{
+       if (!space)
+               return -1;
+
+       return !!space->nested[1];
+}
+
+/* Given a space A -> (B -> C), return the corresponding space
+ * (A -> B) -> C.
+ */
+__isl_give isl_space *isl_space_uncurry(__isl_take isl_space *space)
+{
+       isl_space *dom, *ran;
+       isl_space *ran_dom, *ran_ran;
+
+       if (!space)
+               return NULL;
+
+       if (!isl_space_can_uncurry(space))
+               isl_die(space->ctx, isl_error_invalid,
+                       "space cannot be uncurried",
+                       return isl_space_free(space));
+
+       dom = isl_space_domain(isl_space_copy(space));
+       ran = isl_space_unwrap(isl_space_range(space));
+       ran_dom = isl_space_domain(isl_space_copy(ran));
+       ran_ran = isl_space_range(ran);
+       dom = isl_space_join(isl_space_from_domain(dom),
+                          isl_space_from_range(ran_dom));
+       return isl_space_join(isl_space_from_domain(isl_space_wrap(dom)),
+                           isl_space_from_range(ran_ran));
+}
+
 int isl_space_has_named_params(__isl_keep isl_space *dim)
 {
        int i;