summaryrefslogtreecommitdiff
path: root/isl_tab_pip.c
diff options
context:
space:
mode:
authorSven Verdoolaege <skimo@kotnet.org>2009-10-10 13:14:19 +0200
committerSven Verdoolaege <skimo@kotnet.org>2009-10-12 22:26:24 +0200
commitec21e6de21d784ee1ba32689aebcbda9f786fd30 (patch)
tree0ded21b776138d08814336cc12e9c58e45c20ad8 /isl_tab_pip.c
parentd5cbda10655caf8a2b1bbd4532d6c7d78de7d29b (diff)
downloadisl-ec21e6de21d784ee1ba32689aebcbda9f786fd30.tar.gz
isl-ec21e6de21d784ee1ba32689aebcbda9f786fd30.tar.bz2
isl-ec21e6de21d784ee1ba32689aebcbda9f786fd30.zip
isl_tab: improved error handling
Diffstat (limited to 'isl_tab_pip.c')
-rw-r--r--isl_tab_pip.c125
1 files changed, 85 insertions, 40 deletions
diff --git a/isl_tab_pip.c b/isl_tab_pip.c
index 7f7db31f..9f840f04 100644
--- a/isl_tab_pip.c
+++ b/isl_tab_pip.c
@@ -796,6 +796,7 @@ static int first_neg(struct isl_tab *tab)
* smallest increment in the sample point. If there is no such column
* then the tableau is infeasible.
*/
+static struct isl_tab *restore_lexmin(struct isl_tab *tab);
static struct isl_tab *restore_lexmin(struct isl_tab *tab)
{
int row, col;
@@ -810,7 +811,8 @@ static struct isl_tab *restore_lexmin(struct isl_tab *tab)
return isl_tab_mark_empty(tab);
if (col < 0)
goto error;
- isl_tab_pivot(tab, row, col);
+ if (isl_tab_pivot(tab, row, col) < 0)
+ goto error;
}
return tab;
error:
@@ -884,16 +886,20 @@ static struct isl_tab *add_lexmin_valid_eq(struct isl_tab *tab, isl_int *eq)
i = last_var_col_or_int_par_col(tab, r);
if (i < 0) {
tab->con[r].is_nonneg = 1;
- isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]);
+ if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0)
+ goto error;
isl_seq_neg(eq, eq, 1 + tab->n_var);
r = isl_tab_add_row(tab, eq);
if (r < 0)
goto error;
tab->con[r].is_nonneg = 1;
- isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]);
+ if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0)
+ goto error;
} else {
- isl_tab_pivot(tab, r, i);
- isl_tab_kill_col(tab, i);
+ if (isl_tab_pivot(tab, r, i) < 0)
+ goto error;
+ if (isl_tab_kill_col(tab, i) < 0)
+ goto error;
tab->n_eq++;
tab = restore_lexmin(tab);
@@ -937,7 +943,8 @@ static struct isl_tab *add_lexmin_eq(struct isl_tab *tab, isl_int *eq)
if (r1 < 0)
goto error;
tab->con[r1].is_nonneg = 1;
- isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r1]);
+ if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r1]) < 0)
+ goto error;
row = tab->con[r1].index;
if (is_constant(tab, row)) {
@@ -959,35 +966,42 @@ static struct isl_tab *add_lexmin_eq(struct isl_tab *tab, isl_int *eq)
if (r2 < 0)
goto error;
tab->con[r2].is_nonneg = 1;
- isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r2]);
+ if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r2]) < 0)
+ goto error;
tab = restore_lexmin(tab);
if (!tab || tab->empty)
return tab;
- if (!tab->con[r1].is_row)
- isl_tab_kill_col(tab, tab->con[r1].index);
- else if (!tab->con[r2].is_row)
- isl_tab_kill_col(tab, tab->con[r2].index);
- else if (isl_int_is_zero(tab->mat->row[tab->con[r1].index][1])) {
+ if (!tab->con[r1].is_row) {
+ if (isl_tab_kill_col(tab, tab->con[r1].index) < 0)
+ goto error;
+ } else if (!tab->con[r2].is_row) {
+ if (isl_tab_kill_col(tab, tab->con[r2].index) < 0)
+ goto error;
+ } else if (isl_int_is_zero(tab->mat->row[tab->con[r1].index][1])) {
unsigned off = 2 + tab->M;
int i;
int row = tab->con[r1].index;
i = isl_seq_first_non_zero(tab->mat->row[row]+off+tab->n_dead,
tab->n_col - tab->n_dead);
if (i != -1) {
- isl_tab_pivot(tab, row, tab->n_dead + i);
- isl_tab_kill_col(tab, tab->n_dead + i);
+ if (isl_tab_pivot(tab, row, tab->n_dead + i) < 0)
+ goto error;
+ if (isl_tab_kill_col(tab, tab->n_dead + i) < 0)
+ goto error;
}
}
if (tab->bset) {
tab->bset = isl_basic_set_add_ineq(tab->bset, eq);
- isl_tab_push(tab, isl_tab_undo_bset_ineq);
+ if (isl_tab_push(tab, isl_tab_undo_bset_ineq) < 0)
+ goto error;
isl_seq_neg(eq, eq, 1 + tab->n_var);
tab->bset = isl_basic_set_add_ineq(tab->bset, eq);
isl_seq_neg(eq, eq, 1 + tab->n_var);
- isl_tab_push(tab, isl_tab_undo_bset_ineq);
+ if (isl_tab_push(tab, isl_tab_undo_bset_ineq) < 0)
+ goto error;
if (!tab->bset)
goto error;
}
@@ -1009,7 +1023,8 @@ static struct isl_tab *add_lexmin_ineq(struct isl_tab *tab, isl_int *ineq)
return NULL;
if (tab->bset) {
tab->bset = isl_basic_set_add_ineq(tab->bset, ineq);
- isl_tab_push(tab, isl_tab_undo_bset_ineq);
+ if (isl_tab_push(tab, isl_tab_undo_bset_ineq) < 0)
+ goto error;
if (!tab->bset)
goto error;
}
@@ -1017,16 +1032,19 @@ static struct isl_tab *add_lexmin_ineq(struct isl_tab *tab, isl_int *ineq)
if (r < 0)
goto error;
tab->con[r].is_nonneg = 1;
- isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]);
+ if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0)
+ goto error;
if (isl_tab_row_is_redundant(tab, tab->con[r].index)) {
- isl_tab_mark_redundant(tab, tab->con[r].index);
+ if (isl_tab_mark_redundant(tab, tab->con[r].index) < 0)
+ goto error;
return tab;
}
tab = restore_lexmin(tab);
if (tab && !tab->empty && tab->con[r].is_row &&
isl_tab_row_is_redundant(tab, tab->con[r].index))
- isl_tab_mark_redundant(tab, tab->con[r].index);
+ if (isl_tab_mark_redundant(tab, tab->con[r].index) < 0)
+ goto error;
return tab;
error:
isl_tab_free(tab);
@@ -1173,7 +1191,8 @@ static int add_cut(struct isl_tab *tab, int row)
tab->mat->row[row][off + i], tab->mat->row[row][0]);
tab->con[r].is_nonneg = 1;
- isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]);
+ if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0)
+ return -1;
if (tab->row_sign)
tab->row_sign[tab->con[r].index] = isl_tab_row_neg;
@@ -1293,7 +1312,8 @@ static struct isl_tab *check_integer_feasible(struct isl_tab *tab)
return NULL;
snap = isl_tab_snap(tab);
- isl_tab_push_basis(tab);
+ if (isl_tab_push_basis(tab) < 0)
+ goto error;
tab = cut_to_integer_lexmin(tab);
if (!tab)
@@ -1437,7 +1457,8 @@ static int context_tab_add_div(struct isl_tab *tab, struct isl_vec *div,
if (k < 0)
return -1;
isl_seq_cpy(tab->bset->div[k], div->el, div->size);
- isl_tab_push(tab, isl_tab_undo_bset_div);
+ if (isl_tab_push(tab, isl_tab_undo_bset_div) < 0)
+ return -1;
return k;
}
@@ -1617,7 +1638,8 @@ static int add_parametric_cut(struct isl_tab *tab, int row,
}
tab->con[r].is_nonneg = 1;
- isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]);
+ if (isl_tab_push_var(tab, isl_tab_undo_nonneg, &tab->con[r]) < 0)
+ return -1;
if (tab->row_sign)
tab->row_sign[tab->con[r].index] = isl_tab_row_neg;
@@ -1914,7 +1936,8 @@ static int context_lex_test_ineq(struct isl_context *context, isl_int *ineq)
return -1;
snap = isl_tab_snap(clex->tab);
- isl_tab_push_basis(clex->tab);
+ if (isl_tab_push_basis(clex->tab) < 0)
+ return -1;
clex->tab = add_lexmin_ineq(clex->tab, ineq);
clex->tab = check_integer_feasible(clex->tab);
if (!clex->tab)
@@ -1953,7 +1976,8 @@ static int context_lex_best_split(struct isl_context *context,
int r;
snap = isl_tab_snap(clex->tab);
- isl_tab_push_basis(clex->tab);
+ if (isl_tab_push_basis(clex->tab) < 0)
+ return -1;
r = best_split(tab, clex->tab);
if (isl_tab_rollback(clex->tab, snap) < 0)
@@ -1976,8 +2000,10 @@ static void *context_lex_save(struct isl_context *context)
struct isl_tab_undo *snap;
snap = isl_tab_snap(clex->tab);
- isl_tab_push_basis(clex->tab);
- isl_tab_save_samples(clex->tab);
+ if (isl_tab_push_basis(clex->tab) < 0)
+ return NULL;
+ if (isl_tab_save_samples(clex->tab) < 0)
+ return NULL;
return snap;
}
@@ -2062,7 +2088,8 @@ static struct isl_tab *context_lex_detect_nonnegative_parameters(
struct isl_tab_undo *snap;
snap = isl_tab_snap(clex->tab);
- isl_tab_push_basis(clex->tab);
+ if (isl_tab_push_basis(clex->tab) < 0)
+ goto error;
tab = tab_detect_nonnegative_parameters(tab, clex->tab);
@@ -2601,8 +2628,10 @@ static void propagate_equalities(struct isl_context_gbr *cgbr,
goto error;
continue;
}
- isl_tab_pivot(tab, r, j);
- isl_tab_kill_col(tab, j);
+ if (isl_tab_pivot(tab, r, j) < 0)
+ goto error;
+ if (isl_tab_kill_col(tab, j) < 0)
+ goto error;
tab = restore_lexmin(tab);
}
@@ -2673,7 +2702,8 @@ static int context_gbr_add_div(struct isl_context *context, struct isl_vec *div,
if (k < 0)
return -1;
isl_seq_cpy(cgbr->cone->bset->div[k], div->el, div->size);
- isl_tab_push(cgbr->cone, isl_tab_undo_bset_div);
+ if (isl_tab_push(cgbr->cone, isl_tab_undo_bset_div) < 0)
+ return -1;
}
return context_tab_add_div(cgbr->tab, div, nonneg);
}
@@ -2718,7 +2748,8 @@ static void *context_gbr_save(struct isl_context *context)
return NULL;
snap->tab_snap = isl_tab_snap(cgbr->tab);
- isl_tab_save_samples(cgbr->tab);
+ if (isl_tab_save_samples(cgbr->tab) < 0)
+ goto error;
if (cgbr->shifted)
snap->shifted_snap = isl_tab_snap(cgbr->shifted);
@@ -2731,32 +2762,45 @@ static void *context_gbr_save(struct isl_context *context)
snap->cone_snap = NULL;
return snap;
+error:
+ free(snap);
+ return NULL;
}
static void context_gbr_restore(struct isl_context *context, void *save)
{
struct isl_context_gbr *cgbr = (struct isl_context_gbr *)context;
struct isl_gbr_tab_undo *snap = (struct isl_gbr_tab_undo *)save;
+ if (!snap)
+ goto error;
if (isl_tab_rollback(cgbr->tab, snap->tab_snap) < 0) {
isl_tab_free(cgbr->tab);
cgbr->tab = NULL;
}
- if (snap->shifted_snap)
- isl_tab_rollback(cgbr->shifted, snap->shifted_snap);
- else if (cgbr->shifted) {
+ if (snap->shifted_snap) {
+ if (isl_tab_rollback(cgbr->shifted, snap->shifted_snap) < 0)
+ goto error;
+ } else if (cgbr->shifted) {
isl_tab_free(cgbr->shifted);
cgbr->shifted = NULL;
}
- if (snap->cone_snap)
- isl_tab_rollback(cgbr->cone, snap->cone_snap);
- else if (cgbr->cone) {
+ if (snap->cone_snap) {
+ if (isl_tab_rollback(cgbr->cone, snap->cone_snap) < 0)
+ goto error;
+ } else if (cgbr->cone) {
isl_tab_free(cgbr->cone);
cgbr->cone = NULL;
}
free(snap);
+
+ return;
+error:
+ free(snap);
+ isl_tab_free(cgbr->tab);
+ cgbr->tab = NULL;
}
static int context_gbr_is_ok(struct isl_context *context)
@@ -3379,7 +3423,8 @@ static struct isl_sol *find_solutions_main(struct isl_sol *sol,
isl_vec_free(eq);
- isl_tab_mark_redundant(tab, row);
+ if (isl_tab_mark_redundant(tab, row) < 0)
+ goto error;
if (sol->context->op->is_empty(sol->context))
break;