isl_access_info_add_source: plug memory leak on error path
[platform/upstream/isl.git] / isl_map.c
index 64f27c4..26eb7d2 100644 (file)
--- a/isl_map.c
+++ b/isl_map.c
@@ -534,7 +534,7 @@ __isl_give isl_basic_map *isl_basic_map_set_dim_name(
        bmap->dim = isl_space_set_dim_name(bmap->dim, type, pos, s);
        if (!bmap->dim)
                goto error;
-       return bmap;
+       return isl_basic_map_finalize(bmap);
 error:
        isl_basic_map_free(bmap);
        return NULL;
@@ -1594,8 +1594,8 @@ void isl_basic_map_swap_div(struct isl_basic_map *bmap, int a, int b)
 }
 
 /* Eliminate the specified n dimensions starting at first from the
- * constraints using Fourier-Motzkin.  The dimensions themselves
- * are not removed.
+ * constraints, without removing the dimensions from the space.
+ * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
  */
 __isl_give isl_map *isl_map_eliminate(__isl_take isl_map *map,
        enum isl_dim_type type, unsigned first, unsigned n)
@@ -1607,6 +1607,10 @@ __isl_give isl_map *isl_map_eliminate(__isl_take isl_map *map,
        if (n == 0)
                return map;
 
+       if (first + n > isl_map_dim(map, type) || first + n < first)
+               isl_die(map->ctx, isl_error_invalid,
+                       "index out of bounds", goto error);
+
        map = isl_map_cow(map);
        if (!map)
                return NULL;
@@ -1623,8 +1627,8 @@ error:
 }
 
 /* Eliminate the specified n dimensions starting at first from the
- * constraints using Fourier-Motzkin.  The dimensions themselves
- * are not removed.
+ * constraints, without removing the dimensions from the space.
+ * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
  */
 __isl_give isl_set *isl_set_eliminate(__isl_take isl_set *set,
        enum isl_dim_type type, unsigned first, unsigned n)
@@ -1633,8 +1637,8 @@ __isl_give isl_set *isl_set_eliminate(__isl_take isl_set *set,
 }
 
 /* Eliminate the specified n dimensions starting at first from the
- * constraints using Fourier-Motzkin.  The dimensions themselves
- * are not removed.
+ * constraints, without removing the dimensions from the space.
+ * If the set is rational, the dimensions are eliminated using Fourier-Motzkin.
  */
 __isl_give isl_set *isl_set_eliminate_dims(__isl_take isl_set *set,
        unsigned first, unsigned n)
@@ -8968,6 +8972,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)
@@ -9786,6 +9823,7 @@ __isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap)
                isl_space_dim(bmap->dim->nested[0], isl_dim_in);
        n1 = isl_space_dim(bmap->dim->nested[0], isl_dim_out);
        n2 = isl_space_dim(bmap->dim->nested[1], isl_dim_in);
+       bmap = isl_basic_map_cow(bmap);
        bmap = isl_basic_map_swap_vars(bmap, pos, n1, n2);
        if (!bmap)
                return NULL;
@@ -10062,6 +10100,9 @@ static __isl_give isl_basic_map *equator(__isl_take isl_space *space,
                isl_die(isl_space_get_ctx(space), isl_error_invalid,
                        "index out of bounds", goto error);
 
+       if (type1 == type2 && pos1 == pos2)
+               return isl_basic_map_universe(space);
+
        bmap = isl_basic_map_alloc_space(isl_space_copy(space), 0, 1, 0);
        i = isl_basic_map_alloc_equality(bmap);
        if (i < 0)
@@ -10165,6 +10206,12 @@ __isl_give isl_map *isl_map_order_gt(__isl_take isl_map *map,
                isl_die(map->ctx, isl_error_invalid,
                        "index out of bounds", goto error);
 
+       if (type1 == type2 && pos1 == pos2) {
+               isl_space *space = isl_map_get_space(map);
+               isl_map_free(map);
+               return isl_map_empty(space);
+       }
+
        bmap = isl_basic_map_alloc_space(isl_map_get_space(map), 0, 0, 1);
        i = isl_basic_map_alloc_inequality(bmap);
        if (i < 0)
@@ -10186,6 +10233,15 @@ error:
        return NULL;
 }
 
+/* Add a constraint imposing that the value of the first dimension is
+ * smaller than that of the second.
+ */
+__isl_give isl_map *isl_map_order_lt(__isl_take isl_map *map,
+       enum isl_dim_type type1, int pos1, enum isl_dim_type type2, int pos2)
+{
+       return isl_map_order_gt(map, type2, pos2, type1, pos1);
+}
+
 __isl_give isl_aff *isl_basic_map_get_div(__isl_keep isl_basic_map *bmap,
        int pos)
 {