isl_map_product: used nested spaces in result
authorSven Verdoolaege <skimo@kotnet.org>
Tue, 3 Aug 2010 12:46:48 +0000 (14:46 +0200)
committerSven Verdoolaege <skimo@kotnet.org>
Thu, 5 Aug 2010 17:14:59 +0000 (19:14 +0200)
That is, the product of A -> B and C -> D now has dimension
[A -> C] -> [B -> D].  This allows us to keep all information
about the spaces A, B, C, D, including their names and any
prior nestings.

Since it sometimes also useful to have concatenated spaces in the result,
we also introduct isl_map_flat_product, which produces what isl_map_product
used to produce.

Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
include/isl_map.h
include/isl_set.h
isl_dim.c
isl_dim_private.h
isl_map.c

index ffac0d3..34b172c 100644 (file)
@@ -317,6 +317,8 @@ __isl_give isl_map *isl_map_apply_range(
                __isl_take isl_map *map1,
                __isl_take isl_map *map2);
 struct isl_map *isl_map_product(struct isl_map *map1, struct isl_map *map2);
+__isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1,
+       __isl_take isl_map *map2);
 __isl_give isl_map *isl_map_intersect(__isl_take isl_map *map1,
                                      __isl_take isl_map *map2);
 __isl_give isl_map *isl_map_subtract(
@@ -362,6 +364,7 @@ __isl_give isl_basic_set *isl_basic_map_wrap(__isl_take isl_basic_map *bmap);
 __isl_give isl_set *isl_map_wrap(__isl_take isl_map *map);
 __isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_set *bset);
 __isl_give isl_map *isl_set_unwrap(__isl_take isl_set *set);
+__isl_give isl_map *isl_map_flatten(__isl_take isl_map *map);
 __isl_give isl_set *isl_map_domain(__isl_take isl_map *bmap);
 __isl_give isl_set *isl_map_range(__isl_take isl_map *map);
 __isl_give isl_map *isl_map_from_basic_map(__isl_take isl_basic_map *bmap);
index 6245f94..1ce899c 100644 (file)
@@ -231,6 +231,8 @@ __isl_give isl_set *isl_set_union(
                __isl_take isl_set *set1,
                __isl_take isl_set *set2);
 struct isl_set *isl_set_product(struct isl_set *set1, struct isl_set *set2);
+__isl_give isl_set *isl_set_flat_product(__isl_take isl_set *set1,
+       __isl_take isl_set *set2);
 __isl_give isl_set *isl_set_intersect(
                __isl_take isl_set *set1,
                __isl_take isl_set *set2);
index 2f06824..656839b 100644 (file)
--- a/isl_dim.c
+++ b/isl_dim.c
@@ -683,7 +683,7 @@ error:
 
 struct isl_dim *isl_dim_product(struct isl_dim *left, struct isl_dim *right)
 {
-       struct isl_dim *dim;
+       isl_dim *dom1, *dom2, *nest1, *nest2;
 
        if (!left || !right)
                goto error;
@@ -691,21 +691,15 @@ struct isl_dim *isl_dim_product(struct isl_dim *left, struct isl_dim *right)
        isl_assert(left->ctx, match(left, isl_dim_param, right, isl_dim_param),
                        goto error);
 
-       dim = isl_dim_alloc(left->ctx, left->nparam,
-                       left->n_in + right->n_in, left->n_out + right->n_out);
-       if (!dim)
-               goto error;
+       dom1 = isl_dim_domain(isl_dim_copy(left));
+       dom2 = isl_dim_domain(isl_dim_copy(right));
+       nest1 = isl_dim_wrap(isl_dim_join(isl_dim_reverse(dom1), dom2));
 
-       dim = copy_names(dim, isl_dim_param, 0, left, isl_dim_param);
-       dim = copy_names(dim, isl_dim_in, 0, left, isl_dim_in);
-       dim = copy_names(dim, isl_dim_in, left->n_in, right, isl_dim_in);
-       dim = copy_names(dim, isl_dim_out, 0, left, isl_dim_out);
-       dim = copy_names(dim, isl_dim_out, left->n_out, right, isl_dim_out);
+       dom1 = isl_dim_range(left);
+       dom2 = isl_dim_range(right);
+       nest2 = isl_dim_wrap(isl_dim_join(isl_dim_reverse(dom1), dom2));
 
-       isl_dim_free(left);
-       isl_dim_free(right);
-
-       return dim;
+       return isl_dim_join(isl_dim_reverse(nest1), nest2);
 error:
        isl_dim_free(left);
        isl_dim_free(right);
@@ -1071,3 +1065,18 @@ __isl_give isl_dim *isl_dim_reset(__isl_take isl_dim *dim,
 
        return dim;
 }
+
+__isl_give isl_dim *isl_dim_flatten(__isl_take isl_dim *dim)
+{
+       if (!dim)
+               return NULL;
+       if (!dim->nested[0] && !dim->nested[1])
+               return dim;
+
+       isl_dim_free(dim->nested[0]);
+       dim->nested[0] = NULL;
+       isl_dim_free(dim->nested[1]);
+       dim->nested[1] = NULL;
+
+       return dim;
+}
index 50f63a5..6bc8e1d 100644 (file)
@@ -27,3 +27,4 @@ unsigned isl_dim_offset(__isl_keep isl_dim *dim, enum isl_dim_type type);
 int isl_dim_is_named_or_nested(__isl_keep isl_dim *dim, enum isl_dim_type type);
 __isl_give isl_dim *isl_dim_reset(__isl_take isl_dim *dim,
        enum isl_dim_type type);
+__isl_give isl_dim *isl_dim_flatten(__isl_take isl_dim *dim);
index de52699..b9fed2d 100644 (file)
--- a/isl_map.c
+++ b/isl_map.c
@@ -6455,7 +6455,7 @@ error:
        return NULL;
 }
 
-/* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
+/* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
  */
 struct isl_map *isl_map_product(struct isl_map *map1, struct isl_map *map2)
 {
@@ -6500,6 +6500,18 @@ error:
        return NULL;
 }
 
+/* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
+ */
+__isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1,
+       __isl_take isl_map *map2)
+{
+       isl_map *prod;
+
+       prod = isl_map_product(map1, map2);
+       prod = isl_map_flatten(prod);
+       return prod;
+}
+
 /* Given two set A and B, construct its Cartesian product A x B.
  */
 struct isl_set *isl_set_product(struct isl_set *set1, struct isl_set *set2)
@@ -6508,6 +6520,12 @@ struct isl_set *isl_set_product(struct isl_set *set1, struct isl_set *set2)
                                                 (struct isl_map *)set2);
 }
 
+__isl_give isl_set *isl_set_flat_product(__isl_take isl_set *set1,
+       __isl_take isl_set *set2)
+{
+       return (isl_set *)isl_map_flat_product((isl_map *)set1, (isl_map *)set2);
+}
+
 uint32_t isl_basic_set_get_hash(struct isl_basic_set *bset)
 {
        int i;
@@ -7206,3 +7224,56 @@ error:
        isl_map_free(map);
        return NULL;
 }
+
+__isl_give isl_basic_map *isl_basic_map_flatten(__isl_take isl_basic_map *bmap)
+{
+       if (!bmap)
+               return NULL;
+
+       if (!bmap->dim->nested[0] && !bmap->dim->nested[1])
+               return bmap;
+
+       bmap = isl_basic_map_cow(bmap);
+       if (!bmap)
+               return NULL;
+
+       bmap->dim = isl_dim_flatten(bmap->dim);
+       if (!bmap->dim)
+               goto error;
+
+       bmap = isl_basic_map_finalize(bmap);
+
+       return bmap;
+error:
+       isl_basic_map_free(bmap);
+       return NULL;
+}
+
+__isl_give isl_map *isl_map_flatten(__isl_take isl_map *map)
+{
+       int i;
+
+       if (!map)
+               return NULL;
+
+       if (!map->dim->nested[0] && !map->dim->nested[1])
+               return map;
+
+       map = isl_map_cow(map);
+       if (!map)
+               return NULL;
+
+       for (i = 0; i < map->n; ++i) {
+               map->p[i] = isl_basic_map_flatten(map->p[i]);
+               if (!map->p[i])
+                       goto error;
+       }
+       map->dim = isl_dim_flatten(map->dim);
+       if (!map->dim)
+               goto error;
+
+       return map;
+error:
+       isl_map_free(map);
+       return NULL;
+}