fprintf(stderr, "\n");
}
+unsigned isl_basic_map_dim(const struct isl_basic_map *bmap,
+ enum isl_dim_type type)
+{
+ struct isl_dim *dim = bmap->dim;
+ 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;
+ case isl_dim_div: return bmap->n_div;
+ case isl_dim_all: return isl_basic_map_total_dim(bmap);
+ }
+}
+
+unsigned isl_basic_set_dim(const struct isl_basic_set *bset,
+ enum isl_dim_type type)
+{
+ return isl_basic_map_dim((const struct isl_basic_map*)bset, type);
+}
+
unsigned isl_basic_set_n_dim(const struct isl_basic_set *bset)
{
return bset->dim->n_out;
}
+/* 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;
goto error;
}
isl_basic_map_free(like);
+ bmap = isl_basic_map_simplify(bmap);
bmap = isl_basic_map_finalize(bmap);
return bmap;
error:
{
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]);
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)
if (src->n_div == 0)
return dst;
+ for (i = 0; i < src->n_div; ++i)
+ isl_assert(src->ctx, !isl_int_is_zero(src->div[i][0]), goto error);
+
src = order_divs(src);
dst = isl_basic_map_extend_dim(dst, isl_dim_copy(dst->dim),
src->n_div, 0, 2 * src->n_div);
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 bset;
}
+static struct isl_basic_set *uset_gist(struct isl_basic_set *bset,
+ struct isl_basic_set *context);
+
+static struct isl_basic_set *uset_gist_context_eq(struct isl_basic_set *bset,
+ struct isl_basic_set *context)
+{
+ struct isl_mat *T;
+ struct isl_mat *T2;
+ struct isl_ctx *ctx = context->ctx;
+ struct isl_basic_set *reduced_context;
+ reduced_context = isl_basic_set_remove_equalities(
+ isl_basic_set_copy(context), &T, &T2);
+ if (!reduced_context)
+ goto error;
+ bset = isl_basic_set_preimage(ctx, bset, T);
+ bset = uset_gist(bset, reduced_context);
+ bset = isl_basic_set_preimage(ctx, bset, T2);
+ bset = isl_basic_set_reduce_using_equalities(bset, context);
+ return bset;
+error:
+ isl_basic_set_free(context);
+ isl_basic_set_free(bset);
+ return NULL;
+}
+
+static struct isl_basic_set *uset_gist_set_eq(struct isl_basic_set *bset,
+ struct isl_basic_set *context)
+{
+ struct isl_mat *T;
+ struct isl_mat *T2;
+ struct isl_ctx *ctx = context->ctx;
+ struct isl_basic_set *affine_hull = NULL;
+
+ affine_hull = isl_basic_set_copy(bset);
+ affine_hull = isl_basic_set_cow(affine_hull);
+ if (!affine_hull)
+ goto error;
+ isl_basic_set_free_inequality(affine_hull, affine_hull->n_ineq);
+
+ bset = isl_basic_set_remove_equalities(bset, &T, &T2);
+ if (!bset)
+ goto error;
+ context = isl_basic_set_preimage(ctx, context, T);
+ bset = uset_gist(bset, context);
+ bset = isl_basic_set_preimage(ctx, bset, T2);
+ bset = isl_basic_set_intersect(bset, affine_hull);
+ return bset;
+error:
+ isl_basic_set_free(affine_hull);
+ isl_basic_set_free(context);
+ isl_basic_set_free(bset);
+ return NULL;
+}
+
/* Remove all information from bset that is redundant in the context
* of context. In particular, equalities that are linear combinations
* of those in context are removed. Then the inequalities that are
if (!bset || !context)
goto error;
- if (context->n_eq > 0) {
- struct isl_mat *T;
- struct isl_mat *T2;
- struct isl_ctx *ctx = context->ctx;
- struct isl_basic_set *reduced_context;
- reduced_context = isl_basic_set_remove_equalities(
- isl_basic_set_copy(context), &T, &T2);
- if (!reduced_context)
- goto error;
- bset = isl_basic_set_preimage(ctx, bset, T);
- bset = uset_gist(bset, reduced_context);
- bset = isl_basic_set_preimage(ctx, bset, T2);
- bset = isl_basic_set_reduce_using_equalities(bset, context);
- return bset;
- }
+ if (context->n_eq > 0)
+ return uset_gist_context_eq(bset, context);
if (!context->n_ineq)
goto done;
+ if (bset->n_eq > 0)
+ return uset_gist_set_eq(bset, context);
bset = remove_shifted_constraints(bset, context);
combined = isl_basic_set_extend_constraints(isl_basic_set_copy(bset),
context->n_eq, context->n_ineq);
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) {