X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=isl_local_space.c;h=e279f72b9e589da765de14e8f73739fc819f73b4;hb=b7d848b49611b6bed2bfb1c7ab329beb54eca31d;hp=296ef192feb2fa8bf4521db0ec2c3608b2102c2b;hpb=7a12daf6febfdcfa07bc4a8301cbaaabd7ea7e11;p=platform%2Fupstream%2Fisl.git diff --git a/isl_local_space.c b/isl_local_space.c index 296ef19..e279f72 100644 --- a/isl_local_space.c +++ b/isl_local_space.c @@ -8,6 +8,7 @@ * 91893 Orsay, France */ +#include #include #include #include @@ -112,6 +113,24 @@ void *isl_local_space_free(__isl_take isl_local_space *ls) return NULL; } +/* Return true if the two local spaces are identical, with identical + * expressions for the integer divisions. + */ +int isl_local_space_is_equal(__isl_keep isl_local_space *ls1, + __isl_keep isl_local_space *ls2) +{ + int equal; + + if (!ls1 || !ls2) + return -1; + + equal = isl_dim_equal(ls1->dim, ls2->dim); + if (equal < 0 || !equal) + return equal; + + return isl_mat_is_equal(ls1->div, ls2->div); +} + int isl_local_space_dim(__isl_keep isl_local_space *ls, enum isl_dim_type type) { @@ -173,6 +192,20 @@ __isl_give isl_dim *isl_local_space_get_dim(__isl_keep isl_local_space *ls) return isl_dim_copy(ls->dim); } +__isl_give isl_local_space *isl_local_space_set_dim_name( + __isl_take isl_local_space *ls, + enum isl_dim_type type, unsigned pos, const char *s) +{ + ls = isl_local_space_cow(ls); + if (!ls) + return NULL; + ls->dim = isl_dim_set_name(ls->dim, type, pos, s); + if (!ls->dim) + return isl_local_space_free(ls); + + return ls; +} + __isl_give isl_local_space *isl_local_space_add_div( __isl_take isl_local_space *ls, __isl_take isl_vec *div) { @@ -365,3 +398,68 @@ __isl_give isl_local_space *isl_local_space_add_dim( return ls; } + +/* Remove common factor of non-constant terms and denominator. + */ +static void normalize_div(__isl_keep isl_local_space *ls, int div) +{ + isl_ctx *ctx = ls->div->ctx; + unsigned total = ls->div->n_col - 2; + + isl_seq_gcd(ls->div->row[div] + 2, total, &ctx->normalize_gcd); + isl_int_gcd(ctx->normalize_gcd, + ctx->normalize_gcd, ls->div->row[div][0]); + if (isl_int_is_one(ctx->normalize_gcd)) + return; + + isl_seq_scale_down(ls->div->row[div] + 2, ls->div->row[div] + 2, + ctx->normalize_gcd, total); + isl_int_divexact(ls->div->row[div][0], ls->div->row[div][0], + ctx->normalize_gcd); + isl_int_fdiv_q(ls->div->row[div][1], ls->div->row[div][1], + ctx->normalize_gcd); +} + +/* Exploit the equalities in "eq" to simplify the expressions of + * the integer divisions in "ls". + * The integer divisions in "ls" are assumed to appear as regular + * dimensions in "eq". + */ +__isl_give isl_local_space *isl_local_space_substitute_equalities( + __isl_take isl_local_space *ls, __isl_take isl_basic_set *eq) +{ + int i, j, k; + unsigned total; + unsigned n_div; + + ls = isl_local_space_cow(ls); + if (!ls || !eq) + goto error; + + total = isl_dim_total(eq->dim); + if (isl_local_space_dim(ls, isl_dim_all) != total) + isl_die(isl_local_space_get_ctx(ls), isl_error_invalid, + "dimensions don't match", goto error); + total++; + n_div = eq->n_div; + for (i = 0; i < eq->n_eq; ++i) { + j = isl_seq_last_non_zero(eq->eq[i], total + n_div); + if (j < 0 || j == 0 || j >= total) + continue; + + for (k = 0; k < ls->div->n_row; ++k) { + if (isl_int_is_zero(ls->div->row[k][1 + j])) + continue; + isl_seq_elim(ls->div->row[k] + 1, eq->eq[i], j, total, + &ls->div->row[k][0]); + normalize_div(ls, k); + } + } + + isl_basic_set_free(eq); + return ls; +error: + isl_basic_set_free(eq); + isl_local_space_free(ls); + return NULL; +}