X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=isl_convex_hull.c;h=dc8ac917a517b4396107f48526965ea278f649f8;hb=de51a9bc4da5dd3f1f9f57c2362da6f9752c44e0;hp=a6e26b8448f0ec47d7c2883aabd177894d3d24c2;hpb=a3e3c35fe631d3dbaa923d3199fc49f615269df7;p=platform%2Fupstream%2Fisl.git diff --git a/isl_convex_hull.c b/isl_convex_hull.c index a6e26b8..dc8ac91 100644 --- a/isl_convex_hull.c +++ b/isl_convex_hull.c @@ -1,7 +1,7 @@ /* * Copyright 2008-2009 Katholieke Universiteit Leuven * - * Use of this software is governed by the GNU LGPLv2.1 license + * Use of this software is governed by the MIT license * * Written by Sven Verdoolaege, K.U.Leuven, Departement * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium @@ -94,7 +94,7 @@ __isl_give isl_basic_map *isl_basic_map_remove_redundancies( if (bmap->n_ineq <= 1) return bmap; - tab = isl_tab_from_basic_map(bmap); + tab = isl_tab_from_basic_map(bmap, 0); if (isl_tab_detect_implicit_equalities(tab) < 0) goto error; if (isl_tab_detect_redundant(tab) < 0) @@ -483,7 +483,7 @@ static __isl_give isl_mat *initial_facet_constraint(__isl_keep isl_set *set) int i; unsigned dim = isl_set_n_dim(set); int is_bound; - isl_mat *bounds; + isl_mat *bounds = NULL; isl_assert(set->ctx, set->n > 0, goto error); bounds = isl_mat_alloc(set->ctx, 1, 1 + dim); @@ -1169,7 +1169,7 @@ static struct isl_vec *valid_direction( goto error; lp = valid_direction_lp(isl_basic_set_copy(bset1), isl_basic_set_copy(bset2)); - tab = isl_tab_from_basic_set(lp); + tab = isl_tab_from_basic_set(lp, 0); sample = isl_tab_get_sample_value(tab); isl_tab_free(tab); isl_basic_set_free(lp); @@ -1867,6 +1867,7 @@ static struct isl_basic_set *uset_convex_hull_wrap_bounded(struct isl_set *set) if (set->n == 1) { convex_hull = isl_basic_set_copy(set->p[0]); isl_set_free(set); + convex_hull = isl_basic_map_remove_redundancies(convex_hull); return convex_hull; } if (isl_set_n_dim(set) == 1) @@ -2106,18 +2107,20 @@ error: * it can be relaxed (by increasing the constant term) to become * a bound for that basic set. In the latter case, the constant * term is updated. + * Relaxation of the constant term is only allowed if "shift" is set. + * * Return 1 if "ineq" is a bound * 0 if "ineq" may attain arbitrarily small values on basic set "j" * -1 if some error occurred */ static int is_bound(struct sh_data *data, struct isl_set *set, int j, - isl_int *ineq) + isl_int *ineq, int shift) { enum isl_lp_result res; isl_int opt; if (!data->p[j].tab) { - data->p[j].tab = isl_tab_from_basic_set(set->p[j]); + data->p[j].tab = isl_tab_from_basic_set(set->p[j], 0); if (!data->p[j].tab) return -1; } @@ -2126,8 +2129,12 @@ static int is_bound(struct sh_data *data, struct isl_set *set, int j, res = isl_tab_min(data->p[j].tab, ineq, data->ctx->one, &opt, NULL, 0); - if (res == isl_lp_ok && isl_int_is_neg(opt)) - isl_int_sub(ineq[0], ineq[0], opt); + if (res == isl_lp_ok && isl_int_is_neg(opt)) { + if (shift) + isl_int_sub(ineq[0], ineq[0], opt); + else + res = isl_lp_unbounded; + } isl_int_clear(opt); @@ -2135,9 +2142,9 @@ static int is_bound(struct sh_data *data, struct isl_set *set, int j, res == isl_lp_unbounded ? 0 : -1; } -/* Check if inequality "ineq" from basic set "i" can be relaxed to +/* Check if inequality "ineq" from basic set "i" is or can be relaxed to * become a bound on the whole set. If so, add the (relaxed) inequality - * to "hull". + * to "hull". Relaxation is only allowed if "shift" is set. * * We first check if "hull" already contains a translate of the inequality. * If so, we are done. @@ -2153,7 +2160,8 @@ static int is_bound(struct sh_data *data, struct isl_set *set, int j, * the inequality accordingly. */ static struct isl_basic_set *add_bound(struct isl_basic_set *hull, - struct sh_data *data, struct isl_set *set, int i, isl_int *ineq) + struct sh_data *data, struct isl_set *set, int i, isl_int *ineq, + int shift) { uint32_t c_hash; struct ineq_cmp_data v; @@ -2188,7 +2196,7 @@ static struct isl_basic_set *add_bound(struct isl_basic_set *hull, for (j = 0; j < i; ++j) { int bound; - bound = is_bound(data, set, j, hull->ineq[k]); + bound = is_bound(data, set, j, hull->ineq[k], shift); if (bound < 0) goto error; if (!bound) @@ -2216,7 +2224,7 @@ static struct isl_basic_set *add_bound(struct isl_basic_set *hull, isl_int_neg(ineq_j[0], ineq_j[0]); continue; } - bound = is_bound(data, set, j, hull->ineq[k]); + bound = is_bound(data, set, j, hull->ineq[k], shift); if (bound < 0) goto error; if (!bound) @@ -2239,12 +2247,12 @@ error: return NULL; } -/* Check if any inequality from basic set "i" can be relaxed to +/* Check if any inequality from basic set "i" is or can be relaxed to * become a bound on the whole set. If so, add the (relaxed) inequality - * to "hull". + * to "hull". Relaxation is only allowed if "shift" is set. */ static struct isl_basic_set *add_bounds(struct isl_basic_set *bset, - struct sh_data *data, struct isl_set *set, int i) + struct sh_data *data, struct isl_set *set, int i, int shift) { int j, k; unsigned dim = isl_basic_set_total_dim(bset); @@ -2252,18 +2260,21 @@ static struct isl_basic_set *add_bounds(struct isl_basic_set *bset, for (j = 0; j < set->p[i]->n_eq; ++j) { for (k = 0; k < 2; ++k) { isl_seq_neg(set->p[i]->eq[j], set->p[i]->eq[j], 1+dim); - bset = add_bound(bset, data, set, i, set->p[i]->eq[j]); + bset = add_bound(bset, data, set, i, set->p[i]->eq[j], + shift); } } for (j = 0; j < set->p[i]->n_ineq; ++j) - bset = add_bound(bset, data, set, i, set->p[i]->ineq[j]); + bset = add_bound(bset, data, set, i, set->p[i]->ineq[j], shift); return bset; } /* Compute a superset of the convex hull of set that is described - * by only translates of the constraints in the constituents of set. + * by only (translates of) the constraints in the constituents of set. + * Translation is only allowed if "shift" is set. */ -static struct isl_basic_set *uset_simple_hull(struct isl_set *set) +static __isl_give isl_basic_set *uset_simple_hull(__isl_take isl_set *set, + int shift) { struct sh_data *data = NULL; struct isl_basic_set *hull = NULL; @@ -2289,7 +2300,7 @@ static struct isl_basic_set *uset_simple_hull(struct isl_set *set) goto error; for (i = 0; i < set->n; ++i) - hull = add_bounds(hull, data, set, i); + hull = add_bounds(hull, data, set, i, shift); sh_data_free(data); isl_set_free(set); @@ -2303,9 +2314,11 @@ error: } /* Compute a superset of the convex hull of map that is described - * by only translates of the constraints in the constituents of map. + * by only (translates of) the constraints in the constituents of map. + * Translation is only allowed if "shift" is set. */ -struct isl_basic_map *isl_map_simple_hull(struct isl_map *map) +static __isl_give isl_basic_map *map_simple_hull(__isl_take isl_map *map, + int shift) { struct isl_set *set = NULL; struct isl_basic_map *model = NULL; @@ -2329,28 +2342,54 @@ struct isl_basic_map *isl_map_simple_hull(struct isl_map *map) map = isl_map_detect_equalities(map); affine_hull = isl_map_affine_hull(isl_map_copy(map)); map = isl_map_align_divs(map); - model = isl_basic_map_copy(map->p[0]); + model = map ? isl_basic_map_copy(map->p[0]) : NULL; set = isl_map_underlying_set(map); - bset = uset_simple_hull(set); + bset = uset_simple_hull(set, shift); hull = isl_basic_map_overlying_set(bset, model); hull = isl_basic_map_intersect(hull, affine_hull); hull = isl_basic_map_remove_redundancies(hull); + + if (!hull) + return NULL; ISL_F_SET(hull, ISL_BASIC_MAP_NO_IMPLICIT); ISL_F_SET(hull, ISL_BASIC_MAP_ALL_EQUALITIES); return hull; } +/* Compute a superset of the convex hull of map that is described + * by only translates of the constraints in the constituents of map. + */ +__isl_give isl_basic_map *isl_map_simple_hull(__isl_take isl_map *map) +{ + return map_simple_hull(map, 1); +} + struct isl_basic_set *isl_set_simple_hull(struct isl_set *set) { return (struct isl_basic_set *) isl_map_simple_hull((struct isl_map *)set); } +/* Compute a superset of the convex hull of map that is described + * by only the constraints in the constituents of map. + */ +__isl_give isl_basic_map *isl_map_unshifted_simple_hull( + __isl_take isl_map *map) +{ + return map_simple_hull(map, 0); +} + +__isl_give isl_basic_set *isl_set_unshifted_simple_hull( + __isl_take isl_set *set) +{ + return isl_map_unshifted_simple_hull(set); +} + /* Given a set "set", return parametric bounds on the dimension "dim". */ static struct isl_basic_set *set_bounds(struct isl_set *set, int dim)