isl_map_gist: ensure divs of map are known
[platform/upstream/isl.git] / isl_map.c
index e3d6fb7..281a92b 100644 (file)
--- a/isl_map.c
+++ b/isl_map.c
@@ -1746,11 +1746,32 @@ static struct isl_basic_map *normalize_constraints(struct isl_basic_map *bmap)
 }
 
 
+/* 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;
@@ -1763,10 +1784,13 @@ struct isl_basic_map *isl_basic_map_eliminate_vars(
        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;
@@ -3491,11 +3515,22 @@ error:
 
 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)
@@ -4610,6 +4645,7 @@ int isl_basic_set_compare_at(struct isl_basic_set *bset1,
        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);
@@ -4620,7 +4656,6 @@ int isl_basic_set_compare_at(struct isl_basic_set *bset1,
        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);
@@ -4970,6 +5005,9 @@ error:
        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;
@@ -4978,6 +5016,7 @@ struct isl_map *isl_map_gist(struct isl_map *map, struct isl_basic_map *context)
        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) {