X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=isl_tab_pip.c;h=dd95d885e1431b122fc029a0e9154ba9a790d170;hb=fdf9c99e27483b8c1c4938072119cd8b7c2a4a37;hp=476433440b92f7a2196dea32c20609dcc378c697;hpb=8f52ea51fa97d17c112722a67109410eef78bd93;p=platform%2Fupstream%2Fisl.git diff --git a/isl_tab_pip.c b/isl_tab_pip.c index 4764334..dd95d88 100644 --- a/isl_tab_pip.c +++ b/isl_tab_pip.c @@ -745,6 +745,30 @@ static struct isl_vec *get_row_parameter_ineq(struct isl_tab *tab, int row) return ineq; } +/* Normalize a div expression of the form + * + * [(g*f(x) + c)/(g * m)] + * + * with c the constant term and f(x) the remaining coefficients, to + * + * [(f(x) + [c/g])/m] + */ +static void normalize_div(__isl_keep isl_vec *div) +{ + isl_ctx *ctx = isl_vec_get_ctx(div); + int len = div->size - 2; + + isl_seq_gcd(div->el + 2, len, &ctx->normalize_gcd); + isl_int_gcd(ctx->normalize_gcd, ctx->normalize_gcd, div->el[0]); + + if (isl_int_is_one(ctx->normalize_gcd)) + return; + + isl_int_divexact(div->el[0], div->el[0], ctx->normalize_gcd); + isl_int_fdiv_q(div->el[1], div->el[1], ctx->normalize_gcd); + isl_seq_scale_down(div->el + 2, div->el + 2, ctx->normalize_gcd, len); +} + /* Return a integer division for use in a parametric cut based on the given row. * In particular, let the parametric constant of the row be * @@ -765,8 +789,8 @@ static struct isl_vec *get_row_parameter_div(struct isl_tab *tab, int row) isl_int_set(div->el[0], tab->mat->row[row][0]); get_row_parameter_line(tab, row, div->el + 1); - div = isl_vec_normalize(div); isl_seq_neg(div->el + 1, div->el + 1, div->size - 1); + normalize_div(div); isl_seq_fdiv_r(div->el + 1, div->el + 1, div->el[0], div->size - 1); return div; @@ -793,7 +817,7 @@ static struct isl_vec *get_row_split_div(struct isl_tab *tab, int row) isl_int_set(div->el[0], tab->mat->row[row][0]); get_row_parameter_line(tab, row, div->el + 1); - div = isl_vec_normalize(div); + normalize_div(div); isl_seq_fdiv_r(div->el + 1, div->el + 1, div->el[0], div->size - 1); return div; @@ -1153,8 +1177,8 @@ static int report_conflicting_constraint(struct isl_tab *tab, int con) /* Given a conflicting row in the tableau, report all constraints * involved in the row to the caller. That is, the row itself - * (if represents a constraint) and all constraint columns with - * non-zero (and therefore negative) coefficient. + * (if it represents a constraint) and all constraint columns with + * non-zero (and therefore negative) coefficients. */ static int report_conflict(struct isl_tab *tab, int row) { @@ -1606,6 +1630,9 @@ static int add_cut(struct isl_tab *tab, int row) return tab->con[r].index; } +#define CUT_ALL 1 +#define CUT_ONE 0 + /* Given a non-parametric tableau, add cuts until an integer * sample point is obtained or until the tableau is determined * to be integer infeasible. @@ -1617,8 +1644,12 @@ static int add_cut(struct isl_tab *tab, int row) * combination of variables/constraints plus a non-integral constant, * then there is no way to obtain an integer point and we return * a tableau that is marked empty. + * The parameter cutting_strategy controls the strategy used when adding cuts + * to remove non-integer points. CUT_ALL adds all possible cuts + * before continuing the search. CUT_ONE adds only one cut at a time. */ -static struct isl_tab *cut_to_integer_lexmin(struct isl_tab *tab) +static struct isl_tab *cut_to_integer_lexmin(struct isl_tab *tab, + int cutting_strategy) { int var; int row; @@ -1640,6 +1671,8 @@ static struct isl_tab *cut_to_integer_lexmin(struct isl_tab *tab) row = add_cut(tab, row); if (row < 0) goto error; + if (cutting_strategy == CUT_ONE) + break; } while ((var = next_non_integer_var(tab, var, &flags)) != -1); if (restore_lexmin(tab) < 0) goto error; @@ -1730,7 +1763,7 @@ static struct isl_tab *check_integer_feasible(struct isl_tab *tab) if (isl_tab_push_basis(tab) < 0) goto error; - tab = cut_to_integer_lexmin(tab); + tab = cut_to_integer_lexmin(tab, CUT_ALL); if (!tab) goto error; @@ -4958,7 +4991,7 @@ __isl_give isl_vec *isl_tab_basic_set_non_trivial_lexmin( int side, base; if (init) { - tab = cut_to_integer_lexmin(tab); + tab = cut_to_integer_lexmin(tab, CUT_ONE); if (!tab) goto error; if (tab->empty)