From 49902f3996a6332fc0206d8b40d0d30e7cbb902a Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Sun, 26 Dec 2010 13:12:05 +0100 Subject: [PATCH] add isl_union_map_range_product Signed-off-by: Sven Verdoolaege --- doc/user.pod | 9 ++++++ include/isl/dim.h | 2 ++ include/isl/map.h | 4 +++ include/isl/union_map.h | 2 ++ isl_dim.c | 27 +++++++++++++++++ isl_map.c | 79 ++++++++++++++++++++++++++++++++++++++++++++----- isl_union_map.c | 19 ++++++++++++ 7 files changed, 134 insertions(+), 8 deletions(-) diff --git a/doc/user.pod b/doc/user.pod index 68088faa..23e7aa27 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -1599,6 +1599,15 @@ the same (number of) parameters. __isl_give isl_union_set *isl_union_set_product( __isl_take isl_union_set *uset1, __isl_take isl_union_set *uset2); + __isl_give isl_basic_map *isl_basic_map_range_product( + __isl_take isl_basic_map *bmap1, + __isl_take isl_basic_map *bmap2); + __isl_give isl_map *isl_map_range_product( + __isl_take isl_map *map1, + __isl_take isl_map *map2); + __isl_give isl_union_map *isl_union_map_range_product( + __isl_take isl_union_map *umap1, + __isl_take isl_union_map *umap2); __isl_give isl_map *isl_map_product( __isl_take isl_map *map1, __isl_take isl_map *map2); diff --git a/include/isl/dim.h b/include/isl/dim.h index 41361d6e..e4cfd85b 100644 --- a/include/isl/dim.h +++ b/include/isl/dim.h @@ -61,6 +61,8 @@ __isl_give isl_dim *isl_dim_insert(__isl_take isl_dim *dim, __isl_give isl_dim *isl_dim_join(__isl_take isl_dim *left, __isl_take isl_dim *right); struct isl_dim *isl_dim_product(struct isl_dim *left, struct isl_dim *right); +__isl_give isl_dim *isl_dim_range_product(__isl_take isl_dim *left, + __isl_take isl_dim *right); struct isl_dim *isl_dim_map(struct isl_dim *dim); __isl_give isl_dim *isl_dim_reverse(__isl_take isl_dim *dim); __isl_give isl_dim *isl_dim_drop(__isl_take isl_dim *dim, diff --git a/include/isl/map.h b/include/isl/map.h index dc19591f..f9b67869 100644 --- a/include/isl/map.h +++ b/include/isl/map.h @@ -273,6 +273,10 @@ __isl_give isl_map *isl_map_apply_range( __isl_take isl_map *map2); __isl_give isl_map *isl_map_product(__isl_take isl_map *map1, __isl_take isl_map *map2); +__isl_give isl_basic_map *isl_basic_map_range_product( + __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2); +__isl_give isl_map *isl_map_range_product(__isl_take isl_map *map1, + __isl_take 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, diff --git a/include/isl/union_map.h b/include/isl/union_map.h index d2d142f6..dad469d8 100644 --- a/include/isl/union_map.h +++ b/include/isl/union_map.h @@ -58,6 +58,8 @@ __isl_give isl_union_map *isl_union_map_intersect( __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); __isl_give isl_union_map *isl_union_map_product(__isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); +__isl_give isl_union_map *isl_union_map_range_product( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); __isl_give isl_union_map *isl_union_map_gist(__isl_take isl_union_map *umap, __isl_take isl_union_map *context); diff --git a/isl_dim.c b/isl_dim.c index 2ada2e17..b94a59b9 100644 --- a/isl_dim.c +++ b/isl_dim.c @@ -722,6 +722,33 @@ error: return NULL; } +__isl_give isl_dim *isl_dim_range_product(__isl_take isl_dim *left, + __isl_take isl_dim *right) +{ + isl_dim *dom, *ran1, *ran2, *nest; + + if (!left || !right) + goto error; + + isl_assert(left->ctx, match(left, isl_dim_param, right, isl_dim_param), + goto error); + if (!isl_dim_match(left, isl_dim_in, right, isl_dim_in)) + isl_die(left->ctx, isl_error_invalid, + "domains need to match", goto error); + + dom = isl_dim_domain(isl_dim_copy(left)); + + ran1 = isl_dim_range(left); + ran2 = isl_dim_range(right); + nest = isl_dim_wrap(isl_dim_join(isl_dim_reverse(ran1), ran2)); + + return isl_dim_join(isl_dim_reverse(dom), nest); +error: + isl_dim_free(left); + isl_dim_free(right); + return NULL; +} + struct isl_dim *isl_dim_map(struct isl_dim *dim) { struct isl_name **names = NULL; diff --git a/isl_map.c b/isl_map.c index 288c8581..99af6f8c 100644 --- a/isl_map.c +++ b/isl_map.c @@ -7028,9 +7028,57 @@ error: return NULL; } -/* 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) +__isl_give isl_basic_map *isl_basic_map_range_product( + __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2) +{ + isl_dim *dim_result = NULL; + isl_basic_map *bmap; + unsigned in, out1, out2, nparam, total, pos; + struct isl_dim_map *dim_map1, *dim_map2; + + if (!bmap1 || !bmap2) + goto error; + + dim_result = isl_dim_range_product(isl_dim_copy(bmap1->dim), + isl_dim_copy(bmap2->dim)); + + in = isl_basic_map_dim(bmap1, isl_dim_in); + out1 = isl_basic_map_n_out(bmap1); + out2 = isl_basic_map_n_out(bmap2); + nparam = isl_basic_map_n_param(bmap1); + + total = nparam + in + out1 + out2 + bmap1->n_div + bmap2->n_div; + dim_map1 = isl_dim_map_alloc(bmap1->ctx, total); + dim_map2 = isl_dim_map_alloc(bmap1->ctx, total); + isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0); + isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0); + isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam); + isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos); + isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in); + isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1); + isl_dim_map_div(dim_map1, bmap1, pos += out2); + isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div); + + bmap = isl_basic_map_alloc_dim(dim_result, + bmap1->n_div + bmap2->n_div, + bmap1->n_eq + bmap2->n_eq, + bmap1->n_ineq + bmap2->n_ineq); + bmap = add_constraints_dim_map(bmap, bmap1, dim_map1); + bmap = add_constraints_dim_map(bmap, bmap2, dim_map2); + bmap = isl_basic_map_simplify(bmap); + return isl_basic_map_finalize(bmap); +error: + isl_basic_map_free(bmap1); + isl_basic_map_free(bmap2); + return NULL; +} + +static __isl_give isl_map *map_product(__isl_take isl_map *map1, + __isl_take isl_map *map2, + __isl_give isl_dim *(*dim_product)(__isl_take isl_dim *left, + __isl_take isl_dim *right), + __isl_give isl_basic_map *(*basic_map_product)( + __isl_take isl_basic_map *left, __isl_take isl_basic_map *right)) { unsigned flags = 0; struct isl_map *result; @@ -7046,17 +7094,16 @@ struct isl_map *isl_map_product(struct isl_map *map1, struct isl_map *map2) ISL_F_ISSET(map2, ISL_MAP_DISJOINT)) ISL_FL_SET(flags, ISL_MAP_DISJOINT); - result = isl_map_alloc_dim(isl_dim_product(isl_dim_copy(map1->dim), - isl_dim_copy(map2->dim)), + result = isl_map_alloc_dim(dim_product(isl_dim_copy(map1->dim), + isl_dim_copy(map2->dim)), map1->n * map2->n, flags); if (!result) goto error; for (i = 0; i < map1->n; ++i) for (j = 0; j < map2->n; ++j) { struct isl_basic_map *part; - part = isl_basic_map_product( - isl_basic_map_copy(map1->p[i]), - isl_basic_map_copy(map2->p[j])); + part = basic_map_product(isl_basic_map_copy(map1->p[i]), + isl_basic_map_copy(map2->p[j])); if (isl_basic_map_is_empty(part)) isl_basic_map_free(part); else @@ -7073,6 +7120,13 @@ error: return NULL; } +/* 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) +{ + return map_product(map1, map2, &isl_dim_product, &isl_basic_map_product); +} + /* 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, @@ -7099,6 +7153,15 @@ __isl_give isl_set *isl_set_flat_product(__isl_take isl_set *set1, return (isl_set *)isl_map_flat_product((isl_map *)set1, (isl_map *)set2); } +/* Given two maps A -> B and C -> D, construct a map (A * C) -> [B -> D] + */ +__isl_give isl_map *isl_map_range_product(__isl_take isl_map *map1, + __isl_take isl_map *map2) +{ + return map_product(map1, map2, &isl_dim_range_product, + &isl_basic_map_range_product); +} + uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map *bmap) { int i; diff --git a/isl_union_map.c b/isl_union_map.c index 38e6b598..3e88c557 100644 --- a/isl_union_map.c +++ b/isl_union_map.c @@ -877,6 +877,25 @@ __isl_give isl_union_set *isl_union_set_product(__isl_take isl_union_set *uset1, return isl_union_map_product(uset1, uset2); } +static int range_product_entry(void **entry, void *user) +{ + struct isl_union_map_bin_data *data = user; + isl_map *map2 = *entry; + + map2 = isl_map_range_product(isl_map_copy(data->map), + isl_map_copy(map2)); + + data->res = isl_union_map_add_map(data->res, map2); + + return 0; +} + +__isl_give isl_union_map *isl_union_map_range_product( + __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2) +{ + return bin_op(umap1, umap2, &range_product_entry); +} + __isl_give isl_union_map *isl_union_map_from_range( __isl_take isl_union_set *uset) { -- 2.11.4.GIT