X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=isl_map.c;h=b9f8b01d800ceb9b22386a2e0d59150413d7bfe4;hb=bdc8ebd299c5c3b1b1fac36ab3b1b44e2d7de85c;hp=66612d1f384b83f87c8cb60be1dfd1d7ab056087;hpb=c99c8c9459bb142dcba40d16efe4f88c4bbadd84;p=platform%2Fupstream%2Fisl.git diff --git a/isl_map.c b/isl_map.c index 66612d1..b9f8b01 100644 --- a/isl_map.c +++ b/isl_map.c @@ -14,7 +14,7 @@ #include #include "isl_ctx.h" #include "isl_blk.h" -#include "isl_dim.h" +#include "isl_dim_private.h" #include "isl_equalities.h" #include "isl_list.h" #include "isl_lp.h" @@ -116,6 +116,8 @@ static void isl_dim_map_dump(struct isl_dim_map *dim_map) unsigned isl_basic_map_dim(const struct isl_basic_map *bmap, enum isl_dim_type type) { + if (!bmap) + return 0; switch (type) { case isl_dim_param: case isl_dim_in: @@ -162,12 +164,12 @@ unsigned isl_basic_set_dim(const struct isl_basic_set *bset, unsigned isl_basic_set_n_dim(const struct isl_basic_set *bset) { - return bset->dim->n_out; + return isl_basic_set_dim(bset, isl_dim_set); } unsigned isl_basic_set_n_param(const struct isl_basic_set *bset) { - return bset->dim->nparam; + return isl_basic_set_dim(bset, isl_dim_param); } unsigned isl_basic_set_total_dim(const struct isl_basic_set *bset) @@ -177,12 +179,12 @@ unsigned isl_basic_set_total_dim(const struct isl_basic_set *bset) unsigned isl_set_n_dim(const struct isl_set *set) { - return set->dim->n_out; + return isl_set_dim(set, isl_dim_set); } unsigned isl_set_n_param(const struct isl_set *set) { - return set->dim->nparam; + return isl_set_dim(set, isl_dim_param); } unsigned isl_basic_map_n_in(const struct isl_basic_map *bmap) @@ -207,7 +209,7 @@ unsigned isl_basic_map_n_div(const struct isl_basic_map *bmap) unsigned isl_basic_map_total_dim(const struct isl_basic_map *bmap) { - return isl_dim_total(bmap->dim) + bmap->n_div; + return bmap ? isl_dim_total(bmap->dim) + bmap->n_div : 0; } unsigned isl_map_n_in(const struct isl_map *map) @@ -245,6 +247,11 @@ int isl_basic_map_compatible_range(struct isl_basic_map *bmap, bmap->dim->nparam == bset->dim->nparam; } +isl_ctx *isl_map_get_ctx(__isl_keep isl_map *map) +{ + return map ? map->ctx : NULL; +} + struct isl_dim *isl_basic_map_get_dim(struct isl_basic_map *bmap) { if (!bmap) @@ -273,6 +280,66 @@ struct isl_dim *isl_set_get_dim(struct isl_set *set) return isl_dim_copy(set->dim); } +__isl_give isl_basic_map *isl_basic_map_set_dim_name( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos, const char *s) +{ + if (!bmap) + return NULL; + bmap->dim = isl_dim_set_name(bmap->dim, type, pos, s); + if (!bmap->dim) + goto error; + return bmap; +error: + isl_basic_map_free(bmap); + return NULL; +} + +__isl_give isl_map *isl_map_set_dim_name(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos, const char *s) +{ + int i; + + if (!map) + return NULL; + + map->dim = isl_dim_set_name(map->dim, type, pos, s); + if (!map->dim) + goto error; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_set_dim_name(map->p[i], type, pos, s); + if (!map->p[i]) + goto error; + } + + return map; +error: + isl_map_free(map); + return NULL; +} + +__isl_give isl_basic_set *isl_basic_set_set_dim_name( + __isl_take isl_basic_set *bset, + enum isl_dim_type type, unsigned pos, const char *s) +{ + return (isl_basic_set *)isl_basic_map_set_dim_name( + (isl_basic_map *)bset, type, pos, s); +} + +__isl_give isl_set *isl_set_set_dim_name(__isl_take isl_set *set, + enum isl_dim_type type, unsigned pos, const char *s) +{ + return (isl_set *)isl_map_set_dim_name((isl_map *)set, type, pos, s); +} + +int isl_basic_map_is_rational(__isl_keep isl_basic_map *bmap) +{ + if (!bmap) + return -1; + return ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL); +} + 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) @@ -280,39 +347,28 @@ static struct isl_basic_map *basic_map_init(struct isl_ctx *ctx, int i; size_t row_size = 1 + isl_dim_total(bmap->dim) + extra; + bmap->ctx = ctx; + isl_ctx_ref(ctx); + bmap->block = isl_blk_alloc(ctx, (n_ineq + n_eq) * row_size); - if (isl_blk_is_error(bmap->block)) { - free(bmap); - return NULL; - } + if (isl_blk_is_error(bmap->block)) + goto error; bmap->ineq = isl_alloc_array(ctx, isl_int *, n_ineq + n_eq); - if (!bmap->ineq) { - isl_blk_free(ctx, bmap->block); - free(bmap); - return NULL; - } + if (!bmap->ineq) + goto error; if (extra == 0) { bmap->block2 = isl_blk_empty(); bmap->div = NULL; } else { bmap->block2 = isl_blk_alloc(ctx, extra * (1 + row_size)); - if (isl_blk_is_error(bmap->block2)) { - free(bmap->ineq); - isl_blk_free(ctx, bmap->block); - free(bmap); - return NULL; - } + if (isl_blk_is_error(bmap->block2)) + goto error; bmap->div = isl_alloc_array(ctx, isl_int *, extra); - if (!bmap->div) { - isl_blk_free(ctx, bmap->block2); - free(bmap->ineq); - isl_blk_free(ctx, bmap->block); - free(bmap); - return NULL; - } + if (!bmap->div) + goto error; } for (i = 0; i < n_ineq + n_eq; ++i) @@ -321,8 +377,6 @@ static struct isl_basic_map *basic_map_init(struct isl_ctx *ctx, for (i = 0; i < extra; ++i) bmap->div[i] = bmap->block2.data + i * (1 + row_size); - bmap->ctx = ctx; - isl_ctx_ref(ctx); bmap->ref = 1; bmap->flags = 0; bmap->c_size = n_eq + n_ineq; @@ -334,6 +388,9 @@ static struct isl_basic_map *basic_map_init(struct isl_ctx *ctx, bmap->sample = NULL; return bmap; +error: + isl_basic_map_free(bmap); + return NULL; } struct isl_basic_set *isl_basic_set_alloc(struct isl_ctx *ctx, @@ -363,7 +420,7 @@ struct isl_basic_map *isl_basic_map_alloc_dim(struct isl_dim *dim, if (!dim) return NULL; - bmap = isl_alloc_type(dim->ctx, struct isl_basic_map); + bmap = isl_calloc_type(dim->ctx, struct isl_basic_map); if (!bmap) goto error; bmap->dim = dim; @@ -466,7 +523,10 @@ struct isl_basic_map *isl_basic_map_copy(struct isl_basic_map *bmap) bmap->ref++; return bmap; } - return isl_basic_map_dup(bmap); + bmap = isl_basic_map_dup(bmap); + if (bmap) + ISL_F_SET(bmap, ISL_BASIC_SET_FINAL); + return bmap; } struct isl_map *isl_map_copy(struct isl_map *map) @@ -987,10 +1047,13 @@ struct isl_basic_map *isl_basic_map_extend(struct isl_basic_map *base, return NULL; dim = isl_dim_alloc(base->ctx, nparam, n_in, n_out); if (!dim) - return NULL; + goto error; bmap = isl_basic_map_extend_dim(base, dim, extra, n_eq, n_ineq); return bmap; +error: + isl_basic_map_free(base); + return NULL; } struct isl_basic_set *isl_basic_set_extend(struct isl_basic_set *base, @@ -1025,7 +1088,8 @@ struct isl_basic_map *isl_basic_map_cow(struct isl_basic_map *bmap) bmap->ref--; bmap = isl_basic_map_dup(bmap); } - ISL_F_CLR(bmap, ISL_BASIC_SET_FINAL); + if (bmap) + ISL_F_CLR(bmap, ISL_BASIC_SET_FINAL); return bmap; } @@ -1712,10 +1776,10 @@ struct isl_basic_map *isl_basic_map_intersect_domain( isl_basic_map_compatible_domain(bmap, bset), goto error); bmap = isl_basic_map_cow(bmap); - bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim), - bset->n_div, bset->n_eq, bset->n_ineq); if (!bmap) goto error; + bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim), + bset->n_div, bset->n_eq, bset->n_ineq); dim = isl_dim_reverse(isl_dim_copy(bset->dim)); bmap_domain = isl_basic_map_from_basic_set(bset, dim); bmap = add_constraints(bmap, bmap_domain, 0, 0); @@ -1744,10 +1808,10 @@ struct isl_basic_map *isl_basic_map_intersect_range( isl_basic_map_compatible_range(bmap, bset), goto error); bmap = isl_basic_map_cow(bmap); - bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim), - bset->n_div, bset->n_eq, bset->n_ineq); if (!bmap) goto error; + bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim), + bset->n_div, bset->n_eq, bset->n_ineq); bmap_range = isl_basic_map_from_basic_set(bset, isl_dim_copy(bset->dim)); bmap = add_constraints(bmap, bmap_range, 0, 0); @@ -1828,13 +1892,15 @@ struct isl_basic_map *isl_basic_map_intersect( sample = isl_vec_copy(bmap2->sample); bmap1 = isl_basic_map_cow(bmap1); - bmap1 = isl_basic_map_extend_dim(bmap1, isl_dim_copy(bmap1->dim), - bmap2->n_div, bmap2->n_eq, bmap2->n_ineq); if (!bmap1) goto error; + bmap1 = isl_basic_map_extend_dim(bmap1, isl_dim_copy(bmap1->dim), + bmap2->n_div, bmap2->n_eq, bmap2->n_ineq); bmap1 = add_constraints(bmap1, bmap2, 0, 0); - if (sample) { + if (!bmap1) + isl_vec_free(sample); + else if (sample) { isl_vec_free(bmap1->sample); bmap1->sample = sample; } @@ -2149,6 +2215,8 @@ __isl_give isl_basic_map *isl_basic_map_move_dims( if (!bmap->dim) goto error; + bmap = isl_basic_map_finalize(bmap); + return bmap; } @@ -2180,7 +2248,7 @@ __isl_give isl_basic_map *isl_basic_map_move_dims( off += size; } } - isl_dim_map_div(dim_map, bmap, off + n); + isl_dim_map_div(dim_map, bmap, off); res = isl_basic_map_alloc_dim(isl_basic_map_get_dim(bmap), bmap->n_div, bmap->n_eq, bmap->n_ineq); @@ -2335,6 +2403,8 @@ __isl_give isl_basic_map *isl_basic_map_project_out( bmap = move_last(bmap, type, first, n); bmap = isl_basic_map_cow(bmap); + if (!bmap) + return NULL; row_size = 1 + isl_dim_total(bmap->dim) + bmap->extra; old = bmap->block2.data; @@ -2342,7 +2412,7 @@ __isl_give isl_basic_map *isl_basic_map_project_out( (bmap->extra + n) * (1 + row_size)); if (!bmap->block2.data) goto error; - new_div = isl_alloc_array(ctx, isl_int *, bmap->extra + n); + new_div = isl_alloc_array(bmap->ctx, isl_int *, bmap->extra + n); if (!new_div) goto error; for (i = 0; i < n; ++i) { @@ -2411,7 +2481,7 @@ __isl_give isl_map *isl_map_project_out(__isl_take isl_map *map, return map; error: isl_map_free(map); - return map; + return NULL; } /* Turn the n dimensions of type type, starting at first @@ -2951,6 +3021,9 @@ static __isl_give isl_map *map_lex_lte_first(__isl_take isl_dim *dims, struct isl_map *map; int i; + if (n == 0 && equal) + return isl_map_universe(dims); + map = isl_map_alloc_dim(isl_dim_copy(dims), n, ISL_MAP_DISJOINT); for (i = 0; i + 1 < n; ++i) @@ -3002,6 +3075,9 @@ static __isl_give isl_map *map_lex_gte_first(__isl_take isl_dim *dims, struct isl_map *map; int i; + if (n == 0 && equal) + return isl_map_universe(dims); + map = isl_map_alloc_dim(isl_dim_copy(dims), n, ISL_MAP_DISJOINT); for (i = 0; i + 1 < n; ++i) @@ -3309,17 +3385,80 @@ struct isl_set *isl_set_to_underlying_set(struct isl_set *set) return (struct isl_set *)isl_map_underlying_set((struct isl_map *)set); } +static __isl_give isl_basic_map *isl_basic_map_reset_dim( + __isl_take isl_basic_map *bmap, __isl_take isl_dim *dim) +{ + bmap = isl_basic_map_cow(bmap); + if (!bmap || !dim) + goto error; + + isl_dim_free(bmap->dim); + bmap->dim = dim; + + return bmap; +error: + isl_basic_map_free(bmap); + isl_dim_free(dim); + return NULL; +} + +static __isl_give isl_basic_set *isl_basic_set_reset_dim( + __isl_take isl_basic_set *bset, __isl_take isl_dim *dim) +{ + return (isl_basic_set *)isl_basic_map_reset_dim((isl_basic_map *)bset, + dim); +} + +__isl_give isl_map *isl_map_reset_dim(__isl_take isl_map *map, + __isl_take isl_dim *dim) +{ + int i; + + map = isl_map_cow(map); + if (!map || !dim) + goto error; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_reset_dim(map->p[i], + isl_dim_copy(dim)); + if (!map->p[i]) + goto error; + } + isl_dim_free(map->dim); + map->dim = dim; + + return map; +error: + isl_map_free(map); + isl_dim_free(dim); + return NULL; +} + +__isl_give isl_set *isl_set_reset_dim(__isl_take isl_set *set, + __isl_take isl_dim *dim) +{ + return (struct isl_set *) isl_map_reset_dim((struct isl_map *)set, dim); +} + struct isl_basic_set *isl_basic_map_domain(struct isl_basic_map *bmap) { + isl_dim *dim; struct isl_basic_set *domain; unsigned n_in; unsigned n_out; + if (!bmap) return NULL; + dim = isl_dim_domain(isl_basic_map_get_dim(bmap)); + n_in = isl_basic_map_n_in(bmap); n_out = isl_basic_map_n_out(bmap); domain = isl_basic_set_from_basic_map(bmap); - return isl_basic_set_project_out(domain, isl_dim_set, n_in, n_out); + domain = isl_basic_set_project_out(domain, isl_dim_set, n_in, n_out); + + domain = isl_basic_set_reset_dim(domain, dim); + + return domain; } struct isl_basic_set *isl_basic_map_range(struct isl_basic_map *bmap) @@ -3390,14 +3529,14 @@ struct isl_map *isl_map_from_range(struct isl_set *set) __isl_give isl_map *isl_map_from_domain(__isl_take isl_set *set) { - return isl_map_reverse(isl_map_from_range(set));; + return isl_map_reverse(isl_map_from_range(set)); } __isl_give isl_map *isl_map_from_domain_and_range(__isl_take isl_set *domain, __isl_take isl_set *range) { - return isl_map_product(isl_map_from_domain(domain), - isl_map_from_range(range)); + return isl_map_apply_range(isl_map_from_domain(domain), + isl_map_from_range(range)); } struct isl_set *isl_set_from_map(struct isl_map *map) @@ -4272,34 +4411,6 @@ __isl_give isl_set *isl_set_lexmax(__isl_take isl_set *set) return (isl_set *)isl_map_lexmax((isl_map *)set); } -static struct isl_map *isl_map_reset_dim(struct isl_map *map, - struct isl_dim *dim) -{ - int i; - - if (!map || !dim) - goto error; - - for (i = 0; i < map->n; ++i) { - isl_dim_free(map->p[i]->dim); - map->p[i]->dim = isl_dim_copy(dim); - } - isl_dim_free(map->dim); - map->dim = dim; - - return map; -error: - isl_map_free(map); - isl_dim_free(dim); - return NULL; -} - -static struct isl_set *isl_set_reset_dim(struct isl_set *set, - struct isl_dim *dim) -{ - return (struct isl_set *) isl_map_reset_dim((struct isl_map *)set, dim); -} - /* Apply a preimage specified by "mat" on the parameters of "bset". * bset is assumed to have only parameters and divs. */ @@ -5131,12 +5242,12 @@ int isl_map_is_empty(struct isl_map *map) int isl_map_fast_is_empty(struct isl_map *map) { - return map->n == 0; + return map ? map->n == 0 : -1; } int isl_set_fast_is_empty(struct isl_set *set) { - return set->n == 0; + return set ? set->n == 0 : -1; } int isl_set_is_empty(struct isl_set *set) @@ -5209,10 +5320,18 @@ int isl_basic_set_is_universe(struct isl_basic_set *bset) int isl_map_fast_is_universe(__isl_keep isl_map *map) { + int i; + if (!map) return -1; - return map->n == 1 && isl_basic_map_is_universe(map->p[0]); + for (i = 0; i < map->n; ++i) { + int r = isl_basic_map_is_universe(map->p[i]); + if (r < 0 || r) + return r; + } + + return 0; } int isl_set_fast_is_universe(__isl_keep isl_set *set) @@ -5235,7 +5354,7 @@ int isl_basic_map_is_empty(struct isl_basic_map *bmap) if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) { struct isl_basic_map *copy = isl_basic_map_copy(bmap); - copy = isl_basic_map_convex_hull(copy); + copy = isl_basic_map_remove_redundancies(copy); empty = ISL_F_ISSET(copy, ISL_BASIC_MAP_EMPTY); isl_basic_map_free(copy); return empty; @@ -5318,7 +5437,12 @@ struct isl_set *isl_basic_set_union( struct isl_basic_map *isl_basic_map_order_divs(struct isl_basic_map *bmap) { int i; - unsigned off = isl_dim_total(bmap->dim); + unsigned off; + + if (!bmap) + return NULL; + + off = isl_dim_total(bmap->dim); for (i = 0; i < bmap->n_div; ++i) { int pos; @@ -5945,13 +6069,20 @@ error: return NULL; } +__isl_give isl_basic_set *isl_basic_set_sort_constraints( + __isl_take isl_basic_set *bset) +{ + return (struct isl_basic_set *)isl_basic_map_sort_constraints( + (struct isl_basic_map *)bset); +} + struct isl_basic_map *isl_basic_map_normalize(struct isl_basic_map *bmap) { if (!bmap) return NULL; if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_NORMALIZED)) return bmap; - bmap = isl_basic_map_convex_hull(bmap); + bmap = isl_basic_map_remove_redundancies(bmap); bmap = isl_basic_map_sort_constraints(bmap); ISL_F_SET(bmap, ISL_BASIC_MAP_NORMALIZED); return bmap; @@ -5963,8 +6094,8 @@ struct isl_basic_set *isl_basic_set_normalize(struct isl_basic_set *bset) (struct isl_basic_map *)bset); } -static int isl_basic_map_fast_cmp(const struct isl_basic_map *bmap1, - const struct isl_basic_map *bmap2) +int isl_basic_map_fast_cmp(const __isl_keep isl_basic_map *bmap1, + const __isl_keep isl_basic_map *bmap2) { int i, cmp; unsigned total; @@ -6009,12 +6140,19 @@ static int isl_basic_map_fast_cmp(const struct isl_basic_map *bmap1, return 0; } -static int isl_basic_map_fast_is_equal(struct isl_basic_map *bmap1, - struct isl_basic_map *bmap2) +int isl_basic_map_fast_is_equal(__isl_keep isl_basic_map *bmap1, + __isl_keep isl_basic_map *bmap2) { return isl_basic_map_fast_cmp(bmap1, bmap2) == 0; } +int isl_basic_set_fast_is_equal(__isl_keep isl_basic_set *bset1, + __isl_keep isl_basic_set *bset2) +{ + return isl_basic_map_fast_is_equal((isl_basic_map *)bset1, + (isl_basic_map *)bset2); +} + static int qsort_bmap_cmp(const void *p1, const void *p2) { const struct isl_basic_map *bmap1 = *(const struct isl_basic_map **)p1; @@ -6439,6 +6577,8 @@ __isl_give isl_basic_set *isl_basic_set_lift(__isl_take isl_basic_set *bset) bset->dim = dim; bset->n_div = 0; + bset = isl_basic_set_finalize(bset); + return bset; error: isl_basic_set_free(bset); @@ -6702,3 +6842,123 @@ int isl_basic_set_dims_get_sign(__isl_keep isl_basic_set *bset, first += pos(bset->dim, type) - 1; return isl_basic_set_vars_get_sign(bset, first, n, signs); } + +/* Check if the given map is single-valued. + * We simply compute + * + * M \circ M^-1 + * + * and check if the result is a subset of the identity mapping. + */ +int isl_map_is_single_valued(__isl_keep isl_map *map) +{ + isl_map *test; + isl_map *id; + int sv; + + test = isl_map_reverse(isl_map_copy(map)); + test = isl_map_apply_range(test, isl_map_copy(map)); + + id = isl_map_identity(isl_dim_range(isl_map_get_dim(map))); + + sv = isl_map_is_subset(test, id); + + isl_map_free(test); + isl_map_free(id); + + return sv; +} + +int isl_map_is_bijective(__isl_keep isl_map *map) +{ + int sv; + + sv = isl_map_is_single_valued(map); + if (sv < 0 || !sv) + return sv; + + map = isl_map_copy(map); + map = isl_map_reverse(map); + sv = isl_map_is_single_valued(map); + isl_map_free(map); + + return sv; +} + +int isl_set_is_singleton(__isl_keep isl_set *set) +{ + return isl_map_is_single_valued((isl_map *)set); +} + +int isl_map_is_translation(__isl_keep isl_map *map) +{ + int ok; + isl_set *delta; + + delta = isl_map_deltas(isl_map_copy(map)); + ok = isl_set_is_singleton(delta); + isl_set_free(delta); + + return ok; +} + +static int unique(isl_int *p, unsigned pos, unsigned len) +{ + if (isl_seq_first_non_zero(p, pos) != -1) + return 0; + if (isl_seq_first_non_zero(p + pos + 1, len - pos - 1) != -1) + return 0; + return 1; +} + +int isl_basic_set_is_box(__isl_keep isl_basic_set *bset) +{ + int i, j; + unsigned nvar; + unsigned ovar; + + if (!bset) + return -1; + + if (isl_basic_set_dim(bset, isl_dim_div) != 0) + return 0; + + nvar = isl_basic_set_dim(bset, isl_dim_set); + ovar = isl_dim_offset(bset->dim, isl_dim_set); + for (j = 0; j < nvar; ++j) { + int lower = 0, upper = 0; + for (i = 0; i < bset->n_eq; ++i) { + if (isl_int_is_zero(bset->eq[i][1 + ovar + j])) + continue; + if (!unique(bset->eq[i] + 1 + ovar, j, nvar)) + return 0; + break; + } + if (i < bset->n_eq) + continue; + for (i = 0; i < bset->n_ineq; ++i) { + if (isl_int_is_zero(bset->ineq[i][1 + ovar + j])) + continue; + if (!unique(bset->ineq[i] + 1 + ovar, j, nvar)) + return 0; + if (isl_int_is_pos(bset->ineq[i][1 + ovar + j])) + lower = 1; + else + upper = 1; + } + if (!lower || !upper) + return 0; + } + + return 1; +} + +int isl_set_is_box(__isl_keep isl_set *set) +{ + if (!set) + return -1; + if (set->n != 1) + return 0; + + return isl_basic_set_is_box(set->p[0]); +}