X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=isl_map.c;h=602b2c0aa54d0ce2ea308d810747333ceb4ce1dd;hb=d7276caf78702c11e9448c67d46bb362de734357;hp=3112e968f65bcafae13c2dc168f7a40ec818a13f;hpb=c26908be75820a6d1389791de624fe676e7dd2a0;p=platform%2Fupstream%2Fisl.git diff --git a/isl_map.c b/isl_map.c index 3112e96..602b2c0 100644 --- a/isl_map.c +++ b/isl_map.c @@ -541,6 +541,12 @@ __isl_give isl_set *isl_set_set_dim_name(__isl_take isl_set *set, return (isl_set *)isl_map_set_dim_name((isl_map *)set, type, pos, s); } +int isl_basic_map_has_dim_id(__isl_keep isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos) +{ + return bmap ? isl_space_has_dim_id(bmap->dim, type, pos) : -1; +} + int isl_map_has_dim_id(__isl_keep isl_map *map, enum isl_dim_type type, unsigned pos) { @@ -597,6 +603,14 @@ int isl_set_find_dim_by_id(__isl_keep isl_set *set, enum isl_dim_type type, return isl_map_find_dim_by_id(set, type, id); } +int isl_map_find_dim_by_name(__isl_keep isl_map *map, enum isl_dim_type type, + const char *name) +{ + if (!map) + return -1; + return isl_space_find_dim_by_name(map->dim, type, name); +} + int isl_basic_map_is_rational(__isl_keep isl_basic_map *bmap) { if (!bmap) @@ -609,6 +623,35 @@ int isl_basic_set_is_rational(__isl_keep isl_basic_set *bset) return isl_basic_map_is_rational(bset); } +/* Is this basic set a parameter domain? + */ +int isl_basic_set_is_params(__isl_keep isl_basic_set *bset) +{ + if (!bset) + return -1; + return isl_space_is_params(bset->dim); +} + +/* Is this set a parameter domain? + */ +int isl_set_is_params(__isl_keep isl_set *set) +{ + if (!set) + return -1; + return isl_space_is_params(set->dim); +} + +/* Is this map actually a parameter domain? + * Users should never call this function. Outside of isl, + * a map can never be a parameter domain. + */ +int isl_map_is_params(__isl_keep isl_map *map) +{ + if (!map) + return -1; + return isl_space_is_params(map->dim); +} + static struct isl_basic_map *basic_map_init(struct isl_ctx *ctx, struct isl_basic_map *bmap, unsigned extra, unsigned n_eq, unsigned n_ineq) @@ -1747,11 +1790,11 @@ int isl_map_involves_dims(__isl_keep isl_map *map, for (i = 0; i < map->n; ++i) { int involves = isl_basic_map_involves_dims(map->p[i], type, first, n); - if (involves < 0 || !involves) + if (involves < 0 || involves) return involves; } - return 1; + return 0; } int isl_basic_set_involves_dims(__isl_keep isl_basic_set *bset, @@ -2465,6 +2508,8 @@ static __isl_give isl_map *map_intersect(__isl_take isl_map *map1, (map1->p[0]->n_eq + map1->p[0]->n_ineq == 1 || map2->p[0]->n_eq + map2->p[0]->n_ineq == 1)) return map_intersect_add_constraint(map1, map2); + if (isl_map_is_params(map1) && !isl_map_is_params(map2)) + return isl_map_intersect(map2, map1); if (isl_space_dim(map1->dim, isl_dim_all) == isl_space_dim(map1->dim, isl_dim_param) && isl_space_dim(map2->dim, isl_dim_all) != @@ -4064,6 +4109,9 @@ __isl_give isl_basic_set *isl_basic_set_params(__isl_take isl_basic_set *bset) isl_space *space; unsigned n; + if (isl_basic_set_is_params(bset)) + return bset; + n = isl_basic_set_dim(bset, isl_dim_set); bset = isl_basic_set_project_out(bset, isl_dim_set, 0, n); space = isl_basic_set_get_space(bset); @@ -4079,6 +4127,9 @@ __isl_give isl_set *isl_set_params(__isl_take isl_set *set) isl_space *space; unsigned n; + if (isl_set_is_params(set)) + return set; + n = isl_set_dim(set, isl_dim_set); set = isl_set_project_out(set, isl_dim_set, 0, n); space = isl_set_get_space(set); @@ -4087,6 +4138,34 @@ __isl_give isl_set *isl_set_params(__isl_take isl_set *set) return set; } +/* Construct a zero-dimensional set with the given parameter domain. + */ +__isl_give isl_set *isl_set_from_params(__isl_take isl_set *set) +{ + isl_space *space; + space = isl_set_get_space(set); + space = isl_space_set_from_params(space); + set = isl_set_reset_space(set, space); + return set; +} + +/* Compute the parameter domain of the given map. + */ +__isl_give isl_set *isl_map_params(__isl_take isl_map *map) +{ + isl_space *space; + unsigned n; + + n = isl_map_dim(map, isl_dim_in); + map = isl_map_project_out(map, isl_dim_in, 0, n); + n = isl_map_dim(map, isl_dim_out); + map = isl_map_project_out(map, isl_dim_out, 0, n); + space = isl_map_get_space(map); + space = isl_space_params(space); + map = isl_map_reset_space(map, space); + return map; +} + struct isl_basic_set *isl_basic_map_domain(struct isl_basic_map *bmap) { isl_space *dim; @@ -4115,11 +4194,22 @@ int isl_basic_map_may_be_set(__isl_keep isl_basic_map *bmap) return isl_space_may_be_set(bmap->dim); } +/* Is this basic map actually a set? + * Users should never call this function. Outside of isl, + * the type should indicate whether something is a set or a map. + */ +int isl_basic_map_is_set(__isl_keep isl_basic_map *bmap) +{ + if (!bmap) + return -1; + return isl_space_is_set(bmap->dim); +} + struct isl_basic_set *isl_basic_map_range(struct isl_basic_map *bmap) { if (!bmap) return NULL; - if (isl_basic_map_may_be_set(bmap)) + if (isl_basic_map_is_set(bmap)) return bmap; return isl_basic_map_domain(isl_basic_map_reverse(bmap)); } @@ -4207,6 +4297,17 @@ int isl_map_may_be_set(__isl_keep isl_map *map) return isl_space_may_be_set(map->dim); } +/* Is this map actually a set? + * Users should never call this function. Outside of isl, + * the type should indicate whether something is a set or a map. + */ +int isl_map_is_set(__isl_keep isl_map *map) +{ + if (!map) + return -1; + return isl_space_is_set(map->dim); +} + struct isl_set *isl_map_range(struct isl_map *map) { int i; @@ -4214,7 +4315,7 @@ struct isl_set *isl_map_range(struct isl_map *map) if (!map) goto error; - if (isl_map_may_be_set(map)) + if (isl_map_is_set(map)) return (isl_set *)map; map = isl_map_cow(map); @@ -4328,11 +4429,19 @@ __isl_give isl_basic_map *isl_basic_map_from_domain( __isl_give isl_basic_map *isl_basic_map_from_range( __isl_take isl_basic_set *bset) { + isl_space *space; + space = isl_basic_set_get_space(bset); + space = isl_space_from_range(space); + bset = isl_basic_set_reset_space(bset, space); return (isl_basic_map *)bset; } struct isl_map *isl_map_from_range(struct isl_set *set) { + isl_space *space; + space = isl_set_get_space(set); + space = isl_space_from_range(space); + set = isl_set_reset_space(set, space); return (struct isl_map *)set; } @@ -4344,15 +4453,13 @@ __isl_give isl_map *isl_map_from_domain(__isl_take isl_set *set) __isl_give isl_basic_map *isl_basic_map_from_domain_and_range( __isl_take isl_basic_set *domain, __isl_take isl_basic_set *range) { - return isl_basic_map_apply_range(isl_basic_map_from_domain(domain), - isl_basic_map_from_range(range)); + return isl_basic_map_apply_range(isl_basic_map_reverse(domain), range); } __isl_give isl_map *isl_map_from_domain_and_range(__isl_take isl_set *domain, __isl_take isl_set *range) { - return isl_map_apply_range(isl_map_from_domain(domain), - isl_map_from_range(range)); + return isl_map_apply_range(isl_map_reverse(domain), range); } struct isl_set *isl_set_from_map(struct isl_map *map) @@ -5328,35 +5435,10 @@ __isl_give isl_set *isl_set_lexmax(__isl_take isl_set *set) return (isl_set *)isl_map_lexmax((isl_map *)set); } -/* Construct a map that equates the two given dimensions in the given space. - */ -static __isl_give isl_map *equate(__isl_take isl_space *dim, - enum isl_dim_type src_type, int src_pos, - enum isl_dim_type dst_type, int dst_pos) -{ - isl_basic_map *bmap; - int k; - - bmap = isl_basic_map_alloc_space(dim, 0, 1, 0); - k = isl_basic_map_alloc_equality(bmap); - if (k < 0) - goto error; - isl_seq_clr(bmap->eq[k], 1 + isl_basic_map_total_dim(bmap)); - src_pos += isl_basic_map_offset(bmap, src_type); - dst_pos += isl_basic_map_offset(bmap, dst_type); - isl_int_set_si(bmap->eq[k][src_pos], 1); - isl_int_set_si(bmap->eq[k][dst_pos], -1); - - return isl_map_from_basic_map(bmap); -error: - isl_basic_map_free(bmap); - return NULL; -} - /* Extract the first and only affine expression from list * and then add it to *pwaff with the given dom. * This domain is known to be disjoint from other domains - * because of the way isl_basic_set_foreach_lexmax works. + * because of the way isl_basic_map_foreach_lexmax works. */ static int update_dim_opt(__isl_take isl_basic_set *dom, __isl_take isl_aff_list *list, void *user) @@ -5384,73 +5466,90 @@ error: return -1; } -/* Given a one-dimensional basic set, compute the minimum or maximum of that - * dimension as an isl_pw_aff. +/* Given a basic map with one output dimension, compute the minimum or + * maximum of that dimension as an isl_pw_aff. * - * The isl_pw_aff is constructed by having isl_basic_set_foreach_lexopt + * The isl_pw_aff is constructed by having isl_basic_map_foreach_lexopt * call update_dim_opt on each leaf of the result. */ -static __isl_give isl_pw_aff *basic_set_dim_opt(__isl_keep isl_basic_set *bset, +static __isl_give isl_pw_aff *basic_map_dim_opt(__isl_keep isl_basic_map *bmap, int max) { - isl_space *dim = isl_basic_set_get_space(bset); + isl_space *dim = isl_basic_map_get_space(bmap); isl_pw_aff *pwaff; int r; - dim = isl_space_domain(isl_space_from_range(dim)); + dim = isl_space_from_domain(isl_space_domain(dim)); + dim = isl_space_add_dims(dim, isl_dim_out, 1); pwaff = isl_pw_aff_empty(dim); - r = isl_basic_set_foreach_lexopt(bset, max, &update_dim_opt, &pwaff); + r = isl_basic_map_foreach_lexopt(bmap, max, &update_dim_opt, &pwaff); if (r < 0) return isl_pw_aff_free(pwaff); return pwaff; } -/* Compute the minimum or maximum of the given set dimension - * as a function of the parameters, but independently of - * the other set dimensions. +/* Compute the minimum or maximum of the given output dimension + * as a function of the parameters and the input dimensions, + * but independently of the other output dimensions. * - * We first project the set onto the given dimension and then compute - * the "lexicographic" maximum in each basic set, combining the results + * We first project out the other output dimension and then compute + * the "lexicographic" maximum in each basic map, combining the results * using isl_pw_aff_union_max. */ -static __isl_give isl_pw_aff *set_dim_opt(__isl_take isl_set *set, int pos, +static __isl_give isl_pw_aff *map_dim_opt(__isl_take isl_map *map, int pos, int max) { int i; - isl_map *map; isl_pw_aff *pwaff; + unsigned n_out; - map = isl_map_from_domain(set); - map = isl_map_add_dims(map, isl_dim_out, 1); - map = isl_map_intersect(map, - equate(isl_map_get_space(map), isl_dim_in, pos, - isl_dim_out, 0)); - set = isl_map_range(map); - if (!set) + n_out = isl_map_dim(map, isl_dim_out); + map = isl_map_project_out(map, isl_dim_out, pos + 1, n_out - (pos + 1)); + map = isl_map_project_out(map, isl_dim_out, 0, pos); + if (!map) return NULL; - if (set->n == 0) { - isl_space *dim = isl_set_get_space(set); + if (map->n == 0) { + isl_space *dim = isl_map_get_space(map); dim = isl_space_domain(isl_space_from_range(dim)); - isl_set_free(set); + isl_map_free(map); return isl_pw_aff_empty(dim); } - pwaff = basic_set_dim_opt(set->p[0], max); - for (i = 1; i < set->n; ++i) { + pwaff = basic_map_dim_opt(map->p[0], max); + for (i = 1; i < map->n; ++i) { isl_pw_aff *pwaff_i; - pwaff_i = basic_set_dim_opt(set->p[i], max); + pwaff_i = basic_map_dim_opt(map->p[i], max); pwaff = isl_pw_aff_union_opt(pwaff, pwaff_i, max); } - isl_set_free(set); + isl_map_free(map); return pwaff; } +/* Compute the maximum of the given output dimension as a function of the + * parameters and input dimensions, but independently of + * the other output dimensions. + */ +__isl_give isl_pw_aff *isl_map_dim_max(__isl_take isl_map *map, int pos) +{ + return map_dim_opt(map, pos, 1); +} + +/* Compute the minimum or maximum of the given set dimension + * as a function of the parameters, + * but independently of the other set dimensions. + */ +static __isl_give isl_pw_aff *set_dim_opt(__isl_take isl_set *set, int pos, + int max) +{ + return map_dim_opt(set, pos, max); +} + /* Compute the maximum of the given set dimension as a function of the * parameters, but independently of the other set dimensions. */ @@ -7299,6 +7398,12 @@ int isl_map_plain_is_fixed(__isl_keep isl_map *map, map_offset(map, type) - 1 + pos, val); } +int isl_set_plain_is_fixed(__isl_keep isl_set *set, + enum isl_dim_type type, unsigned pos, isl_int *val) +{ + return isl_map_plain_is_fixed(set, type, pos, val); +} + int isl_map_fast_is_fixed(__isl_keep isl_map *map, enum isl_dim_type type, unsigned pos, isl_int *val) { @@ -7541,6 +7646,31 @@ int isl_basic_map_plain_cmp(const __isl_keep isl_basic_map *bmap1, return 0; } +int isl_basic_set_plain_cmp(const __isl_keep isl_basic_set *bset1, + const __isl_keep isl_basic_set *bset2) +{ + return isl_basic_map_plain_cmp(bset1, bset2); +} + +int isl_set_plain_cmp(const __isl_keep isl_set *set1, + const __isl_keep isl_set *set2) +{ + int i, cmp; + + if (set1 == set2) + return 0; + if (set1->n != set2->n) + return set1->n - set2->n; + + for (i = 0; i < set1->n; ++i) { + cmp = isl_basic_set_plain_cmp(set1->p[i], set2->p[i]); + if (cmp) + return cmp; + } + + return 0; +} + int isl_basic_map_plain_is_equal(__isl_keep isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2) { @@ -9440,8 +9570,6 @@ __isl_give isl_basic_map *isl_basic_map_from_aff(__isl_take isl_aff *aff) return NULL; ls = isl_aff_get_local_space(aff); - ls = isl_local_space_from_domain(ls); - ls = isl_local_space_add_dims(ls, isl_dim_out, 1); bmap = isl_basic_map_from_local_space(ls); bmap = isl_basic_map_extend_constraints(bmap, 1, 0); k = isl_basic_map_alloc_equality(bmap); @@ -9463,6 +9591,43 @@ error: return NULL; } +/* Construct a basic map mapping the domain the multi-affine expression + * to its range, with each dimension in the range equated to the + * corresponding affine expression. + */ +__isl_give isl_basic_map *isl_basic_map_from_multi_aff( + __isl_take isl_multi_aff *maff) +{ + int i; + isl_space *space; + isl_basic_map *bmap; + + if (!maff) + return NULL; + + if (isl_space_dim(maff->space, isl_dim_out) != maff->n) + isl_die(isl_multi_aff_get_ctx(maff), isl_error_internal, + "invalid space", return isl_multi_aff_free(maff)); + + space = isl_space_domain(isl_multi_aff_get_space(maff)); + bmap = isl_basic_map_universe(isl_space_from_domain(space)); + + for (i = 0; i < maff->n; ++i) { + isl_aff *aff; + isl_basic_map *bmap_i; + + aff = isl_aff_copy(maff->p[i]); + bmap_i = isl_basic_map_from_aff(aff); + + bmap = isl_basic_map_flat_range_product(bmap, bmap_i); + } + + bmap = isl_basic_map_reset_space(bmap, isl_multi_aff_get_space(maff)); + + isl_multi_aff_free(maff); + return bmap; +} + /* Construct a basic map mapping a domain in the given space to * to an n-dimensional range, with n the number of elements in the list, * where each coordinate in the range is prescribed by the @@ -9578,3 +9743,148 @@ error: isl_map_free(map); return NULL; } + +__isl_give isl_aff *isl_basic_map_get_div(__isl_keep isl_basic_map *bmap, + int pos) +{ + isl_aff *div; + isl_local_space *ls; + + if (!bmap) + return NULL; + + if (!isl_basic_map_divs_known(bmap)) + isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid, + "some divs are unknown", return NULL); + + ls = isl_basic_map_get_local_space(bmap); + div = isl_local_space_get_div(ls, pos); + isl_local_space_free(ls); + + return div; +} + +__isl_give isl_aff *isl_basic_set_get_div(__isl_keep isl_basic_set *bset, + int pos) +{ + return isl_basic_map_get_div(bset, pos); +} + +/* Plug in "subs" for dimension "type", "pos" of "bset". + * + * Let i be the dimension to replace and let "subs" be of the form + * + * f/d + * + * Any integer division with a non-zero coefficient for i, + * + * floor((a i + g)/m) + * + * is replaced by + * + * floor((a f + d g)/(m d)) + * + * Constraints of the form + * + * a i + g + * + * are replaced by + * + * a f + d g + */ +__isl_give isl_basic_set *isl_basic_set_substitute( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs) +{ + int i; + isl_int v; + isl_ctx *ctx; + + if (bset && isl_basic_set_plain_is_empty(bset)) + return bset; + + bset = isl_basic_set_cow(bset); + if (!bset || !subs) + goto error; + + ctx = isl_basic_set_get_ctx(bset); + if (!isl_space_is_equal(bset->dim, subs->ls->dim)) + isl_die(ctx, isl_error_invalid, + "spaces don't match", goto error); + if (isl_local_space_dim(subs->ls, isl_dim_div) != 0) + isl_die(ctx, isl_error_unsupported, + "cannot handle divs yet", goto error); + + pos += isl_basic_set_offset(bset, type); + + isl_int_init(v); + + for (i = 0; i < bset->n_eq; ++i) { + if (isl_int_is_zero(bset->eq[i][pos])) + continue; + isl_int_set(v, bset->eq[i][pos]); + isl_int_set_si(bset->eq[i][pos], 0); + isl_seq_combine(bset->eq[i], subs->v->el[0], bset->eq[i], + v, subs->v->el + 1, subs->v->size - 1); + } + + for (i = 0; i < bset->n_ineq; ++i) { + if (isl_int_is_zero(bset->ineq[i][pos])) + continue; + isl_int_set(v, bset->ineq[i][pos]); + isl_int_set_si(bset->ineq[i][pos], 0); + isl_seq_combine(bset->ineq[i], subs->v->el[0], bset->ineq[i], + v, subs->v->el + 1, subs->v->size - 1); + } + + for (i = 0; i < bset->n_div; ++i) { + if (isl_int_is_zero(bset->div[i][1 + pos])) + continue; + isl_int_set(v, bset->div[i][1 + pos]); + isl_int_set_si(bset->div[i][1 + pos], 0); + isl_seq_combine(bset->div[i] + 1, + subs->v->el[0], bset->div[i] + 1, + v, subs->v->el + 1, subs->v->size - 1); + isl_int_mul(bset->div[i][0], bset->div[i][0], subs->v->el[0]); + } + + isl_int_clear(v); + + bset = isl_basic_set_simplify(bset); + return isl_basic_set_finalize(bset); +error: + isl_basic_set_free(bset); + return NULL; +} + +/* Plug in "subs" for dimension "type", "pos" of "set". + */ +__isl_give isl_set *isl_set_substitute(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs) +{ + int i; + + if (set && isl_set_plain_is_empty(set)) + return set; + + set = isl_set_cow(set); + if (!set || !subs) + goto error; + + for (i = set->n - 1; i >= 0; --i) { + set->p[i] = isl_basic_set_substitute(set->p[i], type, pos, subs); + if (!set->p[i]) + goto error; + if (isl_basic_set_plain_is_empty(set->p[i])) { + isl_basic_set_free(set->p[i]); + if (i != set->n - 1) + set->p[i] = set->p[set->n - 1]; + set->n--; + } + } + + return set; +error: + isl_set_free(set); + return NULL; +}