From: Sven Verdoolaege Date: Thu, 12 May 2011 10:24:16 +0000 (+0200) Subject: isl_polynomial.c: move merge_divs to isl_local_space.c X-Git-Tag: isl-0.07~191 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0b90c0e67236a9f47530297a3fa45dfb2cb06a7a;p=platform%2Fupstream%2Fisl.git isl_polynomial.c: move merge_divs to isl_local_space.c In time, we will want to define isl_qpolynomials over isl_local_spaces. We start by moving some of the handling of divs to isl_local_space.c as it also useful for local spaces in general. The merging is adapted to handle possibly unknown divs, which should never be merged. Signed-off-by: Sven Verdoolaege --- diff --git a/isl_local_space.c b/isl_local_space.c index a2d6fca..a74ef13 100644 --- a/isl_local_space.c +++ b/isl_local_space.c @@ -218,3 +218,92 @@ error: isl_local_space_free(ls); return NULL; } + +/* Copy row "s" of "src" to row "d" of "dst", applying the expansion + * defined by "exp". + */ +static void expand_row(__isl_keep isl_mat *dst, int d, + __isl_keep isl_mat *src, int s, int *exp) +{ + int i; + unsigned c = src->n_col - src->n_row; + + isl_seq_cpy(dst->row[d], src->row[s], c); + isl_seq_clr(dst->row[d] + c, dst->n_col - c); + + for (i = 0; i < s; ++i) + isl_int_set(dst->row[d][c + exp[i]], src->row[s][c + i]); +} + +/* Compare (known) divs. + * Return non-zero if at least one of the two divs is unknown. + */ +static int cmp_row(__isl_keep isl_mat *div, int i, int j) +{ + int li, lj; + + if (isl_int_is_zero(div->row[j][0])) + return -1; + if (isl_int_is_zero(div->row[i][0])) + return 1; + + li = isl_seq_last_non_zero(div->row[i], div->n_col); + lj = isl_seq_last_non_zero(div->row[j], div->n_col); + + if (li != lj) + return li - lj; + + return isl_seq_cmp(div->row[i], div->row[j], div->n_col); +} + +/* Combine the two lists of divs into a single list. + * For each row i in div1, exp1[i] is set to the position of the corresponding + * row in the result. Similarly for div2 and exp2. + * This function guarantees + * exp1[i] >= i + * exp1[i+1] > exp1[i] + * For optimal merging, the two input list should have been sorted. + */ +__isl_give isl_mat *isl_merge_divs(__isl_keep isl_mat *div1, + __isl_keep isl_mat *div2, int *exp1, int *exp2) +{ + int i, j, k; + isl_mat *div = NULL; + unsigned d = div1->n_col - div1->n_row; + + div = isl_mat_alloc(div1->ctx, 1 + div1->n_row + div2->n_row, + d + div1->n_row + div2->n_row); + if (!div) + return NULL; + + for (i = 0, j = 0, k = 0; i < div1->n_row && j < div2->n_row; ++k) { + int cmp; + + expand_row(div, k, div1, i, exp1); + expand_row(div, k + 1, div2, j, exp2); + + cmp = cmp_row(div, k, k + 1); + if (cmp == 0) { + exp1[i++] = k; + exp2[j++] = k; + } else if (cmp < 0) { + exp1[i++] = k; + } else { + exp2[j++] = k; + isl_seq_cpy(div->row[k], div->row[k + 1], div->n_col); + } + } + for (; i < div1->n_row; ++i, ++k) { + expand_row(div, k, div1, i, exp1); + exp1[i] = k; + } + for (; j < div2->n_row; ++j, ++k) { + expand_row(div, k, div2, j, exp2); + exp2[j] = k; + } + + div->n_row = k; + div->n_col = d + k; + + return div; +} diff --git a/isl_local_space_private.h b/isl_local_space_private.h index b77d091..b0760ed 100644 --- a/isl_local_space_private.h +++ b/isl_local_space_private.h @@ -18,6 +18,9 @@ __isl_give isl_local_space *isl_local_space_alloc(__isl_take isl_dim *dim, __isl_give isl_local_space *isl_local_space_add_div( __isl_take isl_local_space *ls, __isl_take isl_vec *div); +__isl_give isl_mat *isl_merge_divs(__isl_keep isl_mat *div1, + __isl_keep isl_mat *div2, int *exp1, int *exp2); + unsigned isl_local_space_offset(__isl_keep isl_local_space *ls, enum isl_dim_type type); diff --git a/isl_polynomial.c b/isl_polynomial.c index 42d4e3f..db081ee 100644 --- a/isl_polynomial.c +++ b/isl_polynomial.c @@ -21,6 +21,7 @@ #include #include #include +#include static unsigned pos(__isl_keep isl_dim *dim, enum isl_dim_type type) { @@ -1116,19 +1117,6 @@ static int compatible_divs(__isl_keep isl_mat *div1, __isl_keep isl_mat *div2) return equal; } -static void expand_row(__isl_keep isl_mat *dst, int d, - __isl_keep isl_mat *src, int s, int *exp) -{ - int i; - unsigned c = src->n_col - src->n_row; - - isl_seq_cpy(dst->row[d], src->row[s], c); - isl_seq_clr(dst->row[d] + c, dst->n_col - c); - - for (i = 0; i < s; ++i) - isl_int_set(dst->row[d][c + exp[i]], src->row[s][c + i]); -} - static int cmp_row(__isl_keep isl_mat *div, int i, int j) { int li, lj; @@ -1242,50 +1230,6 @@ error: return NULL; } -static __isl_give isl_mat *merge_divs(__isl_keep isl_mat *div1, - __isl_keep isl_mat *div2, int *exp1, int *exp2) -{ - int i, j, k; - isl_mat *div = NULL; - unsigned d = div1->n_col - div1->n_row; - - div = isl_mat_alloc(div1->ctx, 1 + div1->n_row + div2->n_row, - d + div1->n_row + div2->n_row); - if (!div) - return NULL; - - for (i = 0, j = 0, k = 0; i < div1->n_row && j < div2->n_row; ++k) { - int cmp; - - expand_row(div, k, div1, i, exp1); - expand_row(div, k + 1, div2, j, exp2); - - cmp = cmp_row(div, k, k + 1); - if (cmp == 0) { - exp1[i++] = k; - exp2[j++] = k; - } else if (cmp < 0) { - exp1[i++] = k; - } else { - exp2[j++] = k; - isl_seq_cpy(div->row[k], div->row[k + 1], div->n_col); - } - } - for (; i < div1->n_row; ++i, ++k) { - expand_row(div, k, div1, i, exp1); - exp1[i] = k; - } - for (; j < div2->n_row; ++j, ++k) { - expand_row(div, k, div2, j, exp2); - exp2[j] = k; - } - - div->n_row = k; - div->n_col = d + k; - - return div; -} - static __isl_give struct isl_upoly *expand(__isl_take struct isl_upoly *up, int *exp, int first) { @@ -1346,7 +1290,7 @@ static __isl_give isl_qpolynomial *with_merged_divs( if (!exp1 || !exp2) goto error; - div = merge_divs(qp1->div, qp2->div, exp1, exp2); + div = isl_merge_divs(qp1->div, qp2->div, exp1, exp2); if (!div) goto error;