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;
isl_assert(dim->ctx, src_pos + n <= isl_dim_size(dim, src_type),
goto error);
- /* just the simple case for now */
- isl_assert(dim->ctx,
- offset(dim, dst_type) + dst_pos ==
- offset(dim, src_type) + src_pos + ((src_type < dst_type) ? n : 0),
- goto error);
-
- if (dst_type == src_type)
+ if (dst_type == src_type && dst_pos == src_pos)
return dim;
+ isl_assert(dim->ctx, dst_type != src_type, goto error);
+
dim = isl_dim_cow(dim);
if (!dim)
return NULL;
+ if (dim->names) {
+ struct isl_name **names;
+ enum isl_dim_type t;
+ int off;
+ int size[3];
+ 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;
enum isl_dim_type src_type, unsigned src_pos, unsigned n)
{
int i;
+ struct isl_dim_map *dim_map;
+ struct isl_basic_map *res;
+ enum isl_dim_type t;
+ unsigned total, off;
if (!bmap)
return NULL;
isl_assert(bmap->ctx, src_pos + n <= isl_basic_map_dim(bmap, src_type),
goto error);
- /* just the simple case for now */
- isl_assert(bmap->ctx,
- pos(bmap->dim, dst_type) + dst_pos ==
- pos(bmap->dim, src_type) + src_pos + ((src_type < dst_type) ? n : 0),
- goto error);
+ if (dst_type == src_type && dst_pos == src_pos)
+ return bmap;
+
+ isl_assert(bmap->ctx, dst_type != src_type, goto error);
+
+ if (pos(bmap->dim, dst_type) + dst_pos ==
+ pos(bmap->dim, src_type) + src_pos +
+ ((src_type < dst_type) ? n : 0)) {
+ bmap = isl_basic_map_cow(bmap);
+ if (!bmap)
+ return NULL;
+
+ bmap->dim = isl_dim_move(bmap->dim, dst_type, dst_pos,
+ src_type, src_pos, n);
+ if (!bmap->dim)
+ goto error;
- if (dst_type == src_type)
return bmap;
+ }
- bmap = isl_basic_map_cow(bmap);
- if (!bmap)
- return NULL;
+ total = isl_basic_map_total_dim(bmap);
+ dim_map = isl_dim_map_alloc(bmap->ctx, total);
+
+ off = 0;
+ for (t = isl_dim_param; t <= isl_dim_out; ++t) {
+ unsigned size = isl_dim_size(bmap->dim, t);
+ if (t == dst_type) {
+ isl_dim_map_dim_range(dim_map, bmap->dim, t,
+ 0, dst_pos, off);
+ off += dst_pos;
+ isl_dim_map_dim_range(dim_map, bmap->dim, src_type,
+ src_pos, n, off);
+ off += n;
+ isl_dim_map_dim_range(dim_map, bmap->dim, t,
+ dst_pos, size - dst_pos, off);
+ off += size - dst_pos;
+ } else if (t == src_type) {
+ isl_dim_map_dim_range(dim_map, bmap->dim, t,
+ 0, src_pos, off);
+ off += src_pos;
+ isl_dim_map_dim_range(dim_map, bmap->dim, t,
+ src_pos + n, size - src_pos - n, off);
+ off += size - src_pos - n;
+ } else {
+ isl_dim_map_dim(dim_map, bmap->dim, t, off);
+ off += size;
+ }
+ }
+ isl_dim_map_div(dim_map, bmap, off + n);
+
+ res = isl_basic_map_alloc_dim(isl_basic_map_get_dim(bmap),
+ bmap->n_div, bmap->n_eq, bmap->n_ineq);
+ bmap = add_constraints_dim_map(res, bmap, dim_map);
- bmap->dim = isl_dim_move(bmap->dim, dst_type, dst_pos, src_type, src_pos, n);
+ bmap->dim = isl_dim_move(bmap->dim, dst_type, dst_pos,
+ src_type, src_pos, n);
if (!bmap->dim)
goto error;
isl_assert(map->ctx, src_pos + n <= isl_map_dim(map, src_type),
goto error);
- /* just the simple case for now */
- isl_assert(map->ctx,
- map_offset(map, dst_type) + dst_pos ==
- map_offset(map, src_type) + src_pos + ((src_type < dst_type) ? n : 0),
- goto error);
-
- if (dst_type == src_type)
+ if (dst_type == src_type && dst_pos == src_pos)
return map;
+ isl_assert(map->ctx, dst_type != src_type, goto error);
+
map = isl_map_cow(map);
if (!map)
return NULL;
+#include <stdlib.h>
#include <isl_seq.h>
#include <isl_polynomial_private.h>
#include <isl_point_private.h>
#include <isl_dim_private.h>
#include <isl_map_private.h>
+#include <isl_map_private.h>
+
+static unsigned pos(__isl_keep isl_dim *dim, enum isl_dim_type type)
+{
+ switch (type) {
+ case isl_dim_param: return 0;
+ case isl_dim_in: return dim->nparam;
+ case isl_dim_out: return dim->nparam + dim->n_in;
+ }
+}
int isl_upoly_is_cst(__isl_keep struct isl_upoly *up)
{
return isl_seq_cmp(div->row[i], div->row[j], div->n_col);
}
+struct isl_div_sort_info {
+ isl_mat *div;
+ int row;
+};
+
+static int div_sort_cmp(const void *p1, const void *p2)
+{
+ const struct isl_div_sort_info *i1, *i2;
+ i1 = (const struct isl_div_sort_info *) p1;
+ i2 = (const struct isl_div_sort_info *) p2;
+
+ return cmp_row(i1->div, i1->row, i2->row);
+}
+
+static __isl_give isl_mat *sort_divs(__isl_take isl_mat *div)
+{
+ int i;
+ struct isl_div_sort_info *array = NULL;
+ int *pos = NULL;
+
+ if (!div)
+ return NULL;
+ if (div->n_row <= 1)
+ return div;
+
+ array = isl_alloc_array(div->ctx, struct isl_div_sort_info, div->n_row);
+ pos = isl_alloc_array(div->ctx, int, div->n_row);
+ if (!array || !pos)
+ goto error;
+
+ for (i = 0; i < div->n_row; ++i) {
+ array[i].div = div;
+ array[i].row = i;
+ pos[i] = i;
+ }
+
+ qsort(array, div->n_row, sizeof(struct isl_div_sort_info),
+ div_sort_cmp);
+
+ for (i = 0; i < div->n_row; ++i) {
+ int t;
+ if (pos[array[i].row] == i)
+ continue;
+ div = isl_mat_cow(div);
+ div = isl_mat_swap_rows(div, i, pos[array[i].row]);
+ t = pos[array[i].row];
+ pos[array[i].row] = pos[i];
+ pos[i] = t;
+ }
+
+ free(array);
+
+ return div;
+error:
+ free(pos);
+ free(array);
+ isl_mat_free(div);
+ return NULL;
+}
+
static __isl_give isl_mat *merge_divs(__isl_keep isl_mat *div1,
__isl_keep isl_mat *div2, int *exp1, int *exp2)
{
upoly_update_den(qp->upoly, d);
}
-__isl_give isl_qpolynomial *isl_qpolynomial_pow(__isl_take isl_dim *dim,
- int pos, int power)
+__isl_give struct isl_upoly *isl_upoly_pow(isl_ctx *ctx, int pos, int power)
{
int i;
- struct isl_qpolynomial *qp;
+ struct isl_upoly *up;
struct isl_upoly_rec *rec;
struct isl_upoly_cst *cst;
+
+ rec = isl_upoly_alloc_rec(ctx, pos, 1 + power);
+ if (!rec)
+ return NULL;
+ for (i = 0; i < 1 + power; ++i) {
+ rec->p[i] = isl_upoly_zero(ctx);
+ if (!rec->p[i])
+ goto error;
+ rec->n++;
+ }
+ cst = isl_upoly_as_cst(rec->p[power]);
+ isl_int_set_si(cst->n, 1);
+
+ return &rec->up;
+error:
+ isl_upoly_free(&rec->up);
+ return NULL;
+}
+
+__isl_give isl_qpolynomial *isl_qpolynomial_pow(__isl_take isl_dim *dim,
+ int pos, int power)
+{
+ struct isl_qpolynomial *qp;
struct isl_ctx *ctx;
if (!dim)
if (!qp)
return NULL;
- qp->upoly = &isl_upoly_alloc_rec(ctx, pos, 1 + power)->up;
+ qp->upoly = isl_upoly_pow(ctx, pos, power);
if (!qp->upoly)
goto error;
- rec = isl_upoly_as_rec(qp->upoly);
- for (i = 0; i < 1 + power; ++i) {
- rec->p[i] = isl_upoly_zero(ctx);
- if (!rec->p[i])
- goto error;
- rec->n++;
- }
- cst = isl_upoly_as_cst(rec->p[power]);
- isl_int_set_si(cst->n, 1);
return qp;
error:
return NULL;
}
+static int *reordering_move(isl_ctx *ctx,
+ unsigned len, unsigned dst, unsigned src, unsigned n)
+{
+ int i;
+ int *reordering;
+
+ reordering = isl_alloc_array(ctx, int, len);
+ if (!reordering)
+ return NULL;
+
+ if (dst <= src) {
+ for (i = 0; i < dst; ++i)
+ reordering[i] = i;
+ for (i = 0; i < n; ++i)
+ reordering[src + i] = dst + i;
+ for (i = 0; i < src - dst; ++i)
+ reordering[dst + i] = dst + n + i;
+ for (i = 0; i < len - src - n; ++i)
+ reordering[src + n + i] = src + n + i;
+ } else {
+ for (i = 0; i < src; ++i)
+ reordering[i] = i;
+ for (i = 0; i < n; ++i)
+ reordering[src + i] = dst + i;
+ for (i = 0; i < dst - src; ++i)
+ reordering[src + n + i] = src + i;
+ for (i = 0; i < len - dst - n; ++i)
+ reordering[dst + n + i] = dst + n + i;
+ }
+
+ return reordering;
+}
+
+static __isl_give struct isl_upoly *reorder(__isl_take struct isl_upoly *up,
+ int *r)
+{
+ int i;
+ struct isl_upoly_rec *rec;
+ struct isl_upoly *base;
+ struct isl_upoly *res;
+
+ if (isl_upoly_is_cst(up))
+ return up;
+
+ rec = isl_upoly_as_rec(up);
+ if (!rec)
+ goto error;
+
+ isl_assert(up->ctx, rec->n >= 1, goto error);
+
+ base = isl_upoly_pow(up->ctx, r[up->var], 1);
+ res = reorder(isl_upoly_copy(rec->p[rec->n - 1]), r);
+
+ for (i = rec->n - 2; i >= 0; --i) {
+ res = isl_upoly_mul(res, isl_upoly_copy(base));
+ res = isl_upoly_sum(res, reorder(isl_upoly_copy(rec->p[i]), r));
+ }
+
+ isl_upoly_free(base);
+ isl_upoly_free(up);
+
+ return res;
+error:
+ isl_upoly_free(up);
+ return NULL;
+}
+
__isl_give isl_qpolynomial *isl_qpolynomial_move(__isl_take isl_qpolynomial *qp,
enum isl_dim_type dst_type, unsigned dst_pos,
enum isl_dim_type src_type, unsigned src_pos, unsigned n)
{
+ unsigned g_dst_pos;
+ unsigned g_src_pos;
+ int *reordering;
+
+ qp = isl_qpolynomial_cow(qp);
if (!qp)
return NULL;
+ isl_assert(qp->dim->ctx, src_pos + n <= isl_dim_size(qp->dim, src_type),
+ goto error);
+
+ g_dst_pos = pos(qp->dim, dst_type) + dst_pos;
+ g_src_pos = pos(qp->dim, src_type) + src_pos;
+ if (dst_type > src_type)
+ g_dst_pos -= n;
+
+ qp->div = isl_mat_move_cols(qp->div, 2 + g_dst_pos, 2 + g_src_pos, n);
+ qp->div = sort_divs(qp->div);
+ if (!qp->div)
+ goto error;
+
+ reordering = reordering_move(qp->dim->ctx,
+ qp->div->n_col - 2, g_dst_pos, g_src_pos, n);
+ if (!reordering)
+ goto error;
+
+ qp->upoly = reorder(qp->upoly, reordering);
+ free(reordering);
+ if (!qp->upoly)
+ goto error;
+
qp->dim = isl_dim_move(qp->dim, dst_type, dst_pos, src_type, src_pos, n);
if (!qp->dim)
goto error;
-
- /* Do something to polynomials when needed; later */
return qp;
error:
{
int i;
+ pwqp = isl_pw_qpolynomial_cow(pwqp);
if (!pwqp)
return NULL;