update .gitignore
[platform/upstream/isl.git] / isl_tab.c
index bb1aff9..b8a80be 100644 (file)
--- a/isl_tab.c
+++ b/isl_tab.c
@@ -87,11 +87,13 @@ error:
 
 int isl_tab_extend_cons(struct isl_tab *tab, unsigned n_new)
 {
-       unsigned off = 2 + tab->M;
+       unsigned off;
 
        if (!tab)
                return -1;
 
+       off = 2 + tab->M;
+
        if (tab->max_con < tab->n_con + n_new) {
                struct isl_tab_var *con;
 
@@ -209,34 +211,34 @@ struct isl_tab *isl_tab_dup(struct isl_tab *tab)
                return NULL;
 
        off = 2 + tab->M;
-       dup = isl_calloc_type(tab->ctx, struct isl_tab);
+       dup = isl_calloc_type(tab->mat->ctx, struct isl_tab);
        if (!dup)
                return NULL;
        dup->mat = isl_mat_dup(tab->mat);
        if (!dup->mat)
                goto error;
-       dup->var = isl_alloc_array(tab->ctx, struct isl_tab_var, tab->max_var);
+       dup->var = isl_alloc_array(tab->mat->ctx, struct isl_tab_var, tab->max_var);
        if (!dup->var)
                goto error;
        for (i = 0; i < tab->n_var; ++i)
                dup->var[i] = tab->var[i];
-       dup->con = isl_alloc_array(tab->ctx, struct isl_tab_var, tab->max_con);
+       dup->con = isl_alloc_array(tab->mat->ctx, struct isl_tab_var, tab->max_con);
        if (!dup->con)
                goto error;
        for (i = 0; i < tab->n_con; ++i)
                dup->con[i] = tab->con[i];
-       dup->col_var = isl_alloc_array(tab->ctx, int, tab->mat->n_col - off);
+       dup->col_var = isl_alloc_array(tab->mat->ctx, int, tab->mat->n_col - off);
        if (!dup->col_var)
                goto error;
        for (i = 0; i < tab->n_col; ++i)
                dup->col_var[i] = tab->col_var[i];
-       dup->row_var = isl_alloc_array(tab->ctx, int, tab->mat->n_row);
+       dup->row_var = isl_alloc_array(tab->mat->ctx, int, tab->mat->n_row);
        if (!dup->row_var)
                goto error;
        for (i = 0; i < tab->n_row; ++i)
                dup->row_var[i] = tab->row_var[i];
        if (tab->row_sign) {
-               dup->row_sign = isl_alloc_array(tab->ctx, enum isl_tab_row_sign,
+               dup->row_sign = isl_alloc_array(tab->mat->ctx, enum isl_tab_row_sign,
                                                tab->mat->n_row);
                if (!dup->row_sign)
                        goto error;
@@ -310,6 +312,8 @@ static struct isl_mat *tab_mat_product(struct isl_mat *mat1,
 
        prod = isl_mat_alloc(mat1->ctx, mat1->n_row + mat2->n_row,
                                        off + col1 + col2);
+       if (!prod)
+               return NULL;
 
        n = 0;
        for (i = 0; i < r1; ++i) {
@@ -1534,11 +1538,15 @@ static int close_row(struct isl_tab *tab, struct isl_tab_var *var)
                if (isl_tab_push_var(tab, isl_tab_undo_zero, var) < 0)
                        return -1;
        for (j = tab->n_dead; j < tab->n_col; ++j) {
+               int recheck;
                if (isl_int_is_zero(mat->row[var->index][off + j]))
                        continue;
                isl_assert(tab->mat->ctx,
                    isl_int_is_neg(mat->row[var->index][off + j]), return -1);
-               if (isl_tab_kill_col(tab, j))
+               recheck = isl_tab_kill_col(tab, j);
+               if (recheck < 0)
+                       return -1;
+               if (recheck)
                        --j;
        }
        if (isl_tab_mark_redundant(tab, var->index) < 0)
@@ -1825,24 +1833,24 @@ static int row_is_manifestly_zero(struct isl_tab *tab, int row)
 
 /* Add an equality that is known to be valid for the given tableau.
  */
-struct isl_tab *isl_tab_add_valid_eq(struct isl_tab *tab, isl_int *eq)
+int isl_tab_add_valid_eq(struct isl_tab *tab, isl_int *eq)
 {
        struct isl_tab_var *var;
        int r;
 
        if (!tab)
-               return NULL;
+               return -1;
        r = isl_tab_add_row(tab, eq);
        if (r < 0)
-               goto error;
+               return -1;
 
        var = &tab->con[r];
        r = var->index;
        if (row_is_manifestly_zero(tab, r)) {
                var->is_zero = 1;
                if (isl_tab_mark_redundant(tab, r) < 0)
-                       goto error;
-               return tab;
+                       return -1;
+               return 0;
        }
 
        if (isl_int_is_neg(tab->mat->row[r][1])) {
@@ -1852,15 +1860,12 @@ struct isl_tab *isl_tab_add_valid_eq(struct isl_tab *tab, isl_int *eq)
        }
        var->is_nonneg = 1;
        if (to_col(tab, var) < 0)
-               goto error;
+               return -1;
        var->is_nonneg = 0;
        if (isl_tab_kill_col(tab, var->index) < 0)
-               goto error;
+               return -1;
 
-       return tab;
-error:
-       isl_tab_free(tab);
-       return NULL;
+       return 0;
 }
 
 static int add_zero_row(struct isl_tab *tab)
@@ -1882,7 +1887,7 @@ static int add_zero_row(struct isl_tab *tab)
 /* Add equality "eq" and check if it conflicts with the
  * previously added constraints or if it is obviously redundant.
  */
-struct isl_tab *isl_tab_add_eq(struct isl_tab *tab, isl_int *eq)
+int isl_tab_add_eq(struct isl_tab *tab, isl_int *eq)
 {
        struct isl_tab_undo *snap = NULL;
        struct isl_tab_var *var;
@@ -1892,8 +1897,8 @@ struct isl_tab *isl_tab_add_eq(struct isl_tab *tab, isl_int *eq)
        isl_int cst;
 
        if (!tab)
-               return NULL;
-       isl_assert(tab->mat->ctx, !tab->M, goto error);
+               return -1;
+       isl_assert(tab->mat->ctx, !tab->M, return -1);
 
        if (tab->need_undo)
                snap = isl_tab_snap(tab);
@@ -1908,32 +1913,32 @@ struct isl_tab *isl_tab_add_eq(struct isl_tab *tab, isl_int *eq)
                isl_int_clear(cst);
        }
        if (r < 0)
-               goto error;
+               return -1;
 
        var = &tab->con[r];
        row = var->index;
        if (row_is_manifestly_zero(tab, row)) {
                if (snap) {
                        if (isl_tab_rollback(tab, snap) < 0)
-                               goto error;
+                               return -1;
                } else
                        drop_row(tab, row);
-               return tab;
+               return 0;
        }
 
        if (tab->bmap) {
                tab->bmap = isl_basic_map_add_ineq(tab->bmap, eq);
                if (isl_tab_push(tab, isl_tab_undo_bmap_ineq) < 0)
-                       goto error;
+                       return -1;
                isl_seq_neg(eq, eq, 1 + tab->n_var);
                tab->bmap = isl_basic_map_add_ineq(tab->bmap, eq);
                isl_seq_neg(eq, eq, 1 + tab->n_var);
                if (isl_tab_push(tab, isl_tab_undo_bmap_ineq) < 0)
-                       goto error;
+                       return -1;
                if (!tab->bmap)
-                       goto error;
+                       return -1;
                if (add_zero_row(tab) < 0)
-                       goto error;
+                       return -1;
        }
 
        sgn = isl_int_sgn(tab->mat->row[row][1]);
@@ -1948,25 +1953,22 @@ struct isl_tab *isl_tab_add_eq(struct isl_tab *tab, isl_int *eq)
        if (sgn < 0) {
                sgn = sign_of_max(tab, var);
                if (sgn < -1)
-                       goto error;
+                       return -1;
                if (sgn < 0) {
                        if (isl_tab_mark_empty(tab) < 0)
-                               goto error;
-                       return tab;
+                               return -1;
+                       return 0;
                }
        }
 
        var->is_nonneg = 1;
        if (to_col(tab, var) < 0)
-               goto error;
+               return -1;
        var->is_nonneg = 0;
        if (isl_tab_kill_col(tab, var->index) < 0)
-               goto error;
+               return -1;
 
-       return tab;
-error:
-       isl_tab_free(tab);
-       return NULL;
+       return 0;
 }
 
 /* Construct and return an inequality that expresses an upper bound
@@ -2177,9 +2179,10 @@ struct isl_tab *isl_tab_from_recession_cone(__isl_keep isl_basic_set *bset,
        isl_int_init(cst);
        for (i = 0; i < bset->n_eq; ++i) {
                isl_int_swap(bset->eq[i][offset], cst);
-               if (offset > 0)
-                       tab = isl_tab_add_eq(tab, bset->eq[i] + offset);
-               else
+               if (offset > 0) {
+                       if (isl_tab_add_eq(tab, bset->eq[i] + offset) < 0)
+                               goto error;
+               } else
                        tab = add_eq(tab, bset->eq[i]);
                isl_int_swap(bset->eq[i][offset], cst);
                if (!tab)
@@ -2726,6 +2729,9 @@ enum isl_lp_result isl_tab_min(struct isl_tab *tab,
        struct isl_tab_var *var;
        struct isl_tab_undo *snap;
 
+       if (!tab)
+               return isl_lp_error;
+
        if (tab->empty)
                return isl_lp_empty;
 
@@ -3024,6 +3030,7 @@ int isl_tab_rollback(struct isl_tab *tab, struct isl_tab_undo *snap)
                if (undo == snap)
                        break;
                if (perform_undo(tab, undo) < 0) {
+                       tab->top = undo;
                        free_undo(tab);
                        tab->in_undo = 0;
                        return -1;