From d7276caf78702c11e9448c67d46bb362de734357 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 16 Aug 2011 11:02:36 +0200 Subject: [PATCH] add isl_set_substitute Signed-off-by: Sven Verdoolaege --- isl_map.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ isl_map_private.h | 3 ++ 2 files changed, 122 insertions(+) diff --git a/isl_map.c b/isl_map.c index b9212c8..602b2c0 100644 --- a/isl_map.c +++ b/isl_map.c @@ -9769,3 +9769,122 @@ __isl_give isl_aff *isl_basic_set_get_div(__isl_keep isl_basic_set *bset, { return isl_basic_map_get_div(bset, pos); } + +/* Plug in "subs" for dimension "type", "pos" of "bset". + * + * Let i be the dimension to replace and let "subs" be of the form + * + * f/d + * + * Any integer division with a non-zero coefficient for i, + * + * floor((a i + g)/m) + * + * is replaced by + * + * floor((a f + d g)/(m d)) + * + * Constraints of the form + * + * a i + g + * + * are replaced by + * + * a f + d g + */ +__isl_give isl_basic_set *isl_basic_set_substitute( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs) +{ + int i; + isl_int v; + isl_ctx *ctx; + + if (bset && isl_basic_set_plain_is_empty(bset)) + return bset; + + bset = isl_basic_set_cow(bset); + if (!bset || !subs) + goto error; + + ctx = isl_basic_set_get_ctx(bset); + if (!isl_space_is_equal(bset->dim, subs->ls->dim)) + isl_die(ctx, isl_error_invalid, + "spaces don't match", goto error); + if (isl_local_space_dim(subs->ls, isl_dim_div) != 0) + isl_die(ctx, isl_error_unsupported, + "cannot handle divs yet", goto error); + + pos += isl_basic_set_offset(bset, type); + + isl_int_init(v); + + for (i = 0; i < bset->n_eq; ++i) { + if (isl_int_is_zero(bset->eq[i][pos])) + continue; + isl_int_set(v, bset->eq[i][pos]); + isl_int_set_si(bset->eq[i][pos], 0); + isl_seq_combine(bset->eq[i], subs->v->el[0], bset->eq[i], + v, subs->v->el + 1, subs->v->size - 1); + } + + for (i = 0; i < bset->n_ineq; ++i) { + if (isl_int_is_zero(bset->ineq[i][pos])) + continue; + isl_int_set(v, bset->ineq[i][pos]); + isl_int_set_si(bset->ineq[i][pos], 0); + isl_seq_combine(bset->ineq[i], subs->v->el[0], bset->ineq[i], + v, subs->v->el + 1, subs->v->size - 1); + } + + for (i = 0; i < bset->n_div; ++i) { + if (isl_int_is_zero(bset->div[i][1 + pos])) + continue; + isl_int_set(v, bset->div[i][1 + pos]); + isl_int_set_si(bset->div[i][1 + pos], 0); + isl_seq_combine(bset->div[i] + 1, + subs->v->el[0], bset->div[i] + 1, + v, subs->v->el + 1, subs->v->size - 1); + isl_int_mul(bset->div[i][0], bset->div[i][0], subs->v->el[0]); + } + + isl_int_clear(v); + + bset = isl_basic_set_simplify(bset); + return isl_basic_set_finalize(bset); +error: + isl_basic_set_free(bset); + return NULL; +} + +/* Plug in "subs" for dimension "type", "pos" of "set". + */ +__isl_give isl_set *isl_set_substitute(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs) +{ + int i; + + if (set && isl_set_plain_is_empty(set)) + return set; + + set = isl_set_cow(set); + if (!set || !subs) + goto error; + + for (i = set->n - 1; i >= 0; --i) { + set->p[i] = isl_basic_set_substitute(set->p[i], type, pos, subs); + if (!set->p[i]) + goto error; + if (isl_basic_set_plain_is_empty(set->p[i])) { + isl_basic_set_free(set->p[i]); + if (i != set->n - 1) + set->p[i] = set->p[set->n - 1]; + set->n--; + } + } + + return set; +error: + isl_set_free(set); + return NULL; +} diff --git a/isl_map_private.h b/isl_map_private.h index 121e5cd..f3202c0 100644 --- a/isl_map_private.h +++ b/isl_map_private.h @@ -327,4 +327,7 @@ int isl_basic_set_foreach_lexopt(__isl_keep isl_basic_set *bset, int max, void *user), void *user); +__isl_give isl_set *isl_set_substitute(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs); + #endif -- 2.7.4