allow parameters and dimensions to be named
authorSven Verdoolaege <skimo@kotnet.org>
Fri, 5 Dec 2008 18:06:17 +0000 (19:06 +0100)
committerSven Verdoolaege <skimo@kotnet.org>
Sun, 14 Dec 2008 16:31:06 +0000 (17:31 +0100)
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.

15 files changed:
Makefile.am
include/isl_ctx.h.in
include/isl_dim.h
include/isl_map.h
include/isl_map_polylib.h
include/isl_set.h
include/isl_set_polylib.h
isl_ctx.c
isl_dim.c
isl_input_omega.c
isl_map.c
isl_map_polylib.c
isl_map_private.h
isl_name.c [new file with mode: 0644]
isl_name.h [new file with mode: 0644]

index b4b5349..3bc5b21 100644 (file)
@@ -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 \
index 7aac125..9f8da8c 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <isl_int.h>
 #include <isl_blk.h>
+#include <isl_hash.h>
 
 #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
 };
 
index 50febb6..cf4432d 100644 (file)
@@ -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);
index 3c66e8d..fd933c3 100644 (file)
@@ -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);
index 0028fa4..88f72d8 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef ISL_MAP_POLYLIB_H
 #define ISL_MAP_POLYLIB_H
 
+#include <isl_dim.h>
 #include <isl_map.h>
 #include <isl_polylib.h>
 
@@ -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);
 
index 36558d3..a0aec04 100644 (file)
@@ -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);
index b6963ba..2fba47f 100644 (file)
@@ -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)
index 7b83243..24f1455 100644 (file)
--- 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);
index 060c005..75c2b12 100644 (file)
--- 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)
index 34e3385..7dea12f 100644 (file)
@@ -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) {
index 4719329..3c9aeb5 100644 (file)
--- 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;
index efce50c..4cdc00b 100644 (file)
@@ -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)
index 7e7a93a..9837a3f 100644 (file)
@@ -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 (file)
index 0000000..2ef6cbe
--- /dev/null
@@ -0,0 +1,80 @@
+#include <string.h>
+#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 (file)
index 0000000..8d2ffc4
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef ISL_NAME_H
+#define ISL_NAME_H
+
+#include <isl_ctx.h>
+
+#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