#include "isl_sample.h"
#include "isl_vec.h"
+/* Maps dst positions to src positions */
+struct isl_dim_map {
+ unsigned len;
+ int pos[1];
+};
+
+static struct isl_dim_map *isl_dim_map_alloc(struct isl_ctx *ctx, unsigned len)
+{
+ int i;
+ struct isl_dim_map *dim_map;
+ dim_map = isl_alloc(ctx, struct isl_dim_map,
+ sizeof(struct isl_dim_map) + len * sizeof(int));
+ if (!dim_map)
+ return NULL;
+ dim_map->len = 1 + len;
+ dim_map->pos[0] = 0;
+ for (i = 0; i < len; ++i)
+ dim_map->pos[1 + i] = -1;
+ return dim_map;
+}
+
+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 unsigned pos(struct isl_dim *dim, enum isl_dim_type type)
+{
+ switch (type) {
+ case isl_dim_param: return 1;
+ case isl_dim_in: return 1 + dim->nparam;
+ case isl_dim_out: return 1 + dim->nparam + dim->n_in;
+ }
+}
+
+static void isl_dim_map_dim(struct isl_dim_map *dim_map, struct isl_dim *dim,
+ enum isl_dim_type type, unsigned dst_pos)
+{
+ int i;
+ unsigned src_pos;
+
+ if (!dim_map || !dim)
+ return;
+
+ src_pos = pos(dim, type);
+ for (i = 0; i < n(dim, type); ++i)
+ dim_map->pos[1 + dst_pos + i] = src_pos + i;
+}
+
+static void isl_dim_map_div(struct isl_dim_map *dim_map,
+ struct isl_basic_map *bmap, unsigned dst_pos)
+{
+ int i;
+ unsigned src_pos;
+
+ if (!dim_map || !bmap)
+ return;
+
+ src_pos = 1 + isl_dim_total(bmap->dim);
+ for (i = 0; i < bmap->n_div; ++i)
+ dim_map->pos[1 + dst_pos + i] = src_pos + i;
+}
+
+static void isl_dim_map_dump(struct isl_dim_map *dim_map)
+{
+ int i;
+
+ for (i = 0; i < dim_map->len; ++i)
+ fprintf(stderr, "%d -> %d; ", i, dim_map->pos[i]);
+ fprintf(stderr, "\n");
+}
+
unsigned isl_basic_set_n_dim(const struct isl_basic_set *bset)
{
return bset->dim->n_out;
return (struct isl_basic_set *)bmap;
}
-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)
+struct isl_basic_set *isl_basic_set_alloc_dim(struct isl_dim *dim,
+ unsigned extra, unsigned n_eq, unsigned n_ineq)
{
struct isl_basic_map *bmap;
if (!dim)
return NULL;
- isl_assert(ctx, dim->n_in == 0, return NULL);
- bmap = isl_basic_map_alloc_dim(ctx, dim, extra, n_eq, n_ineq);
+ isl_assert(dim->ctx, dim->n_in == 0, return NULL);
+ bmap = isl_basic_map_alloc_dim(dim, extra, n_eq, n_ineq);
return (struct isl_basic_set *)bmap;
}
-struct isl_basic_map *isl_basic_map_alloc_dim(struct isl_ctx *ctx,
- struct isl_dim *dim, unsigned extra,
- unsigned n_eq, unsigned n_ineq)
+struct isl_basic_map *isl_basic_map_alloc_dim(struct isl_dim *dim,
+ unsigned extra, unsigned n_eq, unsigned n_ineq)
{
struct isl_basic_map *bmap;
if (!dim)
return NULL;
- bmap = isl_alloc_type(ctx, struct isl_basic_map);
+ bmap = isl_alloc_type(dim->ctx, struct isl_basic_map);
if (!bmap)
goto error;
bmap->dim = dim;
- return basic_map_init(ctx, bmap, extra, n_eq, n_ineq);
+ return basic_map_init(dim->ctx, bmap, extra, n_eq, n_ineq);
error:
isl_dim_free(dim);
return NULL;
if (!dim)
return NULL;
- bmap = isl_basic_map_alloc_dim(ctx, dim, extra, n_eq, n_ineq);
+ bmap = isl_basic_map_alloc_dim(dim, extra, n_eq, n_ineq);
return bmap;
}
if (!bmap)
return NULL;
- dup = isl_basic_map_alloc_dim(bmap->ctx, isl_dim_copy(bmap->dim),
+ dup = isl_basic_map_alloc_dim(isl_dim_copy(bmap->dim),
bmap->n_div, bmap->n_eq, bmap->n_ineq);
if (!dup)
return NULL;
return NULL;
}
+static void copy_constraint_dim_map(isl_int *dst, isl_int *src,
+ struct isl_dim_map *dim_map)
+{
+ int i;
+
+ for (i = 0; i < dim_map->len; ++i) {
+ if (dim_map->pos[i] < 0)
+ isl_int_set_si(dst[i], 0);
+ else
+ isl_int_set(dst[i], src[dim_map->pos[i]]);
+ }
+}
+
+static void copy_div_dim_map(isl_int *dst, isl_int *src,
+ struct isl_dim_map *dim_map)
+{
+ isl_int_set(dst[0], src[0]);
+ copy_constraint_dim_map(dst+1, src+1, dim_map);
+}
+
+static struct isl_basic_map *add_constraints_dim_map(struct isl_basic_map *dst,
+ struct isl_basic_map *src, struct isl_dim_map *dim_map)
+{
+ int i;
+
+ if (!src || !dst || !dim_map)
+ goto error;
+
+ for (i = 0; i < src->n_eq; ++i) {
+ int i1 = isl_basic_map_alloc_equality(dst);
+ if (i1 < 0)
+ goto error;
+ copy_constraint_dim_map(dst->eq[i1], src->eq[i], dim_map);
+ }
+
+ for (i = 0; i < src->n_ineq; ++i) {
+ int i1 = isl_basic_map_alloc_inequality(dst);
+ if (i1 < 0)
+ goto error;
+ copy_constraint_dim_map(dst->ineq[i1], src->ineq[i], dim_map);
+ }
+
+ for (i = 0; i < src->n_div; ++i) {
+ int i1 = isl_basic_map_alloc_div(dst);
+ if (i1 < 0)
+ goto error;
+ copy_div_dim_map(dst->div[i1], src->div[i], dim_map);
+ }
+
+ free(dim_map);
+ isl_basic_map_free(src);
+
+ return dst;
+error:
+ free(dim_map);
+ isl_basic_map_free(src);
+ isl_basic_map_free(dst);
+ return NULL;
+}
+
static struct isl_basic_set *set_add_constraints(struct isl_basic_set *bset1,
struct isl_basic_set *bset2, unsigned pos)
{
n_eq += base->n_eq;
n_ineq += base->n_ineq;
- ext = isl_basic_map_alloc_dim(base->ctx, dim, extra, n_eq, n_ineq);
+ ext = isl_basic_map_alloc_dim(dim, extra, n_eq, n_ineq);
dim = NULL;
if (!ext)
goto error;
isl_seq_clr(c + rem, n);
}
+/* Drop n dimensions starting at first.
+ *
+ * In principle, this frees up some extra variables as the number
+ * of columns remains constant, but we would have to extend
+ * the div array too as the number of rows in this array is assumed
+ * to be equal to extra.
+ */
struct isl_basic_set *isl_basic_set_drop_dims(
struct isl_basic_set *bset, unsigned first, unsigned n)
{
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,
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->extra += n;
+ bset->dim = isl_dim_drop_outputs(bset->dim, first, n);
+ if (!bset->dim)
+ goto error;
F_CLR(bset, ISL_BASIC_SET_NORMALIZED);
bset = isl_basic_set_simplify(bset);
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;
if (!set->p[i])
goto error;
}
- set->dim->n_out -= n;
F_CLR(set, ISL_SET_NORMALIZED);
return set;
return NULL;
}
+/* Drop n input dimensions starting at first.
+ *
+ * In principle, this frees up some extra variables as the number
+ * of columns remains constant, but we would have to extend
+ * the div array too as the number of rows in this array is assumed
+ * to be equal to extra.
+ */
struct isl_basic_map *isl_basic_map_drop_inputs(
struct isl_basic_map *bmap, unsigned first, unsigned n)
{
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,
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->extra += n;
+ bmap->dim = isl_dim_drop_inputs(bmap->dim, first, n);
+ if (!bmap->dim)
+ goto error;
F_CLR(bmap, ISL_BASIC_MAP_NORMALIZED);
bmap = isl_basic_map_simplify(bmap);
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;
if (!map->p[i])
goto error;
}
- map->dim->n_in -= n;
F_CLR(map, ISL_MAP_NORMALIZED);
return map;
}
+/* Remove any div that is defined in terms of the given variable.
+ */
+static struct isl_basic_map *remove_dependent_vars(struct isl_basic_map *bmap,
+ int pos)
+{
+ int i;
+ unsigned dim = isl_dim_total(bmap->dim);
+
+ for (i = 0; i < bmap->n_div; ++i) {
+ if (isl_int_is_zero(bmap->div[i][0]))
+ continue;
+ if (isl_int_is_zero(bmap->div[i][1+1+pos]))
+ continue;
+ bmap = isl_basic_map_eliminate_vars(bmap, dim + i, 1);
+ if (!bmap)
+ return NULL;
+ }
+ return bmap;
+}
+
+
/* Eliminate the specified variables from the constraints using
* Fourier-Motzkin. The variables themselves are not removed.
*/
struct isl_basic_map *isl_basic_map_eliminate_vars(
- struct isl_basic_map *bmap, int pos, unsigned n)
+ struct isl_basic_map *bmap, unsigned pos, unsigned n)
{
int d;
int i, j, k;
total = isl_basic_map_total_dim(bmap);
bmap = isl_basic_map_cow(bmap);
- for (d = pos + n - 1; d >= pos; --d) {
+ for (d = pos + n - 1; d >= 0 && d >= pos; --d) {
int n_lower, n_upper;
+ bmap = remove_dependent_vars(bmap, d);
if (!bmap)
return NULL;
+ if (d >= total - bmap->n_div)
+ isl_seq_clr(bmap->div[d-(total-bmap->n_div)], 2+total);
for (i = 0; i < bmap->n_eq; ++i) {
if (isl_int_is_zero(bmap->eq[i][1+d]))
continue;
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);
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);
}
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);
}
return 0;
}
-struct isl_set *isl_set_alloc_dim(struct isl_ctx *ctx,
- struct isl_dim *dim, int n, unsigned flags)
+struct isl_set *isl_set_alloc_dim(struct isl_dim *dim, int n, unsigned flags)
{
struct isl_set *set;
if (!dim)
return NULL;
- isl_assert(ctx, dim->n_in == 0, return NULL);
- isl_assert(ctx, n >= 0, return NULL);
- set = isl_alloc(ctx, struct isl_set,
+ isl_assert(dim->ctx, dim->n_in == 0, return NULL);
+ isl_assert(dim->ctx, n >= 0, return NULL);
+ set = isl_alloc(dim->ctx, struct isl_set,
sizeof(struct isl_set) +
n * sizeof(struct isl_basic_set *));
if (!set)
goto error;
- set->ctx = ctx;
- isl_ctx_ref(ctx);
+ set->ctx = dim->ctx;
+ isl_ctx_ref(set->ctx);
set->ref = 1;
set->size = n;
set->n = 0;
if (!dims)
return NULL;
- set = isl_set_alloc_dim(ctx, dims, n, flags);
+ set = isl_set_alloc_dim(dims, n, flags);
return set;
}
if (!set)
return NULL;
- dup = isl_set_alloc_dim(set->ctx, isl_dim_copy(set->dim),
- set->n, set->flags);
+ dup = isl_set_alloc_dim(isl_dim_copy(set->dim), set->n, set->flags);
if (!dup)
return NULL;
for (i = 0; i < set->n; ++i)
if (!bset)
return NULL;
- set = isl_set_alloc_dim(bset->ctx, isl_dim_copy(bset->dim),
- 1, ISL_MAP_DISJOINT);
+ set = isl_set_alloc_dim(isl_dim_copy(bset->dim), 1, ISL_MAP_DISJOINT);
if (!set) {
isl_basic_set_free(bset);
return NULL;
if (!bmap)
return NULL;
- map = isl_map_alloc_dim(bmap->ctx, isl_dim_copy(bmap->dim),
- 1, ISL_MAP_DISJOINT);
+ map = isl_map_alloc_dim(isl_dim_copy(bmap->dim), 1, ISL_MAP_DISJOINT);
if (!map) {
isl_basic_map_free(bmap);
return NULL;
}
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);
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;
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;
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;
F_ISSET(map2, ISL_MAP_DISJOINT))
FL_SET(flags, ISL_MAP_DISJOINT);
- result = isl_map_alloc_dim(map1->ctx, isl_dim_copy(map1->dim),
+ result = isl_map_alloc_dim(isl_dim_copy(map1->dim),
map1->n * map2->n, flags);
if (!result)
goto error;
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:
return NULL;
}
+struct isl_basic_map *add_divs(struct isl_basic_map *bmap, unsigned n)
+{
+ int i, j;
+
+ for (i = 0; i < n; ++i) {
+ j = isl_basic_map_alloc_div(bmap);
+ if (j < 0)
+ goto error;
+ isl_seq_clr(bmap->div[j], 1+1+isl_basic_map_total_dim(bmap));
+ }
+ return bmap;
+error:
+ isl_basic_map_free(bmap);
+ return NULL;
+}
+
struct isl_basic_map *isl_basic_map_apply_range(
struct isl_basic_map *bmap1, struct isl_basic_map *bmap2)
{
struct isl_dim *dim_result = NULL;
- struct isl_basic_set *bset;
- unsigned n_in, n_out, n, nparam;
+ struct isl_basic_map *bmap;
+ unsigned n_in, n_out, n, nparam, total, pos;
+ struct isl_dim_map *dim_map1, *dim_map2;
if (!bmap1 || !bmap2)
goto error;
n = isl_basic_map_n_out(bmap1);
nparam = isl_basic_map_n_param(bmap1);
- isl_assert(bmap->ctx, n == isl_basic_map_n_in(bmap2), goto error);
- isl_assert(bmap->ctx, nparam == isl_basic_map_n_param(bmap2), goto error);
-
- bmap2 = isl_basic_map_reverse(bmap2);
- if (!bmap2)
- goto error;
- bmap1 = isl_basic_map_extend(bmap1, nparam, n_in + n_out, n,
- bmap2->extra, bmap2->n_eq, bmap2->n_ineq);
- if (!bmap1)
- goto error;
- bmap1 = add_constraints(bmap1, bmap2, n_in, 0);
- bmap1 = isl_basic_map_simplify(bmap1);
- bset = isl_basic_set_from_basic_map(bmap1);
- bset = isl_basic_set_project_out(bset, n, 0);
- return isl_basic_map_from_basic_set(bset, dim_result);
+ total = nparam + n_in + n_out + bmap1->n_div + bmap2->n_div + n;
+ dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
+ dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
+ isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
+ isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
+ isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
+ isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += n_in);
+ isl_dim_map_div(dim_map1, bmap1, pos += n_out);
+ isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
+ isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += bmap2->n_div);
+ isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
+
+ bmap = isl_basic_map_alloc_dim(dim_result,
+ bmap1->n_div + bmap2->n_div + n,
+ bmap1->n_eq + bmap2->n_eq,
+ bmap1->n_ineq + bmap2->n_ineq);
+ bmap = add_constraints_dim_map(bmap, bmap1, dim_map1);
+ bmap = add_constraints_dim_map(bmap, bmap2, dim_map2);
+ bmap = add_divs(bmap, n);
+ bmap = isl_basic_map_simplify(bmap);
+ return isl_basic_map_finalize(bmap);
error:
- isl_dim_free(dim_result);
isl_basic_map_free(bmap1);
isl_basic_map_free(bmap2);
return NULL;
struct isl_basic_map *bmap;
struct isl_ctx *ctx;
unsigned total;
- int i, k;
+ int i;
if (!bset || !like)
goto error;
ctx = bset->ctx;
+ isl_assert(ctx, bset->n_div == 0, goto error);
+ isl_assert(ctx, isl_basic_set_n_param(bset) == 0, goto error);
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;
}
bmap->dim = isl_dim_copy(like->dim);
if (!bmap->dim)
goto error;
+ bmap->n_div = like->n_div;
bmap->extra += like->n_div;
if (bmap->extra) {
unsigned ltotal;
bmap->extra);
if (!bmap->div)
goto error;
+ for (i = 0; i < bmap->extra; ++i)
+ bmap->div[i] = bmap->block2.data + i * (1 + 1 + total);
+ for (i = 0; i < like->n_div; ++i) {
+ isl_seq_cpy(bmap->div[i], like->div[i], 1 + 1 + ltotal);
+ isl_seq_clr(bmap->div[i]+1+1+ltotal, total - ltotal);
+ }
bmap = isl_basic_map_extend_constraints(bmap,
0, 2 * like->n_div);
- for (i = 0; i < like->n_div; ++i) {
- k = isl_basic_map_alloc_div(bmap);
- if (k < 0)
- goto error;
- isl_seq_cpy(bmap->div[k], like->div[i], 1 + 1 + ltotal);
- isl_seq_clr(bmap->div[k]+1+1+ltotal, total - ltotal);
- if (add_div_constraints(bmap, k) < 0)
+ for (i = 0; i < like->n_div; ++i)
+ if (add_div_constraints(bmap, i) < 0)
goto error;
- }
}
isl_basic_map_free(like);
bmap = isl_basic_map_finalize(bmap);
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;
}
{
int i;
- map = isl_map_align_divs(map);
map = isl_map_cow(map);
if (!map)
return NULL;
if (!map->dim)
goto error;
+ for (i = 1; i < map->n; ++i)
+ isl_assert(map->ctx, map->p[0]->n_div == map->p[i]->n_div,
+ goto error);
for (i = 0; i < map->n; ++i) {
map->p[i] = (struct isl_basic_map *)
isl_basic_map_underlying_set(map->p[i]);
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]);
return NULL;
}
-struct isl_map *isl_map_alloc_dim(struct isl_ctx *ctx,
- struct isl_dim *dim, int n, unsigned flags)
+struct isl_map *isl_map_alloc_dim(struct isl_dim *dim, int n, unsigned flags)
{
struct isl_map *map;
if (!dim)
return NULL;
- isl_assert(ctx, n >= 0, return NULL);
- map = isl_alloc(ctx, struct isl_map,
+ isl_assert(dim->ctx, n >= 0, return NULL);
+ map = isl_alloc(dim->ctx, struct isl_map,
sizeof(struct isl_map) +
n * sizeof(struct isl_basic_map *));
if (!map)
goto error;
- map->ctx = ctx;
- isl_ctx_ref(ctx);
+ map->ctx = dim->ctx;
+ isl_ctx_ref(map->ctx);
map->ref = 1;
map->size = n;
map->n = 0;
if (!dims)
return NULL;
- map = isl_map_alloc_dim(ctx, dims, n, flags);
+ map = isl_map_alloc_dim(dims, n, flags);
return map;
}
return bmap;
}
-struct isl_basic_set *isl_basic_set_empty(struct isl_ctx *ctx,
- unsigned nparam, unsigned dim)
+struct isl_basic_set *isl_basic_set_empty(struct isl_dim *dim)
{
struct isl_basic_set *bset;
- bset = isl_basic_set_alloc(ctx, nparam, dim, 0, 1, 0);
+ bset = isl_basic_set_alloc_dim(dim, 0, 1, 0);
bset = isl_basic_set_set_to_empty(bset);
return bset;
}
struct isl_basic_map *bmap;
if (!model)
return NULL;
- bmap = isl_basic_map_alloc_dim(model->ctx, isl_dim_copy(model->dim),
- 0, 1, 0);
+ bmap = isl_basic_map_alloc_dim(isl_dim_copy(model->dim), 0, 1, 0);
bmap = isl_basic_map_set_to_empty(bmap);
return bmap;
}
struct isl_basic_map *bmap;
if (!model)
return NULL;
- bmap = isl_basic_map_alloc_dim(model->ctx, isl_dim_copy(model->dim),
- 0, 1, 0);
+ bmap = isl_basic_map_alloc_dim(isl_dim_copy(model->dim), 0, 1, 0);
bmap = isl_basic_map_set_to_empty(bmap);
return bmap;
}
struct isl_basic_set *bset;
if (!model)
return NULL;
- bset = isl_basic_set_alloc_dim(model->ctx, isl_dim_copy(model->dim),
- 0, 1, 0);
+ bset = isl_basic_set_alloc_dim(isl_dim_copy(model->dim), 0, 1, 0);
bset = isl_basic_set_set_to_empty(bset);
return bset;
}
-struct isl_basic_map *isl_basic_map_universe(struct isl_ctx *ctx,
- unsigned nparam, unsigned in, unsigned out)
+struct isl_basic_map *isl_basic_map_universe(struct isl_dim *dim)
{
struct isl_basic_map *bmap;
- bmap = isl_basic_map_alloc(ctx, nparam, in, out, 0, 0, 0);
+ bmap = isl_basic_map_alloc_dim(dim, 0, 0, 0);
return bmap;
}
-struct isl_basic_set *isl_basic_set_universe(struct isl_ctx *ctx,
- unsigned nparam, unsigned dim)
+struct isl_basic_set *isl_basic_set_universe(struct isl_dim *dim)
{
struct isl_basic_set *bset;
- bset = isl_basic_set_alloc(ctx, nparam, dim, 0, 0, 0);
+ bset = isl_basic_set_alloc_dim(dim, 0, 0, 0);
return bset;
}
{
if (!model)
return NULL;
- return isl_basic_set_alloc_dim(model->ctx, isl_dim_copy(model->dim),
- 0, 0, 0);
+ return isl_basic_set_alloc_dim(isl_dim_copy(model->dim), 0, 0, 0);
}
struct isl_map *isl_map_empty(struct isl_ctx *ctx,
{
if (!model)
return NULL;
- return isl_map_alloc_dim(model->ctx, isl_dim_copy(model->dim),
- 0, ISL_MAP_DISJOINT);
+ return isl_map_alloc_dim(isl_dim_copy(model->dim), 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_dim *dim)
{
- return isl_set_alloc(ctx, nparam, dim, 0, ISL_MAP_DISJOINT);
+ return isl_set_alloc_dim(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(isl_dim_copy(model->dim));
+}
+
+struct isl_set *isl_set_universe(struct isl_dim *dim)
+{
+ struct isl_set *set;
+ if (!dim)
+ return NULL;
+ set = isl_set_alloc_dim(isl_dim_copy(dim), 1, ISL_MAP_DISJOINT);
+ set = isl_set_add(set, isl_basic_set_universe(dim));
+ return set;
}
struct isl_map *isl_map_dup(struct isl_map *map)
if (!map)
return NULL;
- dup = isl_map_alloc_dim(map->ctx, isl_dim_copy(map->dim),
- map->n, map->flags);
+ dup = isl_map_alloc_dim(isl_dim_copy(map->dim), map->n, map->flags);
for (i = 0; i < map->n; ++i)
dup = isl_map_add(dup, isl_basic_map_copy(map->p[i]));
return dup;
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;
}
struct isl_basic_map *bmap = NULL;
struct isl_basic_set *dom = NULL;
struct isl_map *min;
+ struct isl_dim *param_dim;
if (!bset)
goto error;
bmap = isl_basic_map_from_basic_set(bset, isl_dim_copy(bset->dim));
if (!bmap)
goto error;
- dom = isl_basic_set_universe(bmap->ctx, isl_basic_map_n_param(bmap), 0);
+ param_dim = isl_dim_domain(isl_dim_copy(bmap->dim));
+ dom = isl_basic_set_universe(param_dim);
if (!dom)
goto error;
min = isl_basic_map_lexmin(bmap, dom, NULL);
struct isl_map *isl_basic_map_compute_divs(struct isl_basic_map *bmap)
{
+ int i;
+ unsigned off;
+
if (!bmap)
return NULL;
- if (bmap->n_div == 0)
- return isl_map_from_basic_map(bmap);
- return isl_pip_basic_map_compute_divs(bmap);
+ off = isl_dim_total(bmap->dim);
+ for (i = 0; i < bmap->n_div; ++i) {
+ if (isl_int_is_zero(bmap->div[i][0]))
+ return isl_pip_basic_map_compute_divs(bmap);
+ isl_assert(bmap->ctx, isl_int_is_zero(bmap->div[i][1+1+off+i]),
+ goto error);
+ }
+ return isl_map_from_basic_map(bmap);
+error:
+ isl_basic_map_free(bmap);
+ return NULL;
}
struct isl_map *isl_map_compute_divs(struct isl_map *map)
return NULL;
set = (struct isl_set *)map;
- set->dim = isl_dim_cow(set->dim);
+ set->dim = isl_dim_domain(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])
F_ISSET(map2, ISL_MAP_DISJOINT))
FL_SET(flags, ISL_MAP_DISJOINT);
- map = isl_map_alloc_dim(map1->ctx, isl_dim_copy(map1->dim),
+ map = isl_map_alloc_dim(isl_dim_copy(map1->dim),
map1->n + map2->n, flags);
if (!map)
goto error;
F_ISSET(set, ISL_MAP_DISJOINT))
FL_SET(flags, ISL_MAP_DISJOINT);
- result = isl_map_alloc_dim(map->ctx, isl_dim_copy(map->dim),
+ result = isl_map_alloc_dim(isl_dim_copy(map->dim),
map->n * set->n, flags);
if (!result)
goto error;
dim_result = isl_dim_join(isl_dim_copy(map1->dim),
isl_dim_copy(map2->dim));
- result = isl_map_alloc_dim(map1->ctx, dim_result, map1->n * map2->n, 0);
+ result = isl_map_alloc_dim(dim_result, map1->n * map2->n, 0);
if (!result)
goto error;
for (i = 0; i < map1->n; ++i)
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, 0, dim, 0);
if (!bmap)
goto 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, 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)
isl_assert(map1->ctx, isl_dim_equal(bmap1->dim, bmap2->dim), goto error);
- map = isl_map_alloc_dim(bmap1->ctx, isl_dim_copy(bmap1->dim), 2, 0);
+ map = isl_map_alloc_dim(isl_dim_copy(bmap1->dim), 2, 0);
if (!map)
goto error;
map = isl_map_add(map, bmap1);
return bmap;
}
+/* Look for a div in dst that corresponds to the div "div" in src.
+ * The divs before "div" in src and dst are assumed to be the same.
+ *
+ * Returns -1 if no corresponding div was found and the position
+ * of the corresponding div in dst otherwise.
+ */
static int find_div(struct isl_basic_map *dst,
struct isl_basic_map *src, unsigned div)
{
int i;
- unsigned total = isl_basic_map_total_dim(src);
+ unsigned total = isl_dim_total(src->dim);
- for (i = 0; i < dst->n_div; ++i)
- if (isl_seq_eq(dst->div[i], src->div[div], 1+1+total) &&
- isl_seq_first_non_zero(dst->div[i]+1+1+total,
- dst->n_div - src->n_div) == -1)
+ isl_assert(dst->ctx, div <= dst->n_div, return -1);
+ for (i = div; i < dst->n_div; ++i)
+ if (isl_seq_eq(dst->div[i], src->div[div], 1+1+total+div) &&
+ isl_seq_first_non_zero(dst->div[i]+1+1+total+div,
+ dst->n_div - div) == -1)
return i;
return -1;
}
struct isl_basic_map *dst, struct isl_basic_map *src)
{
int i;
- unsigned total = isl_basic_map_total_dim(src);
+ unsigned total = isl_dim_total(src->dim);
if (!dst || !src)
goto error;
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;
j = isl_basic_map_alloc_div(dst);
if (j < 0)
goto error;
- isl_seq_cpy(dst->div[j], src->div[i], 1+1+total);
- isl_seq_clr(dst->div[j]+1+1+total,
- dst->n_div - src->n_div);
+ isl_seq_cpy(dst->div[j], src->div[i], 1+1+total+i);
+ isl_seq_clr(dst->div[j]+1+1+total+i, dst->n_div - i);
if (add_div_constraints(dst, j) < 0)
goto error;
}
FL_SET(flags, ISL_MAP_DISJOINT);
max = map->n * (2 * bmap->n_eq + bmap->n_ineq);
- rest = isl_map_alloc_dim(map->ctx, isl_dim_copy(map->dim), max, flags);
+ rest = isl_map_alloc_dim(isl_dim_copy(map->dim), max, flags);
if (!rest)
goto error;
bmap1 = isl_basic_map_extend(bmap1, nparam,
pos, (dim1 - pos) + (dim2 - pos),
bmap2->n_div, bmap2->n_eq, bmap2->n_ineq);
+ bmap1 = add_constraints(bmap1, bmap2, 0, dim1 - pos);
if (!bmap1)
goto error;
total = isl_basic_map_total_dim(bmap1);
isl_int_set_si(obj->block.data[nparam+pos+(dim1-pos)], -1);
if (!obj)
goto error;
- bmap1 = add_constraints(bmap1, bmap2, 0, dim1 - pos);
isl_int_init(num);
isl_int_init(den);
res = isl_solve_lp(bmap1, 0, obj->block.data, ctx->one, &num, &den);
return NULL;
}
+/*
+ * Assumes context has no implicit divs.
+ */
struct isl_map *isl_map_gist(struct isl_map *map, struct isl_basic_map *context)
{
int i;
if (!map || !context)
return NULL;
isl_assert(map->ctx, isl_dim_equal(map->dim, context->dim), goto error);
+ map = isl_map_compute_divs(map);
for (i = 0; i < map->n; ++i)
context = isl_basic_map_align_divs(context, map->p[i]);
for (i = 0; i < map->n; ++i) {
if (!set)
return 0;
- isl_hash_init(hash);
+ hash = isl_hash_init();
for (i = 0; i < set->n; ++i) {
uint32_t bset_hash;
bset_hash = isl_basic_set_get_hash(set->p[i]);