isl_union_set_compute_schedule: components may also involve proximity edges
[platform/upstream/isl.git] / isl_map.c
index 6276119..691c88c 100644 (file)
--- a/isl_map.c
+++ b/isl_map.c
@@ -474,6 +474,14 @@ __isl_give isl_id *isl_set_get_tuple_id(__isl_keep isl_set *set)
        return isl_map_get_tuple_id(set, isl_dim_set);
 }
 
+/* Does the set tuple have a name?
+ */
+int isl_set_has_tuple_name(__isl_keep isl_set *set)
+{
+       return set ? isl_space_has_tuple_name(set->dim, isl_dim_set) : -1;
+}
+
+
 const char *isl_basic_set_get_tuple_name(__isl_keep isl_basic_set *bset)
 {
        return bset ? isl_space_get_tuple_name(bset->dim, isl_dim_set) : NULL;
@@ -577,6 +585,12 @@ int isl_basic_map_has_dim_id(__isl_keep isl_basic_map *bmap,
        return bmap ? isl_space_has_dim_id(bmap->dim, type, pos) : -1;
 }
 
+__isl_give isl_id *isl_basic_set_get_dim_id(__isl_keep isl_basic_set *bset,
+       enum isl_dim_type type, unsigned pos)
+{
+       return bset ? isl_space_get_dim_id(bset->dim, type, pos) : NULL;
+}
+
 int isl_map_has_dim_id(__isl_keep isl_map *map,
        enum isl_dim_type type, unsigned pos)
 {
@@ -8954,6 +8968,39 @@ int isl_basic_map_plain_is_single_valued(__isl_keep isl_basic_map *bmap)
        return 1;
 }
 
+/* Check if the given basic map is single-valued.
+ * We simply compute
+ *
+ *     M \circ M^-1
+ *
+ * and check if the result is a subset of the identity mapping.
+ */
+int isl_basic_map_is_single_valued(__isl_keep isl_basic_map *bmap)
+{
+       isl_space *space;
+       isl_basic_map *test;
+       isl_basic_map *id;
+       int sv;
+
+       sv = isl_basic_map_plain_is_single_valued(bmap);
+       if (sv < 0 || sv)
+               return sv;
+
+       test = isl_basic_map_reverse(isl_basic_map_copy(bmap));
+       test = isl_basic_map_apply_range(test, isl_basic_map_copy(bmap));
+
+       space = isl_basic_map_get_space(bmap);
+       space = isl_space_map_from_set(isl_space_range(space));
+       id = isl_basic_map_identity(space);
+
+       sv = isl_basic_map_is_subset(test, id);
+
+       isl_basic_map_free(test);
+       isl_basic_map_free(id);
+
+       return sv;
+}
+
 /* Check if the given map is obviously single-valued.
  */
 int isl_map_plain_is_single_valued(__isl_keep isl_map *map)
@@ -9818,6 +9865,83 @@ error:
        return NULL;
 }
 
+/* Can we apply isl_basic_map_curry to "bmap"?
+ * That is, does it have a nested relation in its domain?
+ */
+int isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap)
+{
+       if (!bmap)
+               return -1;
+
+       return isl_space_can_curry(bmap->dim);
+}
+
+/* Can we apply isl_map_curry to "map"?
+ * That is, does it have a nested relation in its domain?
+ */
+int isl_map_can_curry(__isl_keep isl_map *map)
+{
+       if (!map)
+               return -1;
+
+       return isl_space_can_curry(map->dim);
+}
+
+/* Given a basic map (A -> B) -> C, return the corresponding basic map
+ * A -> (B -> C).
+ */
+__isl_give isl_basic_map *isl_basic_map_curry(__isl_take isl_basic_map *bmap)
+{
+
+       if (!bmap)
+               return NULL;
+
+       if (!isl_basic_map_can_curry(bmap))
+               isl_die(bmap->ctx, isl_error_invalid,
+                       "basic map cannot be curried", goto error);
+       bmap->dim = isl_space_curry(bmap->dim);
+       if (!bmap->dim)
+               goto error;
+       return bmap;
+error:
+       isl_basic_map_free(bmap);
+       return NULL;
+}
+
+/* Given a map (A -> B) -> C, return the corresponding map
+ * A -> (B -> C).
+ */
+__isl_give isl_map *isl_map_curry(__isl_take isl_map *map)
+{
+       int i;
+
+       if (!map)
+               return NULL;
+
+       if (!isl_map_can_curry(map))
+               isl_die(map->ctx, isl_error_invalid, "map cannot be curried",
+                       goto error);
+
+       map = isl_map_cow(map);
+       if (!map)
+               return NULL;
+
+       for (i = 0; i < map->n; ++i) {
+               map->p[i] = isl_basic_map_curry(map->p[i]);
+               if (!map->p[i])
+                       goto error;
+       }
+
+       map->dim = isl_space_curry(map->dim);
+       if (!map->dim)
+               goto error;
+
+       return map;
+error:
+       isl_map_free(map);
+       return NULL;
+}
+
 /* Construct a basic map mapping the domain of the affine expression
  * to a one-dimensional range prescribed by the affine expression.
  */
@@ -9953,25 +10077,25 @@ __isl_give isl_set *isl_set_equate(__isl_take isl_set *set,
        return isl_map_equate(set, type1, pos1, type2, pos2);
 }
 
-/* Add a constraint imposing that the given two dimensions are equal.
+/* Construct a basic map where the given dimensions are equal to each other.
  */
-__isl_give isl_map *isl_map_equate(__isl_take isl_map *map,
+static __isl_give isl_basic_map *equator(__isl_take isl_space *space,
        enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
 {
        isl_basic_map *bmap = NULL;
        int i;
 
-       if (!map)
+       if (!space)
                return NULL;
 
-       if (pos1 >= isl_map_dim(map, type1))
-               isl_die(map->ctx, isl_error_invalid,
+       if (pos1 >= isl_space_dim(space, type1))
+               isl_die(isl_space_get_ctx(space), isl_error_invalid,
                        "index out of bounds", goto error);
-       if (pos2 >= isl_map_dim(map, type2))
-               isl_die(map->ctx, isl_error_invalid,
+       if (pos2 >= isl_space_dim(space, type2))
+               isl_die(isl_space_get_ctx(space), isl_error_invalid,
                        "index out of bounds", goto error);
 
-       bmap = isl_basic_map_alloc_space(isl_map_get_space(map), 0, 1, 0);
+       bmap = isl_basic_map_alloc_space(isl_space_copy(space), 0, 1, 0);
        i = isl_basic_map_alloc_equality(bmap);
        if (i < 0)
                goto error;
@@ -9981,14 +10105,40 @@ __isl_give isl_map *isl_map_equate(__isl_take isl_map *map,
        isl_int_set_si(bmap->eq[i][pos1], -1);
        isl_int_set_si(bmap->eq[i][pos2], 1);
        bmap = isl_basic_map_finalize(bmap);
+       isl_space_free(space);
+       return bmap;
+error:
+       isl_space_free(space);
+       isl_basic_map_free(bmap);
+       return NULL;
+}
+
+/* Add a constraint imposing that the given two dimensions are equal.
+ */
+__isl_give isl_basic_map *isl_basic_map_equate(__isl_take isl_basic_map *bmap,
+       enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
+{
+       isl_basic_map *eq;
+
+       eq = equator(isl_basic_map_get_space(bmap), type1, pos1, type2, pos2);
+
+       bmap = isl_basic_map_intersect(bmap, eq);
+
+       return bmap;
+}
+
+/* Add a constraint imposing that the given two dimensions are equal.
+ */
+__isl_give isl_map *isl_map_equate(__isl_take isl_map *map,
+       enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
+{
+       isl_basic_map *bmap;
+
+       bmap = equator(isl_map_get_space(map), type1, pos1, type2, pos2);
 
        map = isl_map_intersect(map, isl_map_from_basic_map(bmap));
 
        return map;
-error:
-       isl_basic_map_free(bmap);
-       isl_map_free(map);
-       return NULL;
 }
 
 /* Add a constraint imposing that the given two dimensions have opposite values.