return 1;
}
+/* Would an expression for div "div" based on inequality "ineq" of "bmap"
+ * be a better expression than the current one?
+ *
+ * If we do not have any expression yet, then any expression would be better.
+ * Otherwise we check if the last variable involved in the inequality
+ * (disregarding the div that it would define) is in an earlier position
+ * than the last variable involved in the current div expression.
+ */
+static int better_div_constraint(__isl_keep isl_basic_map *bmap,
+ int div, int ineq)
+{
+ unsigned total = 1 + isl_space_dim(bmap->dim, isl_dim_all);
+ int last_div;
+ int last_ineq;
+
+ if (isl_int_is_zero(bmap->div[div][0]))
+ return 1;
+
+ if (isl_seq_last_non_zero(bmap->ineq[ineq] + total + div + 1,
+ bmap->n_div - (div + 1)) >= 0)
+ return 0;
+
+ last_ineq = isl_seq_last_non_zero(bmap->ineq[ineq], total + div);
+ last_div = isl_seq_last_non_zero(bmap->div[div] + 1,
+ total + bmap->n_div);
+
+ return last_ineq < last_div;
+}
+
/* Given two constraints "k" and "l" that are opposite to each other,
* except for the constant term, check if we can use them
- * to obtain an expression for one of the hitherto unknown divs.
+ * to obtain an expression for one of the hitherto unknown divs or
+ * a "better" expression for a div for which we already have an expression.
* "sum" is the sum of the constant terms of the constraints.
* If this sum is strictly smaller than the coefficient of one
* of the divs, then this pair can be used define the div.
unsigned total = 1 + isl_space_dim(bmap->dim, isl_dim_all);
for (i = 0; i < bmap->n_div; ++i) {
- if (!isl_int_is_zero(bmap->div[i][0]))
- continue;
if (isl_int_is_zero(bmap->ineq[k][total + i]))
continue;
if (isl_int_abs_ge(sum, bmap->ineq[k][total + i]))
continue;
+ if (!better_div_constraint(bmap, i, k))
+ continue;
if (!ok_to_set_div_from_bound(bmap, i, k))
break;
if (isl_int_is_pos(bmap->ineq[k][total + i]))
return 0;
}
- for (i = 0; i < bmap->n_div; ++i)
+ for (i = 0; i < bmap->n_div; ++i) {
+ if (isl_int_is_zero(bmap->div[i][0]))
+ continue;
if (!isl_int_is_zero(bmap->div[i][1+pos]))
return 0;
+ }
return 1;
}
for (i = 0; i < context->n_eq; ++i) {
int k;
k = isl_basic_map_alloc_equality(bmap);
+ if (k < 0)
+ return isl_basic_map_free(bmap);
isl_seq_cpy(bmap->eq[k], context->eq[i], 1 + total_context);
isl_seq_clr(bmap->eq[k] + 1 + total_context,
isl_basic_map_total_dim(bmap) - total_context);
bmap = isl_basic_map_remove_redundancies(bmap);
context = isl_basic_map_remove_redundancies(context);
+ if (!context)
+ goto error;
if (context->n_eq)
bmap = normalize_divs_in_context(bmap, context);
map = isl_map_compute_divs(map);
if (!map)
goto error;
- for (i = 0; i < map->n; ++i)
- context = isl_basic_map_align_divs(context, map->p[i]);
for (i = map->n - 1; i >= 0; --i) {
map->p[i] = isl_basic_map_gist(map->p[i],
isl_basic_map_copy(context));