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;
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) {
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)
/* 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])) {
}
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)
/* 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;
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);
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]);
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
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)
struct isl_tab_var *var;
struct isl_tab_undo *snap;
+ if (!tab)
+ return isl_lp_error;
+
if (tab->empty)
return isl_lp_empty;
if (undo == snap)
break;
if (perform_undo(tab, undo) < 0) {
+ tab->top = undo;
free_undo(tab);
tab->in_undo = 0;
return -1;