AUTHORS: add Mythri Alle
[platform/upstream/isl.git] / isl_map.c
index 44a2056..290ee4e 100644 (file)
--- a/isl_map.c
+++ b/isl_map.c
@@ -1972,6 +1972,13 @@ error:
        return NULL;
 }
 
+__isl_give isl_basic_set *isl_basic_set_remove_divs_involving_dims(
+       __isl_take isl_basic_set *bset,
+       enum isl_dim_type type, unsigned first, unsigned n)
+{
+       return isl_basic_map_remove_divs_involving_dims(bset, type, first, n);
+}
+
 __isl_give isl_map *isl_map_remove_divs_involving_dims(__isl_take isl_map *map,
        enum isl_dim_type type, unsigned first, unsigned n)
 {
@@ -2471,21 +2478,23 @@ __isl_give isl_set *isl_set_add_basic_set(__isl_take isl_set *set,
                                                (struct isl_basic_map *)bset);
 }
 
-void isl_set_free(struct isl_set *set)
+void *isl_set_free(__isl_take isl_set *set)
 {
        int i;
 
        if (!set)
-               return;
+               return NULL;
 
        if (--set->ref > 0)
-               return;
+               return NULL;
 
        isl_ctx_deref(set->ctx);
        for (i = 0; i < set->n; ++i)
                isl_basic_set_free(set->p[i]);
        isl_space_free(set->dim);
        free(set);
+
+       return NULL;
 }
 
 void isl_set_print_internal(struct isl_set *set, FILE *out, int indent)
@@ -2902,8 +2911,9 @@ static __isl_give isl_basic_map *basic_map_space_reset(
        return bmap;
 }
 
-__isl_give isl_basic_map *isl_basic_map_insert(__isl_take isl_basic_map *bmap,
-               enum isl_dim_type type, unsigned pos, unsigned n)
+__isl_give isl_basic_map *isl_basic_map_insert_dims(
+       __isl_take isl_basic_map *bmap, enum isl_dim_type type,
+       unsigned pos, unsigned n)
 {
        isl_space *res_dim;
        struct isl_basic_map *res;
@@ -2948,12 +2958,19 @@ __isl_give isl_basic_map *isl_basic_map_insert(__isl_take isl_basic_map *bmap,
        return isl_basic_map_finalize(res);
 }
 
+__isl_give isl_basic_set *isl_basic_set_insert_dims(
+       __isl_take isl_basic_set *bset,
+       enum isl_dim_type type, unsigned pos, unsigned n)
+{
+       return isl_basic_map_insert_dims(bset, type, pos, n);
+}
+
 __isl_give isl_basic_map *isl_basic_map_add(__isl_take isl_basic_map *bmap,
                enum isl_dim_type type, unsigned n)
 {
        if (!bmap)
                return NULL;
-       return isl_basic_map_insert(bmap, type,
+       return isl_basic_map_insert_dims(bmap, type,
                                        isl_basic_map_dim(bmap, type), n);
 }
 
@@ -3000,7 +3017,7 @@ __isl_give isl_map *isl_map_insert_dims(__isl_take isl_map *map,
                goto error;
 
        for (i = 0; i < map->n; ++i) {
-               map->p[i] = isl_basic_map_insert(map->p[i], type, pos, n);
+               map->p[i] = isl_basic_map_insert_dims(map->p[i], type, pos, n);
                if (!map->p[i])
                        goto error;
        }
@@ -5601,58 +5618,93 @@ __isl_give isl_pw_multi_aff *isl_basic_map_lexmin_pw_multi_aff(
        return isl_basic_map_lexopt_pw_multi_aff(bmap, 0);
 }
 
-/* Given a basic map "bmap", compute the lexicographically minimal
- * (or maximal) image element for each domain element in dom.
+#undef TYPE
+#define TYPE   isl_pw_multi_aff
+#undef SUFFIX
+#define SUFFIX _pw_multi_aff
+#undef EMPTY
+#define EMPTY  isl_pw_multi_aff_empty
+#undef ADD
+#define ADD    isl_pw_multi_aff_union_add
+#include "isl_map_lexopt_templ.c"
+
+/* Given a map "map", compute the lexicographically minimal
+ * (or maximal) image element for each domain element in dom,
+ * in the form of an isl_pw_multi_aff.
  * Set *empty to those elements in dom that do not have an image element.
  *
- * We first make sure the basic sets in dom are disjoint and then
- * simply collect the results over each of the basic sets separately.
- * We could probably improve the efficiency a bit by moving the union
- * domain down into the parametric integer programming.
+ * We first compute the lexicographically minimal or maximal element
+ * in the first basic map.  This results in a partial solution "res"
+ * and a subset "todo" of dom that still need to be handled.
+ * We then consider each of the remaining maps in "map" and successively
+ * update both "res" and "todo".
  */
-static __isl_give isl_map *basic_map_partial_lexopt(
-               __isl_take isl_basic_map *bmap, __isl_take isl_set *dom,
-               __isl_give isl_set **empty, int max)
+static __isl_give isl_pw_multi_aff *isl_map_partial_lexopt_aligned_pw_multi_aff(
+       __isl_take isl_map *map, __isl_take isl_set *dom,
+       __isl_give isl_set **empty, int max)
 {
        int i;
-       struct isl_map *res;
+       isl_pw_multi_aff *res;
+       isl_set *todo;
 
-       dom = isl_set_make_disjoint(dom);
-       if (!dom)
+       if (!map || !dom)
                goto error;
 
-       if (isl_set_plain_is_empty(dom)) {
-               res = isl_map_empty_like_basic_map(bmap);
-               *empty = isl_set_empty_like(dom);
-               isl_set_free(dom);
-               isl_basic_map_free(bmap);
-               return res;
+       if (isl_map_plain_is_empty(map)) {
+               if (empty)
+                       *empty = dom;
+               else
+                       isl_set_free(dom);
+               return isl_pw_multi_aff_from_map(map);
        }
 
-       res = isl_basic_map_partial_lexopt(isl_basic_map_copy(bmap),
-                       isl_basic_set_copy(dom->p[0]), empty, max);
-               
-       for (i = 1; i < dom->n; ++i) {
-               struct isl_map *res_i;
-               struct isl_set *empty_i;
+       res = basic_map_partial_lexopt_pw_multi_aff(
+                                           isl_basic_map_copy(map->p[0]),
+                                           isl_set_copy(dom), &todo, max);
+
+       for (i = 1; i < map->n; ++i) {
+               isl_pw_multi_aff *res_i;
+               isl_set *todo_i;
 
-               res_i = isl_basic_map_partial_lexopt(isl_basic_map_copy(bmap),
-                               isl_basic_set_copy(dom->p[i]), &empty_i, max);
+               res_i = basic_map_partial_lexopt_pw_multi_aff(
+                                           isl_basic_map_copy(map->p[i]),
+                                           isl_set_copy(dom), &todo_i, max);
 
-               res = isl_map_union_disjoint(res, res_i);
-               *empty = isl_set_union_disjoint(*empty, empty_i);
+               if (max)
+                       res = isl_pw_multi_aff_union_lexmax(res, res_i);
+               else
+                       res = isl_pw_multi_aff_union_lexmin(res, res_i);
+
+               todo = isl_set_intersect(todo, todo_i);
        }
 
        isl_set_free(dom);
-       isl_basic_map_free(bmap);
+       isl_map_free(map);
+
+       if (empty)
+               *empty = todo;
+       else
+               isl_set_free(todo);
+
        return res;
 error:
-       *empty = NULL;
+       if (empty)
+               *empty = NULL;
        isl_set_free(dom);
-       isl_basic_map_free(bmap);
+       isl_map_free(map);
        return NULL;
 }
 
+#undef TYPE
+#define TYPE   isl_map
+#undef SUFFIX
+#define SUFFIX
+#undef EMPTY
+#define EMPTY  isl_map_empty
+#undef ADD
+#define ADD    isl_map_union_disjoint
+#include "isl_map_lexopt_templ.c"
+
 /* Given a map "map", compute the lexicographically minimal
  * (or maximal) image element for each domain element in dom.
  * Set *empty to those elements in dom that do not have an image element.
@@ -5661,7 +5713,7 @@ error:
  * in the first basic map.  This results in a partial solution "res"
  * and a subset "todo" of dom that still need to be handled.
  * We then consider each of the remaining maps in "map" and successively
- * improve both "res" and "todo".
+ * update both "res" and "todo".
  *
  * Let res^k and todo^k be the results after k steps and let i = k + 1.
  * Assume we are computing the lexicographical maximum.
@@ -5780,35 +5832,6 @@ error:
        return NULL;
 }
 
-/* Given a map "map", compute the lexicographically minimal
- * (or maximal) image element for each domain element in dom.
- * Set *empty to those elements in dom that do not have an image element.
- *
- * Align parameters if needed and then call isl_map_partial_lexopt_aligned.
- */
-static __isl_give isl_map *isl_map_partial_lexopt(
-               __isl_take isl_map *map, __isl_take isl_set *dom,
-               __isl_give isl_set **empty, int max)
-{
-       if (!map || !dom)
-               goto error;
-       if (isl_space_match(map->dim, isl_dim_param, dom->dim, isl_dim_param))
-               return isl_map_partial_lexopt_aligned(map, dom, empty, max);
-       if (!isl_space_has_named_params(map->dim) ||
-           !isl_space_has_named_params(dom->dim))
-               isl_die(map->ctx, isl_error_invalid,
-                       "unaligned unnamed parameters", goto error);
-       map = isl_map_align_params(map, isl_map_get_space(dom));
-       dom = isl_map_align_params(dom, isl_map_get_space(map));
-       return isl_map_partial_lexopt_aligned(map, dom, empty, max);
-error:
-       if (empty)
-               *empty = NULL;
-       isl_set_free(dom);
-       isl_map_free(map);
-       return NULL;
-}
-
 __isl_give isl_map *isl_map_partial_lexmax(
                __isl_take isl_map *map, __isl_take isl_set *dom,
                __isl_give isl_set **empty)
@@ -5876,31 +5899,6 @@ __isl_give isl_set *isl_basic_set_lexmax(__isl_take isl_basic_set *bset)
        return (isl_set *)isl_basic_map_lexmax((isl_basic_map *)bset);
 }
 
-__isl_give isl_map *isl_map_lexopt(__isl_take isl_map *map, int max)
-{
-       struct isl_set *dom = NULL;
-       isl_space *dom_dim;
-
-       if (!map)
-               goto error;
-       dom_dim = isl_space_domain(isl_space_copy(map->dim));
-       dom = isl_set_universe(dom_dim);
-       return isl_map_partial_lexopt(map, dom, NULL, max);
-error:
-       isl_map_free(map);
-       return NULL;
-}
-
-__isl_give isl_map *isl_map_lexmin(__isl_take isl_map *map)
-{
-       return isl_map_lexopt(map, 0);
-}
-
-__isl_give isl_map *isl_map_lexmax(__isl_take isl_map *map)
-{
-       return isl_map_lexopt(map, 1);
-}
-
 __isl_give isl_set *isl_set_lexmin(__isl_take isl_set *set)
 {
        return (isl_set *)isl_map_lexmin((isl_map *)set);
@@ -9832,6 +9830,60 @@ __isl_give isl_set *isl_set_align_params(__isl_take isl_set *set,
        return isl_map_align_params(set, model);
 }
 
+/* Align the parameters of "bmap" to those of "model", introducing
+ * additional parameters if needed.
+ */
+__isl_give isl_basic_map *isl_basic_map_align_params(
+       __isl_take isl_basic_map *bmap, __isl_take isl_space *model)
+{
+       isl_ctx *ctx;
+
+       if (!bmap || !model)
+               goto error;
+
+       ctx = isl_space_get_ctx(model);
+       if (!isl_space_has_named_params(model))
+               isl_die(ctx, isl_error_invalid,
+                       "model has unnamed parameters", goto error);
+       if (!isl_space_has_named_params(bmap->dim))
+               isl_die(ctx, isl_error_invalid,
+                       "relation has unnamed parameters", goto error);
+       if (!isl_space_match(bmap->dim, isl_dim_param, model, isl_dim_param)) {
+               isl_reordering *exp;
+               struct isl_dim_map *dim_map;
+
+               model = isl_space_drop_dims(model, isl_dim_in,
+                                       0, isl_space_dim(model, isl_dim_in));
+               model = isl_space_drop_dims(model, isl_dim_out,
+                                       0, isl_space_dim(model, isl_dim_out));
+               exp = isl_parameter_alignment_reordering(bmap->dim, model);
+               exp = isl_reordering_extend_space(exp,
+                                       isl_basic_map_get_space(bmap));
+               dim_map = isl_dim_map_from_reordering(exp);
+               bmap = isl_basic_map_realign(bmap,
+                                   exp ? isl_space_copy(exp->dim) : NULL,
+                                   isl_dim_map_extend(dim_map, bmap));
+               isl_reordering_free(exp);
+               free(dim_map);
+       }
+
+       isl_space_free(model);
+       return bmap;
+error:
+       isl_space_free(model);
+       isl_basic_map_free(bmap);
+       return NULL;
+}
+
+/* Align the parameters of "bset" to those of "model", introducing
+ * additional parameters if needed.
+ */
+__isl_give isl_basic_set *isl_basic_set_align_params(
+       __isl_take isl_basic_set *bset, __isl_take isl_space *model)
+{
+       return isl_basic_map_align_params(bset, model);
+}
+
 __isl_give isl_mat *isl_basic_map_equalities_matrix(
                __isl_keep isl_basic_map *bmap, enum isl_dim_type c1,
                enum isl_dim_type c2, enum isl_dim_type c3,