summaryrefslogtreecommitdiff
path: root/isl_tab.c
diff options
context:
space:
mode:
authorSven Verdoolaege <skimo@kotnet.org>2009-07-23 18:15:17 +0200
committerSven Verdoolaege <skimo@kotnet.org>2009-08-04 19:26:36 +0200
commit35d050172ce3e402c0d95ac6044a311c16cbeda4 (patch)
tree248af6ab148a8a171c4980fa4d23cf8b93aa2b88 /isl_tab.c
parentb6552f15e4d9705858596ae6bcf34c6ce70678e8 (diff)
downloadisl-35d050172ce3e402c0d95ac6044a311c16cbeda4.tar.gz
isl-35d050172ce3e402c0d95ac6044a311c16cbeda4.tar.bz2
isl-35d050172ce3e402c0d95ac6044a311c16cbeda4.zip
isl_tab.c: to_row: allow pivoting in arbitrary direction
While undoing the allocation of a row, we may be dealing with a row that was unbounded in both directions and is now in a column. To move the column back to a row, we just pivot using any non-zero entry.
Diffstat (limited to 'isl_tab.c')
-rw-r--r--isl_tab.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/isl_tab.c b/isl_tab.c
index 4e759e60..3f6d5d13 100644
--- a/isl_tab.c
+++ b/isl_tab.c
@@ -494,6 +494,8 @@ static void pivot(struct isl_tab *tab, int row, int col)
/* If "var" represents a column variable, then pivot is up (sgn > 0)
* or down (sgn < 0) to a row. The variable is assumed not to be
* unbounded in the specified direction.
+ * If sgn = 0, then the variable is unbounded in both directions,
+ * and we pivot with any row we can find.
*/
static void to_row(struct isl_tab *tab, struct isl_tab_var *var, int sign)
{
@@ -502,8 +504,16 @@ static void to_row(struct isl_tab *tab, struct isl_tab_var *var, int sign)
if (var->is_row)
return;
- r = pivot_row(tab, NULL, sign, var->index);
- isl_assert(tab->mat->ctx, r >= 0, return);
+ if (sign == 0) {
+ for (r = tab->n_redundant; r < tab->n_row; ++r)
+ if (!isl_int_is_zero(tab->mat->row[r][2 + var->index]))
+ break;
+ isl_assert(tab->mat->ctx, r < tab->n_row, return);
+ } else {
+ r = pivot_row(tab, NULL, sign, var->index);
+ isl_assert(tab->mat->ctx, r >= 0, return);
+ }
+
pivot(tab, r, var->index);
}
@@ -1668,10 +1678,12 @@ static void perform_undo(struct isl_tab *tab, struct isl_tab_undo *undo)
break;
case isl_tab_undo_allocate:
if (!undo->var->is_row) {
- if (max_is_manifestly_unbounded(tab, undo->var))
+ if (!max_is_manifestly_unbounded(tab, undo->var))
+ to_row(tab, undo->var, 1);
+ else if (!min_is_manifestly_unbounded(tab, undo->var))
to_row(tab, undo->var, -1);
else
- to_row(tab, undo->var, 1);
+ to_row(tab, undo->var, 0);
}
drop_row(tab, undo->var->index);
break;