if (isl_ast_build_has_stride(build, pos)) {
isl_aff *offset;
- isl_int stride;
-
- isl_int_init(stride);
+ isl_val *stride;
offset = isl_ast_build_get_offset(build, pos);
- isl_ast_build_get_stride(build, pos, &stride);
+ stride = isl_ast_build_get_stride(build, pos);
aff = isl_aff_sub(aff, isl_aff_copy(offset));
- aff = isl_aff_scale_down(aff, stride);
+ aff = isl_aff_scale_down_val(aff, isl_val_copy(stride));
aff = isl_aff_ceil(aff);
- aff = isl_aff_scale(aff, stride);
+ aff = isl_aff_scale_val(aff, stride);
aff = isl_aff_add(aff, offset);
-
- isl_int_clear(stride);
}
aff = isl_ast_build_compute_gist_aff(build, aff);
static __isl_give isl_ast_expr *for_inc(__isl_keep isl_ast_build *build)
{
int depth;
- isl_int v;
+ isl_val *v;
isl_ctx *ctx;
- isl_ast_expr *inc;
if (!build)
return NULL;
if (!isl_ast_build_has_stride(build, depth))
return isl_ast_expr_alloc_int_si(ctx, 1);
- isl_int_init(v);
- isl_ast_build_get_stride(build, depth, &v);
- inc = isl_ast_expr_alloc_int(ctx, v);
- isl_int_clear(v);
-
- return inc;
+ v = isl_ast_build_get_stride(build, depth);
+ return isl_ast_expr_from_val(v);
}
/* Should we express the loop condition as
* are multiples of "m", reducing "m" if they are not.
* If "m" is reduced all the way down to "1", then the check has failed
* and we break out of the iteration.
- * "d" is an initialized isl_int that can be used internally.
*/
struct isl_check_scaled_data {
int depth;
- isl_int m, d;
+ isl_val *m;
};
/* If constraint "c" involves the input dimension data->depth,
for (i = 0; i < 4; ++i) {
n = isl_constraint_dim(c, t[i]);
for (j = 0; j < n; ++j) {
+ isl_val *d;
+
if (t[i] == isl_dim_in && j == data->depth)
continue;
if (!isl_constraint_involves_dims(c, t[i], j, 1))
continue;
- isl_constraint_get_coefficient(c, t[i], j, &data->d);
- isl_int_gcd(data->m, data->m, data->d);
- if (isl_int_is_one(data->m))
+ d = isl_constraint_get_coefficient_val(c, t[i], j);
+ data->m = isl_val_gcd(data->m, d);
+ if (isl_val_is_one(data->m))
break;
}
if (j < n)
struct isl_check_scaled_data data;
isl_ctx *ctx;
isl_aff *offset;
+ isl_val *d;
ctx = isl_ast_build_get_ctx(build);
if (!isl_options_get_ast_build_scale_strides(ctx))
if (!isl_ast_build_has_stride(build, data.depth))
return create_node_scaled(executed, bounds, domain, build);
- isl_int_init(data.m);
- isl_int_init(data.d);
-
offset = isl_ast_build_get_offset(build, data.depth);
- if (isl_ast_build_get_stride(build, data.depth, &data.m) < 0)
+ data.m = isl_ast_build_get_stride(build, data.depth);
+ if (!data.m)
offset = isl_aff_free(offset);
- offset = isl_aff_scale_down(offset, data.m);
- if (isl_aff_get_denominator(offset, &data.d) < 0)
+ offset = isl_aff_scale_down_val(offset, isl_val_copy(data.m));
+ d = isl_aff_get_denominator_val(offset);
+ if (!d)
executed = isl_union_map_free(executed);
- if (executed && isl_int_is_divisible_by(data.m, data.d))
- isl_int_divexact(data.m, data.m, data.d);
- else
- isl_int_set_si(data.m, 1);
+ if (executed && isl_val_is_divisible_by(data.m, d))
+ data.m = isl_val_div(data.m, d);
+ else {
+ data.m = isl_val_set_si(data.m, 1);
+ isl_val_free(d);
+ }
- if (!isl_int_is_one(data.m)) {
+ if (!isl_val_is_one(data.m)) {
if (isl_union_map_foreach_map(executed, &map_check_scaled,
&data) < 0 &&
- !isl_int_is_one(data.m))
+ !isl_val_is_one(data.m))
executed = isl_union_map_free(executed);
}
- if (!isl_int_is_one(data.m)) {
+ if (!isl_val_is_one(data.m)) {
isl_space *space;
isl_multi_aff *ma;
isl_aff *aff;
space = isl_space_map_from_set(space);
ma = isl_multi_aff_identity(space);
aff = isl_multi_aff_get_aff(ma, data.depth);
- aff = isl_aff_scale(aff, data.m);
+ aff = isl_aff_scale_val(aff, isl_val_copy(data.m));
ma = isl_multi_aff_set_aff(ma, data.depth, aff);
bounds = isl_basic_set_preimage_multi_aff(bounds,
umap = isl_union_map_from_map(map);
executed = isl_union_map_apply_domain(executed,
isl_union_map_copy(umap));
- build = isl_ast_build_scale_down(build, data.m, umap);
+ build = isl_ast_build_scale_down(build, isl_val_copy(data.m),
+ umap);
}
isl_aff_free(offset);
-
- isl_int_clear(data.d);
- isl_int_clear(data.m);
+ isl_val_free(data.m);
return create_node_scaled(executed, bounds, domain, build);
}
return empty < 0 ? -1 : !empty;
}
+/* Split up each element of "list" into a part that is related to "bset"
+ * according to "gt" and a part that is not.
+ * Return a list that consist of "bset" and all the pieces.
+ */
+static __isl_give isl_basic_set_list *add_split_on(
+ __isl_take isl_basic_set_list *list, __isl_take isl_basic_set *bset,
+ __isl_keep isl_basic_map *gt)
+{
+ int i, n;
+ isl_basic_set_list *res;
+
+ gt = isl_basic_map_copy(gt);
+ gt = isl_basic_map_intersect_domain(gt, isl_basic_set_copy(bset));
+ n = isl_basic_set_list_n_basic_set(list);
+ res = isl_basic_set_list_from_basic_set(bset);
+ for (i = 0; res && i < n; ++i) {
+ isl_basic_set *bset;
+ isl_set *set1, *set2;
+ isl_basic_map *bmap;
+ int empty;
+
+ bset = isl_basic_set_list_get_basic_set(list, i);
+ bmap = isl_basic_map_copy(gt);
+ bmap = isl_basic_map_intersect_range(bmap, bset);
+ bset = isl_basic_map_range(bmap);
+ empty = isl_basic_set_is_empty(bset);
+ if (empty < 0)
+ res = isl_basic_set_list_free(res);
+ if (empty) {
+ isl_basic_set_free(bset);
+ bset = isl_basic_set_list_get_basic_set(list, i);
+ res = isl_basic_set_list_add(res, bset);
+ continue;
+ }
+
+ res = isl_basic_set_list_add(res, isl_basic_set_copy(bset));
+ set1 = isl_set_from_basic_set(bset);
+ bset = isl_basic_set_list_get_basic_set(list, i);
+ set2 = isl_set_from_basic_set(bset);
+ set1 = isl_set_subtract(set2, set1);
+ set1 = isl_set_make_disjoint(set1);
+
+ res = isl_basic_set_list_concat(res,
+ isl_basic_set_list_from_set(set1));
+ }
+ isl_basic_map_free(gt);
+ isl_basic_set_list_free(list);
+ return res;
+}
+
static __isl_give isl_ast_graft_list *generate_sorted_domains(
__isl_keep isl_basic_set_list *domain_list,
__isl_keep isl_union_map *executed,
* This may happen in particular in case of unrolling since the domain
* of each slice is replaced by its simple hull.
*
- * We collect the basic sets in the component, call isl_set_make_disjoint
- * and try again. Note that we rely here on isl_set_make_disjoint also
- * making the basic sets rationally disjoint. If the basic sets
- * are rationally disjoint, then the ordering problem does not occur.
- * To see this, there can only be a problem if there are points
- * (i,a) and (j,b) in one set and (i,c) and (j,d) in the other with
- * a < c and b > d. This means that either the interval spanned
- * by a en b lies inside that spanned by c and or the other way around.
- * In either case, there is a point inside both intervals with the
- * convex combination in terms of a and b and in terms of c and d.
- * Taking the same combination of i and j gives a point in the intersection.
+ * For each basic set i in "scc" and for each of the following basic sets j,
+ * we split off that part of the basic set i that shares the outer dimensions
+ * with j and lies before j in the current dimension.
+ * We collect all the pieces in a new list that replaces "scc".
*/
static int add_nodes(__isl_take isl_basic_set_list *scc, void *user)
{
struct isl_add_nodes_data *data = user;
- int i, n;
+ int i, n, depth;
isl_basic_set *bset;
- isl_set *set;
+ isl_basic_set_list *list;
+ isl_space *space;
+ isl_basic_map *gt;
n = isl_basic_set_list_n_basic_set(scc);
bset = isl_basic_set_list_get_basic_set(scc, 0);
return data->list ? 0 : -1;
}
- set = isl_set_from_basic_set(bset);
+ depth = isl_ast_build_get_depth(data->build);
+ space = isl_basic_set_get_space(bset);
+ space = isl_space_map_from_set(space);
+ gt = isl_basic_map_universe(space);
+ for (i = 0; i < depth; ++i)
+ gt = isl_basic_map_equate(gt, isl_dim_in, i, isl_dim_out, i);
+ gt = isl_basic_map_order_gt(gt, isl_dim_in, depth, isl_dim_out, depth);
+
+ list = isl_basic_set_list_from_basic_set(bset);
for (i = 1; i < n; ++i) {
bset = isl_basic_set_list_get_basic_set(scc, i);
- set = isl_set_union(set, isl_set_from_basic_set(bset));
+ list = add_split_on(list, bset, gt);
}
-
- set = isl_set_make_disjoint(set);
- if (isl_set_n_basic_set(set) == n)
- isl_die(isl_basic_set_list_get_ctx(scc), isl_error_internal,
- "unable to separate loop parts",
- set = isl_set_free(set));
+ isl_basic_map_free(gt);
isl_basic_set_list_free(scc);
- scc = isl_basic_set_list_from_set(set);
+ scc = list;
data->list = isl_ast_graft_list_concat(data->list,
generate_sorted_domains(scc, data->executed, data->build));
isl_basic_set_list_free(scc);