isl_printer_print_qpolynomial: properly print nested divs
[platform/upstream/isl.git] / isl_map.c
index a149744..93ffa58 100644 (file)
--- a/isl_map.c
+++ b/isl_map.c
@@ -377,6 +377,12 @@ const char *isl_set_get_tuple_name(__isl_keep isl_set *set)
        return set ? isl_dim_get_tuple_name(set->dim, isl_dim_set) : NULL;
 }
 
+const char *isl_basic_map_get_dim_name(__isl_keep isl_basic_map *bmap,
+       enum isl_dim_type type, unsigned pos)
+{
+       return bmap ? isl_dim_get_name(bmap->dim, type, pos) : NULL;
+}
+
 const char *isl_map_get_dim_name(__isl_keep isl_map *map,
        enum isl_dim_type type, unsigned pos)
 {
@@ -517,9 +523,12 @@ struct isl_basic_set *isl_basic_set_alloc_dim(struct isl_dim *dim,
        struct isl_basic_map *bmap;
        if (!dim)
                return NULL;
-       isl_assert(dim->ctx, dim->n_in == 0, return NULL);
+       isl_assert(dim->ctx, dim->n_in == 0, goto error);
        bmap = isl_basic_map_alloc_dim(dim, extra, n_eq, n_ineq);
        return (struct isl_basic_set *)bmap;
+error:
+       isl_dim_free(dim);
+       return NULL;
 }
 
 struct isl_basic_map *isl_basic_map_alloc_dim(struct isl_dim *dim,
@@ -1401,15 +1410,6 @@ __isl_give isl_set *isl_set_eliminate_dims(__isl_take isl_set *set,
        return isl_set_eliminate(set, isl_dim_set, first, n);
 }
 
-/* Project out n dimensions starting at first using Fourier-Motzkin */
-struct isl_set *isl_set_remove_dims(struct isl_set *set,
-       unsigned first, unsigned n)
-{
-       set = isl_set_eliminate_dims(set, first, n);
-       set = isl_set_drop_dims(set, first, n);
-       return set;
-}
-
 __isl_give isl_basic_map *isl_basic_map_remove_divs(
        __isl_take isl_basic_map *bmap)
 {
@@ -1452,7 +1452,7 @@ error:
        return NULL;
 }
 
-struct isl_basic_map *isl_basic_map_remove(struct isl_basic_map *bmap,
+struct isl_basic_map *isl_basic_map_remove_dims(struct isl_basic_map *bmap,
        enum isl_dim_type type, unsigned first, unsigned n)
 {
        if (!bmap)
@@ -1474,14 +1474,99 @@ error:
        return NULL;
 }
 
-__isl_give isl_basic_set *isl_basic_set_remove(__isl_take isl_basic_set *bset,
+/* Return true if the definition of the given div (recursively) involves
+ * any of the given variables.
+ */
+static int div_involves_vars(__isl_keep isl_basic_map *bmap, int div,
+       unsigned first, unsigned n)
+{
+       int i;
+       unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div);
+
+       if (isl_int_is_zero(bmap->div[div][0]))
+               return 0;
+       if (isl_seq_first_non_zero(bmap->div[div] + 1 + first, n) >= 0)
+               return 1;
+
+       for (i = bmap->n_div - 1; i >= 0; --i) {
+               if (isl_int_is_zero(bmap->div[div][1 + div_offset + i]))
+                       continue;
+               if (div_involves_vars(bmap, i, first, n))
+                       return 1;
+       }
+
+       return 0;
+}
+
+/* Remove all divs (recursively) involving any of the given dimensions
+ * in their definitions.
+ */
+__isl_give isl_basic_map *isl_basic_map_remove_divs_involving_dims(
+       __isl_take isl_basic_map *bmap,
+       enum isl_dim_type type, unsigned first, unsigned n)
+{
+       int i;
+
+       if (!bmap)
+               return NULL;
+       isl_assert(bmap->ctx, first + n <= isl_basic_map_dim(bmap, type),
+                       goto error);
+       first += isl_basic_map_offset(bmap, type);
+
+       for (i = bmap->n_div - 1; i >= 0; --i) {
+               if (!div_involves_vars(bmap, i, first, n))
+                       continue;
+               bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1);
+       }
+
+       return bmap;
+error:
+       isl_basic_map_free(bmap);
+       return NULL;
+}
+
+__isl_give isl_map *isl_map_remove_divs_involving_dims(__isl_take isl_map *map,
+       enum isl_dim_type type, unsigned first, unsigned n)
+{
+       int i;
+
+       if (!map)
+               return NULL;
+       if (map->n == 0)
+               return map;
+
+       map = isl_map_cow(map);
+       if (!map)
+               return NULL;
+
+       for (i = 0; i < map->n; ++i) {
+               map->p[i] = isl_basic_map_remove_divs_involving_dims(map->p[i],
+                                                               type, first, n);
+               if (!map->p[i])
+                       goto error;
+       }
+       return map;
+error:
+       isl_map_free(map);
+       return NULL;
+}
+
+__isl_give isl_set *isl_set_remove_divs_involving_dims(__isl_take isl_set *set,
+       enum isl_dim_type type, unsigned first, unsigned n)
+{
+       return (isl_set *)isl_map_remove_divs_involving_dims((isl_map *)set,
+                                                             type, first, n);
+}
+
+__isl_give isl_basic_set *isl_basic_set_remove_dims(
+       __isl_take isl_basic_set *bset,
        enum isl_dim_type type, unsigned first, unsigned n)
 {
        return (isl_basic_set *)
-               isl_basic_map_remove((isl_basic_map *)bset, type, first, n);
+           isl_basic_map_remove_dims((isl_basic_map *)bset, type, first, n);
 }
 
-struct isl_map *isl_map_remove(struct isl_map *map,
+struct isl_map *isl_map_remove_dims(struct isl_map *map,
        enum isl_dim_type type, unsigned first, unsigned n)
 {
        int i;
@@ -1507,27 +1592,17 @@ error:
        return NULL;
 }
 
-__isl_give isl_set *isl_set_remove(__isl_take isl_set *bset,
+__isl_give isl_set *isl_set_remove_dims(__isl_take isl_set *bset,
        enum isl_dim_type type, unsigned first, unsigned n)
 {
-       return (isl_set *)isl_map_remove((isl_map *)bset, type, first, n);
+       return (isl_set *)isl_map_remove_dims((isl_map *)bset, type, first, n);
 }
 
 /* Project out n inputs starting at first using Fourier-Motzkin */
 struct isl_map *isl_map_remove_inputs(struct isl_map *map,
        unsigned first, unsigned n)
 {
-       return isl_map_remove(map, isl_dim_in, first, n);
-}
-
-/* Project out n dimensions starting at first using Fourier-Motzkin */
-struct isl_basic_set *isl_basic_set_remove_dims(struct isl_basic_set *bset,
-       unsigned first, unsigned n)
-{
-       unsigned nparam = isl_basic_set_n_param(bset);
-       bset = isl_basic_set_eliminate_vars(bset, nparam + first, n);
-       bset = isl_basic_set_drop_dims(bset, first, n);
-       return bset;
+       return isl_map_remove_dims(map, isl_dim_in, first, n);
 }
 
 static void dump_term(struct isl_basic_map *bmap,
@@ -1695,8 +1770,8 @@ struct isl_set *isl_set_alloc_dim(struct isl_dim *dim, int n, unsigned flags)
 
        if (!dim)
                return NULL;
-       isl_assert(dim->ctx, dim->n_in == 0, return NULL);
-       isl_assert(dim->ctx, n >= 0, return NULL);
+       isl_assert(dim->ctx, dim->n_in == 0, goto error);
+       isl_assert(dim->ctx, n >= 0, goto error);
        set = isl_alloc(dim->ctx, struct isl_set,
                        sizeof(struct isl_set) +
                        (n - 1) * sizeof(struct isl_basic_set *));
@@ -2520,7 +2595,7 @@ __isl_give isl_basic_map *isl_basic_map_project_out(
                return NULL;
 
        if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL))
-               return isl_basic_map_remove(bmap, type, first, n);
+               return isl_basic_map_remove_dims(bmap, type, first, n);
 
        isl_assert(bmap->ctx, first + n <= isl_basic_map_dim(bmap, type),
                        goto error);
@@ -3418,7 +3493,9 @@ struct isl_basic_set *isl_basic_map_underlying_set(
        if (!bmap)
                goto error;
        if (bmap->dim->nparam == 0 && bmap->dim->n_in == 0 &&
-           bmap->n_div == 0 && !isl_dim_get_tuple_name(bmap->dim, isl_dim_out))
+           bmap->n_div == 0 &&
+           !isl_dim_is_named_or_nested(bmap->dim, isl_dim_in) &&
+           !isl_dim_is_named_or_nested(bmap->dim, isl_dim_out))
                return (struct isl_basic_set *)bmap;
        bmap = isl_basic_map_cow(bmap);
        if (!bmap)
@@ -3588,7 +3665,7 @@ struct isl_set *isl_set_to_underlying_set(struct isl_set *set)
        return (struct isl_set *)isl_map_underlying_set((struct isl_map *)set);
 }
 
-static __isl_give isl_basic_map *isl_basic_map_reset_dim(
+__isl_give isl_basic_map *isl_basic_map_reset_dim(
        __isl_take isl_basic_map *bmap, __isl_take isl_dim *dim)
 {
        bmap = isl_basic_map_cow(bmap);
@@ -5456,6 +5533,14 @@ struct isl_map *isl_map_identity_like_basic_map(struct isl_basic_map *model)
        return map_identity(isl_dim_copy(model->dim));
 }
 
+__isl_give isl_map *isl_set_identity(__isl_take isl_set *set)
+{
+       isl_dim *dim = isl_set_get_dim(set);
+       isl_map *id;
+       id = isl_map_identity(dim);
+       return isl_map_intersect_range(id, set);
+}
+
 /* Construct a basic set with all set dimensions having only non-negative
  * values.
  */
@@ -7570,6 +7655,24 @@ error:
        return NULL;
 }
 
+__isl_give isl_set *isl_set_flatten(__isl_take isl_set *set)
+{
+       return (isl_set *)isl_map_flatten((isl_map *)set);
+}
+
+__isl_give isl_map *isl_set_flatten_map(__isl_take isl_set *set)
+{
+       isl_dim *dim, *flat_dim;
+       isl_map *map;
+
+       dim = isl_set_get_dim(set);
+       flat_dim = isl_dim_flatten(isl_dim_copy(dim));
+       map = map_identity(isl_dim_join(isl_dim_reverse(dim), flat_dim));
+       map = isl_map_intersect_domain(map, set);
+
+       return map;
+}
+
 /* Extend the given dim_map with mappings for the divs in bmap.
  */
 static __isl_give struct isl_dim_map *extend_dim_map(