From: Sven Verdoolaege Date: Fri, 5 Dec 2008 18:06:17 +0000 (+0100) Subject: allow parameters and dimensions to be named X-Git-Tag: isl-0.01~345 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=49e6195ea8560fb07832f8299d4859916c3b60fa;p=platform%2Fupstream%2Fisl.git allow parameters and dimensions to be named The names of the parameters and dimensions are stored in the recently introduced isl_dim structure. To preserve the names during set or map operations, many direct manipulations of dimensions have been rewritten in terms of operations on isl_dim structures. --- diff --git a/Makefile.am b/Makefile.am index b4b5349..3bc5b21 100644 --- a/Makefile.am +++ b/Makefile.am @@ -60,6 +60,8 @@ libisl_la_SOURCES = \ isl_map_private.h \ isl_mat.c \ isl_mat.h \ + isl_name.c \ + isl_name.h \ isl_output.c \ isl_sample.h \ isl_sample.c \ diff --git a/include/isl_ctx.h.in b/include/isl_ctx.h.in index 7aac125..9f8da8c 100644 --- a/include/isl_ctx.h.in +++ b/include/isl_ctx.h.in @@ -6,6 +6,7 @@ #include #include +#include #undef ISL_POLYLIB #undef ISL_PIPLIB @@ -38,16 +39,16 @@ extern "C" { * (in case of pointer return type). * The only exception is the isl_ctx argument, which shoud never be NULL. */ -struct isl_vec; struct isl_ctx { - int ref; + int ref; - isl_int one; + isl_int one; - int n_cached; - struct isl_blk cache[ISL_BLK_CACHE_SIZE]; + int n_cached; + struct isl_blk cache[ISL_BLK_CACHE_SIZE]; + struct isl_hash_table name_hash; #ifdef ISL_POLYLIB - unsigned MaxRays; + unsigned MaxRays; #endif }; diff --git a/include/isl_dim.h b/include/isl_dim.h index 50febb6..cf4432d 100644 --- a/include/isl_dim.h +++ b/include/isl_dim.h @@ -7,6 +7,7 @@ extern "C" { #endif +struct isl_name; struct isl_dim { int ref; @@ -15,6 +16,9 @@ struct isl_dim { unsigned nparam; unsigned n_in; /* zero for sets */ unsigned n_out; /* dim for sets */ + + unsigned n_name; + struct isl_name **names; }; enum isl_dim_type { @@ -26,12 +30,27 @@ enum isl_dim_type { struct isl_dim *isl_dim_alloc(struct isl_ctx *ctx, unsigned nparam, unsigned n_in, unsigned n_out); +struct isl_dim *isl_dim_set_alloc(struct isl_ctx *ctx, + unsigned nparam, unsigned dim); struct isl_dim *isl_dim_copy(struct isl_dim *dim); struct isl_dim *isl_dim_cow(struct isl_dim *dim); void isl_dim_free(struct isl_dim *dim); +struct isl_dim *isl_dim_set_name(struct isl_dim *dim, + enum isl_dim_type type, unsigned pos, + const char *name); +const char *isl_dim_get_name(struct isl_dim *dim, + enum isl_dim_type type, unsigned pos); + +struct isl_dim *isl_dim_extend(struct isl_dim *dim, + unsigned nparam, unsigned n_in, unsigned n_out); struct isl_dim *isl_dim_join(struct isl_dim *left, struct isl_dim *right); +struct isl_dim *isl_dim_map(struct isl_dim *dim); struct isl_dim *isl_dim_reverse(struct isl_dim *dim); +struct isl_dim *isl_dim_drop_inputs(struct isl_dim *dim, + unsigned first, unsigned n); +struct isl_dim *isl_dim_drop_outputs(struct isl_dim *dim, + unsigned first, unsigned n); int isl_dim_equal(struct isl_dim *dim1, struct isl_dim *dim2); int isl_dim_compatible(struct isl_dim *dim1, struct isl_dim *dim2); diff --git a/include/isl_map.h b/include/isl_map.h index 3c66e8d..fd933c3 100644 --- a/include/isl_map.h +++ b/include/isl_map.h @@ -105,8 +105,8 @@ unsigned isl_map_n_param(const struct isl_map *map); struct isl_basic_map *isl_basic_map_alloc(struct isl_ctx *ctx, unsigned nparam, unsigned in, unsigned out, unsigned extra, unsigned n_eq, unsigned n_ineq); -struct isl_basic_map *isl_basic_map_identity(struct isl_ctx *ctx, - unsigned nparam, unsigned dim); +struct isl_basic_map *isl_basic_map_identity(struct isl_dim *set_dim); +struct isl_basic_map *isl_basic_map_identity_like(struct isl_basic_map *model); struct isl_basic_map *isl_basic_map_finalize(struct isl_basic_map *bmap); void isl_basic_map_free(struct isl_basic_map *bmap); struct isl_basic_map *isl_basic_map_copy(struct isl_basic_map *bmap); @@ -181,8 +181,8 @@ struct isl_map *isl_map_empty_like(struct isl_map *model); struct isl_map *isl_map_empty_like_basic_map(struct isl_basic_map *model); struct isl_map *isl_map_dup(struct isl_map *map); struct isl_map *isl_map_add(struct isl_map *map, struct isl_basic_map *bmap); -struct isl_map *isl_map_identity(struct isl_ctx *ctx, - unsigned nparam, unsigned dim); +struct isl_map *isl_map_identity(struct isl_dim *set_dim); +struct isl_map *isl_map_identity_like(struct isl_basic_map *model); struct isl_map *isl_map_finalize(struct isl_map *map); void isl_map_free(struct isl_map *map); struct isl_map *isl_map_copy(struct isl_map *map); diff --git a/include/isl_map_polylib.h b/include/isl_map_polylib.h index 0028fa4..88f72d8 100644 --- a/include/isl_map_polylib.h +++ b/include/isl_map_polylib.h @@ -1,6 +1,7 @@ #ifndef ISL_MAP_POLYLIB_H #define ISL_MAP_POLYLIB_H +#include #include #include @@ -10,10 +11,10 @@ extern "C" { struct isl_basic_map *isl_basic_map_new_from_polylib( struct isl_ctx *ctx, Polyhedron *P, - unsigned nparam, unsigned in, unsigned out); + struct isl_dim *dim); struct isl_map *isl_map_new_from_polylib(struct isl_ctx *ctx, Polyhedron *D, - unsigned nparam, unsigned in, unsigned out); + struct isl_dim *dim); Polyhedron *isl_basic_map_to_polylib(struct isl_basic_map *bmap); Polyhedron *isl_map_to_polylib(struct isl_map *map); diff --git a/include/isl_set.h b/include/isl_set.h index 36558d3..a0aec04 100644 --- a/include/isl_set.h +++ b/include/isl_set.h @@ -134,8 +134,7 @@ struct isl_set *isl_set_alloc(struct isl_ctx *ctx, unsigned nparam, unsigned dim, int n, unsigned flags); struct isl_set *isl_set_extend(struct isl_set *base, unsigned nparam, unsigned dim); -struct isl_set *isl_set_empty(struct isl_ctx *ctx, - unsigned nparam, unsigned dim); +struct isl_set *isl_set_empty(struct isl_ctx *ctx, struct isl_dim *dim); struct isl_set *isl_set_empty_like(struct isl_set *set); struct isl_set *isl_set_add(struct isl_set *set, struct isl_basic_set *bset); struct isl_set *isl_set_finalize(struct isl_set *set); diff --git a/include/isl_set_polylib.h b/include/isl_set_polylib.h index b6963ba..2fba47f 100644 --- a/include/isl_set_polylib.h +++ b/include/isl_set_polylib.h @@ -10,11 +10,11 @@ extern "C" { struct isl_basic_set *isl_basic_set_new_from_polylib( struct isl_ctx *ctx, - Polyhedron *P, unsigned nparam, unsigned dim); + Polyhedron *P, struct isl_dim *dim); Polyhedron *isl_basic_set_to_polylib(struct isl_basic_set *bset); struct isl_set *isl_set_new_from_polylib(struct isl_ctx *ctx, - Polyhedron *D, unsigned nparam, unsigned dim); + Polyhedron *D, struct isl_dim *dim); Polyhedron *isl_set_to_polylib(struct isl_set *set); #if defined(__cplusplus) diff --git a/isl_ctx.c b/isl_ctx.c index 7b83243..24f1455 100644 --- a/isl_ctx.c +++ b/isl_ctx.c @@ -12,6 +12,9 @@ struct isl_ctx *isl_ctx_alloc() if (!ctx) goto error; + if (isl_hash_table_init(ctx, &ctx->name_hash, 0)) + goto error; + ctx->ref = 0; isl_int_init(ctx->one); @@ -45,6 +48,7 @@ void isl_ctx_free(struct isl_ctx *ctx) if (!ctx) return; isl_assert(ctx, ctx->ref == 0, return); + isl_hash_table_clear(&ctx->name_hash); isl_blk_clear_cache(ctx); isl_int_clear(ctx->one); free(ctx); diff --git a/isl_dim.c b/isl_dim.c index 060c005..75c2b12 100644 --- a/isl_dim.c +++ b/isl_dim.c @@ -1,4 +1,5 @@ #include "isl_dim.h" +#include "isl_name.h" struct isl_dim *isl_dim_alloc(struct isl_ctx *ctx, unsigned nparam, unsigned n_in, unsigned n_out) @@ -16,12 +17,132 @@ struct isl_dim *isl_dim_alloc(struct isl_ctx *ctx, dim->n_in = n_in; dim->n_out = n_out; + dim->n_name = 0; + dim->names = NULL; + return dim; } +struct isl_dim *isl_dim_set_alloc(struct isl_ctx *ctx, + unsigned nparam, unsigned dim) +{ + return isl_dim_alloc(ctx, nparam, 0, dim); +} + +static unsigned global_pos(struct isl_dim *dim, + enum isl_dim_type type, unsigned pos) +{ + struct isl_ctx *ctx = dim->ctx; + + switch (type) { + case isl_dim_param: + isl_assert(ctx, pos < dim->nparam, return isl_dim_total(dim)); + return pos; + case isl_dim_in: + isl_assert(ctx, pos < dim->n_in, return isl_dim_total(dim)); + return pos + dim->nparam; + case isl_dim_out: + isl_assert(ctx, pos < dim->n_out, return isl_dim_total(dim)); + return pos + dim->nparam + dim->n_in; + default: + isl_assert(ctx, 0, goto error); + } + return isl_dim_total(dim); +} + +static struct isl_dim *set_name(struct isl_dim *dim, + enum isl_dim_type type, unsigned pos, + struct isl_name *name) +{ + struct isl_ctx *ctx = dim->ctx; + dim = isl_dim_cow(dim); + + if (!dim) + goto error; + + pos = global_pos(dim, type, pos); + isl_assert(ctx, pos != isl_dim_total(dim), goto error); + + if (pos >= dim->n_name) { + if (!name) + return dim; + if (!dim->names) { + dim->names = isl_calloc_array(dim->ctx, + struct isl_name *, isl_dim_total(dim)); + if (!dim->names) + goto error; + } else { + int i; + dim->names = isl_realloc_array(dim->ctx, dim->names, + struct isl_name *, isl_dim_total(dim)); + if (!dim->names) + goto error; + for (i = dim->n_name; i < isl_dim_total(dim); ++i) + dim->names[i] = NULL; + } + } + dim->n_name = isl_dim_total(dim); + + dim->names[pos] = name; + + return dim; +error: + isl_name_free(ctx, name); + isl_dim_free(dim); + return NULL; +} + +static struct isl_name *get_name(struct isl_dim *dim, + enum isl_dim_type type, unsigned pos) +{ + if (!dim) + return NULL; + + pos = global_pos(dim, type, pos); + if (pos == isl_dim_total(dim)) + return NULL; + if (pos >= dim->n_name) + return NULL; + return dim->names[pos]; +} + +static unsigned n(struct isl_dim *dim, enum isl_dim_type type) +{ + switch (type) { + case isl_dim_param: return dim->nparam; + case isl_dim_in: return dim->n_in; + case isl_dim_out: return dim->n_out; + } +} + +static struct isl_dim *copy_names(struct isl_dim *dst, + enum isl_dim_type dst_type, struct isl_dim *src, + enum isl_dim_type src_type) +{ + int i; + struct isl_name *name; + + for (i = 0; i < n(dst, dst_type); ++i) { + name = get_name(src, src_type, i); + if (!name) + continue; + dst = set_name(dst, dst_type, i, isl_name_copy(dst->ctx, name)); + if (!dst) + return NULL; + } + return dst; +} + struct isl_dim *isl_dim_dup(struct isl_dim *dim) { - return isl_dim_alloc(dim->ctx, dim->nparam, dim->n_in, dim->n_out); + struct isl_dim *dup; + dup = isl_dim_alloc(dim->ctx, dim->nparam, dim->n_in, dim->n_out); + if (!dim->names) + return dup; + dup = copy_names(dup, isl_dim_param, dim, isl_dim_param); + dup = copy_names(dup, isl_dim_in, dim, isl_dim_in); + dup = copy_names(dup, isl_dim_out, dim, isl_dim_out); + return dup; } struct isl_dim *isl_dim_cow(struct isl_dim *dim) @@ -46,17 +167,112 @@ struct isl_dim *isl_dim_copy(struct isl_dim *dim) void isl_dim_free(struct isl_dim *dim) { + int i; + if (!dim) return; if (--dim->ref > 0) return; + for (i = 0; i < dim->n_name; ++i) + isl_name_free(dim->ctx, dim->names[i]); + free(dim->names); isl_ctx_deref(dim->ctx); free(dim); } +struct isl_dim *isl_dim_set_name(struct isl_dim *dim, + enum isl_dim_type type, unsigned pos, + const char *s) +{ + struct isl_name *name; + if (!dim) + return NULL; + name = isl_name_get(dim->ctx, s); + if (!name) + goto error; + return set_name(dim, type, pos, name); +error: + isl_dim_free(dim); + return NULL; +} + +const char *isl_dim_get_name(struct isl_dim *dim, + enum isl_dim_type type, unsigned pos) +{ + struct isl_name *name = get_name(dim, type, pos); + return name ? name->name : NULL; +} + +static int match(struct isl_dim *dim1, enum isl_dim_type dim1_type, + struct isl_dim *dim2, enum isl_dim_type dim2_type) +{ + int i; + + if (n(dim1, dim1_type) != n(dim2, dim2_type)) + return 0; + + if (!dim1->names && !dim2->names) + return 1; + + for (i = 0; i < n(dim1, dim1_type); ++i) { + if (get_name(dim1, dim1_type, i) != + get_name(dim2, dim2_type, i)) + return 0; + } + return 1; +} + +static void get_names(struct isl_dim *dim, enum isl_dim_type type, + unsigned first, unsigned n, struct isl_name **names) +{ + int i; + + for (i = 0; i < n ; ++i) + names[i] = get_name(dim, type, first+i); +} + +struct isl_dim *isl_dim_extend(struct isl_dim *dim, + unsigned nparam, unsigned n_in, unsigned n_out) +{ + struct isl_name **names = NULL; + + if (!dim) + return NULL; + if (dim->nparam == nparam && dim->n_in == n_in && dim->n_out == n_out) + return dim; + + isl_assert(dim->ctx, dim->nparam <= nparam, goto error); + isl_assert(dim->ctx, dim->n_in <= n_in, goto error); + isl_assert(dim->ctx, dim->n_out <= n_out, goto error); + + dim = isl_dim_cow(dim); + + if (dim->names) { + names = isl_calloc_array(dim->ctx, struct isl_name *, + nparam + n_in + n_out); + if (!names) + goto error; + get_names(dim, isl_dim_param, 0, dim->nparam, names); + get_names(dim, isl_dim_in, 0, dim->n_in, names + nparam); + get_names(dim, isl_dim_out, 0, dim->n_out, + names + nparam + n_in); + free(dim->names); + dim->names = names; + } + dim->nparam = nparam; + dim->n_in = n_in; + dim->n_out = n_out; + + return dim; +error: + free(names); + isl_dim_free(dim); + return NULL; +} + struct isl_dim *isl_dim_join(struct isl_dim *left, struct isl_dim *right) { struct isl_dim *dim; @@ -64,13 +280,19 @@ struct isl_dim *isl_dim_join(struct isl_dim *left, struct isl_dim *right) if (!left || !right) goto error; - isl_assert(left->ctx, left->nparam == right->nparam, goto error); - isl_assert(left->ctx, left->n_out == right->n_in, goto error); + isl_assert(left->ctx, match(left, isl_dim_param, right, isl_dim_param), + goto error); + isl_assert(left->ctx, match(left, isl_dim_out, right, isl_dim_in), + goto error); dim = isl_dim_alloc(left->ctx, left->nparam, left->n_in, right->n_out); if (!dim) goto error; + dim = copy_names(dim, isl_dim_param, left, isl_dim_param); + dim = copy_names(dim, isl_dim_in, left, isl_dim_in); + dim = copy_names(dim, isl_dim_out, right, isl_dim_out); + isl_dim_free(left); isl_dim_free(right); @@ -81,23 +303,147 @@ error: return NULL; } +struct isl_dim *isl_dim_map(struct isl_dim *dim) +{ + struct isl_name **names = NULL; + + if (!dim) + return NULL; + isl_assert(dim->ctx, dim->n_in == 0, goto error); + if (dim->n_out == 0) + return dim; + dim = isl_dim_cow(dim); + if (!dim) + return NULL; + if (dim->names) { + names = isl_calloc_array(dim->ctx, struct isl_name *, + dim->nparam + dim->n_out + dim->n_out); + if (!names) + goto error; + get_names(dim, isl_dim_param, 0, dim->nparam, names); + get_names(dim, isl_dim_out, 0, dim->n_out, names + dim->nparam); + } + dim->n_in = dim->n_out; + if (names) { + copy_names(dim, isl_dim_out, dim, isl_dim_in); + free(dim->names); + dim->names = names; + } + return dim; +error: + isl_dim_free(dim); + return NULL; +} + +static struct isl_dim *set_names(struct isl_dim *dim, enum isl_dim_type type, + unsigned first, unsigned n, struct isl_name **names) +{ + int i; + + for (i = 0; i < n ; ++i) + dim = set_name(dim, type, first+i, names[i]); + + return dim; +} + struct isl_dim *isl_dim_reverse(struct isl_dim *dim) { unsigned t; + struct isl_name **names = NULL; if (!dim) return NULL; - if (dim->n_in == dim->n_out) + if (match(dim, isl_dim_in, dim, isl_dim_out)) return dim; dim = isl_dim_cow(dim); if (!dim) return NULL; + if (dim->names) { + names = isl_alloc_array(dim->ctx, struct isl_name *, + dim->n_in + dim->n_out); + if (!names) + goto error; + get_names(dim, isl_dim_in, 0, dim->n_in, names); + get_names(dim, isl_dim_out, 0, dim->n_out, names + dim->n_in); + } + t = dim->n_in; dim->n_in = dim->n_out; dim->n_out = t; + if (dim->names) { + dim = set_names(dim, isl_dim_out, 0, dim->n_out, names); + dim = set_names(dim, isl_dim_in, 0, dim->n_in, names + dim->n_out); + free(names); + } + + return dim; +error: + free(names); + isl_dim_free(dim); + return NULL; +} + +struct isl_dim *isl_dim_drop_inputs(struct isl_dim *dim, + unsigned first, unsigned n) +{ + int i; + + if (!dim) + return NULL; + + if (n == 0) + return dim; + + isl_assert(dim->ctx, first + n <= dim->n_in, goto error); + dim = isl_dim_cow(dim); + if (!dim) + goto error; + if (dim->names) { + for (i = 0; i < n; ++i) { + isl_name_free(dim->ctx, + get_name(dim, isl_dim_in, first+i)); + } + for (i = first+n; i < dim->n_in; ++i) + set_name(dim, isl_dim_in, i - n, + get_name(dim, isl_dim_in, i)); + get_names(dim, isl_dim_out, 0, dim->n_out, + dim->names + dim->nparam + dim->n_in - n); + } + dim->n_in -= n; + return dim; +error: + isl_dim_free(dim); + return NULL; +} + +struct isl_dim *isl_dim_drop_outputs(struct isl_dim *dim, + unsigned first, unsigned n) +{ + int i; + + if (!dim) + return NULL; + + if (n == 0) + return dim; + + isl_assert(dim->ctx, first + n <= dim->n_out, goto error); + dim = isl_dim_cow(dim); + if (!dim) + goto error; + if (dim->names) { + for (i = 0; i < n; ++i) { + isl_name_free(dim->ctx, + get_name(dim, isl_dim_out, first+i)); + } + for (i = first+n; i < dim->n_out; ++i) + set_name(dim, isl_dim_out, i - n, + get_name(dim, isl_dim_out, i)); + } + dim->n_out -= n; return dim; error: isl_dim_free(dim); @@ -111,9 +457,9 @@ unsigned isl_dim_total(struct isl_dim *dim) int isl_dim_equal(struct isl_dim *dim1, struct isl_dim *dim2) { - return dim1->nparam == dim2->nparam && - dim1->n_in == dim2->n_in && - dim1->n_out == dim2->n_out; + return match(dim1, isl_dim_param, dim2, isl_dim_param) && + match(dim1, isl_dim_in, dim2, isl_dim_in) && + match(dim1, isl_dim_out, dim2, isl_dim_out); } int isl_dim_compatible(struct isl_dim *dim1, struct isl_dim *dim2) diff --git a/isl_input_omega.c b/isl_input_omega.c index 34e3385..7dea12f 100644 --- a/isl_input_omega.c +++ b/isl_input_omega.c @@ -497,8 +497,7 @@ static struct isl_basic_map *add_exists(struct stream *s, if (!*v) goto error; extra = (*v)->n - n; - bmap = isl_basic_map_extend(bmap, isl_basic_map_n_param(bmap), - isl_basic_map_n_in(bmap), isl_basic_map_n_out(bmap), + bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim), extra, 0, 0); total = isl_basic_map_total_dim(bmap); for (i = 0; i < extra; ++i) { diff --git a/isl_map.c b/isl_map.c index 4719329..3c9aeb5 100644 --- a/isl_map.c +++ b/isl_map.c @@ -956,9 +956,6 @@ struct isl_basic_set *isl_basic_set_drop_dims( bset = isl_basic_set_cow(bset); if (!bset) return NULL; - bset->dim = isl_dim_cow(bset->dim); - if (!bset->dim) - goto error; for (i = 0; i < bset->n_eq; ++i) constraint_drop_vars(bset->eq[i]+1+bset->dim->nparam+first, n, @@ -972,7 +969,9 @@ struct isl_basic_set *isl_basic_set_drop_dims( constraint_drop_vars(bset->div[i]+1+1+bset->dim->nparam+first, n, (bset->dim->n_out-first-n)+bset->extra); - bset->dim->n_out -= n; + bset->dim = isl_dim_drop_outputs(bset->dim, first, n); + if (!bset->dim) + goto error; bset->extra += n; F_CLR(bset, ISL_BASIC_SET_NORMALIZED); @@ -998,7 +997,7 @@ static struct isl_set *isl_set_drop_dims( set = isl_set_cow(set); if (!set) goto error; - set->dim = isl_dim_cow(set->dim); + set->dim = isl_dim_drop_outputs(set->dim, first, n); if (!set->dim) goto error; @@ -1007,7 +1006,6 @@ static struct isl_set *isl_set_drop_dims( if (!set->p[i]) goto error; } - set->dim->n_out -= n; F_CLR(set, ISL_SET_NORMALIZED); return set; @@ -1038,9 +1036,6 @@ struct isl_basic_map *isl_basic_map_drop_inputs( bmap = isl_basic_map_cow(bmap); if (!bmap) return NULL; - bmap->dim = isl_dim_cow(bmap->dim); - if (!bmap->dim) - goto error; for (i = 0; i < bmap->n_eq; ++i) constraint_drop_vars(bmap->eq[i]+1+nparam+first, n, @@ -1054,7 +1049,9 @@ struct isl_basic_map *isl_basic_map_drop_inputs( constraint_drop_vars(bmap->div[i]+1+1+nparam+first, n, (n_in-first-n)+n_out+bmap->extra); - bmap->dim->n_in -= n; + bmap->dim = isl_dim_drop_inputs(bmap->dim, first, n); + if (!bmap->dim) + goto error; bmap->extra += n; F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED); @@ -1080,7 +1077,7 @@ static struct isl_map *isl_map_drop_inputs( map = isl_map_cow(map); if (!map) goto error; - map->dim = isl_dim_cow(map->dim); + map->dim = isl_dim_drop_inputs(map->dim, first, n); if (!map->dim) goto error; @@ -1089,7 +1086,6 @@ static struct isl_map *isl_map_drop_inputs( if (!map->p[i]) goto error; } - map->dim->n_in -= n; F_CLR(map, ISL_MAP_NORMALIZED); return map; @@ -2007,6 +2003,7 @@ struct isl_basic_set *isl_basic_set_simplify(struct isl_basic_set *bset) static void dump_term(struct isl_basic_map *bmap, isl_int c, int pos, FILE *out) { + const char *name; unsigned in = isl_basic_map_n_in(bmap); unsigned dim = in + isl_basic_map_n_out(bmap); unsigned nparam = isl_basic_map_n_param(bmap); @@ -2015,9 +2012,14 @@ static void dump_term(struct isl_basic_map *bmap, else { if (!isl_int_is_one(c)) isl_int_print(out, c, 0); - if (pos < 1 + nparam) - fprintf(out, "p%d", pos - 1); - else if (pos < 1 + nparam + in) + if (pos < 1 + nparam) { + name = isl_dim_get_name(bmap->dim, + isl_dim_param, pos - 1); + if (name) + fprintf(out, "%s", name); + else + fprintf(out, "p%d", pos - 1); + } else if (pos < 1 + nparam + in) fprintf(out, "i%d", pos - 1 - nparam); else if (pos < 1 + nparam + dim) fprintf(out, "o%d", pos - 1 - nparam - in); @@ -2136,10 +2138,11 @@ void isl_basic_map_dump(struct isl_basic_map *bmap, FILE *out, int indent) } fprintf(out, "%*s", indent, ""); - fprintf(out, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, flags: %x\n", + fprintf(out, "ref: %d, nparam: %d, in: %d, out: %d, extra: %d, " + "flags: %x, n_name: %d\n", bmap->ref, bmap->dim->nparam, bmap->dim->n_in, bmap->dim->n_out, - bmap->extra, bmap->flags); + bmap->extra, bmap->flags, bmap->dim->n_name); dump(bmap, out, indent); } @@ -2311,9 +2314,10 @@ void isl_map_dump(struct isl_map *map, FILE *out, int indent) } fprintf(out, "%*s", indent, ""); - fprintf(out, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, flags: %x\n", + fprintf(out, "ref: %d, n: %d, nparam: %d, in: %d, out: %d, " + "flags: %x, n_name: %d\n", map->ref, map->n, map->dim->nparam, map->dim->n_in, - map->dim->n_out, map->flags); + map->dim->n_out, map->flags, map->dim->n_name); for (i = 0; i < map->n; ++i) { fprintf(out, "%*s", indent, ""); fprintf(out, "basic map %d:\n", i); @@ -2333,9 +2337,7 @@ struct isl_basic_map *isl_basic_map_intersect_domain( isl_assert(set->ctx, isl_basic_map_compatible_domain(bmap, bset), goto error); - bmap = isl_basic_map_extend(bmap, - isl_basic_map_n_param(bmap), isl_basic_map_n_in(bmap), - isl_basic_map_n_out(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; @@ -2362,9 +2364,7 @@ struct isl_basic_map *isl_basic_map_intersect_range( isl_assert(bset->ctx, isl_basic_map_compatible_range(bmap, bset), goto error); - bmap = isl_basic_map_extend(bmap, - isl_basic_map_n_param(bmap), isl_basic_map_n_in(bmap), - isl_basic_map_n_out(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; @@ -2387,8 +2387,7 @@ struct isl_basic_map *isl_basic_map_intersect( isl_assert(map1->ctx, isl_dim_equal(bmap1->dim, bmap2->dim), goto error); - bmap1 = isl_basic_map_extend(bmap1, isl_basic_map_n_param(bmap1), - isl_basic_map_n_in(bmap1), isl_basic_map_n_out(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; @@ -2515,10 +2514,10 @@ struct isl_basic_set *isl_basic_set_project_out( bset->div = new_div; bset->n_div += n; bset->extra += n; - bset->dim = isl_dim_cow(bset->dim); + bset->dim = isl_dim_drop_outputs(bset->dim, + isl_basic_set_n_dim(bset) - n, n); if (!bset->dim) goto error; - bset->dim->n_out -= n; bset = isl_basic_set_simplify(bset); return isl_basic_set_finalize(bset); error: @@ -2842,7 +2841,7 @@ struct isl_basic_map *isl_basic_map_overlying_set( ctx = bset->ctx; isl_assert(ctx, bset->dim->n_out == isl_basic_map_total_dim(like), goto error); - if (like->dim->nparam == 0 && like->dim->n_in == 0 && like->n_div == 0) { + if (isl_dim_equal(bset->dim, like->dim) && like->n_div == 0) { isl_basic_map_free(like); return (struct isl_basic_map *)bset; } @@ -2906,7 +2905,7 @@ struct isl_set *isl_set_from_underlying_set( goto error; isl_assert(set->ctx, set->dim->n_out == isl_basic_set_total_dim(like), goto error); - if (like->dim->nparam == 0 && like->n_div == 0) { + if (isl_dim_equal(set->dim, like->dim) && like->n_div == 0) { isl_basic_set_free(like); return set; } @@ -2995,10 +2994,9 @@ struct isl_set *isl_map_range(struct isl_map *map) set = (struct isl_set *) map; if (set->dim->n_in != 0) { - set->dim = isl_dim_cow(set->dim); + set->dim = isl_dim_drop_inputs(set->dim, 0, set->dim->n_in); if (!set->dim) goto error; - set->dim->n_in = 0; } for (i = 0; i < map->n; ++i) { set->p[i] = isl_basic_map_range(map->p[i]); @@ -3196,17 +3194,16 @@ struct isl_map *isl_map_empty_like_basic_map(struct isl_basic_map *model) 0, ISL_MAP_DISJOINT); } -struct isl_set *isl_set_empty(struct isl_ctx *ctx, - unsigned nparam, unsigned dim) +struct isl_set *isl_set_empty(struct isl_ctx *ctx, struct isl_dim *dim) { - return isl_set_alloc(ctx, nparam, dim, 0, ISL_MAP_DISJOINT); + return isl_set_alloc_dim(ctx, dim, 0, ISL_MAP_DISJOINT); } struct isl_set *isl_set_empty_like(struct isl_set *model) { if (!model) return NULL; - return isl_set_alloc_dim(model->ctx, model->dim, 0, ISL_MAP_DISJOINT); + return isl_set_empty(model->ctx, isl_dim_copy(model->dim)); } struct isl_map *isl_map_dup(struct isl_map *map) @@ -3267,18 +3264,12 @@ struct isl_map *isl_map_extend(struct isl_map *base, if (!base) return NULL; - isl_assert(base->ctx, base->dim->nparam <= nparam, goto error); - isl_assert(base->ctx, base->dim->n_in <= n_in, goto error); - isl_assert(base->ctx, base->dim->n_out <= n_out, goto error); - base->dim = isl_dim_cow(base->dim); + base->dim = isl_dim_extend(base->dim, nparam, n_in, n_out); if (!base->dim) goto error; - base->dim->nparam = nparam; - base->dim->n_in = n_in; - base->dim->n_out = n_out; for (i = 0; i < base->n; ++i) { - base->p[i] = isl_basic_map_extend(base->p[i], - nparam, n_in, n_out, 0, 0, 0); + base->p[i] = isl_basic_map_extend_dim(base->p[i], + isl_dim_copy(base->dim), 0, 0, 0); if (!base->p[i]) goto error; } @@ -3542,11 +3533,10 @@ struct isl_set *isl_map_domain(struct isl_map *map) return NULL; set = (struct isl_set *)map; - set->dim = isl_dim_cow(set->dim); + set->dim = isl_dim_drop_outputs(set->dim, 0, set->dim->n_out); + set->dim = isl_dim_reverse(set->dim); if (!set->dim) goto error; - set->dim->n_out = map->dim->n_in; - set->dim->n_in = 0; for (i = 0; i < map->n; ++i) { set->p[i] = isl_basic_map_domain(map->p[i]); if (!set->p[i]) @@ -3912,13 +3902,19 @@ error: return NULL; } -struct isl_basic_map *isl_basic_map_identity(struct isl_ctx *ctx, - unsigned nparam, unsigned dim) +static struct isl_basic_map *basic_map_identity(struct isl_dim *dims) { struct isl_basic_map *bmap; + unsigned nparam; + unsigned dim; int i; - bmap = isl_basic_map_alloc(ctx, nparam, dim, dim, 0, dim, 0); + if (!dims) + return NULL; + + nparam = dims->nparam; + dim = dims->n_out; + bmap = isl_basic_map_alloc_dim(dims->ctx, dims, 0, dim, 0); if (!bmap) goto error; @@ -3936,19 +3932,44 @@ error: return NULL; } -struct isl_map *isl_map_identity(struct isl_ctx *ctx, - unsigned nparam, unsigned dim) +struct isl_basic_map *isl_basic_map_identity(struct isl_dim *set_dim) { - struct isl_map *map = isl_map_alloc(ctx, nparam, dim, dim, 1, - ISL_MAP_DISJOINT); - if (!map) - goto error; - map = isl_map_add(map, - isl_basic_map_identity(ctx, nparam, dim)); - return map; -error: - isl_map_free(map); - return NULL; + struct isl_dim *dim = isl_dim_map(set_dim); + if (!dim) + return NULL; + return basic_map_identity(dim); +} + +struct isl_basic_map *isl_basic_map_identity_like(struct isl_basic_map *model) +{ + if (!model || !model->dim) + return NULL; + isl_assert(model->ctx, + model->dim->n_in == model->dim->n_out, return NULL); + return basic_map_identity(isl_dim_copy(model->dim)); +} + +static struct isl_map *map_identity(struct isl_dim *dim) +{ + struct isl_map *map = isl_map_alloc_dim(dim->ctx, dim, 1, ISL_MAP_DISJOINT); + return isl_map_add(map, basic_map_identity(isl_dim_copy(dim))); +} + +struct isl_map *isl_map_identity(struct isl_dim *set_dim) +{ + struct isl_dim *dim = isl_dim_map(set_dim); + if (!dim) + return NULL; + return map_identity(dim); +} + +struct isl_map *isl_map_identity_like(struct isl_basic_map *model) +{ + if (!model || !model->dim) + return NULL; + isl_assert(model->ctx, + model->dim->n_in == model->dim->n_out, return NULL); + return map_identity(isl_dim_copy(model->dim)); } int isl_set_is_equal(struct isl_set *set1, struct isl_set *set2) @@ -4238,8 +4259,7 @@ struct isl_basic_map *isl_basic_map_align_divs( return dst; src = order_divs(src); - dst = isl_basic_map_extend(dst, isl_basic_map_n_param(dst), - isl_basic_map_n_in(dst), isl_basic_map_n_out(dst), + dst = isl_basic_map_extend_dim(dst, isl_dim_copy(dst->dim), src->n_div, 0, 2 * src->n_div); if (!dst) return NULL; diff --git a/isl_map_polylib.c b/isl_map_polylib.c index efce50c..4cdc00b 100644 --- a/isl_map_polylib.c +++ b/isl_map_polylib.c @@ -102,24 +102,26 @@ error: struct isl_basic_set *isl_basic_set_new_from_polylib( struct isl_ctx *ctx, - Polyhedron *P, unsigned nparam, unsigned dim) + Polyhedron *P, struct isl_dim *dim) { + isl_assert(ctx, dim->n_in == 0, return NULL); + return (struct isl_basic_set *) - isl_basic_map_new_from_polylib(ctx, P, nparam, 0, dim); + isl_basic_map_new_from_polylib(ctx, P, dim); } struct isl_basic_map *isl_basic_map_new_from_polylib( struct isl_ctx *ctx, Polyhedron *P, - unsigned nparam, unsigned in, unsigned out) + struct isl_dim *dim) { struct isl_basic_map *bmap; unsigned extra; - isl_assert(ctx, P, return NULL); - isl_assert(ctx, P->Dimension >= nparam + in + out, return NULL); + isl_assert(ctx, P, goto error); + isl_assert(ctx, P->Dimension >= isl_dim_total(dim), goto error); - extra = P->Dimension - nparam - in - out; - bmap = isl_basic_map_alloc(ctx, nparam, in, out, extra, + extra = P->Dimension - isl_dim_total(dim); + bmap = isl_basic_map_alloc_dim(ctx, dim, extra, P->NbEq, P->NbConstraints - P->NbEq); if (!bmap) return NULL; @@ -127,32 +129,43 @@ struct isl_basic_map *isl_basic_map_new_from_polylib( bmap = copy_constraints(ctx, bmap, P); bmap = isl_basic_map_simplify(bmap); return isl_basic_map_finalize(bmap); +error: + isl_dim_free(dim); + return NULL; } struct isl_set *isl_set_new_from_polylib(struct isl_ctx *ctx, - Polyhedron *D, unsigned nparam, unsigned dim) + Polyhedron *D, struct isl_dim *dim) { struct isl_set *set = NULL; Polyhedron *P; int n = 0; + if (!dim) + return NULL; + isl_assert(ctx, dim->n_in == 0, goto error); + for (P = D; P; P = P->next) ++n; - set = isl_set_alloc(ctx, nparam, dim, n, ISL_MAP_DISJOINT); + set = isl_set_alloc_dim(ctx, isl_dim_copy(dim), n, ISL_MAP_DISJOINT); if (!set) - return NULL; + goto error; for (P = D; P; P = P->next) isl_set_add(set, - isl_basic_set_new_from_polylib(ctx, P, nparam, dim)); + isl_basic_set_new_from_polylib(ctx, P, isl_dim_copy(dim))); + isl_dim_free(dim); set = isl_set_remove_empty_parts(set); return set; +error: + isl_dim_free(dim); + return NULL; } struct isl_map *isl_map_new_from_polylib(struct isl_ctx *ctx, Polyhedron *D, - unsigned nparam, unsigned in, unsigned out) + struct isl_dim *dim) { struct isl_map *map = NULL; Polyhedron *P; @@ -161,15 +174,19 @@ struct isl_map *isl_map_new_from_polylib(struct isl_ctx *ctx, for (P = D; P; P = P->next) ++n; - map = isl_map_alloc(ctx, nparam, in, out, n, ISL_MAP_DISJOINT); + map = isl_map_alloc_dim(ctx, isl_dim_copy(dim), n, ISL_MAP_DISJOINT); if (!map) - return NULL; + goto error; for (P = D; P; P = P->next) - isl_map_add(map, isl_basic_map_new_from_polylib(ctx, P, - nparam, in, out)); + isl_map_add(map, + isl_basic_map_new_from_polylib(ctx, P, isl_dim_copy(dim))); + isl_dim_free(dim); map = isl_map_remove_empty_parts(map); return map; +error: + isl_dim_free(dim); + return NULL; } Polyhedron *isl_basic_map_to_polylib(struct isl_basic_map *bmap) diff --git a/isl_map_private.h b/isl_map_private.h index 7e7a93a..9837a3f 100644 --- a/isl_map_private.h +++ b/isl_map_private.h @@ -7,6 +7,10 @@ int isl_basic_map_compatible_domain(struct isl_basic_map *bmap, int isl_basic_map_compatible_range(struct isl_basic_map *bmap, struct isl_basic_set *bset); +struct isl_basic_map *isl_basic_map_extend_dim(struct isl_basic_map *base, + struct isl_dim *dim, unsigned extra, + unsigned n_eq, unsigned n_ineq); + struct isl_basic_set *isl_basic_set_alloc_dim(struct isl_ctx *ctx, struct isl_dim *dim, unsigned extra, unsigned n_eq, unsigned n_ineq); diff --git a/isl_name.c b/isl_name.c new file mode 100644 index 0000000..2ef6cbe --- /dev/null +++ b/isl_name.c @@ -0,0 +1,80 @@ +#include +#include "isl_name.h" + +struct isl_name *isl_name_alloc(struct isl_ctx *ctx, const char *s) +{ + const char *copy = strdup(s); + struct isl_name *name; + + if (!copy) + return NULL; + name = isl_alloc_type(ctx, struct isl_name); + if (!name) + return NULL; + + name->ref = 1; + name->name = copy; + + return name; +} + +static int isl_name_has_name(const void *entry, const void *val) +{ + struct isl_name *name = (struct isl_name *)entry; + const char *s = (const char *)val; + + return !strcmp(name->name, s); +} + +struct isl_name *isl_name_get(struct isl_ctx *ctx, const char *name) +{ + struct isl_hash_table_entry *entry; + uint32_t name_hash; + + name_hash = isl_hash_string(isl_hash_init(), name); + entry = isl_hash_table_find(ctx, &ctx->name_hash, name_hash, + isl_name_has_name, name, 1); + if (!entry) + return NULL; + if (entry->data) + return isl_name_copy(ctx, entry->data); + entry->data = isl_name_alloc(ctx, name); + if (!entry->data) + ctx->name_hash.n--; + return entry->data; +} + +struct isl_name *isl_name_copy(struct isl_ctx *ctx, struct isl_name *name) +{ + if (!name) + return NULL; + + name->ref++; + return name; +} + +static int isl_name_eq(const void *entry, const void *name) +{ + return entry == name; +} + +void isl_name_free(struct isl_ctx *ctx, struct isl_name *name) +{ + uint32_t name_hash; + struct isl_hash_table_entry *entry; + + if (!name) + return; + + if (--name->ref > 0) + return; + + name_hash = isl_hash_string(isl_hash_init(), name->name); + entry = isl_hash_table_find(ctx, &ctx->name_hash, name_hash, + isl_name_eq, name, 0); + isl_assert(ctx, entry, return); + isl_hash_table_remove(ctx, &ctx->name_hash, entry); + + free((char *)name->name); + free(name); +} diff --git a/isl_name.h b/isl_name.h new file mode 100644 index 0000000..8d2ffc4 --- /dev/null +++ b/isl_name.h @@ -0,0 +1,25 @@ +#ifndef ISL_NAME_H +#define ISL_NAME_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +struct isl_name { + int ref; + + const char *name; +}; + +struct isl_name *isl_name_alloc(struct isl_ctx *ctx, const char *name); +struct isl_name *isl_name_get(struct isl_ctx *ctx, const char *name); +struct isl_name *isl_name_copy(struct isl_ctx *ctx, struct isl_name *name); +void isl_name_free(struct isl_ctx *ctx, struct isl_name *name); + +#if defined(__cplusplus) +} +#endif + +#endif