From 5bbabc09ad02091329a467def2c5a4b910200d02 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 2 Jun 2011 14:11:35 +0200 Subject: [PATCH] add isl_aff_add and isl_aff_sub Signed-off-by: Sven Verdoolaege --- doc/user.pod | 4 +++ include/isl/aff.h | 5 ++++ isl_aff.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+) diff --git a/doc/user.pod b/doc/user.pod index 1ff5198a..9a345c7a 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -2120,6 +2120,10 @@ the possibly rational constant or coefficient. Operations include #include + __isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_aff *isl_aff_sub(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); __isl_give isl_aff *isl_aff_neg(__isl_take isl_aff *aff); __isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff); diff --git a/include/isl/aff.h b/include/isl/aff.h index 1769857e..80836eb6 100644 --- a/include/isl/aff.h +++ b/include/isl/aff.h @@ -46,6 +46,11 @@ __isl_give isl_div *isl_aff_get_div(__isl_keep isl_aff *aff, int pos); __isl_give isl_aff *isl_aff_neg(__isl_take isl_aff *aff); __isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff); +__isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); +__isl_give isl_aff *isl_aff_sub(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2); + __isl_give isl_printer *isl_printer_print_aff(__isl_take isl_printer *p, __isl_keep isl_aff *aff); void isl_aff_dump(__isl_keep isl_aff *aff); diff --git a/isl_aff.c b/isl_aff.c index d0a4e751..fe07d4a9 100644 --- a/isl_aff.c +++ b/isl_aff.c @@ -10,6 +10,7 @@ #include #include +#include #include __isl_give isl_aff *isl_aff_alloc_vec(__isl_take isl_local_space *ls, @@ -432,3 +433,83 @@ error: isl_mat_free(div); return NULL; } + +/* Add two affine expressions that live in the same local space. + */ +static __isl_give isl_aff *add_expanded(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + isl_int gcd, f; + + aff1 = isl_aff_cow(aff1); + if (!aff1 || !aff2) + goto error; + + aff1->v = isl_vec_cow(aff1->v); + if (!aff1->v) + goto error; + + isl_int_init(gcd); + isl_int_init(f); + isl_int_gcd(gcd, aff1->v->el[0], aff2->v->el[0]); + isl_int_divexact(f, aff2->v->el[0], gcd); + isl_seq_scale(aff1->v->el + 1, aff1->v->el + 1, f, aff1->v->size - 1); + isl_int_divexact(f, aff1->v->el[0], gcd); + isl_seq_addmul(aff1->v->el + 1, f, aff2->v->el + 1, aff1->v->size - 1); + isl_int_divexact(f, aff2->v->el[0], gcd); + isl_int_mul(aff1->v->el[0], aff1->v->el[0], f); + isl_int_clear(f); + isl_int_clear(gcd); + + isl_aff_free(aff2); + return aff1; +error: + isl_aff_free(aff1); + isl_aff_free(aff2); + return NULL; +} + +__isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + isl_ctx *ctx; + int *exp1 = NULL; + int *exp2 = NULL; + isl_mat *div; + + if (!aff1 || !aff2) + goto error; + + ctx = isl_aff_get_ctx(aff1); + if (!isl_dim_equal(aff1->ls->dim, aff2->ls->dim)) + isl_die(ctx, isl_error_invalid, + "spaces don't match", goto error); + + if (aff1->ls->div->n_row == 0 && aff2->ls->div->n_row == 0) + return add_expanded(aff1, aff2); + + exp1 = isl_alloc_array(ctx, int, aff1->ls->div->n_row); + exp2 = isl_alloc_array(ctx, int, aff2->ls->div->n_row); + if (!exp1 || !exp2) + goto error; + + div = isl_merge_divs(aff1->ls->div, aff2->ls->div, exp1, exp2); + aff1 = isl_aff_expand_divs(aff1, isl_mat_copy(div), exp1); + aff2 = isl_aff_expand_divs(aff2, div, exp2); + free(exp1); + free(exp2); + + return add_expanded(aff1, aff2); +error: + free(exp1); + free(exp2); + isl_aff_free(aff1); + isl_aff_free(aff2); + return NULL; +} + +__isl_give isl_aff *isl_aff_sub(__isl_take isl_aff *aff1, + __isl_take isl_aff *aff2) +{ + return isl_aff_add(aff1, isl_aff_neg(aff2)); +} -- 2.11.4.GIT