add isl_union_map_deltas_map
authorSven Verdoolaege <skimo@kotnet.org>
Wed, 9 Mar 2011 20:17:20 +0000 (21:17 +0100)
committerSven Verdoolaege <skimo@kotnet.org>
Thu, 10 Mar 2011 22:43:37 +0000 (23:43 +0100)
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
doc/user.pod
include/isl/map.h
include/isl/union_map.h
isl_map.c
isl_union_map.c

index 5087c22..b08896f 100644 (file)
@@ -1321,6 +1321,16 @@ Construct an identity relation on the given (union) set.
 These functions return a (basic) set containing the differences
 between image elements and corresponding domain elements in the input.
 
+       __isl_give isl_basic_map *isl_basic_map_deltas_map(
+               __isl_take isl_basic_map *bmap);
+       __isl_give isl_map *isl_map_deltas_map(
+               __isl_take isl_map *map);
+       __isl_give isl_union_map *isl_union_map_deltas_map(
+               __isl_take isl_union_map *umap);
+
+The functions above construct a (basic, regular or union) relation
+that maps (a wrapped version of) the input relation to its delta set.
+
 =item * Coalescing
 
 Simplify the representation of a set or relation by trying
index fbacf24..f01dc30 100644 (file)
@@ -300,6 +300,9 @@ __isl_give isl_map *isl_map_lower_bound_si(__isl_take isl_map *map,
                enum isl_dim_type type, unsigned pos, int value);
 __isl_give isl_basic_set *isl_basic_map_deltas(__isl_take isl_basic_map *bmap);
 __isl_give isl_set *isl_map_deltas(__isl_take isl_map *map);
+__isl_give isl_basic_map *isl_basic_map_deltas_map(
+       __isl_take isl_basic_map *bmap);
+__isl_give isl_map *isl_map_deltas_map(__isl_take isl_map *map);
 struct isl_map *isl_map_detect_equalities(struct isl_map *map);
 __isl_give isl_basic_map *isl_map_affine_hull(__isl_take isl_map *map);
 __isl_give isl_basic_map *isl_map_convex_hull(__isl_take isl_map *map);
index a0f7a74..47bf4e1 100644 (file)
@@ -79,6 +79,8 @@ __isl_give isl_union_map *isl_union_map_from_domain_and_range(
 __isl_give isl_union_map *isl_union_map_detect_equalities(
        __isl_keep isl_union_map *umap);
 __isl_give isl_union_set *isl_union_map_deltas(__isl_take isl_union_map *umap);
+__isl_give isl_union_map *isl_union_map_deltas_map(
+       __isl_take isl_union_map *umap);
 __isl_give isl_union_map *isl_union_set_identity(__isl_take isl_union_set *uset);
 
 int isl_union_map_is_empty(__isl_keep isl_union_map *umap);
index 65834b4..ccceeb1 100644 (file)
--- a/isl_map.c
+++ b/isl_map.c
@@ -5615,6 +5615,88 @@ error:
        return NULL;
 }
 
+/*
+ * returns [domain -> range] -> range - domain
+ */
+__isl_give isl_basic_map *isl_basic_map_deltas_map(
+       __isl_take isl_basic_map *bmap)
+{
+       int i, k;
+       isl_dim *dim;
+       isl_basic_map *domain;
+       isl_basic_set *bset;
+       int nparam, n;
+       unsigned total;
+
+       if (!isl_dim_tuple_match(bmap->dim, isl_dim_in, bmap->dim, isl_dim_out))
+               isl_die(bmap->ctx, isl_error_invalid,
+                       "domain and range don't match", goto error);
+
+       nparam = isl_basic_map_dim(bmap, isl_dim_param);
+       n = isl_basic_map_dim(bmap, isl_dim_in);
+
+       dim = isl_dim_from_range(isl_dim_domain(isl_basic_map_get_dim(bmap)));
+       domain = isl_basic_map_universe(dim);
+
+       bmap = isl_basic_map_from_domain(isl_basic_map_wrap(bmap));
+       bmap = isl_basic_map_apply_range(bmap, domain);
+       bmap = isl_basic_map_extend_constraints(bmap, n, 0);
+
+       total = isl_basic_map_total_dim(bmap);
+
+       for (i = 0; i < n; ++i) {
+               k = isl_basic_map_alloc_equality(bmap);
+               if (k < 0)
+                       goto error;
+               isl_seq_clr(bmap->eq[k], 1 + total);
+               isl_int_set_si(bmap->eq[k][1 + nparam + i], 1);
+               isl_int_set_si(bmap->eq[k][1 + nparam + n + i], -1);
+               isl_int_set_si(bmap->eq[k][1 + nparam + n + n + i], 1);
+       }
+
+       bmap = isl_basic_map_gauss(bmap, NULL);
+       return isl_basic_map_finalize(bmap);
+error:
+       isl_basic_map_free(bmap);
+       return NULL;
+}
+
+/*
+ * returns [domain -> range] -> range - domain
+ */
+__isl_give isl_map *isl_map_deltas_map(__isl_take isl_map *map)
+{
+       int i;
+       isl_dim *domain_dim;
+
+       if (!map)
+               return NULL;
+
+       if (!isl_dim_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
+               isl_die(map->ctx, isl_error_invalid,
+                       "domain and range don't match", goto error);
+
+       map = isl_map_cow(map);
+       if (!map)
+               return NULL;
+
+       domain_dim = isl_dim_from_range(isl_dim_domain(isl_map_get_dim(map)));
+       map->dim = isl_dim_from_domain(isl_dim_wrap(map->dim));
+       map->dim = isl_dim_join(map->dim, domain_dim);
+       if (!map->dim)
+               goto error;
+       for (i = 0; i < map->n; ++i) {
+               map->p[i] = isl_basic_map_deltas_map(map->p[i]);
+               if (!map->p[i])
+                       goto error;
+       }
+       ISL_F_CLR(map, ISL_MAP_NORMALIZED);
+       return map;
+error:
+       isl_map_free(map);
+       return NULL;
+}
+
 static struct isl_basic_map *basic_map_identity(struct isl_dim *dims)
 {
        struct isl_basic_map *bmap;
index 5472261..fa1bc12 100644 (file)
@@ -1222,6 +1222,26 @@ __isl_give isl_union_set *isl_union_map_deltas(__isl_take isl_union_map *umap)
        return cond_un_op(umap, &deltas_entry);
 }
 
+static int deltas_map_entry(void **entry, void *user)
+{
+       isl_map *map = *entry;
+       isl_union_map **res = user;
+
+       if (!isl_dim_tuple_match(map->dim, isl_dim_in, map->dim, isl_dim_out))
+               return 0;
+
+       *res = isl_union_map_add_map(*res,
+                                    isl_map_deltas_map(isl_map_copy(map)));
+
+       return 0;
+}
+
+__isl_give isl_union_map *isl_union_map_deltas_map(
+       __isl_take isl_union_map *umap)
+{
+       return cond_un_op(umap, &deltas_map_entry);
+}
+
 static int identity_entry(void **entry, void *user)
 {
        isl_set *set = *entry;