isl_map_inline_foreach_basic_map: drop basic maps that have become empty
[platform/upstream/isl.git] / isl_map.c
index a22fc94..b0554cf 100644 (file)
--- a/isl_map.c
+++ b/isl_map.c
@@ -2993,6 +2993,8 @@ static __isl_give isl_basic_map *basic_map_space_reset(
 {
        isl_space *space;
 
+       if (!bmap)
+               return NULL;
        if (!isl_space_is_named_or_nested(bmap->dim, type))
                return bmap;
 
@@ -3218,6 +3220,8 @@ __isl_give isl_basic_map *isl_basic_map_move_dims(
        res = isl_basic_map_alloc_space(isl_basic_map_get_space(bmap),
                        bmap->n_div, bmap->n_eq, bmap->n_ineq);
        bmap = isl_basic_map_add_constraints_dim_map(res, bmap, dim_map);
+       if (!bmap)
+               goto error;
 
        bmap->dim = isl_space_move_dims(bmap->dim, dst_type, dst_pos,
                                        src_type, src_pos, n);
@@ -4352,10 +4356,12 @@ struct isl_basic_map *isl_basic_map_overlying_set(
                bmap = isl_basic_map_extend_constraints(bmap, 
                                                        0, 2 * like->n_div);
                for (i = 0; i < like->n_div; ++i) {
+                       if (!bmap)
+                               break;
                        if (isl_int_is_zero(bmap->div[i][0]))
                                continue;
                        if (isl_basic_map_add_div_constraints(bmap, i) < 0)
-                               goto error;
+                               bmap = isl_basic_map_free(bmap);
                }
        }
        isl_basic_map_free(like);
@@ -5325,6 +5331,39 @@ static int remove_if_empty(__isl_keep isl_map *map, int i)
        return 0;
 }
 
+/* Perform "fn" on each basic map of "map", where we may not be holding
+ * the only reference to "map".
+ * In particular, "fn" should be a semantics preserving operation
+ * that we want to apply to all copies of "map".  We therefore need
+ * to be careful not to modify "map" in a way that breaks "map"
+ * in case anything goes wrong.
+ */
+__isl_give isl_map *isl_map_inline_foreach_basic_map(__isl_take isl_map *map,
+       __isl_give isl_basic_map *(*fn)(__isl_take isl_basic_map *bmap))
+{
+       struct isl_basic_map *bmap;
+       int i;
+
+       if (!map)
+               return NULL;
+
+       for (i = map->n - 1; i >= 0; --i) {
+               bmap = isl_basic_map_copy(map->p[i]);
+               bmap = fn(bmap);
+               if (!bmap)
+                       goto error;
+               isl_basic_map_free(map->p[i]);
+               map->p[i] = bmap;
+               if (remove_if_empty(map, i) < 0)
+                       goto error;
+       }
+
+       return map;
+error:
+       isl_map_free(map);
+       return NULL;
+}
+
 struct isl_map *isl_map_fix_si(struct isl_map *map,
                enum isl_dim_type type, unsigned pos, int value)
 {
@@ -6823,8 +6862,10 @@ struct isl_basic_set *isl_basic_map_deltas(struct isl_basic_map *bmap)
        for (i = 0; i < dim; ++i) {
                int j = isl_basic_map_alloc_equality(
                                            (struct isl_basic_map *)bset);
-               if (j < 0)
-                       goto error;
+               if (j < 0) {
+                       bset = isl_basic_set_free(bset);
+                       break;
+               }
                isl_seq_clr(bset->eq[j], 1 + isl_basic_set_total_dim(bset));
                isl_int_set_si(bset->eq[j][1+nparam+i], 1);
                isl_int_set_si(bset->eq[j][1+nparam+dim+i], 1);
@@ -7417,7 +7458,7 @@ int isl_basic_map_is_empty(struct isl_basic_map *bmap)
        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);
-               empty = ISL_F_ISSET(copy, ISL_BASIC_MAP_EMPTY);
+               empty = isl_basic_map_plain_is_empty(copy);
                isl_basic_map_free(copy);
                return empty;
        }
@@ -7573,11 +7614,11 @@ __isl_give isl_basic_set *isl_basic_set_expand_divs(
                isl_die(isl_mat_get_ctx(div), isl_error_invalid,
                        "not an expansion", goto error);
 
+       n_div = bset->n_div;
        bset = isl_basic_map_extend_space(bset, isl_space_copy(bset->dim),
-                                       div->n_row - bset->n_div, 0,
-                                       2 * (div->n_row - bset->n_div));
+                                           div->n_row - n_div, 0,
+                                           2 * (div->n_row - n_div));
 
-       n_div = bset->n_div;
        for (i = n_div; i < div->n_row; ++i)
                if (isl_basic_set_alloc_div(bset) < 0)
                        goto error;
@@ -7834,19 +7875,20 @@ static enum isl_lp_result basic_set_maximal_difference_at(
        total = isl_basic_map_total_dim(bmap1);
        ctx = bmap1->ctx;
        obj = isl_vec_alloc(ctx, 1 + total);
+       if (!obj)
+               goto error2;
        isl_seq_clr(obj->block.data, 1 + total);
        isl_int_set_si(obj->block.data[1+nparam+pos], 1);
        isl_int_set_si(obj->block.data[1+nparam+pos+(dim1-pos)], -1);
-       if (!obj)
-               goto error;
        res = isl_basic_map_solve_lp(bmap1, 1, obj->block.data, ctx->one,
                                        opt, NULL, NULL);
        isl_basic_map_free(bmap1);
        isl_vec_free(obj);
        return res;
 error:
-       isl_basic_map_free(bmap1);
        isl_basic_map_free(bmap2);
+error2:
+       isl_basic_map_free(bmap1);
        return isl_lp_error;
 }
 
@@ -8235,7 +8277,8 @@ struct isl_basic_map *isl_basic_map_normalize(struct isl_basic_map *bmap)
                return bmap;
        bmap = isl_basic_map_remove_redundancies(bmap);
        bmap = isl_basic_map_sort_constraints(bmap);
-       ISL_F_SET(bmap, ISL_BASIC_MAP_NORMALIZED);
+       if (bmap)
+               ISL_F_SET(bmap, ISL_BASIC_MAP_NORMALIZED);
        return bmap;
 }