+struct isl_dim *isl_dim_add(struct isl_dim *dim, enum isl_dim_type type,
+ unsigned n)
+{
+ if (!dim)
+ return NULL;
+ dim = isl_dim_reset(dim, type);
+ switch (type) {
+ case isl_dim_param:
+ dim = isl_dim_extend(dim,
+ dim->nparam + n, dim->n_in, dim->n_out);
+ if (dim && dim->nested[0] &&
+ !(dim->nested[0] = isl_dim_add(dim->nested[0],
+ isl_dim_param, n)))
+ goto error;
+ if (dim && dim->nested[1] &&
+ !(dim->nested[1] = isl_dim_add(dim->nested[1],
+ isl_dim_param, n)))
+ goto error;
+ return dim;
+ case isl_dim_in:
+ return isl_dim_extend(dim,
+ dim->nparam, dim->n_in + n, dim->n_out);
+ case isl_dim_out:
+ return isl_dim_extend(dim,
+ dim->nparam, dim->n_in, dim->n_out + n);
+ }
+ return dim;
+error:
+ isl_dim_free(dim);
+ return NULL;
+}
+
+__isl_give isl_dim *isl_dim_insert(__isl_take isl_dim *dim,
+ enum isl_dim_type type, unsigned pos, unsigned n)
+{
+ struct isl_name **names = NULL;
+
+ if (!dim)
+ return NULL;
+ if (n == 0)
+ return isl_dim_reset(dim, type);
+
+ isl_assert(dim->ctx, pos <= isl_dim_size(dim, type), goto error);
+
+ dim = isl_dim_cow(dim);
+ if (!dim)
+ return NULL;
+
+ if (dim->names) {
+ enum isl_dim_type t;
+ int off;
+ int s[3];
+ int *size = s - isl_dim_param;
+ names = isl_calloc_array(dim->ctx, struct isl_name *,
+ dim->nparam + dim->n_in + dim->n_out + n);
+ if (!names)
+ goto error;
+ off = 0;
+ size[isl_dim_param] = dim->nparam;
+ size[isl_dim_in] = dim->n_in;
+ size[isl_dim_out] = dim->n_out;
+ for (t = isl_dim_param; t <= isl_dim_out; ++t) {
+ if (t != type) {
+ get_names(dim, t, 0, size[t], names + off);
+ off += size[t];
+ } else {
+ get_names(dim, t, 0, pos, names + off);
+ off += pos + n;
+ get_names(dim, t, pos, size[t]-pos, names+off);
+ off += size[t] - pos;
+ }
+ }
+ free(dim->names);
+ dim->names = names;
+ dim->n_name = dim->nparam + dim->n_in + dim->n_out + n;
+ }
+ switch (type) {
+ case isl_dim_param: dim->nparam += n; break;
+ case isl_dim_in: dim->n_in += n; break;
+ case isl_dim_out: dim->n_out += n; break;
+ }
+ dim = isl_dim_reset(dim, type);
+
+ return dim;
+error:
+ isl_dim_free(dim);
+ return NULL;
+}
+
+__isl_give isl_dim *isl_dim_move(__isl_take isl_dim *dim,
+ enum isl_dim_type dst_type, unsigned dst_pos,
+ enum isl_dim_type src_type, unsigned src_pos, unsigned n)
+{
+ if (!dim)
+ return NULL;
+ if (n == 0)
+ return dim;
+
+ isl_assert(dim->ctx, src_pos + n <= isl_dim_size(dim, src_type),
+ goto error);
+
+ if (dst_type == src_type && dst_pos == src_pos)
+ return dim;
+
+ isl_assert(dim->ctx, dst_type != src_type, goto error);
+
+ dim = isl_dim_reset(dim, src_type);
+ dim = isl_dim_reset(dim, dst_type);
+
+ dim = isl_dim_cow(dim);
+ if (!dim)
+ return NULL;
+
+ if (dim->names) {
+ struct isl_name **names;
+ enum isl_dim_type t;
+ int off;
+ int s[3];
+ int *size = s - isl_dim_param;
+ names = isl_calloc_array(dim->ctx, struct isl_name *,
+ dim->nparam + dim->n_in + dim->n_out);
+ if (!names)
+ goto error;
+ off = 0;
+ size[isl_dim_param] = dim->nparam;
+ size[isl_dim_in] = dim->n_in;
+ size[isl_dim_out] = dim->n_out;
+ for (t = isl_dim_param; t <= isl_dim_out; ++t) {
+ if (t == dst_type) {
+ get_names(dim, t, 0, dst_pos, names + off);
+ off += dst_pos;
+ get_names(dim, src_type, src_pos, n, names+off);
+ off += n;
+ get_names(dim, t, dst_pos, size[t] - dst_pos,
+ names + off);
+ off += size[t] - dst_pos;
+ } else if (t == src_type) {
+ get_names(dim, t, 0, src_pos, names + off);
+ off += src_pos;
+ get_names(dim, t, src_pos + n,
+ size[t] - src_pos - n, names + off);
+ off += size[t] - src_pos - n;
+ } else {
+ get_names(dim, t, 0, size[t], names + off);
+ off += size[t];
+ }
+ }
+ free(dim->names);
+ dim->names = names;
+ dim->n_name = dim->nparam + dim->n_in + dim->n_out;
+ }
+
+ switch (dst_type) {
+ case isl_dim_param: dim->nparam += n; break;
+ case isl_dim_in: dim->n_in += n; break;
+ case isl_dim_out: dim->n_out += n; break;
+ }
+
+ switch (src_type) {
+ case isl_dim_param: dim->nparam -= n; break;
+ case isl_dim_in: dim->n_in -= n; break;
+ case isl_dim_out: dim->n_out -= n; break;
+ }
+
+ return dim;
+error:
+ isl_dim_free(dim);
+ return NULL;
+}
+