From d39e3556a92d74435094f46d998b7df3d19cb875 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 10 Nov 2015 15:22:50 +0100 Subject: [PATCH] extract out shared isl_qpolynomial_{take,restore}_local This isolates the local variables manipulation of a quasi-polynomial. Signed-off-by: Sven Verdoolaege --- isl_polynomial.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/isl_polynomial.c b/isl_polynomial.c index f10e6570..659fef40 100644 --- a/isl_polynomial.c +++ b/isl_polynomial.c @@ -525,6 +525,60 @@ __isl_keep isl_local *isl_qpolynomial_get_local( return qp ? isl_local_copy(qp->div) : NULL; } +/* Return the local variables of "qp". + * This may be either a copy or the local variables themselves + * if there is only one reference to "qp". + * This allows the local variables to be modified in-place + * if both the quasi-polynomial and its local variables + * have only a single reference. + * The caller is not allowed to modify "qp" between this call and + * the subsequent call to isl_qpolynomial_restore_local. + * The only exception is that isl_qpolynomial_free can be called instead. + */ +static __isl_give isl_local *isl_qpolynomial_take_local( + __isl_keep isl_qpolynomial *qp) +{ + isl_local *local; + + if (!qp) + return NULL; + if (qp->ref != 1) + return isl_qpolynomial_get_local(qp); + local = qp->div; + qp->div = NULL; + return local; +} + +/* Set the local variables of "qp" to "local", + * where the local variables of "qp" may be missing + * due to a preceding call to isl_qpolynomial_take_local. + * However, in this case, "qp" only has a single reference and + * then the call to isl_qpolynomial_cow has no effect. + */ +static __isl_give isl_qpolynomial *isl_qpolynomial_restore_local( + __isl_keep isl_qpolynomial *qp, __isl_take isl_local *local) +{ + if (!qp || !local) + goto error; + + if (qp->div == local) { + isl_local_free(local); + return qp; + } + + qp = isl_qpolynomial_cow(qp); + if (!qp) + goto error; + isl_local_free(qp->div); + qp->div = local; + + return qp; +error: + isl_qpolynomial_free(qp); + isl_local_free(local); + return NULL; +} + /* Return a copy of the local space on which "qp" is defined. */ static __isl_give isl_local_space *isl_qpolynomial_get_domain_local_space( @@ -3528,6 +3582,7 @@ __isl_give isl_qpolynomial *isl_qpolynomial_move_dims( isl_size src_off, dst_off; int *reordering; isl_space *space; + isl_local *local; isl_poly *poly; if (!qp) @@ -3553,7 +3608,6 @@ __isl_give isl_qpolynomial *isl_qpolynomial_move_dims( !isl_space_is_named_or_nested(qp->dim, dst_type)) return qp; - qp = isl_qpolynomial_cow(qp); src_off = isl_qpolynomial_domain_var_offset(qp, src_type); dst_off = isl_qpolynomial_domain_var_offset(qp, dst_type); if (src_off < 0 || dst_off < 0) @@ -3564,9 +3618,9 @@ __isl_give isl_qpolynomial *isl_qpolynomial_move_dims( if (dst_type > src_type) g_dst_pos -= n; - qp->div = isl_local_move_vars(qp->div, g_dst_pos, g_src_pos, n); - if (!qp->div) - return isl_qpolynomial_free(qp); + local = isl_qpolynomial_take_local(qp); + local = isl_local_move_vars(local, g_dst_pos, g_src_pos, n); + qp = isl_qpolynomial_restore_local(qp, local); qp = sort_divs(qp); total = isl_qpolynomial_domain_dim(qp, isl_dim_all); @@ -4574,8 +4628,8 @@ __isl_give isl_qpolynomial *isl_qpolynomial_realign_domain( { isl_space *space; isl_poly *poly; + isl_local *local; - qp = isl_qpolynomial_cow(qp); if (!qp) goto error; @@ -4583,9 +4637,9 @@ __isl_give isl_qpolynomial *isl_qpolynomial_realign_domain( if (!r) goto error; - qp->div = isl_local_reorder(qp->div, isl_reordering_copy(r)); - if (!qp->div) - goto error; + local = isl_qpolynomial_take_local(qp); + local = isl_local_reorder(local, isl_reordering_copy(r)); + qp = isl_qpolynomial_restore_local(qp, local); poly = isl_qpolynomial_take_poly(qp); poly = reorder(poly, r->pos); -- 2.11.4.GIT