add isl_basic_set_add_div_constraints
[platform/upstream/isl.git] / isl_map.c
index 0b3af21..0704f5d 100644 (file)
--- a/isl_map.c
+++ b/isl_map.c
@@ -690,6 +690,76 @@ int isl_basic_set_is_rational(__isl_keep isl_basic_set *bset)
        return isl_basic_map_is_rational(bset);
 }
 
+/* Does "bmap" contain any rational points?
+ *
+ * If "bmap" has an equality for each dimension, equating the dimension
+ * to an integer constant, then it has no rational points, even if it
+ * is marked as rational.
+ */
+int isl_basic_map_has_rational(__isl_keep isl_basic_map *bmap)
+{
+       int has_rational = 1;
+       unsigned total;
+
+       if (!bmap)
+               return -1;
+       if (isl_basic_map_plain_is_empty(bmap))
+               return 0;
+       if (!isl_basic_map_is_rational(bmap))
+               return 0;
+       bmap = isl_basic_map_copy(bmap);
+       bmap = isl_basic_map_implicit_equalities(bmap);
+       if (!bmap)
+               return -1;
+       total = isl_basic_map_total_dim(bmap);
+       if (bmap->n_eq == total) {
+               int i, j;
+               for (i = 0; i < bmap->n_eq; ++i) {
+                       j = isl_seq_first_non_zero(bmap->eq[i] + 1, total);
+                       if (j < 0)
+                               break;
+                       if (!isl_int_is_one(bmap->eq[i][1 + j]) &&
+                           !isl_int_is_negone(bmap->eq[i][1 + j]))
+                               break;
+                       j = isl_seq_first_non_zero(bmap->eq[i] + 1 + j + 1,
+                                                   total - j - 1);
+                       if (j >= 0)
+                               break;
+               }
+               if (i == bmap->n_eq)
+                       has_rational = 0;
+       }
+       isl_basic_map_free(bmap);
+
+       return has_rational;
+}
+
+/* Does "map" contain any rational points?
+ */
+int isl_map_has_rational(__isl_keep isl_map *map)
+{
+       int i;
+       int has_rational;
+
+       if (!map)
+               return -1;
+       for (i = 0; i < map->n; ++i) {
+               has_rational = isl_basic_map_has_rational(map->p[i]);
+               if (has_rational < 0)
+                       return -1;
+               if (has_rational)
+                       return 1;
+       }
+       return 0;
+}
+
+/* Does "set" contain any rational points?
+ */
+int isl_set_has_rational(__isl_keep isl_set *set)
+{
+       return isl_map_has_rational(set);
+}
+
 /* Is this basic set a parameter domain?
  */
 int isl_basic_set_is_params(__isl_keep isl_basic_set *bset)
@@ -2133,6 +2203,14 @@ __isl_give isl_basic_map *isl_basic_map_remove_unknown_divs(
        return bmap;
 }
 
+/* Remove all divs that are unknown or defined in terms of unknown divs.
+ */
+__isl_give isl_basic_set *isl_basic_set_remove_unknown_divs(
+       __isl_take isl_basic_set *bset)
+{
+       return isl_basic_map_remove_unknown_divs(bset);
+}
+
 __isl_give isl_map *isl_map_remove_unknown_divs(__isl_take isl_map *map)
 {
        int i;
@@ -4182,6 +4260,11 @@ int isl_basic_map_add_div_constraints(struct isl_basic_map *bmap, unsigned div)
                                                        bmap->div[div]);
 }
 
+int isl_basic_set_add_div_constraints(struct isl_basic_set *bset, unsigned div)
+{
+       return isl_basic_map_add_div_constraints(bset, div);
+}
+
 struct isl_basic_set *isl_basic_map_underlying_set(
                struct isl_basic_map *bmap)
 {
@@ -6438,12 +6521,23 @@ error:
        return NULL;
 }
 
+/* Return the union of "map1" and "map2", where we assume for now that
+ * "map1" and "map2" are disjoint.  Note that the basic maps inside
+ * "map1" or "map2" may not be disjoint from each other.
+ * Also note that this function is also called from isl_map_union,
+ * which takes care of handling the situation where "map1" and "map2"
+ * may not be disjoint.
+ *
+ * If one of the inputs is empty, we can simply return the other input.
+ * Similarly, if one of the inputs is universal, then it is equal to the union.
+ */
 static __isl_give isl_map *map_union_disjoint(__isl_take isl_map *map1,
        __isl_take isl_map *map2)
 {
        int i;
        unsigned flags = 0;
        struct isl_map *map = NULL;
+       int is_universe;
 
        if (!map1 || !map2)
                goto error;
@@ -6457,6 +6551,22 @@ static __isl_give isl_map *map_union_disjoint(__isl_take isl_map *map1,
                return map1;
        }
 
+       is_universe = isl_map_plain_is_universe(map1);
+       if (is_universe < 0)
+               goto error;
+       if (is_universe) {
+               isl_map_free(map2);
+               return map1;
+       }
+
+       is_universe = isl_map_plain_is_universe(map2);
+       if (is_universe < 0)
+               goto error;
+       if (is_universe) {
+               isl_map_free(map1);
+               return map2;
+       }
+
        isl_assert(map1->ctx, isl_space_is_equal(map1->dim, map2->dim), goto error);
 
        if (ISL_F_ISSET(map1, ISL_MAP_DISJOINT) &&
@@ -7283,6 +7393,9 @@ int isl_basic_map_is_empty(struct isl_basic_map *bmap)
        if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_EMPTY))
                return 1;
 
+       if (isl_basic_map_is_universe(bmap))
+               return 0;
+
        if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL)) {
                struct isl_basic_map *copy = isl_basic_map_copy(bmap);
                copy = isl_basic_map_remove_redundancies(copy);
@@ -8168,8 +8281,7 @@ int isl_basic_set_plain_cmp(const __isl_keep isl_basic_set *bset1,
        return isl_basic_map_plain_cmp(bset1, bset2);
 }
 
-int isl_set_plain_cmp(const __isl_keep isl_set *set1,
-       const __isl_keep isl_set *set2)
+int isl_set_plain_cmp(__isl_keep isl_set *set1, __isl_keep isl_set *set2)
 {
        int i, cmp;
 
@@ -10251,6 +10363,78 @@ error:
        return NULL;
 }
 
+/* Can we apply isl_basic_map_uncurry to "bmap"?
+ * That is, does it have a nested relation in its domain?
+ */
+int isl_basic_map_can_uncurry(__isl_keep isl_basic_map *bmap)
+{
+       if (!bmap)
+               return -1;
+
+       return isl_space_can_uncurry(bmap->dim);
+}
+
+/* Can we apply isl_map_uncurry to "map"?
+ * That is, does it have a nested relation in its domain?
+ */
+int isl_map_can_uncurry(__isl_keep isl_map *map)
+{
+       if (!map)
+               return -1;
+
+       return isl_space_can_uncurry(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_uncurry(__isl_take isl_basic_map *bmap)
+{
+
+       if (!bmap)
+               return NULL;
+
+       if (!isl_basic_map_can_uncurry(bmap))
+               isl_die(bmap->ctx, isl_error_invalid,
+                       "basic map cannot be uncurried",
+                       return isl_basic_map_free(bmap));
+       bmap->dim = isl_space_uncurry(bmap->dim);
+       if (!bmap->dim)
+               return isl_basic_map_free(bmap);
+       return bmap;
+}
+
+/* Given a map A -> (B -> C), return the corresponding map
+ * (A -> B) -> C.
+ */
+__isl_give isl_map *isl_map_uncurry(__isl_take isl_map *map)
+{
+       int i;
+
+       if (!map)
+               return NULL;
+
+       if (!isl_map_can_uncurry(map))
+               isl_die(map->ctx, isl_error_invalid, "map cannot be uncurried",
+                       return isl_map_free(map));
+
+       map = isl_map_cow(map);
+       if (!map)
+               return NULL;
+
+       for (i = 0; i < map->n; ++i) {
+               map->p[i] = isl_basic_map_uncurry(map->p[i]);
+               if (!map->p[i])
+                       return isl_map_free(map);
+       }
+
+       map->dim = isl_space_uncurry(map->dim);
+       if (!map->dim)
+               return isl_map_free(map);
+
+       return map;
+}
+
 /* Construct a basic map mapping the domain of the affine expression
  * to a one-dimensional range prescribed by the affine expression.
  */