diff options
Diffstat (limited to 'polly/lib/External/isl/isl_output.c')
| -rw-r--r-- | polly/lib/External/isl/isl_output.c | 223 |
1 files changed, 185 insertions, 38 deletions
diff --git a/polly/lib/External/isl/isl_output.c b/polly/lib/External/isl/isl_output.c index 93442a95201..4888bae1ecb 100644 --- a/polly/lib/External/isl/isl_output.c +++ b/polly/lib/External/isl/isl_output.c @@ -35,6 +35,7 @@ #include <bset_to_bmap.c> #include <set_to_map.c> +#include <uset_to_umap.c> static const char *s_to[2] = { " -> ", " \\to " }; static const char *s_and[2] = { " and ", " \\wedge " }; @@ -49,6 +50,7 @@ static const char *s_such_that[2] = { " : ", " \\mid " }; static const char *s_open_exists[2] = { "exists (", "\\exists \\, " }; static const char *s_close_exists[2] = { ")", "" }; static const char *s_div_prefix[2] = { "e", "\\alpha_" }; +static const char *s_mod[2] = { "mod", "\\bmod" }; static const char *s_param_prefix[2] = { "p", "p_" }; static const char *s_input_prefix[2] = { "i", "i_" }; static const char *s_output_prefix[2] = { "o", "o_" }; @@ -316,15 +318,20 @@ static __isl_give isl_printer *print_affine_of_len(__isl_keep isl_space *dim, return p; } -/* Print an affine expression "c" corresponding to a constraint in "bmap" +/* Print an affine expression "c" * to "p", with the variable names taken from "space" and * the integer division definitions taken from "div". */ -static __isl_give isl_printer *print_affine(__isl_keep isl_basic_map *bmap, - __isl_keep isl_space *space, __isl_keep isl_mat *div, - __isl_take isl_printer *p, isl_int *c) +static __isl_give isl_printer *print_affine(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_mat *div, isl_int *c) { - unsigned len = 1 + isl_basic_map_total_dim(bmap); + unsigned n_div; + unsigned len; + + if (!space || !div) + return isl_printer_free(p); + n_div = isl_mat_rows(div); + len = 1 + isl_space_dim(space, isl_dim_all) + n_div; return print_affine_of_len(space, div, p, c, len); } @@ -493,7 +500,7 @@ static const char *constraint_op(int sign, int strict, int latex) return s_ge[latex]; } -/* Print one side of a constraint "c" from "bmap" to "p", with +/* Print one side of a constraint "c" to "p", with * the variable names taken from "space" and the integer division definitions * taken from "div". * "last" is the position of the last non-zero coefficient. @@ -503,20 +510,13 @@ static const char *constraint_op(int sign, int strict, int latex) * c' op * * is printed. - * "first_constraint" is set if this is the first constraint - * in the conjunction. */ -static __isl_give isl_printer *print_half_constraint( - __isl_keep isl_basic_map *bmap, +static __isl_give isl_printer *print_half_constraint(__isl_take isl_printer *p, __isl_keep isl_space *space, __isl_keep isl_mat *div, - __isl_take isl_printer *p, isl_int *c, int last, const char *op, - int first_constraint, int latex) + isl_int *c, int last, const char *op, int latex) { - if (!first_constraint) - p = isl_printer_print_str(p, s_and[latex]); - isl_int_set_si(c[last], 0); - p = print_affine(bmap, space, div, p, c); + p = print_affine(p, space, div, c); p = isl_printer_print_str(p, " "); p = isl_printer_print_str(p, op); @@ -525,7 +525,7 @@ static __isl_give isl_printer *print_half_constraint( return p; } -/* Print a constraint "c" from "bmap" to "p", with the variable names +/* Print a constraint "c" to "p", with the variable names * taken from "space" and the integer division definitions taken from "div". * "last" is the position of the last non-zero coefficient, which is * moreover assumed to be negative. @@ -533,18 +533,11 @@ static __isl_give isl_printer *print_half_constraint( * the constraint is printed in the form * * -c[last] op c' - * - * "first_constraint" is set if this is the first constraint - * in the conjunction. */ -static __isl_give isl_printer *print_constraint(__isl_keep isl_basic_map *bmap, +static __isl_give isl_printer *print_constraint(__isl_take isl_printer *p, __isl_keep isl_space *space, __isl_keep isl_mat *div, - __isl_take isl_printer *p, - isl_int *c, int last, const char *op, int first_constraint, int latex) + isl_int *c, int last, const char *op, int latex) { - if (!first_constraint) - p = isl_printer_print_str(p, s_and[latex]); - isl_int_abs(c[last], c[last]); p = print_term(space, div, c[last], last, p, latex); @@ -554,11 +547,147 @@ static __isl_give isl_printer *print_constraint(__isl_keep isl_basic_map *bmap, p = isl_printer_print_str(p, " "); isl_int_set_si(c[last], 0); - p = print_affine(bmap, space, div, p, c); + p = print_affine(p, space, div, c); return p; } +/* Given an integer division + * + * floor(f/m) + * + * at position "pos" in "div", print the corresponding modulo expression + * + * (f) mod m + * + * to "p". The variable names are taken from "space", while any + * nested integer division definitions are taken from "div". + */ +static __isl_give isl_printer *print_mod(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_mat *div, int pos, + int latex) +{ + if (!p || !div) + return isl_printer_free(p); + + p = isl_printer_print_str(p, "("); + p = print_affine_of_len(space, div, p, + div->row[pos] + 1, div->n_col - 1); + p = isl_printer_print_str(p, ") "); + p = isl_printer_print_str(p, s_mod[latex]); + p = isl_printer_print_str(p, " "); + p = isl_printer_print_isl_int(p, div->row[pos][0]); + return p; +} + +/* Can the equality constraints "c" be printed as a modulo constraint? + * In particular, is of the form + * + * f - a m floor(g/m) = 0, + * + * with c = -a m the coefficient at position "pos"? + * Return the position of the corresponding integer division if so. + * Return the number of integer divisions if not. + * Return -1 on error. + * + * Modulo constraints are currently not printed in C format. + * Other than that, "pos" needs to correspond to an integer division + * with explicit representation and "c" needs to be a multiple + * of the denominator of the integer division. + */ +static int print_as_modulo_pos(__isl_keep isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_mat *div, unsigned pos, + isl_int c) +{ + isl_bool can_print; + unsigned n_div; + enum isl_dim_type type; + + if (!p) + return -1; + n_div = isl_mat_rows(div); + if (p->output_format == ISL_FORMAT_C) + return n_div; + type = pos2type(space, &pos); + if (type != isl_dim_div) + return n_div; + can_print = can_print_div_expr(p, div, pos); + if (can_print < 0) + return -1; + if (!can_print) + return n_div; + if (!isl_int_is_divisible_by(c, div->row[pos][0])) + return n_div; + return pos; +} + +/* Print equality constraint "c" to "p" as a modulo constraint, + * with the variable names taken from "space" and + * the integer division definitions taken from "div". + * "last" is the position of the last non-zero coefficient, which is + * moreover assumed to be negative and a multiple of the denominator + * of the corresponding integer division. "div_pos" is the corresponding + * position in the sequence of integer divisions. + * + * The equality is of the form + * + * f - a m floor(g/m) = 0. + * + * Print it as + * + * a (g mod m) = -f + a g + */ +static __isl_give isl_printer *print_eq_mod_constraint( + __isl_take isl_printer *p, __isl_keep isl_space *space, + __isl_keep isl_mat *div, unsigned div_pos, + isl_int *c, int last, int latex) +{ + isl_ctx *ctx; + int multiple; + + ctx = isl_printer_get_ctx(p); + isl_int_divexact(c[last], c[last], div->row[div_pos][0]); + isl_int_abs(c[last], c[last]); + multiple = !isl_int_is_one(c[last]); + if (multiple) { + p = isl_printer_print_isl_int(p, c[last]); + p = isl_printer_print_str(p, "*("); + } + p = print_mod(p, space, div, div_pos, latex); + if (multiple) + p = isl_printer_print_str(p, ")"); + p = isl_printer_print_str(p, " = "); + isl_seq_combine(c, ctx->negone, c, + c[last], div->row[div_pos] + 1, last); + isl_int_set_si(c[last], 0); + p = print_affine(p, space, div, c); + return p; +} + +/* Print equality constraint "c" to "p", with the variable names + * taken from "space" and the integer division definitions taken from "div". + * "last" is the position of the last non-zero coefficient, which is + * moreover assumed to be negative. + * + * If possible, print the equality constraint as a modulo constraint. + */ +static __isl_give isl_printer *print_eq_constraint(__isl_take isl_printer *p, + __isl_keep isl_space *space, __isl_keep isl_mat *div, isl_int *c, + int last, int latex) +{ + unsigned n_div; + int div_pos; + + n_div = isl_mat_rows(div); + div_pos = print_as_modulo_pos(p, space, div, last, c[last]); + if (div_pos < 0) + return isl_printer_free(p); + if (div_pos < n_div) + return print_eq_mod_constraint(p, space, div, div_pos, + c, last, latex); + return print_constraint(p, space, div, c, last, "=", latex); +} + /* Print the constraints of "bmap" to "p". * The names of the variables are taken from "space" and * the integer division definitions are taken from "div". @@ -632,12 +761,13 @@ static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap, p = isl_printer_print_str(p, "0 = 0"); continue; } + if (!first) + p = isl_printer_print_str(p, s_and[latex]); if (isl_int_is_neg(bmap->eq[i][l])) isl_seq_cpy(c->el, bmap->eq[i], 1 + total); else isl_seq_neg(c->el, bmap->eq[i], 1 + total); - p = print_constraint(bmap, space, div, p, c->el, l, - "=", first, latex); + p = print_eq_constraint(p, space, div, c->el, l, latex); first = 0; } for (i = 0; i < bmap->n_ineq; ++i) { @@ -657,6 +787,8 @@ static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap, if (is_div) continue; } + if (!first) + p = isl_printer_print_str(p, s_and[latex]); s = isl_int_sgn(bmap->ineq[i][l]); strict = !rational && isl_int_is_negone(bmap->ineq[i][0]); if (s < 0) @@ -667,13 +799,13 @@ static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap, isl_int_set_si(c->el[0], 0); if (!dump && next_is_opposite(bmap, i, l)) { op = constraint_op(-s, strict, latex); - p = print_half_constraint(bmap, space, div, p, c->el, l, - op, first, latex); + p = print_half_constraint(p, space, div, c->el, l, + op, latex); first = 1; } else { op = constraint_op(s, strict, latex); - p = print_constraint(bmap, space, div, p, c->el, l, - op, first, latex); + p = print_constraint(p, space, div, c->el, l, + op, latex); first = 0; } } @@ -787,6 +919,21 @@ static __isl_give isl_printer *open_exists(__isl_take isl_printer *p, return p; } +/* Remove the explicit representations of all local variables in "div". + */ +static __isl_give isl_mat *mark_all_unknown(__isl_take isl_mat *div) +{ + int i, n_div; + + if (!div) + return NULL; + + n_div = isl_mat_rows(div); + for (i = 0; i < n_div; ++i) + div = isl_mat_set_element_si(div, i, 0, 0); + return div; +} + /* Print the constraints of "bmap" to "p". * The names of the variables are taken from "space". * "latex" is set if the constraints should be printed in LaTeX format. @@ -808,7 +955,7 @@ static __isl_give isl_printer *print_disjunct(__isl_keep isl_basic_map *bmap, p = open_exists(p, space, div, latex); if (dump) - div = isl_mat_free(div); + div = mark_all_unknown(div); p = print_constraints(bmap, space, div, p, latex); isl_mat_free(div); @@ -928,7 +1075,7 @@ static __isl_give isl_printer *print_disjuncts_core(__isl_keep isl_map *map, int i; if (map->n == 0) - p = isl_printer_print_str(p, "1 = 0"); + p = isl_printer_print_str(p, "false"); for (i = 0; i < map->n; ++i) { if (i) p = isl_printer_print_str(p, s_or[latex]); @@ -1488,9 +1635,9 @@ __isl_give isl_printer *isl_printer_print_union_set(__isl_take isl_printer *p, goto error; if (p->output_format == ISL_FORMAT_ISL) - return isl_union_map_print_isl((isl_union_map *)uset, p); + return isl_union_map_print_isl(uset_to_umap(uset), p); if (p->output_format == ISL_FORMAT_LATEX) - return isl_union_map_print_latex((isl_union_map *)uset, p); + return isl_union_map_print_latex(uset_to_umap(uset), p); isl_die(p->ctx, isl_error_invalid, "invalid output format for isl_union_set", goto error); @@ -2985,7 +3132,7 @@ static __isl_give isl_printer *print_dim_mpa(__isl_take isl_printer *p, pa = mpa->p[pos]; if (pa->n == 0) - return isl_printer_print_str(p, "(0 : 1 = 0)"); + return isl_printer_print_str(p, "(0 : false)"); need_parens = pa->n != 1 || !isl_set_plain_is_universe(pa->p[0].set); if (need_parens) |

