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);
__isl_take isl_aff *aff, void *user)
{
int *neg = user;
- isl_int v;
+ isl_val *v;
- isl_int_init(v);
- isl_aff_get_constant(aff, &v);
- *neg = isl_int_is_neg(v);
- isl_int_clear(v);
+ v = isl_aff_get_constant_val(aff);
+ *neg = isl_val_is_neg(v);
+ isl_val_free(v);
isl_set_free(set);
isl_aff_free(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);
* found any yet.
* "n" is the corresponding size. If lower is NULL, then the value of n
* is undefined.
- *
- * "tmp" is a temporary initialized isl_int.
*/
struct isl_find_unroll_data {
isl_set *domain;
isl_aff *lower;
int *n;
- isl_int tmp;
};
/* Check if we can use "c" as a lower bound and if it is better than
__isl_keep isl_constraint *c)
{
isl_aff *aff, *lower;
- enum isl_lp_result res;
+ isl_val *max;
if (!isl_constraint_is_lower_bound(c, isl_dim_set, data->depth))
return 0;
aff = isl_aff_neg(aff);
aff = isl_aff_add_coefficient_si(aff, isl_dim_in, data->depth, 1);
aff = isl_aff_add_constant_si(aff, 1);
- res = isl_set_max(data->domain, aff, &data->tmp);
+ max = isl_set_max_val(data->domain, aff);
isl_aff_free(aff);
- if (res == isl_lp_error)
+ if (!max)
goto error;
- if (res == isl_lp_unbounded) {
+ if (isl_val_is_infty(max)) {
+ isl_val_free(max);
isl_aff_free(lower);
return 0;
}
- if (isl_int_cmp_si(data->tmp, INT_MAX) <= 0 &&
- (!data->lower || isl_int_cmp_si(data->tmp, *data->n) < 0)) {
+ if (isl_val_cmp_si(max, INT_MAX) <= 0 &&
+ (!data->lower || isl_val_cmp_si(max, *data->n) < 0)) {
isl_aff_free(data->lower);
data->lower = lower;
- *data->n = isl_int_get_si(data->tmp);
+ *data->n = isl_val_get_num_si(max);
} else
isl_aff_free(lower);
+ isl_val_free(max);
return 1;
error:
struct isl_find_unroll_data data = { domain, depth, NULL, n };
isl_basic_set *hull;
- isl_int_init(data.tmp);
hull = isl_set_simple_hull(isl_set_copy(domain));
if (isl_basic_set_foreach_constraint(hull,
goto error;
isl_basic_set_free(hull);
- isl_int_clear(data.tmp);
if (!data.lower)
isl_die(isl_set_get_ctx(domain), isl_error_invalid,
return data.lower;
error:
isl_basic_set_free(hull);
- isl_int_clear(data.tmp);
return isl_aff_free(data.lower);
}
return generate_shifted_component(executed, build);
}
+/* Does set dimension "pos" of "set" have an obviously fixed value?
+ */
+static int dim_is_fixed(__isl_keep isl_set *set, int pos)
+{
+ int fixed;
+ isl_val *v;
+
+ v = isl_set_plain_get_val_if_fixed(set, isl_dim_set, pos);
+ if (!v)
+ return -1;
+ fixed = !isl_val_is_nan(v);
+ isl_val_free(v);
+
+ return fixed;
+}
+
/* Given an array "domain" of isl_set_map_pairs and an array "order"
* of indices into the "domain" array,
* do all (except for at most one) of the "set" field of the elements
for (i = 0; i < n; ++i) {
int f;
- f = isl_set_plain_is_fixed(domain[order[i]].set,
- isl_dim_set, depth, NULL);
+ f = dim_is_fixed(domain[order[i]].set, depth);
if (f < 0)
return -1;
if (f)
for (i = n - 1; i >= 0; --i) {
int f;
- f = isl_set_plain_is_fixed(domain[order[i]].set,
- isl_dim_set, depth, NULL);
+ f = dim_is_fixed(domain[order[i]].set, depth);
if (f < 0)
return -1;
if (f)
* in all cases.
*/
static __isl_give isl_union_map *contruct_shifted_executed(
- struct isl_set_map_pair *domain, int *order, int n, isl_int stride,
- __isl_keep isl_vec *offset, __isl_keep isl_ast_build *build)
+ struct isl_set_map_pair *domain, int *order, int n,
+ __isl_keep isl_val *stride, __isl_keep isl_multi_val *offset,
+ __isl_take isl_ast_build *build)
{
int i;
- isl_int v;
isl_union_map *executed;
isl_space *space;
isl_map *map;
c = isl_constraint_set_coefficient_si(c, isl_dim_in, depth, 1);
c = isl_constraint_set_coefficient_si(c, isl_dim_out, depth, -1);
- isl_int_init(v);
-
for (i = 0; i < n; ++i) {
isl_map *map_i;
+ isl_val *v;
- if (isl_vec_get_element(offset, i, &v) < 0)
+ v = isl_multi_val_get_val(offset, i);
+ if (!v)
break;
map_i = isl_map_copy(map);
- map_i = isl_map_fix(map_i, isl_dim_out, depth + 1, v);
- isl_int_neg(v, v);
- c = isl_constraint_set_constant(c, v);
+ map_i = isl_map_fix_val(map_i, isl_dim_out, depth + 1,
+ isl_val_copy(v));
+ v = isl_val_neg(v);
+ c = isl_constraint_set_constant_val(c, v);
map_i = isl_map_add_constraint(map_i, isl_constraint_copy(c));
map_i = isl_map_apply_domain(isl_map_copy(domain[order[i]].map),
isl_constraint_free(c);
isl_map_free(map);
- isl_int_clear(v);
-
if (i < n)
executed = isl_union_map_free(executed);
* old schedule domain.
*/
static __isl_give isl_ast_graft_list *generate_shift_component(
- struct isl_set_map_pair *domain, int *order, int n, isl_int stride,
- __isl_keep isl_vec *offset, __isl_take isl_ast_build *build)
+ struct isl_set_map_pair *domain, int *order, int n,
+ __isl_keep isl_val *stride, __isl_keep isl_multi_val *offset,
+ __isl_take isl_ast_build *build)
{
isl_ast_graft_list *list;
int first;
int depth;
isl_ctx *ctx;
- isl_int val;
- isl_vec *v;
+ isl_val *val;
+ isl_multi_val *mv;
isl_space *space;
isl_multi_aff *ma, *zero;
isl_union_map *executed;
if (first < 0)
return isl_ast_build_free(build);
- isl_int_init(val);
- v = isl_vec_alloc(ctx, n);
- if (isl_vec_get_element(offset, first, &val) < 0)
- v = isl_vec_free(v);
- isl_int_neg(val, val);
- v = isl_vec_set(v, val);
- v = isl_vec_add(v, isl_vec_copy(offset));
- v = isl_vec_fdiv_r(v, stride);
+ mv = isl_multi_val_copy(offset);
+ val = isl_multi_val_get_val(offset, first);
+ val = isl_val_neg(val);
+ mv = isl_multi_val_add_val(mv, val);
+ mv = isl_multi_val_mod_val(mv, isl_val_copy(stride));
- executed = contruct_shifted_executed(domain, order, n, stride, v,
+ executed = contruct_shifted_executed(domain, order, n, stride, mv,
build);
space = isl_ast_build_get_space(build, 1);
space = isl_space_map_from_set(space);
list = isl_ast_graft_list_preimage_multi_aff(list, ma);
- isl_vec_free(v);
- isl_int_clear(val);
+ isl_multi_val_free(mv);
return list;
}
isl_ctx *ctx;
isl_map *map;
isl_set *deltas;
- isl_int m, r, gcd;
- isl_vec *v;
+ isl_val *gcd = NULL;
+ isl_multi_val *mv;
int fixed, skip;
int base;
isl_ast_graft_list *list;
ctx = isl_ast_build_get_ctx(build);
- isl_int_init(m);
- isl_int_init(r);
- isl_int_init(gcd);
- v = isl_vec_alloc(ctx, n);
+ mv = isl_multi_val_zero(isl_space_set_alloc(ctx, 0, n));
fixed = 1;
for (i = 0; i < n; ++i) {
+ isl_val *r, *m;
+
map = isl_map_from_domain_and_range(
isl_set_copy(domain[order[base]].set),
isl_set_copy(domain[order[i]].set));
map = isl_map_equate(map, isl_dim_in, d,
isl_dim_out, d);
deltas = isl_map_deltas(map);
- res = isl_set_dim_residue_class(deltas, depth, &m, &r);
+ res = isl_set_dim_residue_class_val(deltas, depth, &m, &r);
isl_set_free(deltas);
if (res < 0)
break;
if (i == 0)
- isl_int_set(gcd, m);
+ gcd = m;
else
- isl_int_gcd(gcd, gcd, m);
- if (isl_int_is_one(gcd))
+ gcd = isl_val_gcd(gcd, m);
+ if (isl_val_is_one(gcd)) {
+ isl_val_free(r);
break;
- v = isl_vec_set_element(v, i, r);
+ }
+ mv = isl_multi_val_set_val(mv, i, r);
- res = isl_set_plain_is_fixed(domain[order[i]].set,
- isl_dim_set, depth, NULL);
+ res = dim_is_fixed(domain[order[i]].set, depth);
if (res < 0)
break;
if (res)
continue;
if (fixed && i > base) {
- isl_vec_get_element(v, base, &m);
- if (isl_int_ne(m, r))
+ isl_val *a, *b;
+ a = isl_multi_val_get_val(mv, i);
+ b = isl_multi_val_get_val(mv, base);
+ if (isl_val_ne(a, b))
fixed = 0;
+ isl_val_free(a);
+ isl_val_free(b);
}
}
- if (res < 0) {
+ if (res < 0 || !gcd) {
isl_ast_build_free(build);
list = NULL;
} else if (i < n || fixed) {
list = generate_shifted_component_from_list(domain,
order, n, build);
} else {
- list = generate_shift_component(domain, order, n, gcd, v,
+ list = generate_shift_component(domain, order, n, gcd, mv,
build);
}
- isl_vec_free(v);
- isl_int_clear(gcd);
- isl_int_clear(r);
- isl_int_clear(m);
+ isl_val_free(gcd);
+ isl_multi_val_free(mv);
return list;
}