From: Sven Verdoolaege Date: Fri, 6 Aug 2010 10:28:04 +0000 (+0200) Subject: isl_qpolynomial_move_dims: plug memory leak and fix reordering of divs X-Git-Tag: isl-0.04~43 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=20273cff26b9164b6761634a93514b0e19dd6322;p=platform%2Fupstream%2Fisl.git isl_qpolynomial_move_dims: plug memory leak and fix reordering of divs In particular, when divs got reordered, the new order would not be reflected in the associated upoly. Signed-off-by: Sven Verdoolaege --- diff --git a/isl_polynomial.c b/isl_polynomial.c index bf51598..de500c2 100644 --- a/isl_polynomial.c +++ b/isl_polynomial.c @@ -941,6 +941,67 @@ void isl_qpolynomial_free(__isl_take isl_qpolynomial *qp) free(qp); } +__isl_give struct isl_upoly *isl_upoly_pow(isl_ctx *ctx, int pos, int power) +{ + int i; + struct isl_upoly *up; + struct isl_upoly_rec *rec; + struct isl_upoly_cst *cst; + + rec = isl_upoly_alloc_rec(ctx, pos, 1 + power); + if (!rec) + return NULL; + for (i = 0; i < 1 + power; ++i) { + rec->p[i] = isl_upoly_zero(ctx); + if (!rec->p[i]) + goto error; + rec->n++; + } + cst = isl_upoly_as_cst(rec->p[power]); + isl_int_set_si(cst->n, 1); + + return &rec->up; +error: + isl_upoly_free(&rec->up); + return NULL; +} + +/* r array maps original positions to new positions. + */ +static __isl_give struct isl_upoly *reorder(__isl_take struct isl_upoly *up, + int *r) +{ + int i; + struct isl_upoly_rec *rec; + struct isl_upoly *base; + struct isl_upoly *res; + + if (isl_upoly_is_cst(up)) + return up; + + rec = isl_upoly_as_rec(up); + if (!rec) + goto error; + + isl_assert(up->ctx, rec->n >= 1, goto error); + + base = isl_upoly_pow(up->ctx, r[up->var], 1); + res = reorder(isl_upoly_copy(rec->p[rec->n - 1]), r); + + for (i = rec->n - 2; i >= 0; --i) { + res = isl_upoly_mul(res, isl_upoly_copy(base)); + res = isl_upoly_sum(res, reorder(isl_upoly_copy(rec->p[i]), r)); + } + + isl_upoly_free(base); + isl_upoly_free(up); + + return res; +error: + isl_upoly_free(up); + return NULL; +} + static int compatible_divs(__isl_keep isl_mat *div1, __isl_keep isl_mat *div2) { int n_row, n_col; @@ -1005,49 +1066,69 @@ static int div_sort_cmp(const void *p1, const void *p2) return cmp_row(i1->div, i1->row, i2->row); } -static __isl_give isl_mat *sort_divs(__isl_take isl_mat *div) +static __isl_give isl_qpolynomial *sort_divs(__isl_take isl_qpolynomial *qp) { int i; struct isl_div_sort_info *array = NULL; int *pos = NULL; + int *reordering = NULL; + unsigned div_pos; - if (!div) + if (!qp) return NULL; - if (div->n_row <= 1) - return div; + if (qp->div->n_row <= 1) + return qp; + + div_pos = isl_dim_total(qp->dim); - array = isl_alloc_array(div->ctx, struct isl_div_sort_info, div->n_row); - pos = isl_alloc_array(div->ctx, int, div->n_row); - if (!array || !pos) + array = isl_alloc_array(qp->div->ctx, struct isl_div_sort_info, + qp->div->n_row); + pos = isl_alloc_array(qp->div->ctx, int, qp->div->n_row); + reordering = isl_alloc_array(qp->div->ctx, int, qp->div->n_col - 2); + if (!array || !pos || !reordering) goto error; - for (i = 0; i < div->n_row; ++i) { - array[i].div = div; + for (i = 0; i < qp->div->n_row; ++i) { + array[i].div = qp->div; array[i].row = i; pos[i] = i; } - qsort(array, div->n_row, sizeof(struct isl_div_sort_info), + qsort(array, qp->div->n_row, sizeof(struct isl_div_sort_info), div_sort_cmp); - for (i = 0; i < div->n_row; ++i) { + for (i = 0; i < div_pos; ++i) + reordering[i] = i; + + for (i = 0; i < qp->div->n_row; ++i) + reordering[div_pos + array[i].row] = div_pos + i; + + for (i = 0; i < qp->div->n_row; ++i) { int t; if (pos[array[i].row] == i) continue; - div = isl_mat_cow(div); - div = isl_mat_swap_rows(div, i, pos[array[i].row]); + qp->div = isl_mat_cow(qp->div); + qp->div = isl_mat_swap_rows(qp->div, i, pos[array[i].row]); t = pos[array[i].row]; pos[array[i].row] = pos[i]; pos[i] = t; } + qp->upoly = reorder(qp->upoly, reordering); + + if (!qp->upoly || !qp->div) + goto error; + + free(pos); free(array); + free(reordering); - return div; + return qp; error: free(pos); free(array); - isl_mat_free(div); + free(reordering); + isl_qpolynomial_free(qp); return NULL; } @@ -1480,31 +1561,6 @@ void isl_qpolynomial_get_den(__isl_keep isl_qpolynomial *qp, isl_int *d) upoly_update_den(qp->upoly, d); } -__isl_give struct isl_upoly *isl_upoly_pow(isl_ctx *ctx, int pos, int power) -{ - int i; - struct isl_upoly *up; - struct isl_upoly_rec *rec; - struct isl_upoly_cst *cst; - - rec = isl_upoly_alloc_rec(ctx, pos, 1 + power); - if (!rec) - return NULL; - for (i = 0; i < 1 + power; ++i) { - rec->p[i] = isl_upoly_zero(ctx); - if (!rec->p[i]) - goto error; - rec->n++; - } - cst = isl_upoly_as_cst(rec->p[power]); - isl_int_set_si(cst->n, 1); - - return &rec->up; -error: - isl_upoly_free(&rec->up); - return NULL; -} - __isl_give isl_qpolynomial *isl_qpolynomial_pow(__isl_take isl_dim *dim, int pos, int power) { @@ -2192,40 +2248,6 @@ static int *reordering_move(isl_ctx *ctx, return reordering; } -static __isl_give struct isl_upoly *reorder(__isl_take struct isl_upoly *up, - int *r) -{ - int i; - struct isl_upoly_rec *rec; - struct isl_upoly *base; - struct isl_upoly *res; - - if (isl_upoly_is_cst(up)) - return up; - - rec = isl_upoly_as_rec(up); - if (!rec) - goto error; - - isl_assert(up->ctx, rec->n >= 1, goto error); - - base = isl_upoly_pow(up->ctx, r[up->var], 1); - res = reorder(isl_upoly_copy(rec->p[rec->n - 1]), r); - - for (i = rec->n - 2; i >= 0; --i) { - res = isl_upoly_mul(res, isl_upoly_copy(base)); - res = isl_upoly_sum(res, reorder(isl_upoly_copy(rec->p[i]), r)); - } - - isl_upoly_free(base); - isl_upoly_free(up); - - return res; -error: - isl_upoly_free(up); - return NULL; -} - __isl_give isl_qpolynomial *isl_qpolynomial_move_dims( __isl_take isl_qpolynomial *qp, enum isl_dim_type dst_type, unsigned dst_pos, @@ -2248,9 +2270,11 @@ __isl_give isl_qpolynomial *isl_qpolynomial_move_dims( g_dst_pos -= n; qp->div = isl_mat_move_cols(qp->div, 2 + g_dst_pos, 2 + g_src_pos, n); - qp->div = sort_divs(qp->div); if (!qp->div) goto error; + qp = sort_divs(qp); + if (!qp) + goto error; reordering = reordering_move(qp->dim->ctx, qp->div->n_col - 2, g_dst_pos, g_src_pos, n); diff --git a/isl_test.c b/isl_test.c index dcb417d..14f633d 100644 --- a/isl_test.c +++ b/isl_test.c @@ -14,6 +14,7 @@ #include #include #include +#include static char *srcdir; @@ -1362,6 +1363,27 @@ void test_bijective(struct isl_ctx *ctx) test_bijective_case(ctx, "[N,M]->{[i,j] -> [x,y] : 2x=i & y =j}", 1); } +void test_pwqp(struct isl_ctx *ctx) +{ + const char *str; + isl_pw_qpolynomial *pwqp1, *pwqp2; + + str = "{ [i,j,k] -> 1 + 9 * [i/5] + 7 * [j/11] + 4 * [k/13] }"; + pwqp1 = isl_pw_qpolynomial_read_from_str(ctx, str); + + pwqp1 = isl_pw_qpolynomial_move_dims(pwqp1, isl_dim_param, 0, + isl_dim_set, 1, 1); + + str = "[j] -> { [i,k] -> 1 + 9 * [i/5] + 7 * [j/11] + 4 * [k/13] }"; + pwqp2 = isl_pw_qpolynomial_read_from_str(ctx, str); + + pwqp1 = isl_pw_qpolynomial_sub(pwqp1, pwqp2); + + assert(isl_pw_qpolynomial_is_zero(pwqp1)); + + isl_pw_qpolynomial_free(pwqp1); +} + int main() { struct isl_ctx *ctx; @@ -1370,6 +1392,7 @@ int main() assert(srcdir); ctx = isl_ctx_alloc(); + test_pwqp(ctx); test_lex(ctx); test_sv(ctx); test_bijective(ctx);