#include <isl_ast_private.h>
#include <isl_ast_build_private.h>
-/* Compute the minimum of the integer affine expression "obj" over the points
- * in build->domain and put the result in *opt.
- */
-enum isl_lp_result isl_ast_build_min(__isl_keep isl_ast_build *build,
- __isl_keep isl_aff *obj, isl_int *opt)
-{
- if (!build)
- return isl_lp_error;
-
- return isl_set_min(build->domain, obj, opt);
-}
-
-/* Compute the maximum of the integer affine expression "obj" over the points
- * in build->domain and put the result in *opt.
- */
-enum isl_lp_result isl_ast_build_max(__isl_keep isl_ast_build *build,
- __isl_keep isl_aff *obj, isl_int *opt)
-{
- if (!build)
- return isl_lp_error;
-
- return isl_set_max(build->domain, obj, opt);
-}
-
/* Compute the "opposite" of the (numerator of the) argument of a div
* with denonimator "d".
*
}
}
- isl_aff_get_constant(aff, &v);
- if (sign * isl_int_sgn(v) > 0) {
- isl_int_abs(v, v);
- expr = isl_ast_expr_add_int(expr, v);
- }
-
isl_local_space_free(ls);
isl_int_clear(v);
return expr;
}
+/* Should the constant term "v" be considered positive?
+ *
+ * A positive constant will be added to "pos" by the caller,
+ * while a negative constant will be added to "neg".
+ * If either "pos" or "neg" is exactly zero, then we prefer
+ * to add the constant "v" to that side, irrespective of the sign of "v".
+ * This results in slightly shorter expressions and may reduce the risk
+ * of overflows.
+ */
+static int constant_is_considered_positive(isl_int v,
+ __isl_keep isl_ast_expr *pos, __isl_keep isl_ast_expr *neg)
+{
+ if (ast_expr_is_zero(pos))
+ return 1;
+ if (ast_expr_is_zero(neg))
+ return 0;
+ return isl_int_is_pos(v);
+}
+
/* Construct an isl_ast_expr that evaluates the condition "constraint",
* The result is simplified in terms of build->domain.
*
* However, if the first expression is an integer constant (and the second
* is not), then we swap the two expressions. This ensures that we construct,
* e.g., "i <= 5" rather than "5 >= i".
+ *
+ * Furthermore, is there are no terms with positive coefficients (or no terms
+ * with negative coefficients), then the constant term is added to "pos"
+ * (or "neg"), ignoring the sign of the constant term.
*/
static __isl_give isl_ast_expr *isl_ast_expr_from_constraint(
__isl_take isl_constraint *constraint, __isl_keep isl_ast_build *build)
isl_ast_expr *expr_neg;
isl_ast_expr *expr;
isl_aff *aff;
+ isl_int v;
int eq;
enum isl_ast_op_type type;
expr_pos = add_signed_terms(expr_pos, aff, 1, build);
expr_neg = add_signed_terms(expr_neg, aff, -1, build);
+ isl_int_init(v);
+ isl_aff_get_constant(aff, &v);
+ if (constant_is_considered_positive(v, expr_pos, expr_neg)) {
+ expr_pos = isl_ast_expr_add_int(expr_pos, v);
+ } else {
+ isl_int_neg(v, v);
+ expr_neg = isl_ast_expr_add_int(expr_neg, v);
+ }
+ isl_int_clear(v);
+
eq = isl_constraint_is_equality(constraint);
if (isl_ast_expr_get_type(expr_pos) == isl_ast_expr_int &&