isl_basic_map_simplify: detect div constraints while looking for duplicates
[platform/upstream/isl.git] / isl_constraint.c
index b16a7fb..7383988 100644 (file)
@@ -17,6 +17,18 @@ static unsigned offset(struct isl_constraint *c, enum isl_dim_type type)
        }
 }
 
+static unsigned basic_set_offset(struct isl_basic_set *bset,
+                                                       enum isl_dim_type type)
+{
+       struct isl_dim *dim = bset->dim;
+       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;
+       case isl_dim_div:       return 1 + dim->nparam + dim->n_in + dim->n_out;
+       }
+}
+
 struct isl_constraint *isl_basic_map_constraint(struct isl_basic_map *bmap,
        isl_int **line)
 {
@@ -141,9 +153,13 @@ struct isl_constraint *isl_basic_set_first_constraint(
 struct isl_constraint *isl_constraint_next(struct isl_constraint *c)
 {
        c = isl_constraint_cow(c);
-       c->line++;
-       if (c->line >= c->bmap->eq + c->bmap->n_eq && c->line < c->bmap->ineq)
+       if (c->line >= c->bmap->eq) {
+               c->line++;
+               if (c->line < c->bmap->eq + c->bmap->n_eq)
+                       return c;
                c->line = c->bmap->ineq;
+       } else
+               c->line++;
        if (c->line < c->bmap->ineq + c->bmap->n_ineq)
                return c;
        isl_constraint_free(c);
@@ -159,22 +175,60 @@ int isl_constraint_is_equal(struct isl_constraint *constraint1,
               constraint1->line == constraint2->line;
 }
 
+struct isl_basic_map *isl_basic_map_add_constraint(
+       struct isl_basic_map *bmap, struct isl_constraint *constraint)
+{
+       if (!bmap || !constraint)
+               goto error;
+
+       isl_assert(constraint->ctx,
+               isl_dim_equal(bmap->dim, constraint->bmap->dim), goto error);
+
+       bmap = isl_basic_map_intersect(bmap,
+                                   isl_basic_map_copy(constraint->bmap));
+       isl_constraint_free(constraint);
+       return bmap;
+error:
+       isl_basic_map_free(bmap);
+       isl_constraint_free(constraint);
+       return NULL;
+}
+
 struct isl_basic_set *isl_basic_set_add_constraint(
        struct isl_basic_set *bset, struct isl_constraint *constraint)
 {
-       if (!bset || !constraint)
+       return (struct isl_basic_set *)
+               isl_basic_map_add_constraint((struct isl_basic_map *)bset,
+                                               constraint);
+}
+
+struct isl_constraint *isl_constraint_add_div(struct isl_constraint *constraint,
+       struct isl_div *div, int *pos)
+{
+       if (!constraint || !div)
                goto error;
 
        isl_assert(constraint->ctx,
-               isl_dim_equal(bset->dim, constraint->bmap->dim), goto error);
+           isl_dim_equal(div->bmap->dim, constraint->bmap->dim), goto error);
+       isl_assert(constraint->ctx,
+           constraint->bmap->n_eq + constraint->bmap->n_ineq == 1, goto error);
 
-       bset = isl_basic_set_intersect(bset,
-               isl_basic_set_copy((struct isl_basic_set *)constraint->bmap));
-       isl_constraint_free(constraint);
-       return bset;
+       constraint->bmap = isl_basic_map_cow(constraint->bmap);
+       constraint->bmap = isl_basic_map_extend_dim(constraint->bmap,
+                               isl_dim_copy(constraint->bmap->dim), 1, 0, 0);
+       if (!constraint->bmap)
+               goto error;
+       constraint->line = &constraint->bmap->eq[0];
+       *pos = isl_basic_map_alloc_div(constraint->bmap);
+       if (*pos < 0)
+               goto error;
+       isl_seq_cpy(constraint->bmap->div[*pos], div->line[0],
+                       1 + 1 + isl_basic_map_total_dim(constraint->bmap));
+       isl_div_free(div);
+       return constraint;
 error:
-       isl_basic_set_free(bset);
        isl_constraint_free(constraint);
+       isl_div_free(div);
        return NULL;
 }
 
@@ -210,7 +264,7 @@ struct isl_div *isl_constraint_div(struct isl_constraint *constraint, int pos)
 
        isl_assert(constraint->ctx, pos < n(constraint, isl_dim_div),
                        return NULL);
-       return isl_basic_map_div(constraint->bmap, constraint->bmap->div+pos);
+       return isl_basic_map_div(isl_basic_map_copy(constraint->bmap), pos);
 }
 
 void isl_constraint_set_constant(struct isl_constraint *constraint, isl_int v)
@@ -254,7 +308,7 @@ struct isl_constraint *isl_constraint_negate(struct isl_constraint *constraint)
        total = isl_basic_map_total_dim(constraint->bmap);
        isl_seq_neg(constraint->line[0], constraint->line[0], 1 + total);
        isl_int_sub_ui(constraint->line[0][0], constraint->line[0][0], 1);
-       F_CLR(constraint->bmap, ISL_BASIC_MAP_NORMALIZED);
+       ISL_F_CLR(constraint->bmap, ISL_BASIC_MAP_NORMALIZED);
        return constraint;
 error:
        isl_constraint_free(constraint);
@@ -265,7 +319,7 @@ int isl_constraint_is_equality(struct isl_constraint *constraint)
 {
        if (!constraint)
                return -1;
-       return constraint->line < constraint->bmap->eq + constraint->bmap->n_eq;
+       return constraint->line >= constraint->bmap->eq;
 }
 
 
@@ -289,6 +343,7 @@ struct isl_basic_set *isl_basic_set_from_constraint(
        bset = isl_basic_set_align_divs(bset, constraint_bset);
        nparam = isl_basic_set_n_param(bset);
        dim = isl_basic_set_n_dim(bset);
+       bset = isl_basic_set_cow(bset);
        bset = isl_basic_set_extend(bset, nparam, dim, 0, 1, 1);
        if (isl_constraint_is_equality(constraint)) {
                k = isl_basic_set_alloc_equality(bset);
@@ -313,21 +368,22 @@ error:
 }
 
 int isl_basic_set_has_defining_equality(
-       struct isl_basic_set *bset, int pos,
+       struct isl_basic_set *bset, enum isl_dim_type type, int pos,
        struct isl_constraint **c)
 {
        int i;
-       unsigned dim, nparam;
+       unsigned offset;
+       unsigned total;
 
        if (!bset)
                return -1;
-       nparam = isl_basic_set_n_param(bset);
-       dim = isl_basic_set_n_dim(bset);
-       isl_assert(bset->ctx, pos < dim, return -1);
+       offset = basic_set_offset(bset, type);
+       total = isl_basic_set_total_dim(bset);
+       isl_assert(bset->ctx, pos < isl_basic_set_dim(bset, type), return -1);
        for (i = 0; i < bset->n_eq; ++i)
-               if (!isl_int_is_zero(bset->eq[i][1 + nparam + pos]) &&
-                   isl_seq_first_non_zero(bset->eq[i]+1+nparam+pos+1,
-                                          dim-pos-1) == -1) {
+               if (!isl_int_is_zero(bset->eq[i][offset + pos]) &&
+                   isl_seq_first_non_zero(bset->eq[i]+offset+pos+1,
+                                          1+total-offset-pos-1) == -1) {
                        *c= isl_basic_set_constraint(isl_basic_set_copy(bset),
                                                                &bset->eq[i]);
                        return 1;
@@ -336,43 +392,41 @@ int isl_basic_set_has_defining_equality(
 }
 
 int isl_basic_set_has_defining_inequalities(
-       struct isl_basic_set *bset, int pos,
+       struct isl_basic_set *bset, enum isl_dim_type type, int pos,
        struct isl_constraint **lower,
        struct isl_constraint **upper)
 {
        int i, j;
-       unsigned dim;
-       unsigned nparam;
+       unsigned offset;
        unsigned total;
        isl_int m;
        isl_int **lower_line, **upper_line;
 
        if (!bset)
                return -1;
-       nparam = isl_basic_set_n_param(bset);
-       dim = isl_basic_set_n_dim(bset);
+       offset = basic_set_offset(bset, type);
        total = isl_basic_set_total_dim(bset);
-       isl_assert(bset->ctx, pos < dim, return -1);
+       isl_assert(bset->ctx, pos < isl_basic_set_dim(bset, type), return -1);
        isl_int_init(m);
        for (i = 0; i < bset->n_ineq; ++i) {
-               if (isl_int_is_zero(bset->ineq[i][1 + nparam + pos]))
+               if (isl_int_is_zero(bset->ineq[i][offset + pos]))
                        continue;
-               if (isl_int_is_one(bset->ineq[i][1 + nparam + pos]))
+               if (isl_int_is_one(bset->ineq[i][offset + pos]))
                        continue;
-               if (isl_int_is_negone(bset->ineq[i][1 + nparam + pos]))
+               if (isl_int_is_negone(bset->ineq[i][offset + pos]))
                        continue;
-               if (isl_seq_first_non_zero(bset->ineq[i]+1+nparam+pos+1,
-                                               dim-pos-1) != -1)
+               if (isl_seq_first_non_zero(bset->ineq[i]+offset+pos+1,
+                                               1+total-offset-pos-1) != -1)
                        continue;
-               for (j = i + i; j < bset->n_ineq; ++j) {
+               for (j = i + 1; j < bset->n_ineq; ++j) {
                        if (!isl_seq_is_neg(bset->ineq[i]+1, bset->ineq[j]+1,
                                            total))
                                continue;
                        isl_int_add(m, bset->ineq[i][0], bset->ineq[j][0]);
-                       if (isl_int_abs_ge(m, bset->ineq[i][1+nparam+pos]))
+                       if (isl_int_abs_ge(m, bset->ineq[i][offset+pos]))
                                continue;
 
-                       if (isl_int_is_pos(bset->ineq[i][1+nparam+pos])) {
+                       if (isl_int_is_pos(bset->ineq[i][offset+pos])) {
                                lower_line = &bset->ineq[i];
                                upper_line = &bset->ineq[j];
                        } else {