X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=isl_aff.c;h=e9d728658aaf234cb2d914662ce1f7b0e566bdec;hb=1b0a4432089a647f419fb4ded6395323424879fd;hp=79fd8d5bc726ca9b9920abbdafb02fdce741c59f;hpb=5dfeb26113fb6828f2973fa3cfd0816dbd7838a8;p=platform%2Fupstream%2Fisl.git diff --git a/isl_aff.c b/isl_aff.c index 79fd8d5..e9d7286 100644 --- a/isl_aff.c +++ b/isl_aff.c @@ -758,7 +758,7 @@ static __isl_give isl_aff *plug_in_integral_divs(__isl_take isl_aff *aff) continue; ls = isl_local_space_copy(aff->ls); ls = isl_local_space_substitute_seq(ls, isl_dim_div, i, - aff->ls->div->row[i], len, i + 1); + aff->ls->div->row[i], len, i + 1, n - (i + 1)); vec = isl_vec_copy(aff->v); vec = isl_vec_cow(vec); if (!ls || !vec) @@ -785,6 +785,50 @@ error: return isl_aff_free(aff); } +/* Look for any divs j that appear with a unit coefficient inside + * the definitions of other divs i and plug them into the definitions + * of the divs i. + * + * In particular, an expression of the form + * + * floor((f(..) + floor(g(..)/n))/m) + * + * is simplified to + * + * floor((n * f(..) + g(..))/(n * m)) + * + * This simplification is correct because we can move the expression + * f(..) into the inner floor in the original expression to obtain + * + * floor(floor((n * f(..) + g(..))/n)/m) + * + * from which we can derive the simplified expression. + */ +static __isl_give isl_aff *plug_in_unit_divs(__isl_take isl_aff *aff) +{ + int i, j, n; + int off; + + if (!aff) + return NULL; + + n = isl_local_space_dim(aff->ls, isl_dim_div); + off = isl_local_space_offset(aff->ls, isl_dim_div); + for (i = 1; i < n; ++i) { + for (j = 0; j < i; ++j) { + if (!isl_int_is_one(aff->ls->div->row[i][1 + off + j])) + continue; + aff->ls = isl_local_space_substitute_seq(aff->ls, + isl_dim_div, j, aff->ls->div->row[j], + aff->v->size, i, 1); + if (!aff->ls) + return isl_aff_free(aff); + } + } + + return aff; +} + /* Swap divs "a" and "b" in "aff", which is assumed to be non-NULL. * * Even though this function is only called on isl_affs with a single @@ -889,6 +933,7 @@ __isl_give isl_aff *isl_aff_normalize(__isl_take isl_aff *aff) if (!aff->v) return isl_aff_free(aff); aff = plug_in_integral_divs(aff); + aff = plug_in_unit_divs(aff); aff = sort_divs(aff); aff = isl_aff_remove_unused_divs(aff); return aff; @@ -955,6 +1000,8 @@ __isl_give isl_aff *isl_aff_floor(__isl_take isl_aff *aff) isl_int_set_si(aff->v->el[0], 1); isl_int_set_si(aff->v->el[size], 1); + aff = isl_aff_normalize(aff); + return aff; } @@ -994,7 +1041,13 @@ __isl_give isl_pw_aff *isl_pw_aff_mod(__isl_take isl_pw_aff *pwaff, isl_int m) /* Given f, return ceil(f). * If f is an integer expression, then just return f. - * Otherwise, create a new div d = [-f] and return the expression -d. + * Otherwise, let f be the expression + * + * e/m + * + * then return + * + * floor((e + m - 1)/m) */ __isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff) { @@ -1004,9 +1057,16 @@ __isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff) if (isl_int_is_one(aff->v->el[0])) return aff; - aff = isl_aff_neg(aff); + aff = isl_aff_cow(aff); + if (!aff) + return NULL; + aff->v = isl_vec_cow(aff->v); + if (!aff->v) + return isl_aff_free(aff); + + isl_int_add(aff->v->el[1], aff->v->el[1], aff->v->el[0]); + isl_int_sub_ui(aff->v->el[1], aff->v->el[1], 1); aff = isl_aff_floor(aff); - aff = isl_aff_neg(aff); return aff; } @@ -1312,7 +1372,7 @@ static __isl_give isl_aff *isl_aff_substitute_equalities( goto error; n_div = isl_local_space_dim(aff->ls, isl_dim_div); if (n_div > 0) - eq = isl_basic_set_add(eq, isl_dim_set, n_div); + eq = isl_basic_set_add_dims(eq, isl_dim_set, n_div); return isl_aff_substitute_equalities_lifted(aff, eq); error: isl_basic_set_free(eq); @@ -2566,14 +2626,15 @@ __isl_give isl_pw_aff *isl_pw_aff_set_rational(__isl_take isl_pw_aff *pwaff) __isl_give isl_pw_aff_list *isl_pw_aff_list_set_rational( __isl_take isl_pw_aff_list *list) { - int i; + int i, n; if (!list) return NULL; if (list->n == 0) return list; - for (i = 0; i < list->n; ++i) { + n = list->n; + for (i = 0; i < n; ++i) { isl_pw_aff *pa; pa = isl_pw_aff_list_get_pw_aff(list, i);