add isl_schedule_node_schedule
[isl.git] / isl_convex_hull.c
index 3507777..a15092e 100644 (file)
@@ -113,7 +113,7 @@ __isl_give isl_set *isl_set_remove_redundancies(__isl_take isl_set *set)
  * constraint c and if so, set the constant term such that the
  * resulting constraint is a bounding constraint for the set.
  */
-static int uset_is_bound(__isl_keep isl_set *set, isl_int *c, unsigned len)
+static isl_bool uset_is_bound(__isl_keep isl_set *set, isl_int *c, unsigned len)
 {
        int first;
        int j;
@@ -150,38 +150,11 @@ static int uset_is_bound(__isl_keep isl_set *set, isl_int *c, unsigned len)
        }
        isl_int_clear(opt);
        isl_int_clear(opt_denom);
-       return j >= set->n;
+       return isl_bool_ok(j >= set->n);
 error:
        isl_int_clear(opt);
        isl_int_clear(opt_denom);
-       return -1;
-}
-
-static __isl_give isl_basic_set *isl_basic_set_add_equality(
-       __isl_take isl_basic_set *bset, isl_int *c)
-{
-       int i;
-       unsigned dim;
-
-       if (!bset)
-               return NULL;
-
-       if (ISL_F_ISSET(bset, ISL_BASIC_SET_EMPTY))
-               return bset;
-
-       isl_assert(bset->ctx, isl_basic_set_n_param(bset) == 0, goto error);
-       isl_assert(bset->ctx, bset->n_div == 0, goto error);
-       dim = isl_basic_set_n_dim(bset);
-       bset = isl_basic_set_cow(bset);
-       bset = isl_basic_set_extend(bset, 0, dim, 0, 1, 0);
-       i = isl_basic_set_alloc_equality(bset);
-       if (i < 0)
-               goto error;
-       isl_seq_cpy(bset->eq[i], c, 1 + dim);
-       return bset;
-error:
-       isl_basic_set_free(bset);
-       return NULL;
+       return isl_bool_error;
 }
 
 static __isl_give isl_set *isl_set_add_basic_set_equality(
@@ -193,7 +166,7 @@ static __isl_give isl_set *isl_set_add_basic_set_equality(
        if (!set)
                return NULL;
        for (i = 0; i < set->n; ++i) {
-               set->p[i] = isl_basic_set_add_equality(set->p[i], c);
+               set->p[i] = isl_basic_set_add_eq(set->p[i], c);
                if (!set->p[i])
                        goto error;
        }
@@ -226,12 +199,13 @@ static __isl_give isl_basic_set *wrap_constraints(__isl_keep isl_set *set)
        unsigned n_eq;
        unsigned n_ineq;
        int i, j, k;
-       unsigned dim, lp_dim;
+       isl_size dim, lp_dim;
 
-       if (!set)
+       dim = isl_set_dim(set, isl_dim_set);
+       if (dim < 0)
                return NULL;
 
-       dim = 1 + isl_set_n_dim(set);
+       dim += 1;
        n_eq = 1;
        n_ineq = set->n;
        for (i = 0; i < set->n; ++i) {
@@ -242,7 +216,9 @@ static __isl_give isl_basic_set *wrap_constraints(__isl_keep isl_set *set)
        lp = isl_basic_set_set_rational(lp);
        if (!lp)
                return NULL;
-       lp_dim = isl_basic_set_n_dim(lp);
+       lp_dim = isl_basic_set_dim(lp, isl_dim_set);
+       if (lp_dim < 0)
+               return isl_basic_set_free(lp);
        k = isl_basic_set_alloc_equality(lp);
        isl_int_set_si(lp->eq[k][0], -1);
        for (i = 0; i < set->n; ++i) {
@@ -339,15 +315,16 @@ isl_int *isl_set_wrap_facet(__isl_keep isl_set *set,
        struct isl_vec *obj;
        enum isl_lp_result res;
        isl_int num, den;
-       unsigned dim;
+       isl_size dim;
 
-       if (!set)
+       dim = isl_set_dim(set, isl_dim_set);
+       if (dim < 0)
                return NULL;
        ctx = set->ctx;
        set = isl_set_copy(set);
        set = isl_set_set_rational(set);
 
-       dim = 1 + isl_set_n_dim(set);
+       dim += 1;
        T = isl_mat_alloc(ctx, 3, dim);
        if (!T)
                goto error;
@@ -414,10 +391,12 @@ static __isl_give isl_mat *initial_facet_constraint(__isl_keep isl_set *set)
        struct isl_set *slice = NULL;
        struct isl_basic_set *face = NULL;
        int i;
-       unsigned dim = isl_set_n_dim(set);
-       int is_bound;
+       isl_size dim = isl_set_dim(set, isl_dim_set);
+       isl_bool is_bound;
        isl_mat *bounds = NULL;
 
+       if (dim < 0)
+               return NULL;
        isl_assert(set->ctx, set->n > 0, goto error);
        bounds = isl_mat_alloc(set->ctx, 1, 1 + dim);
        if (!bounds)
@@ -506,11 +485,13 @@ static __isl_give isl_basic_set *compute_facet(__isl_keep isl_set *set,
        struct isl_mat *m, *U, *Q;
        struct isl_basic_set *facet = NULL;
        struct isl_ctx *ctx;
-       unsigned dim;
+       isl_size dim;
 
+       dim = isl_set_dim(set, isl_dim_set);
+       if (dim < 0)
+               return NULL;
        ctx = set->ctx;
        set = isl_set_copy(set);
-       dim = isl_set_n_dim(set);
        m = isl_mat_alloc(set->ctx, 2, 1 + dim);
        if (!m)
                goto error;
@@ -562,29 +543,27 @@ static __isl_give isl_basic_set *extend(__isl_take isl_basic_set *hull,
        int k;
        struct isl_basic_set *facet = NULL;
        struct isl_basic_set *hull_facet = NULL;
-       unsigned dim;
+       isl_size dim;
 
-       if (!hull)
-               return NULL;
+       dim = isl_set_dim(set, isl_dim_set);
+       if (dim < 0 || !hull)
+               return isl_basic_set_free(hull);
 
        isl_assert(set->ctx, set->n > 0, goto error);
 
-       dim = isl_set_n_dim(set);
-
        for (i = 0; i < hull->n_ineq; ++i) {
                facet = compute_facet(set, hull->ineq[i]);
-               facet = isl_basic_set_add_equality(facet, hull->ineq[i]);
+               facet = isl_basic_set_add_eq(facet, hull->ineq[i]);
                facet = isl_basic_set_gauss(facet, NULL);
                facet = isl_basic_set_normalize_constraints(facet);
                hull_facet = isl_basic_set_copy(hull);
-               hull_facet = isl_basic_set_add_equality(hull_facet, hull->ineq[i]);
+               hull_facet = isl_basic_set_add_eq(hull_facet, hull->ineq[i]);
                hull_facet = isl_basic_set_gauss(hull_facet, NULL);
                hull_facet = isl_basic_set_normalize_constraints(hull_facet);
                if (!facet || !hull_facet)
                        goto error;
                hull = isl_basic_set_cow(hull);
-               hull = isl_basic_set_extend_space(hull,
-                       isl_space_copy(hull->dim), 0, 0, facet->n_ineq);
+               hull = isl_basic_set_extend(hull, 0, 0, facet->n_ineq);
                if (!hull)
                        goto error;
                for (j = 0; j < facet->n_ineq; ++j) {
@@ -768,12 +747,12 @@ static __isl_give isl_basic_set *convex_hull_pair_elim(
        int i, j, k;
        struct isl_basic_set *bset[2];
        struct isl_basic_set *hull = NULL;
-       unsigned dim;
+       isl_size dim;
 
-       if (!bset1 || !bset2)
+       dim = isl_basic_set_dim(bset1, isl_dim_set);
+       if (dim < 0 || !bset2)
                goto error;
 
-       dim = isl_basic_set_n_dim(bset1);
        hull = isl_basic_set_alloc(bset1->ctx, 0, 2 + 3 * dim, 0,
                                1 + dim + bset1->n_eq + bset2->n_eq,
                                2 + bset1->n_ineq + bset2->n_ineq);
@@ -849,10 +828,13 @@ isl_bool isl_basic_set_is_bounded(__isl_keep isl_basic_set *bset)
  */
 isl_bool isl_basic_map_image_is_bounded(__isl_keep isl_basic_map *bmap)
 {
-       unsigned nparam = isl_basic_map_dim(bmap, isl_dim_param);
-       unsigned n_in = isl_basic_map_dim(bmap, isl_dim_in);
+       isl_size nparam = isl_basic_map_dim(bmap, isl_dim_param);
+       isl_size n_in = isl_basic_map_dim(bmap, isl_dim_in);
        isl_bool bounded;
 
+       if (nparam < 0 || n_in < 0)
+               return isl_bool_error;
+
        bmap = isl_basic_map_copy(bmap);
        bmap = isl_basic_map_cow(bmap);
        bmap = isl_basic_map_move_dims(bmap, isl_dim_param, nparam,
@@ -891,12 +873,12 @@ static __isl_give isl_basic_set *induced_lineality_space(
 {
        int i, k;
        struct isl_basic_set *lin = NULL;
-       unsigned dim;
+       isl_size dim;
 
-       if (!bset1 || !bset2)
+       dim = isl_basic_set_dim(bset1, isl_dim_all);
+       if (dim < 0 || !bset2)
                goto error;
 
-       dim = isl_basic_set_total_dim(bset1);
        lin = isl_basic_set_alloc_space(isl_basic_set_get_space(bset1), 0,
                                        bset1->n_eq + bset2->n_eq,
                                        bset1->n_ineq + bset2->n_ineq);
@@ -967,12 +949,12 @@ static __isl_give isl_basic_set *uset_convex_hull(__isl_take isl_set *set);
 static __isl_give isl_basic_set *modulo_lineality(__isl_take isl_set *set,
        __isl_take isl_basic_set *lin)
 {
-       unsigned total = isl_basic_set_total_dim(lin);
+       isl_size total = isl_basic_set_dim(lin, isl_dim_all);
        unsigned lin_dim;
        struct isl_basic_set *hull;
        struct isl_mat *M, *U, *Q;
 
-       if (!set || !lin)
+       if (!set || total < 0)
                goto error;
        lin_dim = total - lin->n_eq;
        M = isl_mat_sub_alloc6(set->ctx, lin->eq, 0, lin->n_eq, 1, total);
@@ -1011,19 +993,21 @@ error:
 static __isl_give isl_basic_set *valid_direction_lp(
        __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
 {
-       isl_space *dim;
+       isl_space *space;
        struct isl_basic_set *lp;
        unsigned d;
        int n;
        int i, j, k;
+       isl_size total;
 
-       if (!bset1 || !bset2)
+       total = isl_basic_set_dim(bset1, isl_dim_all);
+       if (total < 0 || !bset2)
                goto error;
-       d = 1 + isl_basic_set_total_dim(bset1);
+       d = 1 + total;
        n = 2 +
            2 * bset1->n_eq + bset1->n_ineq + 2 * bset2->n_eq + bset2->n_ineq;
-       dim = isl_space_set_alloc(bset1->ctx, 0, n);
-       lp = isl_basic_set_alloc_space(dim, 0, d, n);
+       space = isl_space_set_alloc(bset1->ctx, 0, n);
+       lp = isl_basic_set_alloc_space(space, 0, d, n);
        if (!lp)
                goto error;
        for (i = 0; i < n; ++i) {
@@ -1096,7 +1080,7 @@ static __isl_give isl_vec *valid_direction(
        struct isl_tab *tab;
        struct isl_vec *sample = NULL;
        struct isl_vec *dir;
-       unsigned d;
+       isl_size d;
        int i;
        int n;
 
@@ -1110,7 +1094,9 @@ static __isl_give isl_vec *valid_direction(
        isl_basic_set_free(lp);
        if (!sample)
                goto error;
-       d = isl_basic_set_total_dim(bset1);
+       d = isl_basic_set_dim(bset1, isl_dim_all);
+       if (d < 0)
+               goto error;
        dir = isl_vec_alloc(bset1->ctx, 1 + d);
        if (!dir)
                goto error;
@@ -1156,14 +1142,16 @@ static __isl_give isl_basic_set *homogeneous_map(__isl_take isl_basic_set *bset,
        __isl_take isl_mat *T)
 {
        int k;
+       isl_size total;
 
-       if (!bset)
+       total = isl_basic_set_dim(bset, isl_dim_all);
+       if (total < 0)
                goto error;
        bset = isl_basic_set_extend_constraints(bset, 0, 1);
        k = isl_basic_set_alloc_inequality(bset);
        if (k < 0)
                goto error;
-       isl_seq_clr(bset->ineq[k] + 1, isl_basic_set_total_dim(bset));
+       isl_seq_clr(bset->ineq[k] + 1, total);
        isl_int_set_si(bset->ineq[k][0], 1);
        bset = isl_basic_set_preimage(bset, T);
        return bset;
@@ -1295,7 +1283,8 @@ static __isl_give isl_basic_set *convex_hull_pair(
        __isl_take isl_basic_set *bset1, __isl_take isl_basic_set *bset2)
 {
        isl_basic_set *lin, *aff;
-       int bounded1, bounded2;
+       isl_bool bounded1, bounded2;
+       isl_size total;
 
        if (bset1->ctx->opt->convex == ISL_CONVEX_HULL_FM)
                return convex_hull_pair_elim(bset1, bset2);
@@ -1329,7 +1318,8 @@ static __isl_give isl_basic_set *convex_hull_pair(
                isl_basic_set_free(bset2);
                return lin;
        }
-       if (lin->n_eq < isl_basic_set_total_dim(lin)) {
+       total = isl_basic_set_dim(lin, isl_dim_all);
+       if (lin->n_eq < total) {
                struct isl_set *set;
                set = isl_set_alloc_space(isl_basic_set_get_space(bset1), 2, 0);
                set = isl_set_add_basic_set(set, bset1);
@@ -1337,6 +1327,8 @@ static __isl_give isl_basic_set *convex_hull_pair(
                return modulo_lineality(set, lin);
        }
        isl_basic_set_free(lin);
+       if (total < 0)
+               goto error;
 
        return convex_hull_pair_pointed(bset1, bset2);
 error:
@@ -1357,12 +1349,12 @@ __isl_give isl_basic_set *isl_basic_set_lineality_space(
 {
        int i, k;
        struct isl_basic_set *lin = NULL;
-       unsigned n_div, dim;
+       isl_size n_div, dim;
 
-       if (!bset)
-               goto error;
        n_div = isl_basic_set_dim(bset, isl_dim_div);
-       dim = isl_basic_set_total_dim(bset);
+       dim = isl_basic_set_dim(bset, isl_dim_all);
+       if (n_div < 0 || dim < 0)
+               return isl_basic_set_free(bset);
 
        lin = isl_basic_set_alloc_space(isl_basic_set_get_space(bset),
                                        n_div, dim, 0);
@@ -1441,11 +1433,13 @@ static __isl_give isl_basic_set *uset_convex_hull_unbounded(
        isl_set_free(set);
 
        while (list) {
-               int n;
+               isl_size n, total;
                struct isl_basic_set *t;
                isl_basic_set *bset1, *bset2;
 
                n = isl_basic_set_list_n_basic_set(list);
+               if (n < 0)
+                       goto error;
                if (n < 2)
                        isl_die(isl_basic_set_list_get_ctx(list),
                                isl_error_internal,
@@ -1469,11 +1463,14 @@ static __isl_give isl_basic_set *uset_convex_hull_unbounded(
                        isl_basic_set_list_free(list);
                        return t;
                }
-               if (t->n_eq < isl_basic_set_total_dim(t)) {
+               total = isl_basic_set_dim(t, isl_dim_all);
+               if (t->n_eq < total) {
                        set = isl_basic_set_list_union(list);
                        return modulo_lineality(set, t);
                }
                isl_basic_set_free(t);
+               if (total < 0)
+                       goto error;
        }
 
        return NULL;
@@ -1490,7 +1487,7 @@ static __isl_give isl_basic_set *initial_hull(__isl_take isl_basic_set *hull,
        __isl_keep isl_set *set)
 {
        struct isl_mat *bounds = NULL;
-       unsigned dim;
+       isl_size dim;
        int k;
 
        if (!hull)
@@ -1501,7 +1498,9 @@ static __isl_give isl_basic_set *initial_hull(__isl_take isl_basic_set *hull,
        k = isl_basic_set_alloc_inequality(hull);
        if (k < 0)
                goto error;
-       dim = isl_set_n_dim(set);
+       dim = isl_set_dim(set, isl_dim_set);
+       if (dim < 0)
+               goto error;
        isl_assert(set->ctx, 1 + dim == bounds->n_col, goto error);
        isl_seq_cpy(hull->ineq[k], bounds->row[0], bounds->n_col);
        isl_mat_free(bounds);
@@ -1519,15 +1518,16 @@ struct max_constraint {
        int             ineq;
 };
 
-static int max_constraint_equal(const void *entry, const void *val)
+static isl_bool max_constraint_equal(const void *entry, const void *val)
 {
        struct max_constraint *a = (struct max_constraint *)entry;
        isl_int *b = (isl_int *)val;
 
-       return isl_seq_eq(a->c->row[0] + 1, b, a->c->n_col - 1);
+       return isl_bool_ok(isl_seq_eq(a->c->row[0] + 1, b, a->c->n_col - 1));
 }
 
-static void update_constraint(struct isl_ctx *ctx, struct isl_hash_table *table,
+static isl_stat update_constraint(struct isl_ctx *ctx,
+       struct isl_hash_table *table,
        isl_int *con, unsigned len, int n, int ineq)
 {
        struct isl_hash_table_entry *entry;
@@ -1538,30 +1538,34 @@ static void update_constraint(struct isl_ctx *ctx, struct isl_hash_table *table,
        entry = isl_hash_table_find(ctx, table, c_hash, max_constraint_equal,
                        con + 1, 0);
        if (!entry)
-               return;
+               return isl_stat_error;
+       if (entry == isl_hash_table_entry_none)
+               return isl_stat_ok;
        c = entry->data;
        if (c->count < n) {
                isl_hash_table_remove(ctx, table, entry);
-               return;
+               return isl_stat_ok;
        }
        c->count++;
        if (isl_int_gt(c->c->row[0][0], con[0]))
-               return;
+               return isl_stat_ok;
        if (isl_int_eq(c->c->row[0][0], con[0])) {
                if (ineq)
                        c->ineq = ineq;
-               return;
+               return isl_stat_ok;
        }
        c->c = isl_mat_cow(c->c);
        isl_int_set(c->c->row[0][0], con[0]);
        c->ineq = ineq;
+
+       return isl_stat_ok;
 }
 
 /* Check whether the constraint hash table "table" contains the constraint
  * "con".
  */
-static int has_constraint(struct isl_ctx *ctx, struct isl_hash_table *table,
-       isl_int *con, unsigned len, int n)
+static isl_bool has_constraint(struct isl_ctx *ctx,
+       struct isl_hash_table *table, isl_int *con, unsigned len, int n)
 {
        struct isl_hash_table_entry *entry;
        struct max_constraint *c;
@@ -1571,14 +1575,34 @@ static int has_constraint(struct isl_ctx *ctx, struct isl_hash_table *table,
        entry = isl_hash_table_find(ctx, table, c_hash, max_constraint_equal,
                        con + 1, 0);
        if (!entry)
-               return 0;
+               return isl_bool_error;
+       if (entry == isl_hash_table_entry_none)
+               return isl_bool_false;
        c = entry->data;
        if (c->count < n)
-               return 0;
-       return isl_int_eq(c->c->row[0][0], con[0]);
+               return isl_bool_false;
+       return isl_bool_ok(isl_int_eq(c->c->row[0][0], con[0]));
+}
+
+/* Are the constraints of "bset" known to be facets?
+ * If there are any equality constraints, then they are not.
+ * If there may be redundant constraints, then those
+ * redundant constraints are not facets.
+ */
+static isl_bool has_facets(__isl_keep isl_basic_set *bset)
+{
+       isl_size n_eq;
+
+       n_eq = isl_basic_set_n_equality(bset);
+       if (n_eq < 0)
+               return isl_bool_error;
+       if (n_eq != 0)
+               return isl_bool_false;
+       return ISL_F_ISSET(bset, ISL_BASIC_SET_NO_REDUNDANT);
 }
 
 /* Check for inequality constraints of a basic set without equalities
+ * or redundant constraints
  * such that the same or more stringent copies of the constraint appear
  * in all of the basic sets.  Such constraints are necessarily facet
  * constraints of the convex hull.
@@ -1596,19 +1620,26 @@ static __isl_give isl_basic_set *common_constraints(
        int best;
        struct max_constraint *constraints = NULL;
        struct isl_hash_table *table = NULL;
-       unsigned total;
+       isl_size total;
 
        *is_hull = 0;
 
-       for (i = 0; i < set->n; ++i)
-               if (set->p[i]->n_eq == 0)
+       for (i = 0; i < set->n; ++i) {
+               isl_bool facets = has_facets(set->p[i]);
+               if (facets < 0)
+                       return isl_basic_set_free(hull);
+               if (facets)
                        break;
+       }
        if (i >= set->n)
                return hull;
        min_constraints = set->p[i]->n_ineq;
        best = i;
        for (i = best + 1; i < set->n; ++i) {
-               if (set->p[i]->n_eq != 0)
+               isl_bool facets = has_facets(set->p[i]);
+               if (facets < 0)
+                       return isl_basic_set_free(hull);
+               if (!facets)
                        continue;
                if (set->p[i]->n_ineq >= min_constraints)
                        continue;
@@ -1623,7 +1654,9 @@ static __isl_give isl_basic_set *common_constraints(
        if (isl_hash_table_init(hull->ctx, table, min_constraints))
                goto error;
 
-       total = isl_space_dim(set->dim, isl_dim_all);
+       total = isl_set_dim(set, isl_dim_all);
+       if (total < 0)
+               goto error;
        for (i = 0; i < set->p[best]->n_ineq; ++i) {
                constraints[i].c = isl_mat_sub_alloc6(hull->ctx,
                        set->p[best]->ineq + i, 0, 1, 0, 1 + total);
@@ -1652,14 +1685,16 @@ static __isl_give isl_basic_set *common_constraints(
                        isl_int *eq = set->p[s]->eq[i];
                        for (j = 0; j < 2; ++j) {
                                isl_seq_neg(eq, eq, 1 + total);
-                               update_constraint(hull->ctx, table,
-                                                           eq, total, n, 0);
+                               if (update_constraint(hull->ctx, table,
+                                                   eq, total, n, 0) < 0)
+                                       goto error;
                        }
                }
                for (i = 0; i < set->p[s]->n_ineq; ++i) {
                        isl_int *ineq = set->p[s]->ineq[i];
-                       update_constraint(hull->ctx, table, ineq, total, n,
-                               set->p[s]->n_eq == 0);
+                       if (update_constraint(hull->ctx, table, ineq, total, n,
+                                       set->p[s]->n_eq == 0) < 0)
+                               goto error;
                }
                ++n;
        }
@@ -1681,8 +1716,12 @@ static __isl_give isl_basic_set *common_constraints(
                if (set->p[s]->n_ineq != hull->n_ineq)
                        continue;
                for (i = 0; i < set->p[s]->n_ineq; ++i) {
+                       isl_bool has;
                        isl_int *ineq = set->p[s]->ineq[i];
-                       if (!has_constraint(hull->ctx, table, ineq, total, n))
+                       has = has_constraint(hull->ctx, table, ineq, total, n);
+                       if (has < 0)
+                               goto error;
+                       if (!has)
                                break;
                }
                if (i == set->p[s]->n_ineq)
@@ -1753,10 +1792,14 @@ static __isl_give isl_basic_set *uset_convex_hull_wrap(__isl_take isl_set *set)
 static __isl_give isl_basic_set *uset_convex_hull(__isl_take isl_set *set)
 {
        isl_bool bounded;
+       isl_size dim;
        struct isl_basic_set *convex_hull = NULL;
        struct isl_basic_set *lin;
 
-       if (isl_set_n_dim(set) == 0)
+       dim = isl_set_dim(set, isl_dim_all);
+       if (dim < 0)
+               goto error;
+       if (dim == 0)
                return convex_hull_0d(set);
 
        set = isl_set_coalesce(set);
@@ -1769,7 +1812,7 @@ static __isl_give isl_basic_set *uset_convex_hull(__isl_take isl_set *set)
                isl_set_free(set);
                return convex_hull;
        }
-       if (isl_set_n_dim(set) == 1)
+       if (dim == 1)
                return convex_hull_1d(set);
 
        bounded = isl_set_is_bounded(set);
@@ -1785,7 +1828,7 @@ static __isl_give isl_basic_set *uset_convex_hull(__isl_take isl_set *set)
                isl_set_free(set);
                return lin;
        }
-       if (lin->n_eq < isl_basic_set_total_dim(lin))
+       if (lin->n_eq < dim)
                return modulo_lineality(set, lin);
        isl_basic_set_free(lin);
 
@@ -1804,11 +1847,13 @@ static __isl_give isl_basic_set *uset_convex_hull_wrap_bounded(
        __isl_take isl_set *set)
 {
        struct isl_basic_set *convex_hull = NULL;
+       isl_size dim;
 
-       if (!set)
+       dim = isl_set_dim(set, isl_dim_all);
+       if (dim < 0)
                goto error;
 
-       if (isl_set_n_dim(set) == 0) {
+       if (dim == 0) {
                convex_hull = isl_basic_set_universe(isl_space_copy(set->dim));
                isl_set_free(set);
                convex_hull = isl_basic_set_set_rational(convex_hull);
@@ -1825,7 +1870,7 @@ static __isl_give isl_basic_set *uset_convex_hull_wrap_bounded(
                convex_hull = isl_basic_map_remove_redundancies(convex_hull);
                return convex_hull;
        }
-       if (isl_set_n_dim(set) == 1)
+       if (dim == 1)
                return convex_hull_1d(set);
 
        return uset_convex_hull_wrap(set);
@@ -1927,7 +1972,7 @@ error:
        return NULL;
 }
 
-struct isl_basic_set *isl_set_convex_hull(struct isl_set *set)
+__isl_give isl_basic_set *isl_set_convex_hull(__isl_take isl_set *set)
 {
        return bset_from_bmap(isl_map_convex_hull(set_to_map(set)));
 }
@@ -1985,13 +2030,13 @@ struct ineq_cmp_data {
        isl_int         *p;
 };
 
-static int has_ineq(const void *entry, const void *val)
+static isl_bool has_ineq(const void *entry, const void *val)
 {
        isl_int *row = (isl_int *)entry;
        struct ineq_cmp_data *v = (struct ineq_cmp_data *)val;
 
-       return isl_seq_eq(row + 1, v->p + 1, v->len) ||
-              isl_seq_is_neg(row + 1, v->p + 1, v->len);
+       return isl_bool_ok(isl_seq_eq(row + 1, v->p + 1, v->len) ||
+                          isl_seq_is_neg(row + 1, v->p + 1, v->len));
 }
 
 static int hash_ineq(struct isl_ctx *ctx, struct isl_hash_table *table,
@@ -2015,24 +2060,26 @@ static int hash_ineq(struct isl_ctx *ctx, struct isl_hash_table *table,
  * Equalities are added as two inequalities.
  * The value in the hash table is a pointer to the (in)equality of "bset".
  */
-static int hash_basic_set(struct isl_hash_table *table,
+static isl_stat hash_basic_set(struct isl_hash_table *table,
        __isl_keep isl_basic_set *bset)
 {
        int i, j;
-       unsigned dim = isl_basic_set_total_dim(bset);
+       isl_size dim = isl_basic_set_dim(bset, isl_dim_all);
 
+       if (dim < 0)
+               return isl_stat_error;
        for (i = 0; i < bset->n_eq; ++i) {
                for (j = 0; j < 2; ++j) {
                        isl_seq_neg(bset->eq[i], bset->eq[i], 1 + dim);
                        if (hash_ineq(bset->ctx, table, bset->eq[i], dim) < 0)
-                               return -1;
+                               return isl_stat_error;
                }
        }
        for (i = 0; i < bset->n_ineq; ++i) {
                if (hash_ineq(bset->ctx, table, bset->ineq[i], dim) < 0)
-                       return -1;
+                       return isl_stat_error;
        }
-       return 0;
+       return isl_stat_ok;
 }
 
 static struct sh_data *sh_data_alloc(__isl_keep isl_set *set, unsigned n_ineq)
@@ -2116,7 +2163,8 @@ static int is_bound(struct sh_data *data, __isl_keep isl_set *set, int j,
  * least its constant term) may need to be temporarily negated to get
  * the actually hashed constraint.
  */
-static void set_max_constant_term(struct sh_data *data, __isl_keep isl_set *set,
+static isl_stat set_max_constant_term(struct sh_data *data,
+       __isl_keep isl_set *set,
        int i, isl_int *ineq, uint32_t c_hash, struct ineq_cmp_data *v)
 {
        int j;
@@ -2131,6 +2179,8 @@ static void set_max_constant_term(struct sh_data *data, __isl_keep isl_set *set,
                entry = isl_hash_table_find(ctx, data->p[j].table,
                                                c_hash, &has_ineq, v, 0);
                if (!entry)
+                       return isl_stat_error;
+               if (entry == isl_hash_table_entry_none)
                        continue;
 
                ineq_j = entry->data;
@@ -2142,6 +2192,8 @@ static void set_max_constant_term(struct sh_data *data, __isl_keep isl_set *set,
                if (neg)
                        isl_int_neg(ineq_j[0], ineq_j[0]);
        }
+
+       return isl_stat_ok;
 }
 
 /* Check if inequality "ineq" from basic set "i" is or can be relaxed to
@@ -2173,23 +2225,29 @@ static __isl_give isl_basic_set *add_bound(__isl_take isl_basic_set *hull,
        struct ineq_cmp_data v;
        struct isl_hash_table_entry *entry;
        int j, k;
+       isl_size total;
 
-       if (!hull)
-               return NULL;
+       total = isl_basic_set_dim(hull, isl_dim_all);
+       if (total < 0)
+               return isl_basic_set_free(hull);
 
-       v.len = isl_basic_set_total_dim(hull);
+       v.len = total;
        v.p = ineq;
        c_hash = isl_seq_get_hash(ineq + 1, v.len);
 
        entry = isl_hash_table_find(hull->ctx, data->hull_table, c_hash,
                                        has_ineq, &v, 0);
-       if (entry)
+       if (!entry)
+               return isl_basic_set_free(hull);
+       if (entry != isl_hash_table_entry_none)
                return hull;
 
        for (j = 0; j < i; ++j) {
                entry = isl_hash_table_find(hull->ctx, data->p[j].table,
                                                c_hash, has_ineq, &v, 0);
-               if (entry)
+               if (!entry)
+                       return isl_basic_set_free(hull);
+               if (entry != isl_hash_table_entry_none)
                        break;
        }
        if (j < i)
@@ -2200,7 +2258,8 @@ static __isl_give isl_basic_set *add_bound(__isl_take isl_basic_set *hull,
                goto error;
        isl_seq_cpy(hull->ineq[k], ineq, 1 + v.len);
 
-       set_max_constant_term(data, set, i, hull->ineq[k], c_hash, &v);
+       if (set_max_constant_term(data, set, i, hull->ineq[k], c_hash, &v) < 0)
+               goto error;
        for (j = 0; j < i; ++j) {
                int bound;
                bound = is_bound(data, set, j, hull->ineq[k], shift);
@@ -2209,16 +2268,16 @@ static __isl_give isl_basic_set *add_bound(__isl_take isl_basic_set *hull,
                if (!bound)
                        break;
        }
-       if (j < i) {
-               isl_basic_set_free_inequality(hull, 1);
-               return hull;
-       }
+       if (j < i)
+               return isl_basic_set_free_inequality(hull, 1);
 
        for (j = i + 1; j < set->n; ++j) {
                int bound;
                entry = isl_hash_table_find(hull->ctx, data->p[j].table,
                                                c_hash, has_ineq, &v, 0);
-               if (entry)
+               if (!entry)
+                       return isl_basic_set_free(hull);
+               if (entry != isl_hash_table_entry_none)
                        continue;
                bound = is_bound(data, set, j, hull->ineq[k], shift);
                if (bound < 0)
@@ -2226,10 +2285,8 @@ static __isl_give isl_basic_set *add_bound(__isl_take isl_basic_set *hull,
                if (!bound)
                        break;
        }
-       if (j < set->n) {
-               isl_basic_set_free_inequality(hull, 1);
-               return hull;
-       }
+       if (j < set->n)
+               return isl_basic_set_free_inequality(hull, 1);
 
        entry = isl_hash_table_find(hull->ctx, data->hull_table, c_hash,
                                        has_ineq, &v, 1);
@@ -2251,7 +2308,10 @@ static __isl_give isl_basic_set *add_bounds(__isl_take isl_basic_set *bset,
        struct sh_data *data, __isl_keep isl_set *set, int i, int shift)
 {
        int j, k;
-       unsigned dim = isl_basic_set_total_dim(bset);
+       isl_size dim = isl_basic_set_dim(bset, isl_dim_all);
+
+       if (dim < 0)
+               return isl_basic_set_free(bset);
 
        for (j = 0; j < set->p[i]->n_eq; ++j) {
                for (k = 0; k < 2; ++k) {
@@ -2416,7 +2476,7 @@ __isl_give isl_basic_map *isl_map_simple_hull(__isl_take isl_map *map)
        return map_simple_hull(map, 1);
 }
 
-struct isl_basic_set *isl_set_simple_hull(struct isl_set *set)
+__isl_give isl_basic_set *isl_set_simple_hull(__isl_take isl_set *set)
 {
        return bset_from_bmap(isl_map_simple_hull(set_to_map(set)));
 }
@@ -2502,14 +2562,13 @@ static __isl_give isl_basic_map *select_shared_equalities(
        __isl_take isl_basic_map *bmap1, __isl_keep isl_basic_map *bmap2)
 {
        int i1, i2;
-       unsigned total;
+       isl_size total;
 
        bmap1 = isl_basic_map_cow(bmap1);
-       if (!bmap1 || !bmap2)
+       total = isl_basic_map_dim(bmap1, isl_dim_all);
+       if (total < 0 || !bmap2)
                return isl_basic_map_free(bmap1);
 
-       total = isl_basic_map_total_dim(bmap1);
-
        i1 = bmap1->n_eq - 1;
        i2 = bmap2->n_eq - 1;
        while (bmap1 && i1 >= 0 && i2 >= 0) {
@@ -2554,12 +2613,14 @@ static __isl_give isl_basic_map *select_shared_equalities(
 __isl_give isl_basic_map *isl_basic_map_plain_unshifted_simple_hull(
        __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
 {
-       bmap1 = isl_basic_map_drop_constraint_involving_unknown_divs(bmap1);
-       bmap2 = isl_basic_map_drop_constraint_involving_unknown_divs(bmap2);
+       if (isl_basic_map_check_equal_space(bmap1, bmap2) < 0)
+               goto error;
+
+       bmap1 = isl_basic_map_drop_constraints_involving_unknown_divs(bmap1);
+       bmap2 = isl_basic_map_drop_constraints_involving_unknown_divs(bmap2);
+       bmap1 = isl_basic_map_order_divs(bmap1);
        bmap2 = isl_basic_map_align_divs(bmap2, bmap1);
        bmap1 = isl_basic_map_align_divs(bmap1, bmap2);
-       bmap1 = isl_basic_map_gauss(bmap1, NULL);
-       bmap2 = isl_basic_map_gauss(bmap2, NULL);
        bmap1 = isl_basic_map_sort_constraints(bmap1);
        bmap2 = isl_basic_map_sort_constraints(bmap2);
 
@@ -2569,6 +2630,10 @@ __isl_give isl_basic_map *isl_basic_map_plain_unshifted_simple_hull(
        isl_basic_map_free(bmap2);
        bmap1 = isl_basic_map_finalize(bmap1);
        return bmap1;
+error:
+       isl_basic_map_free(bmap1);
+       isl_basic_map_free(bmap2);
+       return NULL;
 }
 
 /* Compute a superset of the convex hull of "map" that is described
@@ -2593,7 +2658,7 @@ __isl_give isl_basic_map *isl_map_plain_unshifted_simple_hull(
                return NULL;
        if (map->n <= 1)
                return map_simple_hull_trivial(map);
-       map = isl_map_drop_constraint_involving_unknown_divs(map);
+       map = isl_map_drop_constraints_involving_unknown_divs(map);
        hull = isl_basic_map_copy(map->p[0]);
        for (i = 1; i < map->n; ++i) {
                isl_basic_map *bmap_i;
@@ -2634,11 +2699,13 @@ static __isl_give isl_basic_set *add_bound_from_constraint(
        isl_ctx *ctx;
        uint32_t c_hash;
        struct ineq_cmp_data v;
+       isl_size total;
 
-       if (!hull || !set)
+       total = isl_basic_set_dim(hull, isl_dim_all);
+       if (total < 0 || !set)
                return isl_basic_set_free(hull);
 
-       v.len = isl_basic_set_total_dim(hull);
+       v.len = total;
        v.p = ineq;
        c_hash = isl_seq_get_hash(ineq + 1, v.len);
 
@@ -2649,7 +2716,9 @@ static __isl_give isl_basic_set *add_bound_from_constraint(
 
                entry = isl_hash_table_find(ctx, data->p[i].table,
                                                c_hash, &has_ineq, &v, 0);
-               if (entry) {
+               if (!entry)
+                       return isl_basic_set_free(hull);
+               if (entry != isl_hash_table_entry_none) {
                        isl_int *ineq_i = entry->data;
                        int neg, more_relaxed;
 
@@ -2706,7 +2775,7 @@ static __isl_give isl_basic_set *uset_unshifted_simple_hull_from_constraints(
        int last_added = 0;
        struct sh_data *data = NULL;
        isl_basic_set *hull = NULL;
-       unsigned dim;
+       isl_size dim;
 
        hull = isl_basic_set_alloc_space(isl_set_get_space(set), 0, 0, n_ineq);
        if (!hull)
@@ -2717,6 +2786,8 @@ static __isl_give isl_basic_set *uset_unshifted_simple_hull_from_constraints(
                goto error;
 
        dim = isl_set_dim(set, isl_dim_set);
+       if (dim < 0)
+               goto error;
        for (i = 0; i < n_ineq; ++i) {
                int hull_n_ineq = hull->n_ineq;
                int parallel;
@@ -2752,14 +2823,15 @@ error:
 static __isl_give isl_mat *collect_inequalities(__isl_take isl_mat *mat,
        __isl_keep isl_basic_set_list *list, isl_int **ineq)
 {
-       int i, j, n, n_eq, n_ineq;
+       int i, j, n_eq, n_ineq;
+       isl_size n;
 
-       if (!mat)
-               return NULL;
+       n = isl_basic_set_list_n_basic_set(list);
+       if (!mat || n < 0)
+               return isl_mat_free(mat);
 
        n_eq = 0;
        n_ineq = 0;
-       n = isl_basic_set_list_n_basic_set(list);
        for (i = 0; i < n; ++i) {
                isl_basic_set *bset;
                bset = isl_basic_set_list_get_basic_set(list, i);
@@ -2809,20 +2881,21 @@ static int cmp_ineq(const void *a, const void *b, void *arg)
 static __isl_give isl_basic_set *uset_unshifted_simple_hull_from_basic_set_list(
        __isl_take isl_set *set, __isl_take isl_basic_set_list *list)
 {
-       int i, n, n_eq, n_ineq;
-       unsigned dim;
+       int i, n_eq, n_ineq;
+       isl_size n;
+       isl_size dim;
        isl_ctx *ctx;
        isl_mat *mat = NULL;
        isl_int **ineq = NULL;
        isl_basic_set *hull;
 
-       if (!set)
+       n = isl_basic_set_list_n_basic_set(list);
+       if (!set || n < 0)
                goto error;
        ctx = isl_set_get_ctx(set);
 
        n_eq = 0;
        n_ineq = 0;
-       n = isl_basic_set_list_n_basic_set(list);
        for (i = 0; i < n; ++i) {
                isl_basic_set *bset;
                bset = isl_basic_set_list_get_basic_set(list, i);
@@ -2838,6 +2911,8 @@ static __isl_give isl_basic_set *uset_unshifted_simple_hull_from_basic_set_list(
                goto error;
 
        dim = isl_set_dim(set, isl_dim_set);
+       if (dim < 0)
+               goto error;
        mat = isl_mat_alloc(ctx, n_eq, 1 + dim);
        mat = collect_inequalities(mat, list, ineq);
        if (!mat)
@@ -2874,15 +2949,17 @@ error:
 static __isl_give isl_basic_map *map_unshifted_simple_hull_from_basic_map_list(
        __isl_take isl_map *map, __isl_take isl_basic_map_list *list)
 {
+       isl_size n;
        isl_basic_map *model;
        isl_basic_map *hull;
        isl_set *set;
        isl_basic_set_list *bset_list;
 
-       if (!map || !list)
+       n = isl_basic_map_list_n_basic_map(list);
+       if (!map || n < 0)
                goto error;
 
-       if (isl_basic_map_list_n_basic_map(list) == 0) {
+       if (n == 0) {
                isl_space *space;
 
                space = isl_map_get_space(map);
@@ -2920,7 +2997,8 @@ error:
 static __isl_give isl_basic_map_list *collect_basic_maps(
        __isl_take isl_map_list *list)
 {
-       int i, n;
+       int i;
+       isl_size n;
        isl_ctx *ctx;
        isl_basic_map_list *bmap_list;
 
@@ -2929,6 +3007,8 @@ static __isl_give isl_basic_map_list *collect_basic_maps(
        n = isl_map_list_n_map(list);
        ctx = isl_map_list_get_ctx(list);
        bmap_list = isl_basic_map_list_alloc(ctx, 0);
+       if (n < 0)
+               bmap_list = isl_basic_map_list_free(bmap_list);
 
        for (i = 0; i < n; ++i) {
                isl_map *map;
@@ -2985,7 +3065,9 @@ __isl_give isl_basic_set *isl_set_unshifted_simple_hull_from_set_list(
  */
 static __isl_give isl_basic_set *set_bounds(__isl_keep isl_set *set, int dim)
 {
-       unsigned set_dim = isl_set_dim(set, isl_dim_set);
+       isl_size set_dim = isl_set_dim(set, isl_dim_set);
+       if (set_dim < 0)
+               return NULL;
        set = isl_set_copy(set);
        set = isl_set_eliminate_dims(set, dim + 1, set_dim - (dim + 1));
        set = isl_set_eliminate_dims(set, 0, dim);
@@ -3000,19 +3082,22 @@ __isl_give isl_basic_set *isl_set_bounded_simple_hull(__isl_take isl_set *set)
 {
        int i, j;
        struct isl_basic_set *hull;
-       unsigned nparam, left;
+       isl_size nparam, dim, total;
+       unsigned left;
        int removed_divs = 0;
 
        hull = isl_set_simple_hull(isl_set_copy(set));
-       if (!hull)
+       nparam = isl_basic_set_dim(hull, isl_dim_param);
+       dim = isl_basic_set_dim(hull, isl_dim_set);
+       total = isl_basic_set_dim(hull, isl_dim_all);
+       if (nparam < 0 || dim < 0 || total < 0)
                goto error;
 
-       nparam = isl_basic_set_dim(hull, isl_dim_param);
-       for (i = 0; i < isl_basic_set_dim(hull, isl_dim_set); ++i) {
+       for (i = 0; i < dim; ++i) {
                int lower = 0, upper = 0;
                struct isl_basic_set *bounds;
 
-               left = isl_basic_set_total_dim(hull) - nparam - i - 1;
+               left = total - nparam - i - 1;
                for (j = 0; j < hull->n_eq; ++j) {
                        if (isl_int_is_zero(hull->eq[j][1 + nparam + i]))
                                continue;