From be01bd1cee8c2f95b846175a2dc6152e2d626f21 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 24 Aug 2010 21:01:20 +0200 Subject: [PATCH] align parameters of union arguments to binary functions Signed-off-by: Sven Verdoolaege --- Makefile.am | 2 + doc/user.pod | 4 ++ include/isl_polynomial.h | 8 +++ include/isl_union_map.h | 5 ++ isl_fold.c | 39 +++++++++++ isl_map.c | 115 +++++++++++++++++++++++++++++++++ isl_map_private.h | 11 ++++ isl_polynomial.c | 66 +++++++++++++++++++ isl_polynomial_private.h | 10 +++ isl_pw_templ.c | 29 +++++++++ isl_reordering.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++ isl_reordering.h | 31 +++++++++ isl_union_map.c | 107 +++++++++++++++++++++++++++++-- isl_union_templ.c | 73 ++++++++++++++++++++- 14 files changed, 656 insertions(+), 8 deletions(-) create mode 100644 isl_reordering.c create mode 100644 isl_reordering.h diff --git a/Makefile.am b/Makefile.am index 31511c4..e9eb8a3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -82,6 +82,8 @@ libisl_la_SOURCES = \ isl_printer.c \ isl_range.c \ isl_range.h \ + isl_reordering.c \ + isl_reordering.h \ isl_sample.h \ isl_sample.c \ isl_scan.c \ diff --git a/doc/user.pod b/doc/user.pod index 4dc978b..b49d43d 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -442,6 +442,10 @@ Also note that every function that operates on two sets or relations requires that both arguments have the same parameters. This also means that if one of the arguments has named parameters, then the other needs to have named parameters too and the names need to match. +Pairs of C and/or C arguments may +have different parameters (as long as they are named), in which case +the result will have as parameters the union of the parameters of +the arguments. The names of entire spaces may be set or read off using the following functions. diff --git a/include/isl_polynomial.h b/include/isl_polynomial.h index 8a81744..f359616 100644 --- a/include/isl_polynomial.h +++ b/include/isl_polynomial.h @@ -386,6 +386,10 @@ __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_gist( __isl_take isl_union_pw_qpolynomial *upwqp, __isl_take isl_union_set *context); +__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_align_params( + __isl_take isl_union_pw_qpolynomial *upwqp, + __isl_take isl_dim *model); + int isl_union_pw_qpolynomial_foreach_pw_qpolynomial( __isl_keep isl_union_pw_qpolynomial *upwqp, int (*fn)(__isl_take isl_pw_qpolynomial *pwqp, void *user), void *user); @@ -438,6 +442,10 @@ __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_gist( __isl_take isl_union_pw_qpolynomial_fold *upwf, __isl_take isl_union_set *context); +__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_align_params( + __isl_take isl_union_pw_qpolynomial_fold *upwf, + __isl_take isl_dim *model); + int isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold( __isl_keep isl_union_pw_qpolynomial_fold *upwf, int (*fn)(__isl_take isl_pw_qpolynomial_fold *pwf, diff --git a/include/isl_union_map.h b/include/isl_union_map.h index 23bed6b..497a88b 100644 --- a/include/isl_union_map.h +++ b/include/isl_union_map.h @@ -83,6 +83,11 @@ __isl_give isl_printer *isl_printer_print_union_map(__isl_take isl_printer *p, __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_align_params( + __isl_take isl_union_map *umap, __isl_take isl_dim *model); +__isl_give isl_union_set *isl_union_set_align_params( + __isl_take isl_union_set *uset, __isl_take isl_dim *model); + #if defined(__cplusplus) } #endif diff --git a/isl_fold.c b/isl_fold.c index 1898337..803a769 100644 --- a/isl_fold.c +++ b/isl_fold.c @@ -1252,6 +1252,11 @@ __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_add_unio __isl_take isl_union_pw_qpolynomial_fold *upwf, __isl_take isl_union_pw_qpolynomial *upwqp) { + upwf = isl_union_pw_qpolynomial_fold_align_params(upwf, + isl_union_pw_qpolynomial_get_dim(upwqp)); + upwqp = isl_union_pw_qpolynomial_align_params(upwqp, + isl_union_pw_qpolynomial_fold_get_dim(upwf)); + upwf = isl_union_pw_qpolynomial_fold_cow(upwf); if (!upwf || !upwqp) goto error; @@ -1380,6 +1385,11 @@ __isl_give isl_union_pw_qpolynomial_fold *isl_union_map_apply_union_pw_qpolynomi enum isl_fold type; struct isl_apply_fold_data data; + upwf = isl_union_pw_qpolynomial_fold_align_params(upwf, + isl_union_map_get_dim(umap)); + umap = isl_union_map_align_params(umap, + isl_union_pw_qpolynomial_fold_get_dim(upwf)); + data.upwf = upwf; data.tight = tight ? 1 : 0; dim = isl_union_pw_qpolynomial_fold_get_dim(upwf); @@ -1401,3 +1411,32 @@ error: isl_union_pw_qpolynomial_fold_free(data.res); return NULL; } + +/* Reorder the dimension of "fold" according to the given reordering. + */ +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_realign( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_reordering *r) +{ + int i; + + fold = isl_qpolynomial_fold_cow(fold); + if (!fold || !r) + goto error; + + for (i = 0; i < fold->n; ++i) { + fold->qp[i] = isl_qpolynomial_realign(fold->qp[i], + isl_reordering_copy(r)); + if (!fold->qp[i]) + goto error; + } + + fold = isl_qpolynomial_fold_reset_dim(fold, isl_dim_copy(r->dim)); + + isl_reordering_free(r); + + return fold; +error: + isl_qpolynomial_fold_free(fold); + isl_reordering_free(r); + return NULL; +} diff --git a/isl_map.c b/isl_map.c index fec720b..c6eeaf8 100644 --- a/isl_map.c +++ b/isl_map.c @@ -23,6 +23,7 @@ #include "isl_map.h" #include "isl_map_private.h" #include "isl_map_piplib.h" +#include #include "isl_sample.h" #include "isl_tab.h" #include "isl_vec.h" @@ -7292,3 +7293,117 @@ error: isl_map_free(map); return NULL; } + +/* Extend the given dim_map with mappings for the divs in bmap. + */ +static __isl_give struct isl_dim_map *extend_dim_map( + __isl_keep struct isl_dim_map *dim_map, + __isl_keep isl_basic_map *bmap) +{ + int i; + struct isl_dim_map *res; + int offset; + + offset = isl_basic_map_offset(bmap, isl_dim_div); + + res = isl_dim_map_alloc(bmap->ctx, dim_map->len - 1 + bmap->n_div); + if (!res) + return NULL; + + for (i = 0; i < dim_map->len; ++i) + res->pos[i] = dim_map->pos[i]; + for (i = 0; i < bmap->n_div; ++i) + res->pos[dim_map->len + i] = offset + i; + + return res; +} + +/* Extract a dim_map from a reordering. + * We essentially need to reverse the mapping, and add an offset + * of 1 for the constant term. + */ +__isl_give struct isl_dim_map *isl_dim_map_from_reordering( + __isl_keep isl_reordering *exp) +{ + int i; + struct isl_dim_map *dim_map; + + if (!exp) + return NULL; + + dim_map = isl_dim_map_alloc(exp->dim->ctx, isl_dim_total(exp->dim)); + if (!dim_map) + return NULL; + + for (i = 0; i < exp->len; ++i) + dim_map->pos[1 + exp->pos[i]] = 1 + i; + + return dim_map; +} + +/* Reorder the dimensions of "bmap" according to the given dim_map + * and set the dimension specification to "dim". + */ +__isl_give isl_basic_map *isl_basic_map_realign(__isl_take isl_basic_map *bmap, + __isl_take isl_dim *dim, __isl_take struct isl_dim_map *dim_map) +{ + isl_basic_map *res; + + bmap = isl_basic_map_cow(bmap); + if (!bmap || !dim || !dim_map) + goto error; + + res = isl_basic_map_alloc_dim(dim, + bmap->n_div, bmap->n_eq, bmap->n_ineq); + res = add_constraints_dim_map(res, bmap, dim_map); + res = isl_basic_map_finalize(res); + return res; +error: + free(dim_map); + isl_basic_map_free(bmap); + isl_dim_free(dim); + return NULL; +} + +/* Reorder the dimensions of "map" according to given reordering. + */ +__isl_give isl_map *isl_map_realign(__isl_take isl_map *map, + __isl_take isl_reordering *r) +{ + int i; + struct isl_dim_map *dim_map; + + map = isl_map_cow(map); + dim_map = isl_dim_map_from_reordering(r); + if (!map || !r || !dim_map) + goto error; + + for (i = 0; i < map->n; ++i) { + struct isl_dim_map *dim_map_i; + + dim_map_i = extend_dim_map(dim_map, map->p[i]); + + map->p[i] = isl_basic_map_realign(map->p[i], + isl_dim_copy(r->dim), dim_map_i); + + if (!map->p[i]) + goto error; + } + + map = isl_map_reset_dim(map, isl_dim_copy(r->dim)); + + isl_reordering_free(r); + free(dim_map); + return map; +error: + free(dim_map); + isl_map_free(map); + isl_reordering_free(r); + return NULL; +} + +__isl_give isl_set *isl_set_realign(__isl_take isl_set *set, + __isl_take isl_reordering *r) +{ + return (isl_set *)isl_map_realign((isl_map *)set, r); +} diff --git a/isl_map_private.h b/isl_map_private.h index 8053187..93923cb 100644 --- a/isl_map_private.h +++ b/isl_map_private.h @@ -7,10 +7,19 @@ * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium */ +#ifndef ISL_MAP_PRIVATE_H +#define ISL_MAP_PRIVATE_H + #include "isl_set.h" #include "isl_map.h" +#include #include "isl_vec.h" +__isl_give isl_map *isl_map_realign(__isl_take isl_map *map, + __isl_take isl_reordering *r); +__isl_give isl_set *isl_set_realign(__isl_take isl_set *set, + __isl_take isl_reordering *r); + __isl_give isl_map *isl_map_reset(__isl_take isl_map *map, enum isl_dim_type type); @@ -187,3 +196,5 @@ int isl_basic_set_add_div_constraints_var(__isl_keep isl_basic_set *bset, unsigned pos, isl_int *div); int isl_basic_map_is_div_constraint(__isl_keep isl_basic_map *bmap, isl_int *constraint, unsigned div); + +#endif diff --git a/isl_polynomial.c b/isl_polynomial.c index 03d7f1e..e6becb2 100644 --- a/isl_polynomial.c +++ b/isl_polynomial.c @@ -3332,3 +3332,69 @@ __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_mul( { return match_bin_op(upwqp1, upwqp2, &mul_entry); } + +/* Reorder the columns of the given div definitions according to the + * given reordering. + */ +static __isl_give isl_mat *reorder_divs(__isl_take isl_mat *div, + __isl_take isl_reordering *r) +{ + int i, j; + isl_mat *mat; + int extra; + + if (!div || !r) + goto error; + + extra = isl_dim_total(r->dim) + div->n_row - r->len; + mat = isl_mat_alloc(div->ctx, div->n_row, div->n_col + extra); + if (!mat) + goto error; + + for (i = 0; i < div->n_row; ++i) { + isl_seq_cpy(mat->row[i], div->row[i], 2); + isl_seq_clr(mat->row[i] + 2, mat->n_col - 2); + for (j = 0; j < r->len; ++j) + isl_int_set(mat->row[i][2 + r->pos[j]], + div->row[i][2 + j]); + } + + isl_reordering_free(r); + isl_mat_free(div); + return mat; +error: + isl_reordering_free(r); + isl_mat_free(div); + return NULL; +} + +/* Reorder the dimension of "qp" according to the given reordering. + */ +__isl_give isl_qpolynomial *isl_qpolynomial_realign( + __isl_take isl_qpolynomial *qp, __isl_take isl_reordering *r) +{ + qp = isl_qpolynomial_cow(qp); + if (!qp) + goto error; + + r = isl_reordering_extend(r, qp->div->n_row); + if (!r) + goto error; + + qp->div = reorder_divs(qp->div, isl_reordering_copy(r)); + if (!qp->div) + goto error; + + qp->upoly = reorder(qp->upoly, r->pos); + if (!qp->upoly) + goto error; + + qp = isl_qpolynomial_reset_dim(qp, isl_dim_copy(r->dim)); + + isl_reordering_free(r); + return qp; +error: + isl_qpolynomial_free(qp); + isl_reordering_free(r); + return NULL; +} diff --git a/isl_polynomial_private.h b/isl_polynomial_private.h index 4e420ae..32fbc86 100644 --- a/isl_polynomial_private.h +++ b/isl_polynomial_private.h @@ -4,6 +4,7 @@ #include #include #include +#include struct isl_upoly { int ref; @@ -198,3 +199,12 @@ __isl_give isl_qpolynomial *isl_qpolynomial_substitute_equalities( __isl_take isl_qpolynomial *qp, __isl_take isl_basic_set *eq); __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_substitute_equalities( __isl_take isl_qpolynomial_fold *fold, __isl_take isl_basic_set *eq); + +__isl_give isl_qpolynomial *isl_qpolynomial_realign( + __isl_take isl_qpolynomial *qp, __isl_take isl_reordering *r); +__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_realign( + __isl_take isl_qpolynomial_fold *fold, __isl_take isl_reordering *r); +__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_realign( + __isl_take isl_pw_qpolynomial *pwqp, __isl_take isl_reordering *r); +__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_realign( + __isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_reordering *r); diff --git a/isl_pw_templ.c b/isl_pw_templ.c index de96579..fb1f626 100644 --- a/isl_pw_templ.c +++ b/isl_pw_templ.c @@ -847,3 +847,32 @@ error: FN(PW,free)(pw); return NULL; } + +__isl_give PW *FN(PW,realign)(__isl_take PW *pw, __isl_take isl_reordering *exp) +{ + int i; + + pw = FN(PW,cow)(pw); + if (!pw || !exp) + return NULL; + + for (i = 0; i < pw->n; ++i) { + pw->p[i].set = isl_set_realign(pw->p[i].set, + isl_reordering_copy(exp)); + if (!pw->p[i].set) + goto error; + pw->p[i].FIELD = FN(EL,realign)(pw->p[i].FIELD, + isl_reordering_copy(exp)); + if (!pw->p[i].FIELD) + goto error; + } + + pw = FN(PW,reset_dim)(pw, isl_dim_copy(exp->dim)); + + isl_reordering_free(exp); + return pw; +error: + isl_reordering_free(exp); + FN(PW,free)(pw); + return NULL; +} diff --git a/isl_reordering.c b/isl_reordering.c new file mode 100644 index 0000000..63df9e7 --- /dev/null +++ b/isl_reordering.c @@ -0,0 +1,164 @@ +/* + * Copyright 2010 INRIA Saclay + * + * Use of this software is governed by the GNU LGPLv2.1 license + * + * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France, + * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod, + * 91893 Orsay, France + */ + +#include +#include + +__isl_give isl_reordering *isl_reordering_alloc(isl_ctx *ctx, unsigned len) +{ + isl_reordering *exp; + + exp = isl_alloc(ctx, struct isl_reordering, + sizeof(struct isl_reordering) + (len - 1) * sizeof(int)); + if (!exp) + return NULL; + + exp->ref = 1; + exp->len = len; + exp->dim = NULL; + + return exp; +} + +__isl_give isl_reordering *isl_reordering_copy(__isl_keep isl_reordering *exp) +{ + if (!exp) + return NULL; + + exp->ref++; + return exp; +} + +void isl_reordering_free(__isl_take isl_reordering *exp) +{ + if (!exp) + return; + + if (--exp->ref > 0) + return; + + isl_dim_free(exp->dim); + free(exp); +} + +/* Construct a reordering that maps the parameters of "alignee" + * to the corresponding parameters in a new dimension specification + * that has the parameters of "aligner" first, followed by + * any remaining parameters of "alignee" that do not occur in "aligner". + */ +__isl_give isl_reordering *isl_parameter_alignment_reordering( + __isl_keep isl_dim *alignee, __isl_keep isl_dim *aligner) +{ + int i, j; + isl_reordering *exp; + + if (!alignee || !aligner) + return NULL; + + exp = isl_reordering_alloc(alignee->ctx, alignee->nparam); + if (!exp) + return NULL; + + exp->dim = isl_dim_copy(aligner); + + for (i = 0; i < alignee->nparam; ++i) { + const char *name_i; + name_i = isl_dim_get_name(alignee, isl_dim_param, i); + if (!name_i) + isl_die(alignee->ctx, isl_error_invalid, + "cannot align unnamed parameters", goto error); + for (j = 0; j < aligner->nparam; ++j) { + const char *name_j; + name_j = isl_dim_get_name(aligner, isl_dim_param, j); + if (name_i == name_j) + break; + } + if (j < aligner->nparam) + exp->pos[i] = j; + else { + int pos; + pos = isl_dim_size(exp->dim, isl_dim_param); + exp->dim = isl_dim_add(exp->dim, isl_dim_param, 1); + exp->dim = isl_dim_set_name(exp->dim, + isl_dim_param, pos, name_i); + exp->pos[i] = pos; + } + } + + return exp; +error: + isl_reordering_free(exp); + return NULL; +} + +__isl_give isl_reordering *isl_reordering_extend(__isl_take isl_reordering *exp, + unsigned extra) +{ + int i; + isl_reordering *res; + int offset; + + if (!exp) + return NULL; + if (extra == 0) + return exp; + + offset = isl_dim_total(exp->dim) - exp->len; + res = isl_reordering_alloc(exp->dim->ctx, exp->len + extra); + if (!res) + goto error; + res->dim = isl_dim_copy(exp->dim); + for (i = 0; i < exp->len; ++i) + res->pos[i] = exp->pos[i]; + for (i = exp->len; i < res->len; ++i) + res->pos[i] = offset + i; + + isl_reordering_free(exp); + + return res; +error: + isl_reordering_free(exp); + return NULL; +} + +__isl_give isl_reordering *isl_reordering_extend_dim( + __isl_take isl_reordering *exp, __isl_take isl_dim *dim) +{ + int i; + isl_reordering *res; + int offset; + + if (!exp || !dim) + goto error; + + res = isl_reordering_extend(isl_reordering_copy(exp), + isl_dim_total(dim) - exp->len); + if (!res) + goto error; + isl_dim_free(res->dim); + res->dim = isl_dim_replace(dim, isl_dim_param, exp->dim); + + isl_reordering_free(exp); + + return res; +error: + isl_reordering_free(exp); + isl_dim_free(dim); + return NULL; +} + +void isl_reordering_dump(__isl_keep isl_reordering *exp) +{ + int i; + + for (i = 0; i < exp->len; ++i) + fprintf(stderr, "%d -> %d; ", i, exp->pos[i]); + fprintf(stderr, "\n"); +} diff --git a/isl_reordering.h b/isl_reordering.h new file mode 100644 index 0000000..0afb554 --- /dev/null +++ b/isl_reordering.h @@ -0,0 +1,31 @@ +#ifndef ISL_REORDERING_H +#define ISL_REORDERING_H + +#include + +/* pos maps original dimensions to new dimensions. + * The final dimension is given by dim. + * The number of dimensions (i.e., the range of values) in the result + * may be larger than the number of dimensions in the input. + * In particular, the possible values of the entries in pos ranges from 0 to + * the total dimension of dim - 1, unless isl_reordering_extend + * has been called. + */ +struct isl_reordering { + int ref; + isl_dim *dim; + unsigned len; + int pos[1]; +}; +typedef struct isl_reordering isl_reordering; + +__isl_give isl_reordering *isl_parameter_alignment_reordering( + __isl_keep isl_dim *alignee, __isl_keep isl_dim *aligner); +__isl_give isl_reordering *isl_reordering_copy(__isl_keep isl_reordering *exp); +void isl_reordering_free(__isl_take isl_reordering *exp); +__isl_give isl_reordering *isl_reordering_extend_dim( + __isl_take isl_reordering *exp, __isl_take isl_dim *dim); +__isl_give isl_reordering *isl_reordering_extend(__isl_take isl_reordering *exp, + unsigned extra); + +#endif diff --git a/isl_union_map.c b/isl_union_map.c index 96bdc77..f97063b 100644 --- a/isl_union_map.c +++ b/isl_union_map.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -115,9 +116,78 @@ __isl_give isl_union_map *isl_union_map_cow(__isl_take isl_union_map *umap) return isl_union_map_dup(umap); } +struct isl_union_align { + isl_reordering *exp; + isl_union_map *res; +}; + +static int align_entry(void **entry, void *user) +{ + isl_map *map = *entry; + isl_reordering *exp; + struct isl_union_align *data = user; + + exp = isl_reordering_extend_dim(isl_reordering_copy(data->exp), + isl_map_get_dim(map)); + + data->res = isl_union_map_add_map(data->res, + isl_map_realign(isl_map_copy(map), exp)); + + return 0; +} + +/* Align the parameters of umap along those of model. + * The result has the parameters of model first, in the same order + * as they appear in model, followed by any remaining parameters of + * umap that do not appear in model. + */ +__isl_give isl_union_map *isl_union_map_align_params( + __isl_take isl_union_map *umap, __isl_take isl_dim *model) +{ + struct isl_union_align data = { NULL, NULL }; + + if (!umap || !model) + goto error; + + if (isl_dim_match(umap->dim, isl_dim_param, model, isl_dim_param)) { + isl_dim_free(model); + return umap; + } + + data.exp = isl_parameter_alignment_reordering(umap->dim, model); + if (!data.exp) + goto error; + + data.res = isl_union_map_alloc(isl_dim_copy(data.exp->dim), + umap->table.n); + if (isl_hash_table_foreach(umap->dim->ctx, &umap->table, + &align_entry, &data) < 0) + goto error; + + isl_reordering_free(data.exp); + isl_union_map_free(umap); + isl_dim_free(model); + return data.res; +error: + isl_reordering_free(data.exp); + isl_union_map_free(umap); + isl_union_map_free(data.res); + isl_dim_free(model); + return NULL; +} + +__isl_give isl_union_set *isl_union_set_align_params( + __isl_take isl_union_set *uset, __isl_take isl_dim *model) +{ + return isl_union_map_align_params(uset, model); +} + __isl_give isl_union_map *isl_union_map_union(__isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2) { + umap1 = isl_union_map_align_params(umap1, isl_union_map_get_dim(umap2)); + umap2 = isl_union_map_align_params(umap2, isl_union_map_get_dim(umap1)); + umap1 = isl_union_map_cow(umap1); if (!umap1 || !umap2) @@ -347,11 +417,15 @@ static int subtract_entry(void **entry, void *user) static __isl_give isl_union_map *gen_bin_op(__isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2, int (*fn)(void **, void *)) { - struct isl_union_map_gen_bin_data data = { umap2, NULL }; + struct isl_union_map_gen_bin_data data = { NULL, NULL }; + + umap1 = isl_union_map_align_params(umap1, isl_union_map_get_dim(umap2)); + umap2 = isl_union_map_align_params(umap2, isl_union_map_get_dim(umap1)); if (!umap1 || !umap2) goto error; + data.umap2 = umap2; data.res = isl_union_map_alloc(isl_dim_copy(umap1->dim), umap1->table.n); if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table, @@ -422,11 +496,15 @@ static __isl_give isl_union_map *match_bin_op(__isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2, __isl_give isl_map *(*fn)(__isl_take isl_map*, __isl_take isl_map*)) { - struct isl_union_map_match_bin_data data = { umap2, NULL, fn }; + struct isl_union_map_match_bin_data data = { NULL, NULL, fn }; + + umap1 = isl_union_map_align_params(umap1, isl_union_map_get_dim(umap2)); + umap2 = isl_union_map_align_params(umap2, isl_union_map_get_dim(umap1)); if (!umap1 || !umap2) goto error; + data.umap2 = umap2; data.res = isl_union_map_alloc(isl_dim_copy(umap1->dim), umap1->table.n); if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table, @@ -559,11 +637,15 @@ static int bin_entry(void **entry, void *user) static __isl_give isl_union_map *bin_op(__isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2, int (*fn)(void **entry, void *user)) { - struct isl_union_map_bin_data data = { umap2, NULL, NULL, fn }; + struct isl_union_map_bin_data data = { NULL, NULL, NULL, fn }; + + umap1 = isl_union_map_align_params(umap1, isl_union_map_get_dim(umap2)); + umap2 = isl_union_map_align_params(umap2, isl_union_map_get_dim(umap1)); if (!umap1 || !umap2) goto error; + data.umap2 = umap2; data.res = isl_union_map_alloc(isl_dim_copy(umap1->dim), umap1->table.n); if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table, @@ -903,17 +985,30 @@ static int is_subset_entry(void **entry, void *user) int isl_union_map_is_subset(__isl_keep isl_union_map *umap1, __isl_keep isl_union_map *umap2) { - struct isl_union_map_is_subset_data data = { umap2, 1 }; + struct isl_union_map_is_subset_data data = { NULL, 1 }; + + umap1 = isl_union_map_copy(umap1); + umap2 = isl_union_map_copy(umap2); + umap1 = isl_union_map_align_params(umap1, isl_union_map_get_dim(umap2)); + umap2 = isl_union_map_align_params(umap2, isl_union_map_get_dim(umap1)); if (!umap1 || !umap2) - return -1; + goto error; + data.umap2 = umap2; if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table, &is_subset_entry, &data) < 0 && data.is_subset) - return -1; + goto error; + + isl_union_map_free(umap1); + isl_union_map_free(umap2); return data.is_subset; +error: + isl_union_map_free(umap1); + isl_union_map_free(umap2); + return -1; } int isl_union_map_is_equal(__isl_keep isl_union_map *umap1, diff --git a/isl_union_templ.c b/isl_union_templ.c index 36a25d3..4fa60f3 100644 --- a/isl_union_templ.c +++ b/isl_union_templ.c @@ -229,8 +229,69 @@ void FN(UNION,free)(__isl_take UNION *u) free(u); } +S(UNION,align) { + isl_reordering *exp; + UNION *res; +}; + +static int align_entry(__isl_take PART *part, void *user) +{ + isl_reordering *exp; + S(UNION,align) *data = user; + + exp = isl_reordering_extend_dim(isl_reordering_copy(data->exp), + FN(PART,get_dim)(part)); + + data->res = FN(FN(UNION,add),PARTS)(data->res, + FN(PART,realign)(part, exp)); + + return 0; +} + +__isl_give UNION *FN(UNION,align_params)(__isl_take UNION *u, + __isl_take isl_dim *model) +{ + int i, j; + S(UNION,align) data = { NULL, NULL }; + + if (!u || !model) + goto error; + + if (isl_dim_match(u->dim, isl_dim_param, model, isl_dim_param)) { + isl_dim_free(model); + return u; + } + + data.exp = isl_parameter_alignment_reordering(u->dim, model); + if (!data.exp) + goto error; + +#ifdef HAS_TYPE + data.res = FN(UNION,alloc)(isl_dim_copy(data.exp->dim), + u->type, u->table.n); +#else + data.res = FN(UNION,alloc)(isl_dim_copy(data.exp->dim), u->table.n); +#endif + if (FN(FN(UNION,foreach),PARTS)(u, &align_entry, &data) < 0) + goto error; + + isl_reordering_free(data.exp); + FN(UNION,free)(u); + isl_dim_free(model); + return data.res; +error: + isl_reordering_free(data.exp); + FN(UNION,free)(u); + FN(UNION,free)(data.res); + isl_dim_free(model); + return NULL; +} + __isl_give UNION *FN(UNION,add)(__isl_take UNION *u1, __isl_take UNION *u2) { + u1 = FN(UNION,align_params)(u1, FN(UNION,get_dim)(u2)); + u2 = FN(UNION,align_params)(u2, FN(UNION,get_dim)(u1)); + u1 = FN(UNION,cow)(u1); if (!u1 || !u2) @@ -277,11 +338,15 @@ S(UNION,match_bin_data) { static __isl_give UNION *match_bin_op(__isl_take UNION *u1, __isl_take UNION *u2, int (*fn)(void **, void *)) { - S(UNION,match_bin_data) data = { u2, NULL }; + S(UNION,match_bin_data) data = { NULL, NULL }; + + u1 = FN(UNION,align_params)(u1, FN(UNION,get_dim)(u2)); + u2 = FN(UNION,align_params)(u2, FN(UNION,get_dim)(u1)); if (!u1 || !u2) goto error; + data.u2 = u2; #ifdef HAS_TYPE data.res = FN(UNION,alloc)(isl_dim_copy(u1->dim), u1->type, u1->table.n); #else @@ -351,11 +416,15 @@ static __isl_give UNION *match_set_op(__isl_take UNION *u, __isl_take isl_union_set *uset, __isl_give PW *(*fn)(__isl_take PW*, __isl_take isl_set*)) { - S(UNION,match_set_data) data = { uset, NULL, fn }; + S(UNION,match_set_data) data = { NULL, NULL, fn }; + + u = FN(UNION,align_params)(u, isl_union_set_get_dim(uset)); + uset = isl_union_set_align_params(uset, FN(UNION,get_dim)(u)); if (!u || !uset) goto error; + data.uset = uset; #ifdef HAS_TYPE data.res = FN(UNION,alloc)(isl_dim_copy(u->dim), u->type, u->table.n); #else -- 2.7.4