forked from OSchip/llvm-project
Update to isl 99d53692ba
This commit imports the latest isl version into lib/External/isl. The changes relavant for Polly are: 1) Schedule trees [1] have been introduced as a more structured way to describe schedules. Polly does not yet use them, but we may switch to them in the near future. 2) Another set of coalescing changes [2] simplifies some data dependences and removes a couple of code generation artifacts. We now understand that the following sets can be merged: { Stmt_S1[i0, i1] -> Stmt_S2[i0 + i1] : i0 >= 0 and i1 <= 1023 - i0 and i1 >= 1 Stmt_S1[i0, 0] -> Stmt_S2[i0] : i0 <= 1023 and i0 >= 1} into: { Stmt_S1[i0, i1] -> Stmt_S2[i0 + i1] : i1 <= 1023 - i0 and i1 >= 0 and i1 >= 1 - i0 and i0 >= 0 } Changes of this kind reduce unnecessary specialization during code generation. - for (int c3 = 0; c3 <= 1023; c3 += 1) { - if (c3 % 2 == 0) { - Stmt_for_body3(c1, c3); - } else - Stmt_for_body3(c1, c3); - } + for (int c3 = 0; c3 <= 1023; c3 += 1) + Stmt_for_body3(c1, c3); [1] http://impact.gforge.inria.fr/impact2014/papers/impact2014-verdoolaege.pdf [2] http://impact.gforge.inria.fr/impact2015/papers/impact2015-verdoolaege.pdf llvm-svn: 229423
This commit is contained in:
parent
97a59fb464
commit
1fa7b972c0
|
@ -56,6 +56,7 @@ set (ISL_FILES
|
|||
External/isl/isl_local_space.c
|
||||
External/isl/isl_lp.c
|
||||
External/isl/isl_map.c
|
||||
External/isl/isl_map_list.c
|
||||
External/isl/isl_map_simplify.c
|
||||
External/isl/isl_map_subtract.c
|
||||
External/isl/isl_map_to_basic_set.c
|
||||
|
@ -72,6 +73,10 @@ set (ISL_FILES
|
|||
External/isl/isl_sample.c
|
||||
External/isl/isl_scan.c
|
||||
External/isl/isl_schedule.c
|
||||
External/isl/isl_schedule_band.c
|
||||
External/isl/isl_schedule_node.c
|
||||
External/isl/isl_schedule_read.c
|
||||
External/isl/isl_schedule_tree.c
|
||||
External/isl/isl_scheduler.c
|
||||
External/isl/isl_seq.c
|
||||
External/isl/isl_set_list.c
|
||||
|
|
|
@ -107,6 +107,7 @@ libisl_la_SOURCES = \
|
|||
isl_lp.c \
|
||||
isl_lp_private.h \
|
||||
isl_map.c \
|
||||
isl_map_list.c \
|
||||
isl_map_simplify.c \
|
||||
isl_map_subtract.c \
|
||||
isl_map_private.h \
|
||||
|
@ -137,6 +138,13 @@ libisl_la_SOURCES = \
|
|||
isl_scan.c \
|
||||
isl_scan.h \
|
||||
isl_schedule.c \
|
||||
isl_schedule_band.c \
|
||||
isl_schedule_band.h \
|
||||
isl_schedule_node.c \
|
||||
isl_schedule_node_private.h \
|
||||
isl_schedule_read.c \
|
||||
isl_schedule_tree.c \
|
||||
isl_schedule_tree.h \
|
||||
isl_schedule_private.h \
|
||||
isl_scheduler.c \
|
||||
isl_set_list.c \
|
||||
|
@ -162,7 +170,8 @@ libisl_la_SOURCES = \
|
|||
isl_vec.c \
|
||||
isl_version.c \
|
||||
isl_vertices_private.h \
|
||||
isl_vertices.c
|
||||
isl_vertices.c \
|
||||
isl_yaml.h
|
||||
libisl_la_LIBADD = @MP_LIBS@
|
||||
libisl_la_LDFLAGS = -version-info @versioninfo@ \
|
||||
@MP_LDFLAGS@
|
||||
|
@ -246,6 +255,8 @@ pkginclude_HEADERS = \
|
|||
include/isl/polynomial_type.h \
|
||||
include/isl/printer.h \
|
||||
include/isl/schedule.h \
|
||||
include/isl/schedule_node.h \
|
||||
include/isl/schedule_type.h \
|
||||
include/isl/set.h \
|
||||
include/isl/set_type.h \
|
||||
include/isl/space.h \
|
||||
|
@ -282,8 +293,15 @@ EXTRA_DIST = \
|
|||
isl_list_templ.c \
|
||||
isl_list_templ.h \
|
||||
isl_map_lexopt_templ.c \
|
||||
isl_multi_macro.h \
|
||||
isl_multi_templ.c \
|
||||
isl_multi_templ.h \
|
||||
isl_multi_apply_templ.c \
|
||||
isl_multi_apply_set.c \
|
||||
isl_multi_apply_union_set.c \
|
||||
isl_multi_floor.c \
|
||||
isl_multi_gist.c \
|
||||
isl_multi_intersect.c \
|
||||
print_templ.c \
|
||||
isl_power_templ.c \
|
||||
isl_pw_templ.c \
|
||||
|
|
|
@ -242,7 +242,7 @@ int main(int argc, char **argv)
|
|||
isl_ctx *ctx;
|
||||
isl_pw_qpolynomial_fold *copy;
|
||||
isl_pw_qpolynomial_fold *pwf;
|
||||
struct isl_stream *s;
|
||||
isl_stream *s;
|
||||
struct isl_obj obj;
|
||||
struct bound_options *options;
|
||||
int exact;
|
||||
|
|
|
@ -13,15 +13,24 @@ struct isl_arg_choice cat_format[] = {
|
|||
{0}
|
||||
};
|
||||
|
||||
struct isl_arg_choice cat_yaml_style[] = {
|
||||
{ "block", ISL_YAML_STYLE_BLOCK },
|
||||
{ "flow", ISL_YAML_STYLE_FLOW },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
struct cat_options {
|
||||
struct isl_options *isl;
|
||||
unsigned format;
|
||||
unsigned yaml_style;
|
||||
};
|
||||
|
||||
ISL_ARGS_START(struct cat_options, cat_options_args)
|
||||
ISL_ARG_CHILD(struct cat_options, isl, "isl", &isl_options_args, "isl options")
|
||||
ISL_ARG_CHOICE(struct cat_options, format, 0, "format", \
|
||||
cat_format, ISL_FORMAT_ISL, "output format")
|
||||
ISL_ARG_CHOICE(struct cat_options, yaml_style, 0, "yaml-style", \
|
||||
cat_yaml_style, ISL_YAML_STYLE_BLOCK, "output YAML style")
|
||||
ISL_ARGS_END
|
||||
|
||||
ISL_ARG_DEF(cat_options, struct cat_options, cat_options_args)
|
||||
|
@ -29,7 +38,7 @@ ISL_ARG_DEF(cat_options, struct cat_options, cat_options_args)
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
struct isl_ctx *ctx;
|
||||
struct isl_stream *s;
|
||||
isl_stream *s;
|
||||
struct isl_obj obj;
|
||||
struct cat_options *options;
|
||||
isl_printer *p;
|
||||
|
@ -46,6 +55,7 @@ int main(int argc, char **argv)
|
|||
|
||||
p = isl_printer_to_file(ctx, stdout);
|
||||
p = isl_printer_set_output_format(p, options->format);
|
||||
p = isl_printer_set_yaml_style(p, options->yaml_style);
|
||||
p = obj.type->print(p, obj.v);
|
||||
p = isl_printer_end_line(p);
|
||||
isl_printer_free(p);
|
||||
|
|
|
@ -7,6 +7,7 @@ int main(int argc, char **argv)
|
|||
struct isl_ctx *ctx;
|
||||
struct isl_map *map;
|
||||
struct isl_options *options;
|
||||
isl_printer *p;
|
||||
int exact;
|
||||
|
||||
options = isl_options_new_with_defaults();
|
||||
|
@ -15,19 +16,23 @@ int main(int argc, char **argv)
|
|||
|
||||
ctx = isl_ctx_alloc_with_options(&isl_options_args, options);
|
||||
|
||||
p = isl_printer_to_file(ctx, stdout);
|
||||
|
||||
map = isl_map_read_from_file(ctx, stdin);
|
||||
map = isl_map_transitive_closure(map, &exact);
|
||||
if (!exact)
|
||||
printf("# NOT exact\n");
|
||||
isl_map_print(map, stdout, 0, ISL_FORMAT_ISL);
|
||||
printf("\n");
|
||||
p = isl_printer_print_str(p, "# NOT exact\n");
|
||||
p = isl_printer_print_map(p, map);
|
||||
p = isl_printer_end_line(p);
|
||||
map = isl_map_compute_divs(map);
|
||||
map = isl_map_coalesce(map);
|
||||
printf("# coalesced\n");
|
||||
isl_map_print(map, stdout, 0, ISL_FORMAT_ISL);
|
||||
printf("\n");
|
||||
p = isl_printer_print_str(p, "# coalesced\n");
|
||||
p = isl_printer_print_map(p, map);
|
||||
p = isl_printer_end_line(p);
|
||||
isl_map_free(map);
|
||||
|
||||
isl_printer_free(p);
|
||||
|
||||
isl_ctx_free(ctx);
|
||||
|
||||
return 0;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -200,6 +200,7 @@ __isl_give isl_pw_aff *isl_pw_aff_set_tuple_id(__isl_take isl_pw_aff *pwaff,
|
|||
enum isl_dim_type type, __isl_take isl_id *id);
|
||||
__isl_give isl_pw_aff *isl_pw_aff_reset_tuple_id(__isl_take isl_pw_aff *pa,
|
||||
enum isl_dim_type type);
|
||||
__isl_give isl_pw_aff *isl_pw_aff_reset_user(__isl_take isl_pw_aff *pa);
|
||||
|
||||
__isl_give isl_set *isl_pw_aff_params(__isl_take isl_pw_aff *pwa);
|
||||
__isl_give isl_set *isl_pw_aff_domain(__isl_take isl_pw_aff *pwaff);
|
||||
|
@ -231,6 +232,8 @@ __isl_give isl_pw_aff *isl_pw_aff_intersect_params(__isl_take isl_pw_aff *pa,
|
|||
__isl_take isl_set *set);
|
||||
__isl_give isl_pw_aff *isl_pw_aff_intersect_domain(__isl_take isl_pw_aff *pa,
|
||||
__isl_take isl_set *set);
|
||||
__isl_give isl_pw_aff *isl_pw_aff_subtract_domain(__isl_take isl_pw_aff *pa,
|
||||
__isl_take isl_set *set);
|
||||
|
||||
__isl_give isl_pw_aff *isl_pw_aff_cond(__isl_take isl_pw_aff *cond,
|
||||
__isl_take isl_pw_aff *pwaff_true, __isl_take isl_pw_aff *pwaff_false);
|
||||
|
@ -271,6 +274,7 @@ int isl_pw_aff_foreach_piece(__isl_keep isl_pw_aff *pwaff,
|
|||
__isl_give isl_set *isl_set_from_pw_aff(__isl_take isl_pw_aff *pwaff);
|
||||
__isl_give isl_map *isl_map_from_pw_aff(__isl_take isl_pw_aff *pwaff);
|
||||
|
||||
__isl_give isl_set *isl_pw_aff_pos_set(__isl_take isl_pw_aff *pa);
|
||||
__isl_give isl_set *isl_pw_aff_nonneg_set(__isl_take isl_pw_aff *pwaff);
|
||||
__isl_give isl_set *isl_pw_aff_zero_set(__isl_take isl_pw_aff *pwaff);
|
||||
__isl_give isl_set *isl_pw_aff_non_zero_set(__isl_take isl_pw_aff *pwaff);
|
||||
|
@ -288,6 +292,13 @@ __isl_give isl_set *isl_pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1,
|
|||
__isl_give isl_set *isl_pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1,
|
||||
__isl_take isl_pw_aff *pwaff2);
|
||||
|
||||
__isl_give isl_map *isl_pw_aff_eq_map(__isl_take isl_pw_aff *pa1,
|
||||
__isl_take isl_pw_aff *pa2);
|
||||
__isl_give isl_map *isl_pw_aff_lt_map(__isl_take isl_pw_aff *pa1,
|
||||
__isl_take isl_pw_aff *pa2);
|
||||
__isl_give isl_map *isl_pw_aff_gt_map(__isl_take isl_pw_aff *pa1,
|
||||
__isl_take isl_pw_aff *pa2);
|
||||
|
||||
__isl_give isl_pw_aff *isl_pw_aff_read_from_str(isl_ctx *ctx, const char *str);
|
||||
__isl_give isl_printer *isl_printer_print_pw_aff(__isl_take isl_printer *p,
|
||||
__isl_keep isl_pw_aff *pwaff);
|
||||
|
@ -310,6 +321,9 @@ __isl_give isl_set *isl_pw_aff_list_gt_set(__isl_take isl_pw_aff_list *list1,
|
|||
__isl_take isl_pw_aff_list *list2);
|
||||
|
||||
ISL_DECLARE_MULTI(aff)
|
||||
ISL_DECLARE_MULTI_NEG(aff)
|
||||
ISL_DECLARE_MULTI_DIMS(aff)
|
||||
ISL_DECLARE_MULTI_WITH_DOMAIN(aff)
|
||||
|
||||
__isl_give isl_multi_aff *isl_multi_aff_from_aff(__isl_take isl_aff *aff);
|
||||
__isl_give isl_multi_aff *isl_multi_aff_identity(__isl_take isl_space *space);
|
||||
|
@ -326,8 +340,6 @@ __isl_give isl_multi_aff *isl_multi_aff_floor(__isl_take isl_multi_aff *ma);
|
|||
|
||||
__isl_give isl_multi_aff *isl_multi_aff_add(__isl_take isl_multi_aff *maff1,
|
||||
__isl_take isl_multi_aff *maff2);
|
||||
__isl_give isl_multi_aff *isl_multi_aff_sub(__isl_take isl_multi_aff *ma1,
|
||||
__isl_take isl_multi_aff *ma2);
|
||||
|
||||
__isl_give isl_multi_aff *isl_multi_aff_product(
|
||||
__isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2);
|
||||
|
@ -361,10 +373,15 @@ __isl_give isl_multi_aff *isl_multi_aff_read_from_str(isl_ctx *ctx,
|
|||
void isl_multi_aff_dump(__isl_keep isl_multi_aff *maff);
|
||||
|
||||
ISL_DECLARE_MULTI(pw_aff)
|
||||
ISL_DECLARE_MULTI_NEG(pw_aff)
|
||||
ISL_DECLARE_MULTI_DIMS(pw_aff)
|
||||
ISL_DECLARE_MULTI_WITH_DOMAIN(pw_aff)
|
||||
|
||||
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_zero(__isl_take isl_space *space);
|
||||
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity(
|
||||
__isl_take isl_space *space);
|
||||
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map(
|
||||
__isl_take isl_space *space);
|
||||
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_out_map(
|
||||
__isl_take isl_space *space, enum isl_dim_type type,
|
||||
unsigned first, unsigned n);
|
||||
|
@ -405,6 +422,8 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_tuple_id(
|
|||
enum isl_dim_type type, __isl_take isl_id *id);
|
||||
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_tuple_id(
|
||||
__isl_take isl_pw_multi_aff *pma, enum isl_dim_type type);
|
||||
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_user(
|
||||
__isl_take isl_pw_multi_aff *pma);
|
||||
|
||||
int isl_pw_multi_aff_find_dim_by_name(__isl_keep isl_pw_multi_aff *pma,
|
||||
enum isl_dim_type type, const char *name);
|
||||
|
@ -441,6 +460,9 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_fix_si(
|
|||
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_add(
|
||||
__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2);
|
||||
|
||||
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_neg(
|
||||
__isl_take isl_pw_multi_aff *pma);
|
||||
|
||||
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_add(
|
||||
__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2);
|
||||
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_sub(
|
||||
|
@ -474,6 +496,8 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_intersect_params(
|
|||
__isl_take isl_pw_multi_aff *pma, __isl_take isl_set *set);
|
||||
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_intersect_domain(
|
||||
__isl_take isl_pw_multi_aff *pma, __isl_take isl_set *set);
|
||||
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_subtract_domain(
|
||||
__isl_take isl_pw_multi_aff *pma, __isl_take isl_set *set);
|
||||
|
||||
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_domain_on_params(
|
||||
__isl_take isl_pw_multi_aff *pma);
|
||||
|
@ -513,6 +537,8 @@ void isl_pw_multi_aff_dump(__isl_keep isl_pw_multi_aff *pma);
|
|||
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_empty(
|
||||
__isl_take isl_space *space);
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_aff(
|
||||
__isl_take isl_aff *aff);
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_pw_multi_aff(
|
||||
__isl_take isl_pw_multi_aff *pma);
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_domain(
|
||||
|
@ -524,6 +550,12 @@ __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_copy(
|
|||
__isl_null isl_union_pw_multi_aff *isl_union_pw_multi_aff_free(
|
||||
__isl_take isl_union_pw_multi_aff *upma);
|
||||
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_set_identity_union_pw_multi_aff(
|
||||
__isl_take isl_union_set *uset);
|
||||
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_multi_aff_get_union_pw_aff(
|
||||
__isl_keep isl_union_pw_multi_aff *upma, int pos);
|
||||
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_add_pw_multi_aff(
|
||||
__isl_take isl_union_pw_multi_aff *upma,
|
||||
__isl_take isl_pw_multi_aff *pma);
|
||||
|
@ -535,10 +567,20 @@ __isl_give isl_space *isl_union_pw_multi_aff_get_space(
|
|||
|
||||
unsigned isl_union_pw_multi_aff_dim(__isl_keep isl_union_pw_multi_aff *upma,
|
||||
enum isl_dim_type type);
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_set_dim_name(
|
||||
__isl_take isl_union_pw_multi_aff *upma,
|
||||
enum isl_dim_type type, unsigned pos, const char *s);
|
||||
|
||||
int isl_union_pw_multi_aff_find_dim_by_name(
|
||||
__isl_keep isl_union_pw_multi_aff *upma, enum isl_dim_type type,
|
||||
const char *name);
|
||||
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_drop_dims(
|
||||
__isl_take isl_union_pw_multi_aff *upma,
|
||||
enum isl_dim_type type, unsigned first, unsigned n);
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_reset_user(
|
||||
__isl_take isl_union_pw_multi_aff *upma);
|
||||
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_coalesce(
|
||||
__isl_take isl_union_pw_multi_aff *upma);
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_gist_params(
|
||||
|
@ -547,9 +589,17 @@ __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_gist(
|
|||
__isl_take isl_union_pw_multi_aff *upma,
|
||||
__isl_take isl_union_set *context);
|
||||
|
||||
__isl_give isl_union_pw_multi_aff *
|
||||
isl_union_pw_multi_aff_pullback_union_pw_multi_aff(
|
||||
__isl_take isl_union_pw_multi_aff *upma1,
|
||||
__isl_take isl_union_pw_multi_aff *upma2);
|
||||
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_align_params(
|
||||
__isl_take isl_union_pw_multi_aff *upma, __isl_take isl_space *model);
|
||||
|
||||
int isl_union_pw_multi_aff_n_pw_multi_aff(
|
||||
__isl_keep isl_union_pw_multi_aff *upma);
|
||||
|
||||
int isl_union_pw_multi_aff_foreach_pw_multi_aff(
|
||||
__isl_keep isl_union_pw_multi_aff *upma,
|
||||
int (*fn)(__isl_take isl_pw_multi_aff *pma, void *user), void *user);
|
||||
|
@ -563,6 +613,9 @@ int isl_union_pw_multi_aff_plain_is_equal(
|
|||
__isl_give isl_union_set *isl_union_pw_multi_aff_domain(
|
||||
__isl_take isl_union_pw_multi_aff *upma);
|
||||
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_neg(
|
||||
__isl_take isl_union_pw_multi_aff *upma);
|
||||
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_add(
|
||||
__isl_take isl_union_pw_multi_aff *upma1,
|
||||
__isl_take isl_union_pw_multi_aff *upma2);
|
||||
|
@ -589,6 +642,9 @@ __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_intersect_params(
|
|||
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_intersect_domain(
|
||||
__isl_take isl_union_pw_multi_aff *upma,
|
||||
__isl_take isl_union_set *uset);
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_subtract_domain(
|
||||
__isl_take isl_union_pw_multi_aff *upma,
|
||||
__isl_take isl_union_set *uset);
|
||||
|
||||
__isl_give isl_union_map *isl_union_map_from_union_pw_multi_aff(
|
||||
__isl_take isl_union_pw_multi_aff *upma);
|
||||
|
@ -648,12 +704,208 @@ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff(
|
|||
__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_multi_aff(
|
||||
__isl_take isl_pw_multi_aff *pma);
|
||||
|
||||
__isl_give isl_map *isl_multi_pw_aff_eq_map(__isl_take isl_multi_pw_aff *mpa1,
|
||||
__isl_take isl_multi_pw_aff *mpa2);
|
||||
__isl_give isl_map *isl_multi_pw_aff_lex_lt_map(
|
||||
__isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2);
|
||||
__isl_give isl_map *isl_multi_pw_aff_lex_gt_map(
|
||||
__isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2);
|
||||
|
||||
__isl_give isl_multi_pw_aff *isl_multi_pw_aff_read_from_str(isl_ctx *ctx,
|
||||
const char *str);
|
||||
__isl_give isl_printer *isl_printer_print_multi_pw_aff(
|
||||
__isl_take isl_printer *p, __isl_keep isl_multi_pw_aff *mpa);
|
||||
void isl_multi_pw_aff_dump(__isl_keep isl_multi_pw_aff *mpa);
|
||||
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_copy(
|
||||
__isl_keep isl_union_pw_aff *upa);
|
||||
__isl_null isl_union_pw_aff *isl_union_pw_aff_free(
|
||||
__isl_take isl_union_pw_aff *upa);
|
||||
|
||||
isl_ctx *isl_union_pw_aff_get_ctx(__isl_keep isl_union_pw_aff *upa);
|
||||
__isl_give isl_space *isl_union_pw_aff_get_space(
|
||||
__isl_keep isl_union_pw_aff *upa);
|
||||
|
||||
unsigned isl_union_pw_aff_dim(__isl_keep isl_union_pw_aff *upa,
|
||||
enum isl_dim_type type);
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_set_dim_name(
|
||||
__isl_take isl_union_pw_aff *upa, enum isl_dim_type type,
|
||||
unsigned pos, const char *s);
|
||||
|
||||
int isl_union_pw_aff_find_dim_by_name(__isl_keep isl_union_pw_aff *upa,
|
||||
enum isl_dim_type type, const char *name);
|
||||
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_drop_dims(
|
||||
__isl_take isl_union_pw_aff *upa,
|
||||
enum isl_dim_type type, unsigned first, unsigned n);
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_reset_user(
|
||||
__isl_take isl_union_pw_aff *upa);
|
||||
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_empty(
|
||||
__isl_take isl_space *space);
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_from_pw_aff(
|
||||
__isl_take isl_pw_aff *pa);
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_val_on_domain(
|
||||
__isl_take isl_union_set *domain, __isl_take isl_val *v);
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_aff_on_domain(
|
||||
__isl_take isl_union_set *domain, __isl_take isl_aff *aff);
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_add_pw_aff(
|
||||
__isl_take isl_union_pw_aff *upa, __isl_take isl_pw_aff *pa);
|
||||
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_pw_aff(
|
||||
__isl_take isl_union_pw_aff *upa);
|
||||
|
||||
int isl_union_pw_aff_n_pw_aff(__isl_keep isl_union_pw_aff *upa);
|
||||
|
||||
int isl_union_pw_aff_foreach_pw_aff(__isl_keep isl_union_pw_aff *upa,
|
||||
int (*fn)(__isl_take isl_pw_aff *ma, void *user), void *user);
|
||||
__isl_give isl_pw_aff *isl_union_pw_aff_extract_pw_aff(
|
||||
__isl_keep isl_union_pw_aff *upa, __isl_take isl_space *space);
|
||||
|
||||
int isl_union_pw_aff_plain_is_equal(__isl_keep isl_union_pw_aff *upa1,
|
||||
__isl_keep isl_union_pw_aff *upa2);
|
||||
|
||||
__isl_give isl_union_set *isl_union_pw_aff_domain(
|
||||
__isl_take isl_union_pw_aff *upa);
|
||||
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_neg(
|
||||
__isl_take isl_union_pw_aff *upa);
|
||||
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_add(
|
||||
__isl_take isl_union_pw_aff *upa1, __isl_take isl_union_pw_aff *upa2);
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_union_add(
|
||||
__isl_take isl_union_pw_aff *upa1, __isl_take isl_union_pw_aff *upa2);
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_sub(
|
||||
__isl_take isl_union_pw_aff *upa1, __isl_take isl_union_pw_aff *upa2);
|
||||
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_coalesce(
|
||||
__isl_take isl_union_pw_aff *upa);
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_gist(
|
||||
__isl_take isl_union_pw_aff *upa, __isl_take isl_union_set *context);
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_gist_params(
|
||||
__isl_take isl_union_pw_aff *upa, __isl_take isl_set *context);
|
||||
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_pullback_union_pw_multi_aff(
|
||||
__isl_take isl_union_pw_aff *upa,
|
||||
__isl_take isl_union_pw_multi_aff *upma);
|
||||
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_floor(
|
||||
__isl_take isl_union_pw_aff *upa);
|
||||
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_scale_val(
|
||||
__isl_take isl_union_pw_aff *upa, __isl_take isl_val *v);
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_scale_down_val(
|
||||
__isl_take isl_union_pw_aff *upa, __isl_take isl_val *v);
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_mod_val(
|
||||
__isl_take isl_union_pw_aff *upa, __isl_take isl_val *f);
|
||||
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_align_params(
|
||||
__isl_take isl_union_pw_aff *upa, __isl_take isl_space *model);
|
||||
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_intersect_params(
|
||||
__isl_take isl_union_pw_aff *upa, __isl_take isl_set *set);
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_intersect_domain(
|
||||
__isl_take isl_union_pw_aff *upa, __isl_take isl_union_set *uset);
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_subtract_domain(
|
||||
__isl_take isl_union_pw_aff *upa, __isl_take isl_union_set *uset);
|
||||
|
||||
__isl_give isl_union_pw_aff *isl_union_pw_aff_set_dim_name(
|
||||
__isl_take isl_union_pw_aff *upa,
|
||||
enum isl_dim_type type, unsigned pos, const char *s);
|
||||
|
||||
__isl_give isl_union_set *isl_union_pw_aff_zero_union_set(
|
||||
__isl_take isl_union_pw_aff *upa);
|
||||
|
||||
__isl_give isl_union_map *isl_union_map_from_union_pw_aff(
|
||||
__isl_take isl_union_pw_aff *upa);
|
||||
|
||||
__isl_give char *isl_union_pw_aff_to_str(__isl_keep isl_union_pw_aff *upa);
|
||||
__isl_give isl_printer *isl_printer_print_union_pw_aff(
|
||||
__isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa);
|
||||
|
||||
ISL_DECLARE_MULTI(union_pw_aff)
|
||||
ISL_DECLARE_MULTI_NEG(union_pw_aff)
|
||||
|
||||
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_aff(
|
||||
__isl_take isl_multi_aff *ma);
|
||||
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_pw_aff(
|
||||
__isl_take isl_union_pw_aff *upa);
|
||||
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_pw_aff(
|
||||
__isl_take isl_multi_pw_aff *mpa);
|
||||
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_val_on_domain(
|
||||
__isl_take isl_union_set *domain, __isl_take isl_multi_val *mv);
|
||||
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_aff_on_domain(
|
||||
__isl_take isl_union_set *domain, __isl_take isl_multi_aff *ma);
|
||||
|
||||
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_floor(
|
||||
__isl_take isl_multi_union_pw_aff *mupa);
|
||||
|
||||
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_intersect_domain(
|
||||
__isl_take isl_multi_union_pw_aff *mupa,
|
||||
__isl_take isl_union_set *uset);
|
||||
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_intersect_params(
|
||||
__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_set *params);
|
||||
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_intersect_range(
|
||||
__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_set *set);
|
||||
|
||||
__isl_give isl_union_set *isl_multi_union_pw_aff_domain(
|
||||
__isl_take isl_multi_union_pw_aff *mupa);
|
||||
|
||||
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_gist(
|
||||
__isl_take isl_multi_union_pw_aff *aff,
|
||||
__isl_take isl_union_set *context);
|
||||
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_gist_params(
|
||||
__isl_take isl_multi_union_pw_aff *aff, __isl_take isl_set *context);
|
||||
|
||||
__isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_aff(
|
||||
__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff);
|
||||
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_multi_aff(
|
||||
__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma);
|
||||
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_multi_aff(
|
||||
__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma);
|
||||
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_pw_multi_aff(
|
||||
__isl_take isl_multi_union_pw_aff *mupa,
|
||||
__isl_take isl_pw_multi_aff *pma);
|
||||
|
||||
__isl_give isl_multi_union_pw_aff *
|
||||
isl_multi_union_pw_aff_pullback_union_pw_multi_aff(
|
||||
__isl_take isl_multi_union_pw_aff *mupa,
|
||||
__isl_take isl_union_pw_multi_aff *upma);
|
||||
|
||||
__isl_give isl_union_pw_multi_aff *
|
||||
isl_union_pw_multi_aff_from_multi_union_pw_aff(
|
||||
__isl_take isl_multi_union_pw_aff *mupa);
|
||||
|
||||
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_union_add(
|
||||
__isl_take isl_multi_union_pw_aff *mupa1,
|
||||
__isl_take isl_multi_union_pw_aff *mupa2);
|
||||
|
||||
__isl_give isl_multi_union_pw_aff *
|
||||
isl_multi_union_pw_aff_from_union_pw_multi_aff(
|
||||
__isl_take isl_union_pw_multi_aff *upma);
|
||||
|
||||
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_map(
|
||||
__isl_take isl_union_map *umap);
|
||||
__isl_give isl_union_map *isl_union_map_from_multi_union_pw_aff(
|
||||
__isl_take isl_multi_union_pw_aff *mupa);
|
||||
|
||||
__isl_give isl_union_set *isl_multi_union_pw_aff_zero_union_set(
|
||||
__isl_take isl_multi_union_pw_aff *mupa);
|
||||
|
||||
__isl_give isl_multi_pw_aff *isl_multi_union_pw_aff_extract_multi_pw_aff(
|
||||
__isl_keep isl_multi_union_pw_aff *mupa, __isl_take isl_space *space);
|
||||
|
||||
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_read_from_str(
|
||||
isl_ctx *ctx, const char *str);
|
||||
__isl_give char *isl_multi_union_pw_aff_to_str(
|
||||
__isl_keep isl_multi_union_pw_aff *mupa);
|
||||
__isl_give isl_printer *isl_printer_print_multi_union_pw_aff(
|
||||
__isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa);
|
||||
void isl_multi_union_pw_aff_dump(__isl_keep isl_multi_union_pw_aff *mupa);
|
||||
|
||||
ISL_DECLARE_LIST_FN(union_pw_aff)
|
||||
ISL_DECLARE_LIST_FN(union_pw_multi_aff)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -17,6 +17,11 @@ typedef struct isl_pw_aff isl_pw_aff;
|
|||
|
||||
ISL_DECLARE_LIST(pw_aff)
|
||||
|
||||
struct isl_union_pw_aff;
|
||||
typedef struct isl_union_pw_aff isl_union_pw_aff;
|
||||
|
||||
ISL_DECLARE_LIST_TYPE(union_pw_aff)
|
||||
|
||||
struct isl_multi_aff;
|
||||
typedef struct isl_multi_aff isl_multi_aff;
|
||||
|
||||
|
@ -26,9 +31,14 @@ typedef struct isl_pw_multi_aff isl_pw_multi_aff;
|
|||
struct isl_union_pw_multi_aff;
|
||||
typedef struct isl_union_pw_multi_aff isl_union_pw_multi_aff;
|
||||
|
||||
ISL_DECLARE_LIST_TYPE(union_pw_multi_aff)
|
||||
|
||||
struct isl_multi_pw_aff;
|
||||
typedef struct isl_multi_pw_aff isl_multi_pw_aff;
|
||||
|
||||
struct isl_multi_union_pw_aff;
|
||||
typedef struct isl_multi_union_pw_aff isl_multi_union_pw_aff;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -70,6 +70,9 @@ __isl_give isl_local_space *isl_local_space_insert_dims(
|
|||
__isl_give isl_local_space *isl_local_space_intersect(
|
||||
__isl_take isl_local_space *ls1, __isl_take isl_local_space *ls2);
|
||||
|
||||
__isl_give isl_local_space *isl_local_space_wrap(
|
||||
__isl_take isl_local_space *ls);
|
||||
|
||||
int isl_local_space_is_equal(__isl_keep isl_local_space *ls1,
|
||||
__isl_keep isl_local_space *ls2);
|
||||
|
||||
|
|
|
@ -147,6 +147,8 @@ __isl_give isl_map *isl_map_remove_redundancies(__isl_take isl_map *map);
|
|||
__isl_give isl_basic_map *isl_map_simple_hull(__isl_take isl_map *map);
|
||||
__isl_give isl_basic_map *isl_map_unshifted_simple_hull(
|
||||
__isl_take isl_map *map);
|
||||
__isl_give isl_basic_map *isl_map_unshifted_simple_hull_from_map_list(
|
||||
__isl_take isl_map *map, __isl_take isl_map_list *list);
|
||||
|
||||
__isl_export
|
||||
__isl_give isl_basic_map *isl_basic_map_intersect_domain(
|
||||
|
@ -160,6 +162,8 @@ __isl_export
|
|||
__isl_give isl_basic_map *isl_basic_map_intersect(
|
||||
__isl_take isl_basic_map *bmap1,
|
||||
__isl_take isl_basic_map *bmap2);
|
||||
__isl_give isl_basic_map *isl_basic_map_list_intersect(
|
||||
__isl_take isl_basic_map_list *list);
|
||||
__isl_export
|
||||
__isl_give isl_map *isl_basic_map_union(
|
||||
__isl_take isl_basic_map *bmap1,
|
||||
|
@ -211,11 +215,7 @@ __isl_give isl_map *isl_map_read_from_file(isl_ctx *ctx, FILE *input);
|
|||
__isl_constructor
|
||||
__isl_give isl_map *isl_map_read_from_str(isl_ctx *ctx, const char *str);
|
||||
void isl_basic_map_dump(__isl_keep isl_basic_map *bmap);
|
||||
void isl_basic_map_print(__isl_keep isl_basic_map *bmap, FILE *out, int indent,
|
||||
const char *prefix, const char *suffix, unsigned output_format);
|
||||
void isl_map_dump(__isl_keep isl_map *map);
|
||||
void isl_map_print(__isl_keep isl_map *map, FILE *out, int indent,
|
||||
unsigned output_format);
|
||||
__isl_give isl_printer *isl_printer_print_basic_map(
|
||||
__isl_take isl_printer *printer, __isl_keep isl_basic_map *bmap);
|
||||
__isl_give char *isl_map_to_str(__isl_keep isl_map *map);
|
||||
|
@ -609,6 +609,8 @@ void isl_map_print_internal(__isl_keep isl_map *map, FILE *out, int indent);
|
|||
__isl_give isl_val *isl_map_plain_get_val_if_fixed(__isl_keep isl_map *map,
|
||||
enum isl_dim_type type, unsigned pos);
|
||||
|
||||
__isl_give isl_basic_map *isl_basic_map_gist_domain(
|
||||
__isl_take isl_basic_map *bmap, __isl_take isl_basic_set *context);
|
||||
__isl_export
|
||||
__isl_give isl_basic_map *isl_basic_map_gist(__isl_take isl_basic_map *bmap,
|
||||
__isl_take isl_basic_map *context);
|
||||
|
@ -688,6 +690,9 @@ __isl_give isl_map *isl_map_from_multi_aff(__isl_take isl_multi_aff *maff);
|
|||
|
||||
__isl_give isl_pw_aff *isl_map_dim_max(__isl_take isl_map *map, int pos);
|
||||
|
||||
ISL_DECLARE_LIST_FN(basic_map)
|
||||
ISL_DECLARE_LIST_FN(map)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -10,8 +10,10 @@ extern "C" {
|
|||
|
||||
struct __isl_subclass(isl_map) isl_basic_map;
|
||||
typedef struct isl_basic_map isl_basic_map;
|
||||
ISL_DECLARE_LIST_TYPE(basic_map)
|
||||
struct __isl_subclass(isl_union_map) isl_map;
|
||||
typedef struct isl_map isl_map;
|
||||
ISL_DECLARE_LIST_TYPE(map)
|
||||
|
||||
#ifndef isl_basic_set
|
||||
struct __isl_subclass(isl_set) isl_basic_set;
|
||||
|
|
|
@ -60,15 +60,6 @@ __isl_give isl_multi_##BASE *isl_multi_##BASE##_reset_tuple_id( \
|
|||
__isl_take isl_multi_##BASE *multi, enum isl_dim_type type); \
|
||||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_reset_user( \
|
||||
__isl_take isl_multi_##BASE *multi); \
|
||||
int isl_multi_##BASE##_involves_dims( \
|
||||
__isl_keep isl_multi_##BASE *multi, enum isl_dim_type type, \
|
||||
unsigned first, unsigned n); \
|
||||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_insert_dims( \
|
||||
__isl_take isl_multi_##BASE *multi, enum isl_dim_type type, \
|
||||
unsigned first, unsigned n); \
|
||||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_add_dims( \
|
||||
__isl_take isl_multi_##BASE *multi, enum isl_dim_type type, \
|
||||
unsigned n); \
|
||||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_drop_dims( \
|
||||
__isl_take isl_multi_##BASE *multi, enum isl_dim_type type, \
|
||||
unsigned first, unsigned n); \
|
||||
|
@ -80,9 +71,6 @@ __isl_give isl_multi_##BASE *isl_multi_##BASE##_set_##BASE( \
|
|||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_range_splice( \
|
||||
__isl_take isl_multi_##BASE *multi1, unsigned pos, \
|
||||
__isl_take isl_multi_##BASE *multi2); \
|
||||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_splice( \
|
||||
__isl_take isl_multi_##BASE *multi1, unsigned in_pos, \
|
||||
unsigned out_pos, __isl_take isl_multi_##BASE *multi2); \
|
||||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_flatten_range( \
|
||||
__isl_take isl_multi_##BASE *multi); \
|
||||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_flat_range_product( \
|
||||
|
@ -91,9 +79,6 @@ __isl_give isl_multi_##BASE *isl_multi_##BASE##_flat_range_product( \
|
|||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_range_product( \
|
||||
__isl_take isl_multi_##BASE *multi1, \
|
||||
__isl_take isl_multi_##BASE *multi2); \
|
||||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_product( \
|
||||
__isl_take isl_multi_##BASE *multi1, \
|
||||
__isl_take isl_multi_##BASE *multi2); \
|
||||
int isl_multi_##BASE##_range_is_wrapping( \
|
||||
__isl_keep isl_multi_##BASE *multi); \
|
||||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_range_factor_domain( \
|
||||
|
@ -110,12 +95,41 @@ __isl_give isl_multi_##BASE *isl_multi_##BASE##_scale_multi_val( \
|
|||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_scale_down_multi_val( \
|
||||
__isl_take isl_multi_##BASE *multi, \
|
||||
__isl_take isl_multi_val *mv); \
|
||||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_mod_multi_val( \
|
||||
__isl_take isl_multi_##BASE *multi, \
|
||||
__isl_take isl_multi_val *mv); \
|
||||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_sub( \
|
||||
__isl_take isl_multi_##BASE *multi1, \
|
||||
__isl_take isl_multi_##BASE *multi2); \
|
||||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_align_params( \
|
||||
__isl_take isl_multi_##BASE *multi, \
|
||||
__isl_take isl_space *model); \
|
||||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_from_range( \
|
||||
__isl_take isl_multi_##BASE *multi);
|
||||
|
||||
#define ISL_DECLARE_MULTI_NEG(BASE) \
|
||||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_neg( \
|
||||
__isl_take isl_multi_##BASE *multi);
|
||||
|
||||
#define ISL_DECLARE_MULTI_DIMS(BASE) \
|
||||
int isl_multi_##BASE##_involves_dims( \
|
||||
__isl_keep isl_multi_##BASE *multi, enum isl_dim_type type, \
|
||||
unsigned first, unsigned n); \
|
||||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_insert_dims( \
|
||||
__isl_take isl_multi_##BASE *multi, enum isl_dim_type type, \
|
||||
unsigned first, unsigned n); \
|
||||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_add_dims( \
|
||||
__isl_take isl_multi_##BASE *multi, enum isl_dim_type type, \
|
||||
unsigned n);
|
||||
|
||||
#define ISL_DECLARE_MULTI_WITH_DOMAIN(BASE) \
|
||||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_product( \
|
||||
__isl_take isl_multi_##BASE *multi1, \
|
||||
__isl_take isl_multi_##BASE *multi2); \
|
||||
__isl_give isl_multi_##BASE *isl_multi_##BASE##_splice( \
|
||||
__isl_take isl_multi_##BASE *multi1, unsigned in_pos, \
|
||||
unsigned out_pos, __isl_take isl_multi_##BASE *multi2);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,8 @@ extern struct isl_obj_vtable isl_obj_pw_qpolynomial_fold_vtable;
|
|||
#define isl_obj_pw_qpolynomial_fold (&isl_obj_pw_qpolynomial_fold_vtable)
|
||||
extern struct isl_obj_vtable isl_obj_union_pw_qpolynomial_fold_vtable;
|
||||
#define isl_obj_union_pw_qpolynomial_fold (&isl_obj_union_pw_qpolynomial_fold_vtable)
|
||||
extern struct isl_obj_vtable isl_obj_schedule_vtable;
|
||||
#define isl_obj_schedule (&isl_obj_schedule_vtable)
|
||||
struct isl_obj {
|
||||
isl_obj_type type;
|
||||
void *v;
|
||||
|
|
|
@ -170,11 +170,16 @@ __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_set_dim_name(
|
|||
int isl_pw_qpolynomial_find_dim_by_name(__isl_keep isl_pw_qpolynomial *pwqp,
|
||||
enum isl_dim_type type, const char *name);
|
||||
|
||||
__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_reset_user(
|
||||
__isl_take isl_pw_qpolynomial *pwqp);
|
||||
|
||||
__isl_give isl_set *isl_pw_qpolynomial_domain(__isl_take isl_pw_qpolynomial *pwqp);
|
||||
__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_intersect_domain(
|
||||
__isl_take isl_pw_qpolynomial *pwpq, __isl_take isl_set *set);
|
||||
__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_intersect_params(
|
||||
__isl_take isl_pw_qpolynomial *pwpq, __isl_take isl_set *set);
|
||||
__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_subtract_domain(
|
||||
__isl_take isl_pw_qpolynomial *pwpq, __isl_take isl_set *set);
|
||||
|
||||
__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_project_domain_on_params(
|
||||
__isl_take isl_pw_qpolynomial *pwqp);
|
||||
|
@ -361,12 +366,17 @@ int isl_pw_qpolynomial_fold_find_dim_by_name(
|
|||
__isl_keep isl_pw_qpolynomial_fold *pwf,
|
||||
enum isl_dim_type type, const char *name);
|
||||
|
||||
__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_reset_user(
|
||||
__isl_take isl_pw_qpolynomial_fold *pwf);
|
||||
|
||||
__isl_give isl_set *isl_pw_qpolynomial_fold_domain(
|
||||
__isl_take isl_pw_qpolynomial_fold *pwf);
|
||||
__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_intersect_domain(
|
||||
__isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_set *set);
|
||||
__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_intersect_params(
|
||||
__isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_set *set);
|
||||
__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_subtract_domain(
|
||||
__isl_take isl_pw_qpolynomial_fold *pwf, __isl_take isl_set *set);
|
||||
|
||||
__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_add(
|
||||
__isl_take isl_pw_qpolynomial_fold *pwf1,
|
||||
|
@ -486,14 +496,27 @@ __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_intersect_domain(
|
|||
__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_intersect_params(
|
||||
__isl_take isl_union_pw_qpolynomial *upwpq,
|
||||
__isl_take isl_set *set);
|
||||
__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_subtract_domain(
|
||||
__isl_take isl_union_pw_qpolynomial *upwpq,
|
||||
__isl_take isl_union_set *uset);
|
||||
|
||||
__isl_give isl_space *isl_union_pw_qpolynomial_get_space(
|
||||
__isl_keep isl_union_pw_qpolynomial *upwqp);
|
||||
|
||||
__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_set_dim_name(
|
||||
__isl_take isl_union_pw_qpolynomial *upwqp,
|
||||
enum isl_dim_type type, unsigned pos, const char *s);
|
||||
|
||||
int isl_union_pw_qpolynomial_find_dim_by_name(
|
||||
__isl_keep isl_union_pw_qpolynomial *upwqp,
|
||||
enum isl_dim_type type, const char *name);
|
||||
|
||||
__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_drop_dims(
|
||||
__isl_take isl_union_pw_qpolynomial *upwqp,
|
||||
enum isl_dim_type type, unsigned first, unsigned n);
|
||||
__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_reset_user(
|
||||
__isl_take isl_union_pw_qpolynomial *upwqp);
|
||||
|
||||
__isl_give isl_val *isl_union_pw_qpolynomial_eval(
|
||||
__isl_take isl_union_pw_qpolynomial *upwqp, __isl_take isl_point *pnt);
|
||||
|
||||
|
@ -510,6 +533,8 @@ __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_align_params(
|
|||
__isl_take isl_union_pw_qpolynomial *upwqp,
|
||||
__isl_take isl_space *model);
|
||||
|
||||
int isl_union_pw_qpolynomial_n_pw_qpolynomial(
|
||||
__isl_keep isl_union_pw_qpolynomial *upwqp);
|
||||
int isl_union_pw_qpolynomial_foreach_pw_qpolynomial(
|
||||
__isl_keep isl_union_pw_qpolynomial *upwqp,
|
||||
int (*fn)(__isl_take isl_pw_qpolynomial *pwqp, void *user), void *user);
|
||||
|
@ -562,16 +587,33 @@ __isl_give isl_union_pw_qpolynomial_fold *
|
|||
isl_union_pw_qpolynomial_fold_intersect_params(
|
||||
__isl_take isl_union_pw_qpolynomial_fold *upwf,
|
||||
__isl_take isl_set *set);
|
||||
__isl_give isl_union_pw_qpolynomial_fold *
|
||||
isl_union_pw_qpolynomial_fold_subtract_domain(
|
||||
__isl_take isl_union_pw_qpolynomial_fold *upwf,
|
||||
__isl_take isl_union_set *uset);
|
||||
|
||||
enum isl_fold isl_union_pw_qpolynomial_fold_get_type(
|
||||
__isl_keep isl_union_pw_qpolynomial_fold *upwf);
|
||||
__isl_give isl_space *isl_union_pw_qpolynomial_fold_get_space(
|
||||
__isl_keep isl_union_pw_qpolynomial_fold *upwf);
|
||||
|
||||
__isl_give isl_union_pw_qpolynomial_fold *
|
||||
isl_union_pw_qpolynomial_fold_set_dim_name(
|
||||
__isl_take isl_union_pw_qpolynomial_fold *upwf,
|
||||
enum isl_dim_type type, unsigned pos, const char *s);
|
||||
|
||||
int isl_union_pw_qpolynomial_fold_find_dim_by_name(
|
||||
__isl_keep isl_union_pw_qpolynomial_fold *upwf,
|
||||
enum isl_dim_type type, const char *name);
|
||||
|
||||
__isl_give isl_union_pw_qpolynomial_fold *
|
||||
isl_union_pw_qpolynomial_fold_drop_dims(
|
||||
__isl_take isl_union_pw_qpolynomial_fold *upwf,
|
||||
enum isl_dim_type type, unsigned first, unsigned n);
|
||||
__isl_give isl_union_pw_qpolynomial_fold *
|
||||
isl_union_pw_qpolynomial_fold_reset_user(
|
||||
__isl_take isl_union_pw_qpolynomial_fold *upwf);
|
||||
|
||||
__isl_give isl_val *isl_union_pw_qpolynomial_fold_eval(
|
||||
__isl_take isl_union_pw_qpolynomial_fold *upwf,
|
||||
__isl_take isl_point *pnt);
|
||||
|
@ -590,6 +632,8 @@ __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_align_pa
|
|||
__isl_take isl_union_pw_qpolynomial_fold *upwf,
|
||||
__isl_take isl_space *model);
|
||||
|
||||
int isl_union_pw_qpolynomial_fold_n_pw_qpolynomial_fold(
|
||||
__isl_keep isl_union_pw_qpolynomial_fold *upwf);
|
||||
int isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold(
|
||||
__isl_keep isl_union_pw_qpolynomial_fold *upwf,
|
||||
int (*fn)(__isl_take isl_pw_qpolynomial_fold *pwf,
|
||||
|
|
|
@ -36,6 +36,12 @@ __isl_give isl_printer *isl_printer_set_output_format(__isl_take isl_printer *p,
|
|||
int output_format);
|
||||
int isl_printer_get_output_format(__isl_keep isl_printer *p);
|
||||
|
||||
#define ISL_YAML_STYLE_BLOCK 0
|
||||
#define ISL_YAML_STYLE_FLOW 1
|
||||
__isl_give isl_printer *isl_printer_set_yaml_style(__isl_take isl_printer *p,
|
||||
int yaml_style);
|
||||
int isl_printer_get_yaml_style(__isl_keep isl_printer *p);
|
||||
|
||||
__isl_give isl_printer *isl_printer_set_indent_prefix(__isl_take isl_printer *p,
|
||||
const char *prefix);
|
||||
__isl_give isl_printer *isl_printer_set_prefix(__isl_take isl_printer *p,
|
||||
|
@ -53,6 +59,16 @@ __isl_give isl_printer *isl_printer_print_int(__isl_take isl_printer *p, int i);
|
|||
__isl_give isl_printer *isl_printer_print_str(__isl_take isl_printer *p,
|
||||
const char *s);
|
||||
|
||||
__isl_give isl_printer *isl_printer_yaml_start_mapping(
|
||||
__isl_take isl_printer *p);
|
||||
__isl_give isl_printer *isl_printer_yaml_end_mapping(
|
||||
__isl_take isl_printer *p);
|
||||
__isl_give isl_printer *isl_printer_yaml_start_sequence(
|
||||
__isl_take isl_printer *p);
|
||||
__isl_give isl_printer *isl_printer_yaml_end_sequence(
|
||||
__isl_take isl_printer *p);
|
||||
__isl_give isl_printer *isl_printer_yaml_next(__isl_take isl_printer *p);
|
||||
|
||||
__isl_give isl_printer *isl_printer_flush(__isl_take isl_printer *p);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
#include <isl/union_set_type.h>
|
||||
#include <isl/union_map_type.h>
|
||||
#include <isl/schedule_type.h>
|
||||
#include <isl/band.h>
|
||||
#include <isl/space.h>
|
||||
#include <isl/list.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
@ -12,8 +14,6 @@ extern "C" {
|
|||
|
||||
struct isl_schedule_constraints;
|
||||
typedef struct isl_schedule_constraints isl_schedule_constraints;
|
||||
struct isl_schedule;
|
||||
typedef struct isl_schedule isl_schedule;
|
||||
|
||||
int isl_options_set_schedule_max_coefficient(isl_ctx *ctx, int val);
|
||||
int isl_options_get_schedule_max_coefficient(isl_ctx *ctx);
|
||||
|
@ -42,6 +42,8 @@ __isl_give isl_schedule_constraints *isl_schedule_constraints_copy(
|
|||
__isl_keep isl_schedule_constraints *sc);
|
||||
__isl_give isl_schedule_constraints *isl_schedule_constraints_on_domain(
|
||||
__isl_take isl_union_set *domain);
|
||||
__isl_give isl_schedule_constraints *isl_schedule_constraints_set_context(
|
||||
__isl_take isl_schedule_constraints *sc, __isl_take isl_set *context);
|
||||
__isl_give isl_schedule_constraints *isl_schedule_constraints_set_validity(
|
||||
__isl_take isl_schedule_constraints *sc,
|
||||
__isl_take isl_union_map *validity);
|
||||
|
@ -71,14 +73,34 @@ __isl_give isl_schedule *isl_union_set_compute_schedule(
|
|||
__isl_take isl_union_set *domain,
|
||||
__isl_take isl_union_map *validity,
|
||||
__isl_take isl_union_map *proximity);
|
||||
|
||||
__isl_give isl_schedule *isl_schedule_empty(__isl_take isl_space *space);
|
||||
__isl_give isl_schedule *isl_schedule_from_domain(
|
||||
__isl_take isl_union_set *domain);
|
||||
__isl_give isl_schedule *isl_schedule_copy(__isl_keep isl_schedule *sched);
|
||||
__isl_null isl_schedule *isl_schedule_free(__isl_take isl_schedule *sched);
|
||||
__isl_give isl_union_map *isl_schedule_get_map(__isl_keep isl_schedule *sched);
|
||||
|
||||
isl_ctx *isl_schedule_get_ctx(__isl_keep isl_schedule *sched);
|
||||
|
||||
__isl_give isl_schedule_node *isl_schedule_get_root(
|
||||
__isl_keep isl_schedule *schedule);
|
||||
__isl_give isl_union_set *isl_schedule_get_domain(
|
||||
__isl_keep isl_schedule *schedule);
|
||||
|
||||
int isl_schedule_foreach_schedule_node(__isl_keep isl_schedule *sched,
|
||||
int (*fn)(__isl_keep isl_schedule_node *node, void *user), void *user);
|
||||
__isl_give isl_schedule *isl_schedule_map_schedule_node(
|
||||
__isl_take isl_schedule *schedule,
|
||||
__isl_give isl_schedule_node *(*fn)(
|
||||
__isl_take isl_schedule_node *node, void *user), void *user);
|
||||
|
||||
__isl_give isl_band_list *isl_schedule_get_band_forest(
|
||||
__isl_keep isl_schedule *schedule);
|
||||
|
||||
__isl_give isl_schedule *isl_schedule_read_from_file(isl_ctx *ctx, FILE *input);
|
||||
__isl_give isl_schedule *isl_schedule_read_from_str(isl_ctx *ctx,
|
||||
const char *str);
|
||||
__isl_give isl_printer *isl_printer_print_schedule(__isl_take isl_printer *p,
|
||||
__isl_keep isl_schedule *schedule);
|
||||
void isl_schedule_dump(__isl_keep isl_schedule *schedule);
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
#ifndef ISL_SCHEDULE_NODE_H
|
||||
#define ISL_SCHEDULE_NODE_H
|
||||
|
||||
#include <isl/schedule_type.h>
|
||||
#include <isl/union_set_type.h>
|
||||
#include <isl/aff_type.h>
|
||||
#include <isl/val.h>
|
||||
#include <isl/space.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
__isl_give isl_schedule_node *isl_schedule_node_from_domain(
|
||||
__isl_take isl_union_set *domain);
|
||||
__isl_give isl_schedule_node *isl_schedule_node_copy(
|
||||
__isl_keep isl_schedule_node *node);
|
||||
__isl_null isl_schedule_node *isl_schedule_node_free(
|
||||
__isl_take isl_schedule_node *node);
|
||||
|
||||
isl_ctx *isl_schedule_node_get_ctx(__isl_keep isl_schedule_node *node);
|
||||
enum isl_schedule_node_type isl_schedule_node_get_type(
|
||||
__isl_keep isl_schedule_node *node);
|
||||
enum isl_schedule_node_type isl_schedule_node_get_parent_type(
|
||||
__isl_keep isl_schedule_node *node);
|
||||
__isl_give isl_schedule *isl_schedule_node_get_schedule(
|
||||
__isl_keep isl_schedule_node *node);
|
||||
|
||||
int isl_schedule_node_foreach_descendant(__isl_keep isl_schedule_node *node,
|
||||
int (*fn)(__isl_keep isl_schedule_node *node, void *user), void *user);
|
||||
__isl_give isl_schedule_node *isl_schedule_node_map_descendant(
|
||||
__isl_take isl_schedule_node *node,
|
||||
__isl_give isl_schedule_node *(*fn)(__isl_take isl_schedule_node *node,
|
||||
void *user), void *user);
|
||||
|
||||
int isl_schedule_node_get_tree_depth(__isl_keep isl_schedule_node *node);
|
||||
int isl_schedule_node_has_parent(__isl_keep isl_schedule_node *node);
|
||||
int isl_schedule_node_has_children(__isl_keep isl_schedule_node *node);
|
||||
int isl_schedule_node_has_previous_sibling(__isl_keep isl_schedule_node *node);
|
||||
int isl_schedule_node_has_next_sibling(__isl_keep isl_schedule_node *node);
|
||||
int isl_schedule_node_n_children(__isl_keep isl_schedule_node *node);
|
||||
int isl_schedule_node_get_child_position(__isl_keep isl_schedule_node *node);
|
||||
__isl_give isl_schedule_node *isl_schedule_node_get_child(
|
||||
__isl_keep isl_schedule_node *node, int pos);
|
||||
|
||||
__isl_give isl_schedule_node *isl_schedule_node_parent(
|
||||
__isl_take isl_schedule_node *node);
|
||||
__isl_give isl_schedule_node *isl_schedule_node_child(
|
||||
__isl_take isl_schedule_node *node, int pos);
|
||||
__isl_give isl_schedule_node *isl_schedule_node_first_child(
|
||||
__isl_take isl_schedule_node *node);
|
||||
__isl_give isl_schedule_node *isl_schedule_node_previous_sibling(
|
||||
__isl_take isl_schedule_node *node);
|
||||
__isl_give isl_schedule_node *isl_schedule_node_next_sibling(
|
||||
__isl_take isl_schedule_node *node);
|
||||
|
||||
__isl_give isl_space *isl_schedule_node_band_get_space(
|
||||
__isl_keep isl_schedule_node *node);
|
||||
__isl_give isl_multi_union_pw_aff *isl_schedule_node_band_get_partial_schedule(
|
||||
__isl_keep isl_schedule_node *node);
|
||||
__isl_give isl_union_map *isl_schedule_node_band_get_partial_schedule_union_map(
|
||||
__isl_keep isl_schedule_node *node);
|
||||
unsigned isl_schedule_node_band_n_member(__isl_keep isl_schedule_node *node);
|
||||
int isl_schedule_node_band_member_get_coincident(
|
||||
__isl_keep isl_schedule_node *node, int pos);
|
||||
__isl_give isl_schedule_node *isl_schedule_node_band_member_set_coincident(
|
||||
__isl_take isl_schedule_node *node, int pos, int coincident);
|
||||
int isl_schedule_node_band_get_permutable(__isl_keep isl_schedule_node *node);
|
||||
__isl_give isl_schedule_node *isl_schedule_node_band_set_permutable(
|
||||
__isl_take isl_schedule_node *node, int permutable);
|
||||
|
||||
int isl_options_set_tile_scale_tile_loops(isl_ctx *ctx, int val);
|
||||
int isl_options_get_tile_scale_tile_loops(isl_ctx *ctx);
|
||||
int isl_options_set_tile_shift_point_loops(isl_ctx *ctx, int val);
|
||||
int isl_options_get_tile_shift_point_loops(isl_ctx *ctx);
|
||||
|
||||
__isl_give isl_schedule_node *isl_schedule_node_band_scale(
|
||||
__isl_take isl_schedule_node *node, __isl_take isl_multi_val *mv);
|
||||
__isl_give isl_schedule_node *isl_schedule_node_band_scale_down(
|
||||
__isl_take isl_schedule_node *node, __isl_take isl_multi_val *mv);
|
||||
__isl_give isl_schedule_node *isl_schedule_node_band_tile(
|
||||
__isl_take isl_schedule_node *node, __isl_take isl_multi_val *sizes);
|
||||
__isl_give isl_schedule_node *isl_schedule_node_band_sink(
|
||||
__isl_take isl_schedule_node *node);
|
||||
__isl_give isl_schedule_node *isl_schedule_node_band_split(
|
||||
__isl_take isl_schedule_node *node, int pos);
|
||||
|
||||
__isl_give isl_union_set *isl_schedule_node_domain_get_domain(
|
||||
__isl_keep isl_schedule_node *node);
|
||||
__isl_give isl_union_set *isl_schedule_node_filter_get_filter(
|
||||
__isl_keep isl_schedule_node *node);
|
||||
|
||||
__isl_give isl_union_set *isl_schedule_node_get_universe_domain(
|
||||
__isl_keep isl_schedule_node *node);
|
||||
__isl_give isl_union_pw_multi_aff *
|
||||
isl_schedule_node_get_prefix_schedule_union_pw_multi_aff(
|
||||
__isl_keep isl_schedule_node *node);
|
||||
__isl_give isl_union_map *isl_schedule_node_get_prefix_schedule_union_map(
|
||||
__isl_keep isl_schedule_node *node);
|
||||
__isl_give isl_union_map *isl_schedule_node_get_subtree_schedule_union_map(
|
||||
__isl_keep isl_schedule_node *node);
|
||||
|
||||
__isl_give isl_schedule_node *isl_schedule_node_insert_partial_schedule(
|
||||
__isl_take isl_schedule_node *node,
|
||||
__isl_take isl_multi_union_pw_aff *schedule);
|
||||
__isl_give isl_schedule_node *isl_schedule_node_insert_filter(
|
||||
__isl_take isl_schedule_node *node, __isl_take isl_union_set *filter);
|
||||
__isl_give isl_schedule_node *isl_schedule_node_insert_sequence(
|
||||
__isl_take isl_schedule_node *node,
|
||||
__isl_take isl_union_set_list *filters);
|
||||
__isl_give isl_schedule_node *isl_schedule_node_insert_set(
|
||||
__isl_take isl_schedule_node *node,
|
||||
__isl_take isl_union_set_list *filters);
|
||||
|
||||
__isl_give isl_printer *isl_printer_print_schedule_node(
|
||||
__isl_take isl_printer *p, __isl_keep isl_schedule_node *node);
|
||||
void isl_schedule_node_dump(__isl_keep isl_schedule_node *node);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef ISL_SCHEDULE_TYPE_H
|
||||
#define ISL_SCHEDULE_TYPE_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum isl_schedule_node_type {
|
||||
isl_schedule_node_error = -1,
|
||||
isl_schedule_node_band,
|
||||
isl_schedule_node_domain,
|
||||
isl_schedule_node_filter,
|
||||
isl_schedule_node_leaf,
|
||||
isl_schedule_node_sequence,
|
||||
isl_schedule_node_set
|
||||
};
|
||||
|
||||
struct isl_schedule_node;
|
||||
typedef struct isl_schedule_node isl_schedule_node;
|
||||
|
||||
struct isl_schedule;
|
||||
typedef struct isl_schedule isl_schedule;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -158,10 +158,6 @@ __isl_give isl_printer *isl_printer_print_basic_set(
|
|||
__isl_take isl_printer *printer, __isl_keep isl_basic_set *bset);
|
||||
__isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *printer,
|
||||
__isl_keep isl_set *map);
|
||||
void isl_basic_set_print(__isl_keep isl_basic_set *bset, FILE *out, int indent,
|
||||
const char *prefix, const char *suffix, unsigned output_format);
|
||||
void isl_set_print(__isl_keep struct isl_set *set, FILE *out, int indent,
|
||||
unsigned output_format);
|
||||
__isl_give isl_basic_set *isl_basic_set_fix_si(__isl_take isl_basic_set *bset,
|
||||
enum isl_dim_type type, unsigned pos, int value);
|
||||
__isl_give isl_basic_set *isl_basic_set_fix_val(__isl_take isl_basic_set *bset,
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <isl/aff_type.h>
|
||||
#include <isl/obj.h>
|
||||
#include <isl/val.h>
|
||||
#include <isl/schedule_type.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
|
@ -46,55 +47,47 @@ __isl_give char *isl_token_get_str(isl_ctx *ctx, struct isl_token *tok);
|
|||
int isl_token_get_type(struct isl_token *tok);
|
||||
void isl_token_free(struct isl_token *tok);
|
||||
|
||||
struct isl_stream {
|
||||
struct isl_ctx *ctx;
|
||||
FILE *file;
|
||||
const char *str;
|
||||
int line;
|
||||
int col;
|
||||
int eof;
|
||||
struct isl_stream;
|
||||
typedef struct isl_stream isl_stream;
|
||||
|
||||
char *buffer;
|
||||
size_t size;
|
||||
size_t len;
|
||||
int c;
|
||||
int un[5];
|
||||
int n_un;
|
||||
__isl_give isl_stream *isl_stream_new_file(isl_ctx *ctx, FILE *file);
|
||||
__isl_give isl_stream *isl_stream_new_str(isl_ctx *ctx, const char *str);
|
||||
void isl_stream_free(__isl_take isl_stream *s);
|
||||
|
||||
struct isl_token *tokens[5];
|
||||
int n_token;
|
||||
isl_ctx *isl_stream_get_ctx(__isl_keep isl_stream *s);
|
||||
|
||||
struct isl_hash_table *keywords;
|
||||
enum isl_token_type next_type;
|
||||
};
|
||||
void isl_stream_error(__isl_keep isl_stream *s, struct isl_token *tok,
|
||||
char *msg);
|
||||
|
||||
struct isl_stream* isl_stream_new_file(struct isl_ctx *ctx, FILE *file);
|
||||
struct isl_stream* isl_stream_new_str(struct isl_ctx *ctx, const char *str);
|
||||
void isl_stream_free(struct isl_stream *s);
|
||||
struct isl_token *isl_stream_next_token(__isl_keep isl_stream *s);
|
||||
struct isl_token *isl_stream_next_token_on_same_line(__isl_keep isl_stream *s);
|
||||
int isl_stream_next_token_is(__isl_keep isl_stream *s, int type);
|
||||
void isl_stream_push_token(__isl_keep isl_stream *s, struct isl_token *tok);
|
||||
void isl_stream_flush_tokens(__isl_keep isl_stream *s);
|
||||
int isl_stream_eat_if_available(__isl_keep isl_stream *s, int type);
|
||||
char *isl_stream_read_ident_if_available(__isl_keep isl_stream *s);
|
||||
int isl_stream_eat(__isl_keep isl_stream *s, int type);
|
||||
int isl_stream_is_empty(__isl_keep isl_stream *s);
|
||||
int isl_stream_skip_line(__isl_keep isl_stream *s);
|
||||
|
||||
void isl_stream_error(struct isl_stream *s, struct isl_token *tok, char *msg);
|
||||
|
||||
struct isl_token *isl_stream_next_token(struct isl_stream *s);
|
||||
struct isl_token *isl_stream_next_token_on_same_line(struct isl_stream *s);
|
||||
int isl_stream_next_token_is(struct isl_stream *s, int type);
|
||||
void isl_stream_push_token(struct isl_stream *s, struct isl_token *tok);
|
||||
void isl_stream_flush_tokens(struct isl_stream *s);
|
||||
int isl_stream_eat_if_available(struct isl_stream *s, int type);
|
||||
char *isl_stream_read_ident_if_available(struct isl_stream *s);
|
||||
int isl_stream_eat(struct isl_stream *s, int type);
|
||||
int isl_stream_is_empty(struct isl_stream *s);
|
||||
int isl_stream_skip_line(struct isl_stream *s);
|
||||
|
||||
enum isl_token_type isl_stream_register_keyword(struct isl_stream *s,
|
||||
enum isl_token_type isl_stream_register_keyword(__isl_keep isl_stream *s,
|
||||
const char *name);
|
||||
|
||||
struct isl_obj isl_stream_read_obj(struct isl_stream *s);
|
||||
__isl_give isl_multi_aff *isl_stream_read_multi_aff(struct isl_stream *s);
|
||||
__isl_give isl_map *isl_stream_read_map(struct isl_stream *s);
|
||||
__isl_give isl_set *isl_stream_read_set(struct isl_stream *s);
|
||||
struct isl_obj isl_stream_read_obj(__isl_keep isl_stream *s);
|
||||
__isl_give isl_val *isl_stream_read_val(__isl_keep isl_stream *s);
|
||||
__isl_give isl_multi_aff *isl_stream_read_multi_aff(__isl_keep isl_stream *s);
|
||||
__isl_give isl_map *isl_stream_read_map(__isl_keep isl_stream *s);
|
||||
__isl_give isl_set *isl_stream_read_set(__isl_keep isl_stream *s);
|
||||
__isl_give isl_pw_qpolynomial *isl_stream_read_pw_qpolynomial(
|
||||
struct isl_stream *s);
|
||||
__isl_give isl_union_map *isl_stream_read_union_map(struct isl_stream *s);
|
||||
__isl_keep isl_stream *s);
|
||||
__isl_give isl_union_map *isl_stream_read_union_map(__isl_keep isl_stream *s);
|
||||
__isl_give isl_schedule *isl_stream_read_schedule(isl_stream *s);
|
||||
|
||||
int isl_stream_yaml_read_start_mapping(__isl_keep isl_stream *s);
|
||||
int isl_stream_yaml_read_end_mapping(__isl_keep isl_stream *s);
|
||||
int isl_stream_yaml_read_start_sequence(__isl_keep isl_stream *s);
|
||||
int isl_stream_yaml_read_end_sequence(__isl_keep isl_stream *s);
|
||||
int isl_stream_yaml_next(__isl_keep isl_stream *s);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
|
|
@ -43,6 +43,8 @@ __isl_give isl_union_set *isl_union_map_domain(__isl_take isl_union_map *umap);
|
|||
__isl_give isl_union_set *isl_union_map_range(__isl_take isl_union_map *umap);
|
||||
__isl_give isl_union_map *isl_union_map_domain_map(
|
||||
__isl_take isl_union_map *umap);
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_map_domain_map_union_pw_multi_aff(
|
||||
__isl_take isl_union_map *umap);
|
||||
__isl_give isl_union_map *isl_union_map_range_map(
|
||||
__isl_take isl_union_map *umap);
|
||||
__isl_give isl_union_map *isl_union_set_wrapped_domain_map(
|
||||
|
@ -58,6 +60,8 @@ __isl_give isl_union_map *isl_union_map_affine_hull(
|
|||
__isl_export
|
||||
__isl_give isl_union_map *isl_union_map_polyhedral_hull(
|
||||
__isl_take isl_union_map *umap);
|
||||
__isl_give isl_union_map *isl_union_map_remove_redundancies(
|
||||
__isl_take isl_union_map *umap);
|
||||
__isl_give isl_union_map *isl_union_map_simple_hull(
|
||||
__isl_take isl_union_map *umap);
|
||||
__isl_export
|
||||
|
@ -88,6 +92,8 @@ __isl_give isl_union_map *isl_union_map_product(__isl_take isl_union_map *umap1,
|
|||
__isl_take isl_union_map *umap2);
|
||||
__isl_give isl_union_map *isl_union_map_domain_product(
|
||||
__isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2);
|
||||
__isl_give isl_union_map *isl_union_map_flat_domain_product(
|
||||
__isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2);
|
||||
__isl_give isl_union_map *isl_union_map_range_product(
|
||||
__isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2);
|
||||
__isl_give isl_union_map *isl_union_map_flat_range_product(
|
||||
|
@ -186,6 +192,8 @@ int isl_union_map_is_subset(__isl_keep isl_union_map *umap1,
|
|||
__isl_export
|
||||
int isl_union_map_is_equal(__isl_keep isl_union_map *umap1,
|
||||
__isl_keep isl_union_map *umap2);
|
||||
int isl_union_map_is_disjoint(__isl_keep isl_union_map *umap1,
|
||||
__isl_keep isl_union_map *umap2);
|
||||
__isl_export
|
||||
int isl_union_map_is_strict_subset(__isl_keep isl_union_map *umap1,
|
||||
__isl_keep isl_union_map *umap2);
|
||||
|
@ -218,6 +226,16 @@ __isl_give isl_union_map *isl_union_map_lex_gt_union_map(
|
|||
__isl_give isl_union_map *isl_union_map_lex_ge_union_map(
|
||||
__isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2);
|
||||
|
||||
__isl_give isl_union_map *isl_union_map_eq_at_multi_union_pw_aff(
|
||||
__isl_take isl_union_map *umap,
|
||||
__isl_take isl_multi_union_pw_aff *mupa);
|
||||
__isl_give isl_union_map *isl_union_map_lex_lt_at_multi_union_pw_aff(
|
||||
__isl_take isl_union_map *umap,
|
||||
__isl_take isl_multi_union_pw_aff *mupa);
|
||||
__isl_give isl_union_map *isl_union_map_lex_gt_at_multi_union_pw_aff(
|
||||
__isl_take isl_union_map *umap,
|
||||
__isl_take isl_multi_union_pw_aff *mupa);
|
||||
|
||||
__isl_give isl_union_map *isl_union_map_read_from_file(isl_ctx *ctx,
|
||||
FILE *input);
|
||||
__isl_constructor
|
||||
|
@ -240,6 +258,8 @@ __isl_give isl_union_map *isl_union_map_align_params(
|
|||
__isl_give isl_union_set *isl_union_set_align_params(
|
||||
__isl_take isl_union_set *uset, __isl_take isl_space *model);
|
||||
|
||||
ISL_DECLARE_LIST_FN(union_map)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define ISL_UNION_MAP_TYPE_H
|
||||
|
||||
#include <isl/ctx.h>
|
||||
#include <isl/list.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
|
@ -9,9 +10,11 @@ extern "C" {
|
|||
|
||||
struct __isl_export isl_union_map;
|
||||
typedef struct isl_union_map isl_union_map;
|
||||
ISL_DECLARE_LIST_TYPE(union_map)
|
||||
#ifndef isl_union_set
|
||||
struct __isl_export isl_union_set;
|
||||
typedef struct isl_union_set isl_union_set;
|
||||
ISL_DECLARE_LIST_TYPE(union_set)
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -39,6 +39,8 @@ __isl_give isl_union_set *isl_union_set_affine_hull(
|
|||
__isl_export
|
||||
__isl_give isl_union_set *isl_union_set_polyhedral_hull(
|
||||
__isl_take isl_union_set *uset);
|
||||
__isl_give isl_union_set *isl_union_set_remove_redundancies(
|
||||
__isl_take isl_union_set *uset);
|
||||
__isl_give isl_union_set *isl_union_set_simple_hull(
|
||||
__isl_take isl_union_set *uset);
|
||||
__isl_export
|
||||
|
@ -84,6 +86,10 @@ __isl_give isl_union_set *isl_union_set_preimage_union_pw_multi_aff(
|
|||
__isl_take isl_union_set *uset,
|
||||
__isl_take isl_union_pw_multi_aff *upma);
|
||||
|
||||
__isl_give isl_union_set *isl_union_set_project_out(
|
||||
__isl_take isl_union_set *uset,
|
||||
enum isl_dim_type type, unsigned first, unsigned n);
|
||||
|
||||
int isl_union_set_is_params(__isl_keep isl_union_set *uset);
|
||||
__isl_export
|
||||
int isl_union_set_is_empty(__isl_keep isl_union_set *uset);
|
||||
|
@ -94,6 +100,8 @@ int isl_union_set_is_subset(__isl_keep isl_union_set *uset1,
|
|||
__isl_export
|
||||
int isl_union_set_is_equal(__isl_keep isl_union_set *uset1,
|
||||
__isl_keep isl_union_set *uset2);
|
||||
int isl_union_set_is_disjoint(__isl_keep isl_union_set *uset1,
|
||||
__isl_keep isl_union_set *uset2);
|
||||
__isl_export
|
||||
int isl_union_set_is_strict_subset(__isl_keep isl_union_set *uset1,
|
||||
__isl_keep isl_union_set *uset2);
|
||||
|
@ -138,6 +146,11 @@ __isl_give isl_printer *isl_printer_print_union_set(__isl_take isl_printer *p,
|
|||
__isl_keep isl_union_set *uset);
|
||||
void isl_union_set_dump(__isl_keep isl_union_set *uset);
|
||||
|
||||
ISL_DECLARE_LIST_FN(union_set)
|
||||
|
||||
__isl_give isl_union_set *isl_union_set_list_union(
|
||||
__isl_take isl_union_set_list *list);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -19,6 +19,9 @@ struct isl_multi_val;
|
|||
typedef struct isl_multi_val isl_multi_val;
|
||||
|
||||
ISL_DECLARE_MULTI(val)
|
||||
ISL_DECLARE_MULTI_NEG(val)
|
||||
ISL_DECLARE_MULTI_DIMS(val)
|
||||
ISL_DECLARE_MULTI_WITH_DOMAIN(val)
|
||||
|
||||
__isl_give isl_val *isl_val_zero(isl_ctx *ctx);
|
||||
__isl_give isl_val *isl_val_one(isl_ctx *ctx);
|
||||
|
@ -102,6 +105,8 @@ __isl_give isl_multi_val *isl_multi_val_add_val(__isl_take isl_multi_val *mv,
|
|||
__isl_give isl_multi_val *isl_multi_val_mod_val(__isl_take isl_multi_val *mv,
|
||||
__isl_take isl_val *v);
|
||||
|
||||
__isl_give isl_multi_val *isl_multi_val_read_from_str(isl_ctx *ctx,
|
||||
const char *str);
|
||||
__isl_give isl_printer *isl_printer_print_multi_val(__isl_take isl_printer *p,
|
||||
__isl_keep isl_multi_val *mv);
|
||||
void isl_multi_val_dump(__isl_keep isl_multi_val *mv);
|
||||
|
|
|
@ -174,6 +174,14 @@ static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Clang changed its API from 3.5 to 3.6, we fix this with a simple overloaded
|
||||
* function here.
|
||||
*/
|
||||
struct ClangAPI {
|
||||
static Job *command(Job *J) { return J; }
|
||||
static Job *command(Job &J) { return &J; }
|
||||
};
|
||||
|
||||
/* Create a CompilerInvocation object that stores the command line
|
||||
* arguments constructed by the driver.
|
||||
* The arguments are mainly useful for setting up the system include
|
||||
|
@ -191,7 +199,7 @@ static CompilerInvocation *construct_invocation(const char *filename,
|
|||
driver->BuildCompilation(llvm::ArrayRef<const char *>(Argv)));
|
||||
JobList &Jobs = compilation->getJobs();
|
||||
|
||||
Command *cmd = cast<Command>(*Jobs.begin());
|
||||
Command *cmd = cast<Command>(ClangAPI::command(*Jobs.begin()));
|
||||
if (strcmp(cmd->getCreator().getName(), "clang"))
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -220,8 +220,8 @@ static void print_callback(QualType type, int arg)
|
|||
for (int i = 0; i < n_arg - 1; ++i) {
|
||||
string arg_type;
|
||||
arg_type = type2python(extract_type(fn->getArgType(i)));
|
||||
printf(" cb_arg%d = %s(ctx=arg0.ctx, ptr=cb_arg%d)\n",
|
||||
i, arg_type.c_str(), i);
|
||||
printf(" cb_arg%d = %s(ctx=arg0.ctx, "
|
||||
"ptr=cb_arg%d)\n", i, arg_type.c_str(), i);
|
||||
}
|
||||
printf(" try:\n");
|
||||
printf(" arg%d(", arg);
|
||||
|
@ -446,7 +446,8 @@ void isl_class::print(map<string, isl_class> &classes, set<string> &done)
|
|||
printf(" libc.free(ptr)\n");
|
||||
printf(" return res\n");
|
||||
printf(" def __repr__(self):\n");
|
||||
printf(" return 'isl.%s(\"%%s\")' %% str(self)\n", p_name.c_str());
|
||||
printf(" return 'isl.%s(\"%%s\")' %% str(self)\n",
|
||||
p_name.c_str());
|
||||
|
||||
for (in = methods.begin(); in != methods.end(); ++in)
|
||||
print_method(*in, subclass, super);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -141,6 +141,8 @@ void isl_seq_preimage(isl_int *dst, isl_int *src,
|
|||
int n_div_ma, int n_div_bmap,
|
||||
isl_int f, isl_int c1, isl_int c2, isl_int g, int has_denom);
|
||||
|
||||
__isl_give isl_aff *isl_aff_substitute_equalities(__isl_take isl_aff *aff,
|
||||
__isl_take isl_basic_set *eq);
|
||||
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute(
|
||||
__isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, unsigned pos,
|
||||
__isl_keep isl_pw_aff *subs);
|
||||
|
@ -155,4 +157,19 @@ int isl_pw_aff_check_match_domain_space(__isl_keep isl_pw_aff *pa,
|
|||
|
||||
#include <isl_multi_templ.h>
|
||||
|
||||
#undef EL
|
||||
#define EL isl_union_pw_aff
|
||||
|
||||
#include <isl_list_templ.h>
|
||||
|
||||
#undef BASE
|
||||
#define BASE union_pw_aff
|
||||
|
||||
#include <isl_multi_templ.h>
|
||||
|
||||
#undef EL
|
||||
#define EL isl_union_pw_multi_aff
|
||||
|
||||
#include <isl_list_templ.h>
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1147,6 +1147,19 @@ __isl_give isl_set *isl_set_detect_equalities(__isl_take isl_set *set)
|
|||
return (isl_set *)isl_map_detect_equalities((isl_map *)set);
|
||||
}
|
||||
|
||||
/* Return the superset of "bmap" described by the equalities
|
||||
* satisfied by "bmap" that are already known.
|
||||
*/
|
||||
__isl_give isl_basic_map *isl_basic_map_plain_affine_hull(
|
||||
__isl_take isl_basic_map *bmap)
|
||||
{
|
||||
bmap = isl_basic_map_cow(bmap);
|
||||
if (bmap)
|
||||
isl_basic_map_free_inequality(bmap, bmap->n_ineq);
|
||||
bmap = isl_basic_map_finalize(bmap);
|
||||
return bmap;
|
||||
}
|
||||
|
||||
/* After computing the rational affine hull (by detecting the implicit
|
||||
* equalities), we compute the additional equalities satisfied by
|
||||
* the integer points (if any) and add the original equalities back in.
|
||||
|
@ -1154,10 +1167,7 @@ __isl_give isl_set *isl_set_detect_equalities(__isl_take isl_set *set)
|
|||
struct isl_basic_map *isl_basic_map_affine_hull(struct isl_basic_map *bmap)
|
||||
{
|
||||
bmap = isl_basic_map_detect_equalities(bmap);
|
||||
bmap = isl_basic_map_cow(bmap);
|
||||
if (bmap)
|
||||
isl_basic_map_free_inequality(bmap, bmap->n_ineq);
|
||||
bmap = isl_basic_map_finalize(bmap);
|
||||
bmap = isl_basic_map_plain_affine_hull(bmap);
|
||||
return bmap;
|
||||
}
|
||||
|
||||
|
|
|
@ -1807,7 +1807,7 @@ __isl_give isl_aff *isl_ast_build_get_offset(
|
|||
* value that, moreover, can be described by a single affine expression
|
||||
* in terms of the outer dimensions and parameters?
|
||||
*
|
||||
* If not, then the correponding affine expression in build->values
|
||||
* If not, then the corresponding affine expression in build->values
|
||||
* is set to be equal to the same input dimension.
|
||||
* Otherwise, it is set to the requested expression in terms of
|
||||
* outer dimensions and parameters.
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
/*
|
||||
* Copyright 2012-2014 Ecole Normale Superieure
|
||||
* Copyright 2014 INRIA Rocquencourt
|
||||
*
|
||||
* Use of this software is governed by the MIT license
|
||||
*
|
||||
* Written by Sven Verdoolaege,
|
||||
* Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
|
||||
* and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
|
||||
* B.P. 105 - 78153 Le Chesnay, France
|
||||
*/
|
||||
|
||||
#include <isl/ilp.h>
|
||||
|
@ -29,11 +32,120 @@ static __isl_give isl_aff *oppose_div_arg(__isl_take isl_aff *aff,
|
|||
return aff;
|
||||
}
|
||||
|
||||
/* Create an isl_ast_expr evaluating the div at position "pos" in "ls".
|
||||
* The result is simplified in terms of build->domain.
|
||||
/* Internal data structure used inside isl_ast_expr_add_term.
|
||||
* The domain of "build" is used to simplify the expressions.
|
||||
* "build" needs to be set by the caller of isl_ast_expr_add_term.
|
||||
* "cst" is the constant term of the expression in which the added term
|
||||
* appears. It may be modified by isl_ast_expr_add_term.
|
||||
*
|
||||
* "v" is the coefficient of the term that is being constructed and
|
||||
* is set internally by isl_ast_expr_add_term.
|
||||
*/
|
||||
struct isl_ast_add_term_data {
|
||||
isl_ast_build *build;
|
||||
isl_val *cst;
|
||||
isl_val *v;
|
||||
};
|
||||
|
||||
/* Given the numerator "aff" of the argument of an integer division
|
||||
* with denominator "d", check if it can be made non-negative over
|
||||
* data->build->domain by stealing part of the constant term of
|
||||
* the expression in which the integer division appears.
|
||||
*
|
||||
* In particular, the outer expression is of the form
|
||||
*
|
||||
* v * floor(aff/d) + cst
|
||||
*
|
||||
* We already know that "aff" itself may attain negative values.
|
||||
* Here we check if aff + d*floor(cst/v) is non-negative, such
|
||||
* that we could rewrite the expression to
|
||||
*
|
||||
* v * floor((aff + d*floor(cst/v))/d) + cst - v*floor(cst/v)
|
||||
*
|
||||
* Note that aff + d*floor(cst/v) can only possibly be non-negative
|
||||
* if data->cst and data->v have the same sign.
|
||||
* Similarly, if floor(cst/v) is zero, then there is no point in
|
||||
* checking again.
|
||||
*/
|
||||
static int is_non_neg_after_stealing(__isl_keep isl_aff *aff,
|
||||
__isl_keep isl_val *d, struct isl_ast_add_term_data *data)
|
||||
{
|
||||
isl_aff *shifted;
|
||||
isl_val *shift;
|
||||
int is_zero;
|
||||
int non_neg;
|
||||
|
||||
if (isl_val_sgn(data->cst) != isl_val_sgn(data->v))
|
||||
return 0;
|
||||
|
||||
shift = isl_val_div(isl_val_copy(data->cst), isl_val_copy(data->v));
|
||||
shift = isl_val_floor(shift);
|
||||
is_zero = isl_val_is_zero(shift);
|
||||
if (is_zero < 0 || is_zero) {
|
||||
isl_val_free(shift);
|
||||
return is_zero < 0 ? -1 : 0;
|
||||
}
|
||||
shift = isl_val_mul(shift, isl_val_copy(d));
|
||||
shifted = isl_aff_copy(aff);
|
||||
shifted = isl_aff_add_constant_val(shifted, shift);
|
||||
non_neg = isl_ast_build_aff_is_nonneg(data->build, shifted);
|
||||
isl_aff_free(shifted);
|
||||
|
||||
return non_neg;
|
||||
}
|
||||
|
||||
/* Given the numerator "aff' of the argument of an integer division
|
||||
* with denominator "d", steal part of the constant term of
|
||||
* the expression in which the integer division appears to make it
|
||||
* non-negative over data->build->domain.
|
||||
*
|
||||
* In particular, the outer expression is of the form
|
||||
*
|
||||
* v * floor(aff/d) + cst
|
||||
*
|
||||
* We know that "aff" itself may attain negative values,
|
||||
* but that aff + d*floor(cst/v) is non-negative.
|
||||
* Find the minimal positive value that we need to add to "aff"
|
||||
* to make it positive and adjust data->cst accordingly.
|
||||
* That is, compute the minimal value "m" of "aff" over
|
||||
* data->build->domain and take
|
||||
*
|
||||
* s = ceil(m/d)
|
||||
*
|
||||
* such that
|
||||
*
|
||||
* aff + d * s >= 0
|
||||
*
|
||||
* and rewrite the expression to
|
||||
*
|
||||
* v * floor((aff + s*d)/d) + (cst - v*s)
|
||||
*/
|
||||
static __isl_give isl_aff *steal_from_cst(__isl_take isl_aff *aff,
|
||||
__isl_keep isl_val *d, struct isl_ast_add_term_data *data)
|
||||
{
|
||||
isl_set *domain;
|
||||
isl_val *shift, *t;
|
||||
|
||||
domain = isl_ast_build_get_domain(data->build);
|
||||
shift = isl_set_min_val(domain, aff);
|
||||
isl_set_free(domain);
|
||||
|
||||
shift = isl_val_neg(shift);
|
||||
shift = isl_val_div(shift, isl_val_copy(d));
|
||||
shift = isl_val_ceil(shift);
|
||||
|
||||
t = isl_val_copy(shift);
|
||||
t = isl_val_mul(t, isl_val_copy(data->v));
|
||||
data->cst = isl_val_sub(data->cst, t);
|
||||
|
||||
shift = isl_val_mul(shift, isl_val_copy(d));
|
||||
return isl_aff_add_constant_val(aff, shift);
|
||||
}
|
||||
|
||||
/* Create an isl_ast_expr evaluating the div at position "pos" in "ls".
|
||||
* The result is simplified in terms of data->build->domain.
|
||||
* This function may change (the sign of) data->v.
|
||||
*
|
||||
* *change_sign is set by this function if the sign of
|
||||
* the expression has changed.
|
||||
* "ls" is known to be non-NULL.
|
||||
*
|
||||
* Let the div be of the form floor(e/d).
|
||||
|
@ -52,11 +164,20 @@ static __isl_give isl_aff *oppose_div_arg(__isl_take isl_aff *aff,
|
|||
*
|
||||
* floor(e/d) = -ceil(-e/d) = -floor((-e + d - 1)/d)
|
||||
*
|
||||
* and still use pdiv_q.
|
||||
* and still use pdiv_q, while changing the sign of data->v.
|
||||
*
|
||||
* Otherwise, we check if
|
||||
*
|
||||
* e + d*floor(cst/v)
|
||||
*
|
||||
* is non-negative and if so, replace floor(e/d) by
|
||||
*
|
||||
* floor((e + s*d)/d) - s
|
||||
*
|
||||
* with s the minimal shift that makes the argument non-negative.
|
||||
*/
|
||||
static __isl_give isl_ast_expr *var_div(int *change_sign,
|
||||
__isl_keep isl_local_space *ls,
|
||||
int pos, __isl_keep isl_ast_build *build)
|
||||
static __isl_give isl_ast_expr *var_div(struct isl_ast_add_term_data *data,
|
||||
__isl_keep isl_local_space *ls, int pos)
|
||||
{
|
||||
isl_ctx *ctx = isl_local_space_get_ctx(ls);
|
||||
isl_aff *aff;
|
||||
|
@ -71,18 +192,23 @@ static __isl_give isl_ast_expr *var_div(int *change_sign,
|
|||
|
||||
type = isl_ast_op_fdiv_q;
|
||||
if (isl_options_get_ast_build_prefer_pdiv(ctx)) {
|
||||
int non_neg = isl_ast_build_aff_is_nonneg(build, aff);
|
||||
int non_neg = isl_ast_build_aff_is_nonneg(data->build, aff);
|
||||
if (non_neg >= 0 && !non_neg) {
|
||||
isl_aff *opp = oppose_div_arg(isl_aff_copy(aff),
|
||||
isl_val_copy(d));
|
||||
non_neg = isl_ast_build_aff_is_nonneg(build, opp);
|
||||
non_neg = isl_ast_build_aff_is_nonneg(data->build, opp);
|
||||
if (non_neg >= 0 && non_neg) {
|
||||
*change_sign = 1;
|
||||
data->v = isl_val_neg(data->v);
|
||||
isl_aff_free(aff);
|
||||
aff = opp;
|
||||
} else
|
||||
isl_aff_free(opp);
|
||||
}
|
||||
if (non_neg >= 0 && !non_neg) {
|
||||
non_neg = is_non_neg_after_stealing(aff, d, data);
|
||||
if (non_neg >= 0 && non_neg)
|
||||
aff = steal_from_cst(aff, d, data);
|
||||
}
|
||||
if (non_neg < 0)
|
||||
aff = isl_aff_free(aff);
|
||||
else if (non_neg)
|
||||
|
@ -90,33 +216,30 @@ static __isl_give isl_ast_expr *var_div(int *change_sign,
|
|||
}
|
||||
|
||||
isl_val_free(d);
|
||||
num = isl_ast_expr_from_aff(aff, build);
|
||||
num = isl_ast_expr_from_aff(aff, data->build);
|
||||
return isl_ast_expr_alloc_binary(type, num, den);
|
||||
}
|
||||
|
||||
/* Create an isl_ast_expr evaluating the specified dimension of "ls".
|
||||
* The result is simplified in terms of build->domain.
|
||||
*
|
||||
* *change_sign is set by this function if the sign of
|
||||
* the expression has changed.
|
||||
* The result is simplified in terms of data->build->domain.
|
||||
* This function may change (the sign of) data->v.
|
||||
*
|
||||
* The isl_ast_expr is constructed based on the type of the dimension.
|
||||
* - divs are constructed by var_div
|
||||
* - set variables are constructed from the iterator isl_ids in "build"
|
||||
* - set variables are constructed from the iterator isl_ids in data->build
|
||||
* - parameters are constructed from the isl_ids in "ls"
|
||||
*/
|
||||
static __isl_give isl_ast_expr *var(int *change_sign,
|
||||
__isl_keep isl_local_space *ls,
|
||||
enum isl_dim_type type, int pos, __isl_keep isl_ast_build *build)
|
||||
static __isl_give isl_ast_expr *var(struct isl_ast_add_term_data *data,
|
||||
__isl_keep isl_local_space *ls, enum isl_dim_type type, int pos)
|
||||
{
|
||||
isl_ctx *ctx = isl_local_space_get_ctx(ls);
|
||||
isl_id *id;
|
||||
|
||||
if (type == isl_dim_div)
|
||||
return var_div(change_sign, ls, pos, build);
|
||||
return var_div(data, ls, pos);
|
||||
|
||||
if (type == isl_dim_set) {
|
||||
id = isl_ast_build_get_iterator_id(build, pos);
|
||||
id = isl_ast_build_get_iterator_id(data->build, pos);
|
||||
return isl_ast_expr_from_id(id);
|
||||
}
|
||||
|
||||
|
@ -270,6 +393,9 @@ error:
|
|||
|
||||
/* Add an expression for "*v" times the specified dimension of "ls"
|
||||
* to expr.
|
||||
* If the dimension is an integer division, then this function
|
||||
* may modify data->cst in order to make the numerator non-negative.
|
||||
* The result is simplified in terms of data->build->domain.
|
||||
*
|
||||
* Let e be the expression for the specified dimension,
|
||||
* multiplied by the absolute value of "*v".
|
||||
|
@ -291,18 +417,16 @@ error:
|
|||
static __isl_give isl_ast_expr *isl_ast_expr_add_term(
|
||||
__isl_take isl_ast_expr *expr,
|
||||
__isl_keep isl_local_space *ls, enum isl_dim_type type, int pos,
|
||||
__isl_take isl_val *v, __isl_keep isl_ast_build *build)
|
||||
__isl_take isl_val *v, struct isl_ast_add_term_data *data)
|
||||
{
|
||||
isl_ast_expr *term;
|
||||
int change_sign;
|
||||
|
||||
if (!expr)
|
||||
return NULL;
|
||||
|
||||
change_sign = 0;
|
||||
term = var(&change_sign, ls, type, pos, build);
|
||||
if (change_sign)
|
||||
v = isl_val_neg(v);
|
||||
data->v = v;
|
||||
term = var(data, ls, type, pos);
|
||||
v = data->v;
|
||||
|
||||
if (isl_val_is_neg(v) && !ast_expr_is_zero(expr)) {
|
||||
v = isl_val_neg(v);
|
||||
|
@ -683,12 +807,12 @@ static int try_extract_mod(struct isl_extract_mod_data *data)
|
|||
{
|
||||
isl_basic_set *hull;
|
||||
isl_val *v1, *v2;
|
||||
int r;
|
||||
int r, n;
|
||||
|
||||
if (!data->build)
|
||||
goto error;
|
||||
|
||||
int n = isl_aff_dim(data->div, isl_dim_div);
|
||||
n = isl_aff_dim(data->div, isl_dim_div);
|
||||
|
||||
if (isl_aff_involves_dims(data->div, isl_dim_div, 0, n))
|
||||
return extract_nonneg_mod(data);
|
||||
|
@ -948,6 +1072,7 @@ __isl_give isl_ast_expr *isl_ast_expr_from_aff(__isl_take isl_aff *aff,
|
|||
enum isl_dim_type t[] = { isl_dim_param, isl_dim_in, isl_dim_div };
|
||||
enum isl_dim_type l[] = { isl_dim_param, isl_dim_set, isl_dim_div };
|
||||
isl_local_space *ls;
|
||||
struct isl_ast_add_term_data data;
|
||||
|
||||
if (!aff)
|
||||
return NULL;
|
||||
|
@ -962,6 +1087,8 @@ __isl_give isl_ast_expr *isl_ast_expr_from_aff(__isl_take isl_aff *aff,
|
|||
|
||||
ls = isl_aff_get_domain_local_space(aff);
|
||||
|
||||
data.build = build;
|
||||
data.cst = isl_aff_get_constant_val(aff);
|
||||
for (i = 0; i < 3; ++i) {
|
||||
n = isl_aff_dim(aff, t[i]);
|
||||
for (j = 0; j < n; ++j) {
|
||||
|
@ -973,12 +1100,11 @@ __isl_give isl_ast_expr *isl_ast_expr_from_aff(__isl_take isl_aff *aff,
|
|||
continue;
|
||||
}
|
||||
expr = isl_ast_expr_add_term(expr,
|
||||
ls, l[i], j, v, build);
|
||||
ls, l[i], j, v, &data);
|
||||
}
|
||||
}
|
||||
|
||||
v = isl_aff_get_constant_val(aff);
|
||||
expr = isl_ast_expr_add_int(expr, v);
|
||||
expr = isl_ast_expr_add_int(expr, data.cst);
|
||||
|
||||
isl_local_space_free(ls);
|
||||
isl_aff_free(aff);
|
||||
|
@ -987,10 +1113,10 @@ __isl_give isl_ast_expr *isl_ast_expr_from_aff(__isl_take isl_aff *aff,
|
|||
|
||||
/* Add terms to "expr" for each variable in "aff" with a coefficient
|
||||
* with sign equal to "sign".
|
||||
* The result is simplified in terms of build->domain.
|
||||
* The result is simplified in terms of data->build->domain.
|
||||
*/
|
||||
static __isl_give isl_ast_expr *add_signed_terms(__isl_take isl_ast_expr *expr,
|
||||
__isl_keep isl_aff *aff, int sign, __isl_keep isl_ast_build *build)
|
||||
__isl_keep isl_aff *aff, int sign, struct isl_ast_add_term_data *data)
|
||||
{
|
||||
int i, j;
|
||||
isl_val *v;
|
||||
|
@ -1010,7 +1136,7 @@ static __isl_give isl_ast_expr *add_signed_terms(__isl_take isl_ast_expr *expr,
|
|||
}
|
||||
v = isl_val_abs(v);
|
||||
expr = isl_ast_expr_add_term(expr,
|
||||
ls, l[i], j, v, build);
|
||||
ls, l[i], j, v, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1204,9 +1330,9 @@ static __isl_give isl_ast_expr *isl_ast_expr_from_constraint(
|
|||
isl_ast_expr *expr_neg;
|
||||
isl_ast_expr *expr;
|
||||
isl_aff *aff;
|
||||
isl_val *v;
|
||||
int eq;
|
||||
enum isl_ast_op_type type;
|
||||
struct isl_ast_add_term_data data;
|
||||
|
||||
if (!constraint)
|
||||
return NULL;
|
||||
|
@ -1232,15 +1358,18 @@ static __isl_give isl_ast_expr *isl_ast_expr_from_constraint(
|
|||
|
||||
aff = extract_modulos(aff, &expr_pos, &expr_neg, build);
|
||||
|
||||
expr_pos = add_signed_terms(expr_pos, aff, 1, build);
|
||||
expr_neg = add_signed_terms(expr_neg, aff, -1, build);
|
||||
data.build = build;
|
||||
data.cst = isl_aff_get_constant_val(aff);
|
||||
expr_pos = add_signed_terms(expr_pos, aff, 1, &data);
|
||||
data.cst = isl_val_neg(data.cst);
|
||||
expr_neg = add_signed_terms(expr_neg, aff, -1, &data);
|
||||
data.cst = isl_val_neg(data.cst);
|
||||
|
||||
v = isl_aff_get_constant_val(aff);
|
||||
if (constant_is_considered_positive(v, expr_pos, expr_neg)) {
|
||||
expr_pos = isl_ast_expr_add_int(expr_pos, v);
|
||||
if (constant_is_considered_positive(data.cst, expr_pos, expr_neg)) {
|
||||
expr_pos = isl_ast_expr_add_int(expr_pos, data.cst);
|
||||
} else {
|
||||
v = isl_val_neg(v);
|
||||
expr_neg = isl_ast_expr_add_int(expr_neg, v);
|
||||
data.cst = isl_val_neg(data.cst);
|
||||
expr_neg = isl_ast_expr_add_int(expr_neg, data.cst);
|
||||
}
|
||||
|
||||
if (isl_ast_expr_get_type(expr_pos) == isl_ast_expr_int &&
|
||||
|
@ -1406,7 +1535,7 @@ struct isl_from_pw_aff_data {
|
|||
* If this is the last pair, then data->next is set to evaluate aff
|
||||
* and the domain is ignored.
|
||||
* Otherwise, data->next is set to a select operation that selects
|
||||
* an isl_ast_expr correponding to "aff" on "set" and to an expression
|
||||
* an isl_ast_expr corresponding to "aff" on "set" and to an expression
|
||||
* that will be filled in by later calls otherwise.
|
||||
*
|
||||
* In both cases, the constraints of "set" are added to the generated
|
||||
|
|
|
@ -665,36 +665,43 @@ error:
|
|||
* If we have generated a degenerate loop, then add the guard
|
||||
* implied by "bounds" on the outer dimensions, i.e., the guard
|
||||
* that ensures that the single value actually exists.
|
||||
* Since there may also be guards implied by a combination
|
||||
* of these constraints, we first combine them before
|
||||
* deriving the implied constraints.
|
||||
*/
|
||||
static __isl_give isl_set *add_implied_guards(__isl_take isl_set *guard,
|
||||
int degenerate, __isl_keep isl_basic_set *bounds,
|
||||
__isl_keep isl_ast_build *build)
|
||||
{
|
||||
int depth, has_stride;
|
||||
isl_set *dom;
|
||||
isl_space *space;
|
||||
isl_set *dom, *set;
|
||||
|
||||
depth = isl_ast_build_get_depth(build);
|
||||
has_stride = isl_ast_build_has_stride(build, depth);
|
||||
if (!has_stride && !degenerate)
|
||||
return guard;
|
||||
|
||||
space = isl_basic_set_get_space(bounds);
|
||||
dom = isl_set_universe(space);
|
||||
|
||||
if (degenerate) {
|
||||
bounds = isl_basic_set_copy(bounds);
|
||||
bounds = isl_basic_set_drop_constraints_not_involving_dims(
|
||||
bounds, isl_dim_set, depth, 1);
|
||||
dom = isl_set_from_basic_set(bounds);
|
||||
dom = isl_set_eliminate(dom, isl_dim_set, depth, 1);
|
||||
dom = isl_ast_build_compute_gist(build, dom);
|
||||
guard = isl_set_intersect(guard, dom);
|
||||
set = isl_set_from_basic_set(bounds);
|
||||
dom = isl_set_intersect(dom, set);
|
||||
}
|
||||
|
||||
if (has_stride) {
|
||||
dom = isl_ast_build_get_stride_constraint(build);
|
||||
dom = isl_set_eliminate(dom, isl_dim_set, depth, 1);
|
||||
dom = isl_ast_build_compute_gist(build, dom);
|
||||
guard = isl_set_intersect(guard, dom);
|
||||
set = isl_ast_build_get_stride_constraint(build);
|
||||
dom = isl_set_intersect(dom, set);
|
||||
}
|
||||
|
||||
dom = isl_set_eliminate(dom, isl_dim_set, depth, 1);
|
||||
dom = isl_ast_build_compute_gist(build, dom);
|
||||
guard = isl_set_intersect(guard, dom);
|
||||
|
||||
return guard;
|
||||
}
|
||||
|
||||
|
@ -2228,22 +2235,143 @@ static __isl_give isl_set *separate_schedule_domains(
|
|||
|
||||
/* Temporary data used during the search for a lower bound for unrolling.
|
||||
*
|
||||
* "build" is the build in which the unrolling will be performed
|
||||
* "domain" is the original set for which to find a lower bound
|
||||
* "depth" is the dimension for which to find a lower boudn
|
||||
* "expansion" is the expansion that needs to be applied to "domain"
|
||||
* in the unrolling that will be performed
|
||||
*
|
||||
* "lower" is the best lower bound found so far. It is NULL if we have not
|
||||
* found any yet.
|
||||
* "n" is the corresponding size. If lower is NULL, then the value of n
|
||||
* is undefined.
|
||||
* "n_div" is the maximal number of integer divisions in the first
|
||||
* unrolled iteration (after expansion). It is set to -1 if it hasn't
|
||||
* been computed yet.
|
||||
*/
|
||||
struct isl_find_unroll_data {
|
||||
isl_ast_build *build;
|
||||
isl_set *domain;
|
||||
int depth;
|
||||
isl_basic_map *expansion;
|
||||
|
||||
isl_aff *lower;
|
||||
int *n;
|
||||
int n_div;
|
||||
};
|
||||
|
||||
/* Return the constraint
|
||||
*
|
||||
* i_"depth" = aff + offset
|
||||
*/
|
||||
static __isl_give isl_constraint *at_offset(int depth, __isl_keep isl_aff *aff,
|
||||
int offset)
|
||||
{
|
||||
aff = isl_aff_copy(aff);
|
||||
aff = isl_aff_add_coefficient_si(aff, isl_dim_in, depth, -1);
|
||||
aff = isl_aff_add_constant_si(aff, offset);
|
||||
return isl_equality_from_aff(aff);
|
||||
}
|
||||
|
||||
/* Update *user to the number of integer divsions in the first element
|
||||
* of "ma", if it is larger than the current value.
|
||||
*/
|
||||
static int update_n_div(__isl_take isl_set *set, __isl_take isl_multi_aff *ma,
|
||||
void *user)
|
||||
{
|
||||
isl_aff *aff;
|
||||
int *n = user;
|
||||
int n_div;
|
||||
|
||||
aff = isl_multi_aff_get_aff(ma, 0);
|
||||
n_div = isl_aff_dim(aff, isl_dim_div);
|
||||
isl_aff_free(aff);
|
||||
isl_multi_aff_free(ma);
|
||||
isl_set_free(set);
|
||||
|
||||
if (n_div > *n)
|
||||
*n = n_div;
|
||||
|
||||
return aff ? 0 : -1;
|
||||
}
|
||||
|
||||
/* Get the number of integer divisions in the expression for the iterator
|
||||
* value at the first slice in the unrolling based on lower bound "lower",
|
||||
* taking into account the expansion that needs to be performed on this slice.
|
||||
*/
|
||||
static int get_expanded_n_div(struct isl_find_unroll_data *data,
|
||||
__isl_keep isl_aff *lower)
|
||||
{
|
||||
isl_constraint *c;
|
||||
isl_set *set;
|
||||
isl_map *it_map, *expansion;
|
||||
isl_pw_multi_aff *pma;
|
||||
int n;
|
||||
|
||||
c = at_offset(data->depth, lower, 0);
|
||||
set = isl_set_copy(data->domain);
|
||||
set = isl_set_add_constraint(set, c);
|
||||
expansion = isl_map_from_basic_map(isl_basic_map_copy(data->expansion));
|
||||
set = isl_set_apply(set, expansion);
|
||||
it_map = isl_ast_build_map_to_iterator(data->build, set);
|
||||
pma = isl_pw_multi_aff_from_map(it_map);
|
||||
n = 0;
|
||||
if (isl_pw_multi_aff_foreach_piece(pma, &update_n_div, &n) < 0)
|
||||
n = -1;
|
||||
isl_pw_multi_aff_free(pma);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Is the lower bound "lower" with corresponding iteration count "n"
|
||||
* better than the one stored in "data"?
|
||||
* If there is no upper bound on the iteration count ("n" is infinity) or
|
||||
* if the count is too large, then we cannot use this lower bound.
|
||||
* Otherwise, if there was no previous lower bound or
|
||||
* if the iteration count of the new lower bound is smaller than
|
||||
* the iteration count of the previous lower bound, then we consider
|
||||
* the new lower bound to be better.
|
||||
* If the iteration count is the same, then compare the number
|
||||
* of integer divisions that would be needed to express
|
||||
* the iterator value at the first slice in the unrolling
|
||||
* according to the lower bound. If we end up computing this
|
||||
* number, then store the lowest value in data->n_div.
|
||||
*/
|
||||
static int is_better_lower_bound(struct isl_find_unroll_data *data,
|
||||
__isl_keep isl_aff *lower, __isl_keep isl_val *n)
|
||||
{
|
||||
int cmp;
|
||||
int n_div;
|
||||
|
||||
if (!n)
|
||||
return -1;
|
||||
if (isl_val_is_infty(n))
|
||||
return 0;
|
||||
if (isl_val_cmp_si(n, INT_MAX) > 0)
|
||||
return 0;
|
||||
if (!data->lower)
|
||||
return 1;
|
||||
cmp = isl_val_cmp_si(n, *data->n);
|
||||
if (cmp < 0)
|
||||
return 1;
|
||||
if (cmp > 0)
|
||||
return 0;
|
||||
if (data->n_div < 0)
|
||||
data->n_div = get_expanded_n_div(data, data->lower);
|
||||
if (data->n_div < 0)
|
||||
return -1;
|
||||
if (data->n_div == 0)
|
||||
return 0;
|
||||
n_div = get_expanded_n_div(data, lower);
|
||||
if (n_div < 0)
|
||||
return -1;
|
||||
if (n_div >= data->n_div)
|
||||
return 0;
|
||||
data->n_div = n_div;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Check if we can use "c" as a lower bound and if it is better than
|
||||
* any previously found lower bound.
|
||||
*
|
||||
|
@ -2267,14 +2395,15 @@ struct isl_find_unroll_data {
|
|||
*
|
||||
* meaning that we can use ceil(f(j)/a)) as a lower bound for unrolling.
|
||||
* We just need to check if we have found any lower bound before and
|
||||
* if the new lower bound is better (smaller n) than the previously found
|
||||
* lower bounds.
|
||||
* if the new lower bound is better (smaller n or fewer integer divisions)
|
||||
* than the previously found lower bounds.
|
||||
*/
|
||||
static int update_unrolling_lower_bound(struct isl_find_unroll_data *data,
|
||||
__isl_keep isl_constraint *c)
|
||||
{
|
||||
isl_aff *aff, *lower;
|
||||
isl_val *max;
|
||||
int better;
|
||||
|
||||
if (!isl_constraint_is_lower_bound(c, isl_dim_set, data->depth))
|
||||
return 0;
|
||||
|
@ -2288,27 +2417,19 @@ static int update_unrolling_lower_bound(struct isl_find_unroll_data *data,
|
|||
max = isl_set_max_val(data->domain, aff);
|
||||
isl_aff_free(aff);
|
||||
|
||||
if (!max)
|
||||
goto error;
|
||||
if (isl_val_is_infty(max)) {
|
||||
better = is_better_lower_bound(data, lower, max);
|
||||
if (better < 0 || !better) {
|
||||
isl_val_free(max);
|
||||
isl_aff_free(lower);
|
||||
return 0;
|
||||
return better < 0 ? -1 : 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_val_get_num_si(max);
|
||||
} else
|
||||
isl_aff_free(lower);
|
||||
isl_aff_free(data->lower);
|
||||
data->lower = lower;
|
||||
*data->n = isl_val_get_num_si(max);
|
||||
isl_val_free(max);
|
||||
|
||||
return 1;
|
||||
error:
|
||||
isl_aff_free(lower);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if we can use "c" as a lower bound and if it is better than
|
||||
|
@ -2334,6 +2455,9 @@ static int constraint_find_unroll(__isl_take isl_constraint *c, void *user)
|
|||
* where d is "depth" and l(i) depends only on earlier dimensions.
|
||||
* Furthermore, try and find a lower bound such that n is as small as possible.
|
||||
* In particular, "n" needs to be finite.
|
||||
* "build" is the build in which the unrolling will be performed.
|
||||
* "expansion" is the expansion that needs to be applied to "domain"
|
||||
* in the unrolling that will be performed.
|
||||
*
|
||||
* Inner dimensions have been eliminated from "domain" by the caller.
|
||||
*
|
||||
|
@ -2347,10 +2471,12 @@ static int constraint_find_unroll(__isl_take isl_constraint *c, void *user)
|
|||
* If we cannot find a suitable lower bound, then we consider that
|
||||
* to be an error.
|
||||
*/
|
||||
static __isl_give isl_aff *find_unroll_lower_bound(__isl_keep isl_set *domain,
|
||||
int depth, int *n)
|
||||
static __isl_give isl_aff *find_unroll_lower_bound(
|
||||
__isl_keep isl_ast_build *build, __isl_keep isl_set *domain,
|
||||
int depth, __isl_keep isl_basic_map *expansion, int *n)
|
||||
{
|
||||
struct isl_find_unroll_data data = { domain, depth, NULL, n };
|
||||
struct isl_find_unroll_data data =
|
||||
{ build, domain, depth, expansion, NULL, n, -1 };
|
||||
isl_basic_set *hull;
|
||||
|
||||
hull = isl_set_simple_hull(isl_set_copy(domain));
|
||||
|
@ -2371,19 +2497,6 @@ error:
|
|||
return isl_aff_free(data.lower);
|
||||
}
|
||||
|
||||
/* Return the constraint
|
||||
*
|
||||
* i_"depth" = aff + offset
|
||||
*/
|
||||
static __isl_give isl_constraint *at_offset(int depth, __isl_keep isl_aff *aff,
|
||||
int offset)
|
||||
{
|
||||
aff = isl_aff_copy(aff);
|
||||
aff = isl_aff_add_coefficient_si(aff, isl_dim_in, depth, -1);
|
||||
aff = isl_aff_add_constant_si(aff, offset);
|
||||
return isl_equality_from_aff(aff);
|
||||
}
|
||||
|
||||
/* Data structure for storing the results and the intermediate objects
|
||||
* of compute_domains.
|
||||
*
|
||||
|
@ -2482,12 +2595,13 @@ static __isl_give isl_set *do_unroll(struct isl_codegen_domains *domains,
|
|||
|
||||
isl_ast_build_free(build);
|
||||
|
||||
lower = find_unroll_lower_bound(domain, depth, &n);
|
||||
bmap = isl_basic_map_from_multi_aff(expansion);
|
||||
|
||||
lower = find_unroll_lower_bound(domains->build, domain, depth, bmap,
|
||||
&n);
|
||||
if (!lower)
|
||||
class_domain = isl_set_free(class_domain);
|
||||
|
||||
bmap = isl_basic_map_from_multi_aff(expansion);
|
||||
|
||||
unroll_domain = isl_set_empty(isl_set_get_space(domain));
|
||||
|
||||
for (i = 0; class_domain && i < n; ++i) {
|
||||
|
@ -3912,6 +4026,7 @@ __isl_give isl_ast_node *isl_ast_build_ast_from_schedule(
|
|||
build = isl_ast_build_copy(build);
|
||||
build = isl_ast_build_set_single_valued(build, 0);
|
||||
schedule = isl_union_map_coalesce(schedule);
|
||||
schedule = isl_union_map_remove_redundancies(schedule);
|
||||
executed = isl_union_map_reverse(schedule);
|
||||
list = generate_code(executed, isl_ast_build_copy(build), 0);
|
||||
node = isl_ast_node_from_graft_list(list, build);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -595,8 +595,9 @@ static struct isl_basic_set *compute_facet(struct isl_set *set, isl_int *c)
|
|||
set = isl_set_preimage(set, U);
|
||||
facet = uset_convex_hull_wrap_bounded(set);
|
||||
facet = isl_basic_set_preimage(facet, Q);
|
||||
if (facet)
|
||||
isl_assert(ctx, facet->n_eq == 0, goto error);
|
||||
if (facet && facet->n_eq != 0)
|
||||
isl_die(ctx, isl_error_internal, "unexpected equality",
|
||||
return isl_basic_set_free(facet));
|
||||
return facet;
|
||||
error:
|
||||
isl_basic_set_free(facet);
|
||||
|
@ -2638,114 +2639,125 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Compute a superset of the convex hull of "set" that is described
|
||||
/* Compute a superset of the convex hull of "map" that is described
|
||||
* by only constraints in the elements of "list".
|
||||
*
|
||||
* If the list is empty, then we can only describe the universe set.
|
||||
* If the input set is empty, then all constraints are valid, so
|
||||
* If the input map is empty, then all constraints are valid, so
|
||||
* we return the intersection of the elements in "list".
|
||||
*
|
||||
* Otherwise, we align all divs and temporarily treat them
|
||||
* as regular variables, computing the unshifted simple hull in
|
||||
* uset_unshifted_simple_hull_from_basic_set_list.
|
||||
*/
|
||||
static __isl_give isl_basic_set *set_unshifted_simple_hull_from_basic_set_list(
|
||||
__isl_take isl_set *set, __isl_take isl_basic_set_list *list)
|
||||
static __isl_give isl_basic_map *map_unshifted_simple_hull_from_basic_map_list(
|
||||
__isl_take isl_map *map, __isl_take isl_basic_map_list *list)
|
||||
{
|
||||
isl_basic_set *model;
|
||||
isl_basic_set *hull;
|
||||
isl_basic_map *model;
|
||||
isl_basic_map *hull;
|
||||
isl_set *set;
|
||||
isl_basic_set_list *bset_list;
|
||||
|
||||
if (!set || !list)
|
||||
if (!map || !list)
|
||||
goto error;
|
||||
|
||||
if (isl_basic_set_list_n_basic_set(list) == 0) {
|
||||
if (isl_basic_map_list_n_basic_map(list) == 0) {
|
||||
isl_space *space;
|
||||
|
||||
space = isl_set_get_space(set);
|
||||
isl_set_free(set);
|
||||
isl_basic_set_list_free(list);
|
||||
return isl_basic_set_universe(space);
|
||||
space = isl_map_get_space(map);
|
||||
isl_map_free(map);
|
||||
isl_basic_map_list_free(list);
|
||||
return isl_basic_map_universe(space);
|
||||
}
|
||||
if (isl_set_plain_is_empty(set)) {
|
||||
isl_set_free(set);
|
||||
return isl_basic_set_list_intersect(list);
|
||||
if (isl_map_plain_is_empty(map)) {
|
||||
isl_map_free(map);
|
||||
return isl_basic_map_list_intersect(list);
|
||||
}
|
||||
|
||||
set = isl_set_align_divs_to_basic_set_list(set, list);
|
||||
if (!set)
|
||||
map = isl_map_align_divs_to_basic_map_list(map, list);
|
||||
if (!map)
|
||||
goto error;
|
||||
list = isl_basic_set_list_align_divs_to_basic_set(list, set->p[0]);
|
||||
list = isl_basic_map_list_align_divs_to_basic_map(list, map->p[0]);
|
||||
|
||||
model = isl_basic_set_list_get_basic_set(list, 0);
|
||||
model = isl_basic_map_list_get_basic_map(list, 0);
|
||||
|
||||
set = isl_set_to_underlying_set(set);
|
||||
list = isl_basic_set_list_underlying_set(list);
|
||||
set = isl_map_underlying_set(map);
|
||||
bset_list = isl_basic_map_list_underlying_set(list);
|
||||
|
||||
hull = uset_unshifted_simple_hull_from_basic_set_list(set, list);
|
||||
hull = uset_unshifted_simple_hull_from_basic_set_list(set, bset_list);
|
||||
hull = isl_basic_map_overlying_set(hull, model);
|
||||
|
||||
return hull;
|
||||
error:
|
||||
isl_set_free(set);
|
||||
isl_basic_set_list_free(list);
|
||||
isl_map_free(map);
|
||||
isl_basic_map_list_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return a sequence of the basic sets that make up the sets in "list".
|
||||
/* Return a sequence of the basic maps that make up the maps in "list".
|
||||
*/
|
||||
static __isl_give isl_basic_set_list *collect_basic_sets(
|
||||
__isl_take isl_set_list *list)
|
||||
static __isl_give isl_basic_set_list *collect_basic_maps(
|
||||
__isl_take isl_map_list *list)
|
||||
{
|
||||
int i, n;
|
||||
isl_ctx *ctx;
|
||||
isl_basic_set_list *bset_list;
|
||||
isl_basic_map_list *bmap_list;
|
||||
|
||||
if (!list)
|
||||
return NULL;
|
||||
n = isl_set_list_n_set(list);
|
||||
ctx = isl_set_list_get_ctx(list);
|
||||
bset_list = isl_basic_set_list_alloc(ctx, 0);
|
||||
n = isl_map_list_n_map(list);
|
||||
ctx = isl_map_list_get_ctx(list);
|
||||
bmap_list = isl_basic_map_list_alloc(ctx, 0);
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
isl_set *set;
|
||||
isl_basic_set_list *list_i;
|
||||
isl_map *map;
|
||||
isl_basic_map_list *list_i;
|
||||
|
||||
set = isl_set_list_get_set(list, i);
|
||||
set = isl_set_compute_divs(set);
|
||||
list_i = isl_set_get_basic_set_list(set);
|
||||
isl_set_free(set);
|
||||
bset_list = isl_basic_set_list_concat(bset_list, list_i);
|
||||
map = isl_map_list_get_map(list, i);
|
||||
map = isl_map_compute_divs(map);
|
||||
list_i = isl_map_get_basic_map_list(map);
|
||||
isl_map_free(map);
|
||||
bmap_list = isl_basic_map_list_concat(bmap_list, list_i);
|
||||
}
|
||||
|
||||
isl_set_list_free(list);
|
||||
return bset_list;
|
||||
isl_map_list_free(list);
|
||||
return bmap_list;
|
||||
}
|
||||
|
||||
/* Compute a superset of the convex hull of "map" that is described
|
||||
* by only constraints in the elements of "list".
|
||||
*
|
||||
* If "map" is the universe, then the convex hull (and therefore
|
||||
* any superset of the convexhull) is the universe as well.
|
||||
*
|
||||
* Otherwise, we collect all the basic maps in the map list and
|
||||
* continue with map_unshifted_simple_hull_from_basic_map_list.
|
||||
*/
|
||||
__isl_give isl_basic_map *isl_map_unshifted_simple_hull_from_map_list(
|
||||
__isl_take isl_map *map, __isl_take isl_map_list *list)
|
||||
{
|
||||
isl_basic_map_list *bmap_list;
|
||||
int is_universe;
|
||||
|
||||
is_universe = isl_map_plain_is_universe(map);
|
||||
if (is_universe < 0)
|
||||
map = isl_map_free(map);
|
||||
if (is_universe < 0 || is_universe) {
|
||||
isl_map_list_free(list);
|
||||
return isl_map_unshifted_simple_hull(map);
|
||||
}
|
||||
|
||||
bmap_list = collect_basic_maps(list);
|
||||
return map_unshifted_simple_hull_from_basic_map_list(map, bmap_list);
|
||||
}
|
||||
|
||||
/* Compute a superset of the convex hull of "set" that is described
|
||||
* by only constraints in the elements of "list".
|
||||
*
|
||||
* If "set" is the universe, then the convex hull (and therefore
|
||||
* any superset of the convexhull) is the universe as well.
|
||||
*
|
||||
* Otherwise, we collect all the basic sets in the set list and
|
||||
* continue with set_unshifted_simple_hull_from_basic_set_list.
|
||||
*/
|
||||
__isl_give isl_basic_set *isl_set_unshifted_simple_hull_from_set_list(
|
||||
__isl_take isl_set *set, __isl_take isl_set_list *list)
|
||||
{
|
||||
isl_basic_set_list *bset_list;
|
||||
int is_universe;
|
||||
|
||||
is_universe = isl_set_plain_is_universe(set);
|
||||
if (is_universe < 0)
|
||||
set = isl_set_free(set);
|
||||
if (is_universe < 0 || is_universe) {
|
||||
isl_set_list_free(list);
|
||||
return isl_set_unshifted_simple_hull(set);
|
||||
}
|
||||
|
||||
bset_list = collect_basic_sets(list);
|
||||
return set_unshifted_simple_hull_from_basic_set_list(set, bset_list);
|
||||
return isl_map_unshifted_simple_hull_from_map_list(set, list);
|
||||
}
|
||||
|
||||
/* Given a set "set", return parametric bounds on the dimension "dim".
|
||||
|
|
|
@ -641,6 +641,7 @@ __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist_params(
|
|||
#define DEFAULT_IS_ZERO 1
|
||||
|
||||
#define NO_NEG
|
||||
#define NO_SUB
|
||||
#define NO_PULLBACK
|
||||
|
||||
#include <isl_pw_templ.c>
|
||||
|
@ -651,7 +652,6 @@ __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist_params(
|
|||
#define PART isl_pw_qpolynomial_fold
|
||||
#undef PARTS
|
||||
#define PARTS pw_qpolynomial_fold
|
||||
#define ALIGN_DOMAIN
|
||||
|
||||
#define NO_SUB
|
||||
|
||||
|
@ -901,7 +901,8 @@ __isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_fold_fold_pw_
|
|||
|
||||
hash = isl_space_get_hash(part->dim);
|
||||
entry = isl_hash_table_find(u->space->ctx, &u->table, hash,
|
||||
&has_same_domain_space, part->dim, 1);
|
||||
&isl_union_pw_qpolynomial_fold_has_same_domain_space,
|
||||
part->dim, 1);
|
||||
if (!entry)
|
||||
goto error;
|
||||
|
||||
|
@ -1366,7 +1367,8 @@ static int add_pwqp(__isl_take isl_pw_qpolynomial *pwqp, void *user)
|
|||
ctx = pwqp->dim->ctx;
|
||||
hash = isl_space_get_hash(pwqp->dim);
|
||||
entry = isl_hash_table_find(ctx, &(*upwf)->table, hash,
|
||||
&has_same_domain_space, pwqp->dim, 1);
|
||||
&isl_union_pw_qpolynomial_fold_has_same_domain_space,
|
||||
pwqp->dim, 1);
|
||||
if (!entry)
|
||||
goto error;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1361,3 +1361,20 @@ __isl_give isl_local_space *isl_local_space_flatten_range(
|
|||
|
||||
return ls;
|
||||
}
|
||||
|
||||
/* Given the local space "ls" of a map, return the local space of a set
|
||||
* that lives in a space that wraps the space of "ls" and that has
|
||||
* the same divs.
|
||||
*/
|
||||
__isl_give isl_local_space *isl_local_space_wrap(__isl_take isl_local_space *ls)
|
||||
{
|
||||
ls = isl_local_space_cow(ls);
|
||||
if (!ls)
|
||||
return NULL;
|
||||
|
||||
ls->dim = isl_space_wrap(ls->dim);
|
||||
if (!ls->dim)
|
||||
return isl_local_space_free(ls);
|
||||
|
||||
return ls;
|
||||
}
|
||||
|
|
|
@ -1626,8 +1626,10 @@ struct isl_basic_map *isl_basic_map_cow(struct isl_basic_map *bmap)
|
|||
bmap->ref--;
|
||||
bmap = isl_basic_map_dup(bmap);
|
||||
}
|
||||
if (bmap)
|
||||
if (bmap) {
|
||||
ISL_F_CLR(bmap, ISL_BASIC_SET_FINAL);
|
||||
ISL_F_CLR(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS);
|
||||
}
|
||||
return bmap;
|
||||
}
|
||||
|
||||
|
@ -4553,22 +4555,23 @@ __isl_give isl_basic_set *isl_basic_set_underlying_set(
|
|||
}
|
||||
|
||||
/* Replace each element in "list" by the result of applying
|
||||
* isl_basic_set_underlying_set to the element.
|
||||
* isl_basic_map_underlying_set to the element.
|
||||
*/
|
||||
__isl_give isl_basic_set_list *isl_basic_set_list_underlying_set(
|
||||
__isl_take isl_basic_set_list *list)
|
||||
__isl_give isl_basic_set_list *isl_basic_map_list_underlying_set(
|
||||
__isl_take isl_basic_map_list *list)
|
||||
{
|
||||
int i, n;
|
||||
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
n = isl_basic_set_list_n_basic_set(list);
|
||||
n = isl_basic_map_list_n_basic_map(list);
|
||||
for (i = 0; i < n; ++i) {
|
||||
isl_basic_map *bmap;
|
||||
isl_basic_set *bset;
|
||||
|
||||
bset = isl_basic_set_list_get_basic_set(list, i);
|
||||
bset = isl_basic_set_underlying_set(bset);
|
||||
bmap = isl_basic_map_list_get_basic_map(list, i);
|
||||
bset = isl_basic_set_underlying_set(bmap);
|
||||
list = isl_basic_set_list_set_basic_set(list, i, bset);
|
||||
}
|
||||
|
||||
|
@ -8405,54 +8408,54 @@ struct isl_set *isl_set_align_divs(struct isl_set *set)
|
|||
return (struct isl_set *)isl_map_align_divs((struct isl_map *)set);
|
||||
}
|
||||
|
||||
/* Align the divs of the basic sets in "set" to those
|
||||
* of the basic sets in "list", as well as to the other basic sets in "set".
|
||||
/* Align the divs of the basic maps in "map" to those
|
||||
* of the basic maps in "list", as well as to the other basic maps in "map".
|
||||
* The elements in "list" are assumed to have known divs.
|
||||
*/
|
||||
__isl_give isl_set *isl_set_align_divs_to_basic_set_list(
|
||||
__isl_take isl_set *set, __isl_keep isl_basic_set_list *list)
|
||||
__isl_give isl_map *isl_map_align_divs_to_basic_map_list(
|
||||
__isl_take isl_map *map, __isl_keep isl_basic_map_list *list)
|
||||
{
|
||||
int i, n;
|
||||
|
||||
set = isl_set_compute_divs(set);
|
||||
set = isl_set_cow(set);
|
||||
if (!set || !list)
|
||||
return isl_set_free(set);
|
||||
if (set->n == 0)
|
||||
return set;
|
||||
map = isl_map_compute_divs(map);
|
||||
map = isl_map_cow(map);
|
||||
if (!map || !list)
|
||||
return isl_map_free(map);
|
||||
if (map->n == 0)
|
||||
return map;
|
||||
|
||||
n = isl_basic_set_list_n_basic_set(list);
|
||||
n = isl_basic_map_list_n_basic_map(list);
|
||||
for (i = 0; i < n; ++i) {
|
||||
isl_basic_set *bset;
|
||||
isl_basic_map *bmap;
|
||||
|
||||
bset = isl_basic_set_list_get_basic_set(list, i);
|
||||
set->p[0] = isl_basic_set_align_divs(set->p[0], bset);
|
||||
isl_basic_set_free(bset);
|
||||
bmap = isl_basic_map_list_get_basic_map(list, i);
|
||||
map->p[0] = isl_basic_map_align_divs(map->p[0], bmap);
|
||||
isl_basic_map_free(bmap);
|
||||
}
|
||||
if (!set->p[0])
|
||||
return isl_set_free(set);
|
||||
if (!map->p[0])
|
||||
return isl_map_free(map);
|
||||
|
||||
return isl_set_align_divs(set);
|
||||
return isl_map_align_divs(map);
|
||||
}
|
||||
|
||||
/* Align the divs of each element of "list" to those of "bset".
|
||||
* Both "bset" and the elements of "list" are assumed to have known divs.
|
||||
/* Align the divs of each element of "list" to those of "bmap".
|
||||
* Both "bmap" and the elements of "list" are assumed to have known divs.
|
||||
*/
|
||||
__isl_give isl_basic_set_list *isl_basic_set_list_align_divs_to_basic_set(
|
||||
__isl_take isl_basic_set_list *list, __isl_keep isl_basic_set *bset)
|
||||
__isl_give isl_basic_map_list *isl_basic_map_list_align_divs_to_basic_map(
|
||||
__isl_take isl_basic_map_list *list, __isl_keep isl_basic_map *bmap)
|
||||
{
|
||||
int i, n;
|
||||
|
||||
if (!list || !bset)
|
||||
return isl_basic_set_list_free(list);
|
||||
if (!list || !bmap)
|
||||
return isl_basic_map_list_free(list);
|
||||
|
||||
n = isl_basic_set_list_n_basic_set(list);
|
||||
n = isl_basic_map_list_n_basic_map(list);
|
||||
for (i = 0; i < n; ++i) {
|
||||
isl_basic_set *bset_i;
|
||||
isl_basic_map *bmap_i;
|
||||
|
||||
bset_i = isl_basic_set_list_get_basic_set(list, i);
|
||||
bset_i = isl_basic_set_align_divs(bset_i, bset);
|
||||
list = isl_basic_set_list_set_basic_set(list, i, bset_i);
|
||||
bmap_i = isl_basic_map_list_get_basic_map(list, i);
|
||||
bmap_i = isl_basic_map_align_divs(bmap_i, bmap);
|
||||
list = isl_basic_map_list_set_basic_map(list, i, bmap_i);
|
||||
}
|
||||
|
||||
return list;
|
||||
|
@ -9326,25 +9329,25 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Return the basic sets in "set" as a list.
|
||||
/* Return the basic maps in "map" as a list.
|
||||
*/
|
||||
__isl_give isl_basic_set_list *isl_set_get_basic_set_list(
|
||||
__isl_keep isl_set *set)
|
||||
__isl_give isl_basic_map_list *isl_map_get_basic_map_list(
|
||||
__isl_keep isl_map *map)
|
||||
{
|
||||
int i;
|
||||
isl_ctx *ctx;
|
||||
isl_basic_set_list *list;
|
||||
isl_basic_map_list *list;
|
||||
|
||||
if (!set)
|
||||
if (!map)
|
||||
return NULL;
|
||||
ctx = isl_set_get_ctx(set);
|
||||
list = isl_basic_set_list_alloc(ctx, set->n);
|
||||
ctx = isl_map_get_ctx(map);
|
||||
list = isl_basic_map_list_alloc(ctx, map->n);
|
||||
|
||||
for (i = 0; i < set->n; ++i) {
|
||||
isl_basic_set *bset;
|
||||
for (i = 0; i < map->n; ++i) {
|
||||
isl_basic_map *bmap;
|
||||
|
||||
bset = isl_basic_set_copy(set->p[i]);
|
||||
list = isl_basic_set_list_add(list, bset);
|
||||
bmap = isl_basic_map_copy(map->p[i]);
|
||||
list = isl_basic_map_list_add(list, bmap);
|
||||
}
|
||||
|
||||
return list;
|
||||
|
@ -9353,34 +9356,43 @@ __isl_give isl_basic_set_list *isl_set_get_basic_set_list(
|
|||
/* Return the intersection of the elements in the non-empty list "list".
|
||||
* All elements are assumed to live in the same space.
|
||||
*/
|
||||
__isl_give isl_basic_set *isl_basic_set_list_intersect(
|
||||
__isl_take struct isl_basic_set_list *list)
|
||||
__isl_give isl_basic_map *isl_basic_map_list_intersect(
|
||||
__isl_take isl_basic_map_list *list)
|
||||
{
|
||||
int i, n;
|
||||
isl_basic_set *bset;
|
||||
isl_basic_map *bmap;
|
||||
|
||||
if (!list)
|
||||
return NULL;
|
||||
n = isl_basic_set_list_n_basic_set(list);
|
||||
n = isl_basic_map_list_n_basic_map(list);
|
||||
if (n < 1)
|
||||
isl_die(isl_basic_set_list_get_ctx(list), isl_error_invalid,
|
||||
isl_die(isl_basic_map_list_get_ctx(list), isl_error_invalid,
|
||||
"expecting non-empty list", goto error);
|
||||
|
||||
bset = isl_basic_set_list_get_basic_set(list, 0);
|
||||
for (i = 1; i < n; ++i) {
|
||||
isl_basic_set *bset_i;
|
||||
|
||||
bset_i = isl_basic_set_list_get_basic_set(list, i);
|
||||
bset = isl_basic_set_intersect(bset, bset_i);
|
||||
bmap = isl_basic_map_list_get_basic_map(list, 0);
|
||||
for (i = 1; i < n; ++i) {
|
||||
isl_basic_map *bmap_i;
|
||||
|
||||
bmap_i = isl_basic_map_list_get_basic_map(list, i);
|
||||
bmap = isl_basic_map_intersect(bmap, bmap_i);
|
||||
}
|
||||
|
||||
isl_basic_set_list_free(list);
|
||||
return bset;
|
||||
isl_basic_map_list_free(list);
|
||||
return bmap;
|
||||
error:
|
||||
isl_basic_set_list_free(list);
|
||||
isl_basic_map_list_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return the intersection of the elements in the non-empty list "list".
|
||||
* All elements are assumed to live in the same space.
|
||||
*/
|
||||
__isl_give isl_basic_set *isl_basic_set_list_intersect(
|
||||
__isl_take isl_basic_set_list *list)
|
||||
{
|
||||
return isl_basic_map_list_intersect(list);
|
||||
}
|
||||
|
||||
/* Return the Cartesian product of the basic sets in list (in the given order).
|
||||
*/
|
||||
__isl_give isl_basic_set *isl_basic_set_list_product(
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
#include <isl/map.h>
|
||||
|
||||
#undef EL
|
||||
#define EL isl_basic_map
|
||||
|
||||
#include <isl_list_templ.h>
|
||||
|
||||
#undef BASE
|
||||
#define BASE basic_map
|
||||
|
||||
#include <isl_list_templ.c>
|
||||
|
||||
#undef EL
|
||||
#define EL isl_map
|
||||
|
||||
#include <isl_list_templ.h>
|
||||
|
||||
#undef BASE
|
||||
#define BASE map
|
||||
|
||||
#include <isl_list_templ.c>
|
||||
|
||||
#undef EL
|
||||
#define EL isl_union_map
|
||||
|
||||
#include <isl_list_templ.h>
|
||||
|
||||
#undef BASE
|
||||
#define BASE union_map
|
||||
|
||||
#include <isl_list_templ.c>
|
|
@ -15,12 +15,11 @@
|
|||
#define isl_basic_set_list isl_basic_map_list
|
||||
#define isl_set_list isl_map_list
|
||||
#include <isl/list.h>
|
||||
ISL_DECLARE_LIST(basic_map)
|
||||
ISL_DECLARE_LIST(map)
|
||||
#include <isl/set.h>
|
||||
#include <isl/map.h>
|
||||
#include <isl_reordering.h>
|
||||
#include <isl/vec.h>
|
||||
#include <isl/hash.h>
|
||||
#include <isl_blk.h>
|
||||
|
||||
/* A "basic map" is a relation between two sets of variables,
|
||||
|
@ -43,6 +42,7 @@ struct isl_basic_map {
|
|||
#define ISL_BASIC_MAP_NORMALIZED (1 << 5)
|
||||
#define ISL_BASIC_MAP_NORMALIZED_DIVS (1 << 6)
|
||||
#define ISL_BASIC_MAP_ALL_EQUALITIES (1 << 7)
|
||||
#define ISL_BASIC_MAP_REDUCED_COEFFICIENTS (1 << 8)
|
||||
#define ISL_BASIC_SET_FINAL (1 << 0)
|
||||
#define ISL_BASIC_SET_EMPTY (1 << 1)
|
||||
#define ISL_BASIC_SET_NO_IMPLICIT (1 << 2)
|
||||
|
@ -51,6 +51,7 @@ struct isl_basic_map {
|
|||
#define ISL_BASIC_SET_NORMALIZED (1 << 5)
|
||||
#define ISL_BASIC_SET_NORMALIZED_DIVS (1 << 6)
|
||||
#define ISL_BASIC_SET_ALL_EQUALITIES (1 << 7)
|
||||
#define ISL_BASIC_SET_REDUCED_COEFFICIENTS (1 << 8)
|
||||
unsigned flags;
|
||||
|
||||
struct isl_ctx *ctx;
|
||||
|
@ -198,6 +199,8 @@ struct isl_basic_map *isl_basic_map_cow(struct isl_basic_map *bmap);
|
|||
struct isl_set *isl_set_cow(struct isl_set *set);
|
||||
struct isl_map *isl_map_cow(struct isl_map *map);
|
||||
|
||||
uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map *bmap);
|
||||
|
||||
struct isl_basic_map *isl_basic_map_set_to_empty(struct isl_basic_map *bmap);
|
||||
struct isl_basic_set *isl_basic_set_set_to_empty(struct isl_basic_set *bset);
|
||||
struct isl_basic_set *isl_basic_set_order_divs(struct isl_basic_set *bset);
|
||||
|
@ -208,10 +211,10 @@ struct isl_basic_map *isl_basic_map_align_divs(
|
|||
struct isl_basic_map *dst, struct isl_basic_map *src);
|
||||
struct isl_basic_set *isl_basic_set_align_divs(
|
||||
struct isl_basic_set *dst, struct isl_basic_set *src);
|
||||
__isl_give isl_set *isl_set_align_divs_to_basic_set_list(
|
||||
__isl_take isl_set *set, __isl_keep isl_basic_set_list *list);
|
||||
__isl_give isl_basic_set_list *isl_basic_set_list_align_divs_to_basic_set(
|
||||
__isl_take isl_basic_set_list *list, __isl_keep isl_basic_set *bset);
|
||||
__isl_give isl_map *isl_map_align_divs_to_basic_map_list(
|
||||
__isl_take isl_map *map, __isl_keep isl_basic_map_list *list);
|
||||
__isl_give isl_basic_map_list *isl_basic_map_list_align_divs_to_basic_map(
|
||||
__isl_take isl_basic_map_list *list, __isl_keep isl_basic_map *bmap);
|
||||
__isl_give isl_basic_map *isl_basic_map_sort_divs(
|
||||
__isl_take isl_basic_map *bmap);
|
||||
__isl_give isl_map *isl_map_sort_divs(__isl_take isl_map *map);
|
||||
|
@ -234,8 +237,8 @@ struct isl_basic_map *isl_basic_map_implicit_equalities(
|
|||
struct isl_basic_set *isl_basic_map_underlying_set(struct isl_basic_map *bmap);
|
||||
__isl_give isl_basic_set *isl_basic_set_underlying_set(
|
||||
__isl_take isl_basic_set *bset);
|
||||
__isl_give isl_basic_set_list *isl_basic_set_list_underlying_set(
|
||||
__isl_take isl_basic_set_list *list);
|
||||
__isl_give isl_basic_set_list *isl_basic_map_list_underlying_set(
|
||||
__isl_take isl_basic_map_list *list);
|
||||
struct isl_set *isl_map_underlying_set(struct isl_map *map);
|
||||
struct isl_basic_map *isl_basic_map_overlying_set(struct isl_basic_set *bset,
|
||||
struct isl_basic_map *like);
|
||||
|
@ -258,6 +261,8 @@ struct isl_map *isl_map_drop(struct isl_map *map,
|
|||
|
||||
__isl_give isl_basic_map *isl_basic_map_remove_duplicate_constraints(
|
||||
__isl_take isl_basic_map *bmap, int *progress, int detect_divs);
|
||||
__isl_give isl_basic_map *isl_basic_map_detect_inequality_pairs(
|
||||
__isl_take isl_basic_map *bmap, int *progress);
|
||||
|
||||
struct isl_map *isl_map_remove_empty_parts(struct isl_map *map);
|
||||
struct isl_set *isl_set_remove_empty_parts(struct isl_set *set);
|
||||
|
@ -381,6 +386,9 @@ int isl_map_is_set(__isl_keep isl_map *map);
|
|||
int isl_basic_set_plain_dim_is_fixed(__isl_keep isl_basic_set *bset,
|
||||
unsigned dim, isl_int *val);
|
||||
|
||||
__isl_give isl_basic_map *isl_basic_map_plain_affine_hull(
|
||||
__isl_take isl_basic_map *bmap);
|
||||
|
||||
int isl_basic_set_dim_residue_class(struct isl_basic_set *bset,
|
||||
int pos, isl_int *modulo, isl_int *residue);
|
||||
int isl_set_dim_residue_class(struct isl_set *set,
|
||||
|
@ -396,8 +404,14 @@ int isl_map_plain_is_fixed(__isl_keep isl_map *map,
|
|||
int isl_basic_map_output_defining_equality(__isl_keep isl_basic_map *bmap,
|
||||
int pos);
|
||||
|
||||
__isl_give isl_basic_set_list *isl_set_get_basic_set_list(
|
||||
__isl_keep isl_set *set);
|
||||
__isl_give isl_basic_map *isl_basic_map_reduce_coefficients(
|
||||
__isl_take isl_basic_map *bmap);
|
||||
|
||||
__isl_give isl_basic_map *isl_basic_map_shift_div(
|
||||
__isl_take isl_basic_map *bmap, int div, isl_int shift);
|
||||
|
||||
__isl_give isl_basic_map_list *isl_map_get_basic_map_list(
|
||||
__isl_keep isl_map *map);
|
||||
|
||||
__isl_give isl_map *isl_map_fixed_power(__isl_take isl_map *map, isl_int exp);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright 2008-2009 Katholieke Universiteit Leuven
|
||||
* Copyright 2012 Ecole Normale Superieure
|
||||
* Copyright 2012-2013 Ecole Normale Superieure
|
||||
* Copyright 2014 INRIA Rocquencourt
|
||||
*
|
||||
* Use of this software is governed by the MIT license
|
||||
|
@ -1184,6 +1184,26 @@ __isl_give isl_basic_map *isl_basic_map_remove_duplicate_constraints(
|
|||
return bmap;
|
||||
}
|
||||
|
||||
/* Detect all pairs of inequalities that form an equality.
|
||||
*
|
||||
* isl_basic_map_remove_duplicate_constraints detects at most one such pair.
|
||||
* Call it repeatedly while it is making progress.
|
||||
*/
|
||||
__isl_give isl_basic_map *isl_basic_map_detect_inequality_pairs(
|
||||
__isl_take isl_basic_map *bmap, int *progress)
|
||||
{
|
||||
int duplicate;
|
||||
|
||||
do {
|
||||
duplicate = 0;
|
||||
bmap = isl_basic_map_remove_duplicate_constraints(bmap,
|
||||
&duplicate, 0);
|
||||
if (progress && duplicate)
|
||||
*progress = 1;
|
||||
} while (duplicate);
|
||||
|
||||
return bmap;
|
||||
}
|
||||
|
||||
/* Eliminate knowns divs from constraints where they appear with
|
||||
* a (positive or negative) unit coefficient.
|
||||
|
@ -1300,6 +1320,8 @@ struct isl_basic_map *isl_basic_map_simplify(struct isl_basic_map *bmap)
|
|||
bmap = normalize_divs(bmap, &progress);
|
||||
bmap = isl_basic_map_remove_duplicate_constraints(bmap,
|
||||
&progress, 1);
|
||||
if (bmap && progress)
|
||||
ISL_F_CLR(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS);
|
||||
}
|
||||
return bmap;
|
||||
}
|
||||
|
@ -2352,12 +2374,21 @@ error:
|
|||
* return the corresponding universe.
|
||||
*
|
||||
* If none of these cases apply, we have to work a bit harder.
|
||||
* During this computation, we make use of a single disjunct context,
|
||||
* so if the original context consists of more than one disjunct
|
||||
* then we need to approximate the context by a single disjunct set.
|
||||
* Simply taking the simple hull may drop constraints that are
|
||||
* only implicitly available in each disjunct. We therefore also
|
||||
* look for constraints among those defining "map" that are valid
|
||||
* for the context. These can then be used to simplify away
|
||||
* the corresponding constraints in "map".
|
||||
*/
|
||||
static __isl_give isl_map *map_gist(__isl_take isl_map *map,
|
||||
__isl_take isl_map *context)
|
||||
{
|
||||
int equal;
|
||||
int is_universe;
|
||||
isl_basic_map *hull;
|
||||
|
||||
is_universe = isl_map_plain_is_universe(map);
|
||||
if (is_universe >= 0 && !is_universe)
|
||||
|
@ -2380,7 +2411,22 @@ static __isl_give isl_map *map_gist(__isl_take isl_map *map,
|
|||
}
|
||||
|
||||
context = isl_map_compute_divs(context);
|
||||
return isl_map_gist_basic_map(map, isl_map_simple_hull(context));
|
||||
if (!context)
|
||||
goto error;
|
||||
if (isl_map_n_basic_map(context) == 1) {
|
||||
hull = isl_map_simple_hull(context);
|
||||
} else {
|
||||
isl_ctx *ctx;
|
||||
isl_map_list *list;
|
||||
|
||||
ctx = isl_map_get_ctx(map);
|
||||
list = isl_map_list_alloc(ctx, 2);
|
||||
list = isl_map_list_add(list, isl_map_copy(context));
|
||||
list = isl_map_list_add(list, isl_map_copy(map));
|
||||
hull = isl_map_unshifted_simple_hull_from_map_list(context,
|
||||
list);
|
||||
}
|
||||
return isl_map_gist_basic_map(map, hull);
|
||||
error:
|
||||
isl_map_free(map);
|
||||
isl_map_free(context);
|
||||
|
@ -2423,6 +2469,19 @@ __isl_give isl_set *isl_set_gist(__isl_take isl_set *set,
|
|||
(struct isl_map *)context);
|
||||
}
|
||||
|
||||
/* Compute the gist of "bmap" with respect to the constraints "context"
|
||||
* on the domain.
|
||||
*/
|
||||
__isl_give isl_basic_map *isl_basic_map_gist_domain(
|
||||
__isl_take isl_basic_map *bmap, __isl_take isl_basic_set *context)
|
||||
{
|
||||
isl_space *space = isl_basic_map_get_space(bmap);
|
||||
isl_basic_map *bmap_context = isl_basic_map_universe(space);
|
||||
|
||||
bmap_context = isl_basic_map_intersect_domain(bmap_context, context);
|
||||
return isl_basic_map_gist(bmap, bmap_context);
|
||||
}
|
||||
|
||||
__isl_give isl_map *isl_map_gist_domain(__isl_take isl_map *map,
|
||||
__isl_take isl_set *context)
|
||||
{
|
||||
|
@ -3255,3 +3314,207 @@ struct isl_set *isl_set_drop_redundant_divs(struct isl_set *set)
|
|||
return (struct isl_set *)
|
||||
isl_map_drop_redundant_divs((struct isl_map *)set);
|
||||
}
|
||||
|
||||
/* Does "bmap" satisfy any equality that involves more than 2 variables
|
||||
* and/or has coefficients different from -1 and 1?
|
||||
*/
|
||||
static int has_multiple_var_equality(__isl_keep isl_basic_map *bmap)
|
||||
{
|
||||
int i;
|
||||
unsigned total;
|
||||
|
||||
total = isl_basic_map_dim(bmap, isl_dim_all);
|
||||
|
||||
for (i = 0; i < bmap->n_eq; ++i) {
|
||||
int j, k;
|
||||
|
||||
j = isl_seq_first_non_zero(bmap->eq[i] + 1, total);
|
||||
if (j < 0)
|
||||
continue;
|
||||
if (!isl_int_is_one(bmap->eq[i][1 + j]) &&
|
||||
!isl_int_is_negone(bmap->eq[i][1 + j]))
|
||||
return 1;
|
||||
|
||||
j += 1;
|
||||
k = isl_seq_first_non_zero(bmap->eq[i] + 1 + j, total - j);
|
||||
if (k < 0)
|
||||
continue;
|
||||
j += k;
|
||||
if (!isl_int_is_one(bmap->eq[i][1 + j]) &&
|
||||
!isl_int_is_negone(bmap->eq[i][1 + j]))
|
||||
return 1;
|
||||
|
||||
j += 1;
|
||||
k = isl_seq_first_non_zero(bmap->eq[i] + 1 + j, total - j);
|
||||
if (k >= 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove any common factor g from the constraint coefficients in "v".
|
||||
* The constant term is stored in the first position and is replaced
|
||||
* by floor(c/g). If any common factor is removed and if this results
|
||||
* in a tightening of the constraint, then set *tightened.
|
||||
*/
|
||||
static __isl_give isl_vec *normalize_constraint(__isl_take isl_vec *v,
|
||||
int *tightened)
|
||||
{
|
||||
isl_ctx *ctx;
|
||||
|
||||
if (!v)
|
||||
return NULL;
|
||||
ctx = isl_vec_get_ctx(v);
|
||||
isl_seq_gcd(v->el + 1, v->size - 1, &ctx->normalize_gcd);
|
||||
if (isl_int_is_zero(ctx->normalize_gcd))
|
||||
return v;
|
||||
if (isl_int_is_one(ctx->normalize_gcd))
|
||||
return v;
|
||||
v = isl_vec_cow(v);
|
||||
if (!v)
|
||||
return NULL;
|
||||
if (tightened && !isl_int_is_divisible_by(v->el[0], ctx->normalize_gcd))
|
||||
*tightened = 1;
|
||||
isl_int_fdiv_q(v->el[0], v->el[0], ctx->normalize_gcd);
|
||||
isl_seq_scale_down(v->el + 1, v->el + 1, ctx->normalize_gcd,
|
||||
v->size - 1);
|
||||
return v;
|
||||
}
|
||||
|
||||
/* If "bmap" is an integer set that satisfies any equality involving
|
||||
* more than 2 variables and/or has coefficients different from -1 and 1,
|
||||
* then use variable compression to reduce the coefficients by removing
|
||||
* any (hidden) common factor.
|
||||
* In particular, apply the variable compression to each constraint,
|
||||
* factor out any common factor in the non-constant coefficients and
|
||||
* then apply the inverse of the compression.
|
||||
* At the end, we mark the basic map as having reduced constants.
|
||||
* If this flag is still set on the next invocation of this function,
|
||||
* then we skip the computation.
|
||||
*
|
||||
* Removing a common factor may result in a tightening of some of
|
||||
* the constraints. If this happens, then we may end up with two
|
||||
* opposite inequalities that can be replaced by an equality.
|
||||
* We therefore call isl_basic_map_detect_inequality_pairs,
|
||||
* which checks for such pairs of inequalities as well as eliminate_divs_eq
|
||||
* if such a pair was found.
|
||||
*/
|
||||
__isl_give isl_basic_map *isl_basic_map_reduce_coefficients(
|
||||
__isl_take isl_basic_map *bmap)
|
||||
{
|
||||
unsigned total;
|
||||
isl_ctx *ctx;
|
||||
isl_vec *v;
|
||||
isl_mat *eq, *T, *T2;
|
||||
int i;
|
||||
int tightened;
|
||||
|
||||
if (!bmap)
|
||||
return NULL;
|
||||
if (ISL_F_ISSET(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS))
|
||||
return bmap;
|
||||
if (isl_basic_map_is_rational(bmap))
|
||||
return bmap;
|
||||
if (bmap->n_eq == 0)
|
||||
return bmap;
|
||||
if (!has_multiple_var_equality(bmap))
|
||||
return bmap;
|
||||
|
||||
total = isl_basic_map_dim(bmap, isl_dim_all);
|
||||
ctx = isl_basic_map_get_ctx(bmap);
|
||||
v = isl_vec_alloc(ctx, 1 + total);
|
||||
if (!v)
|
||||
return isl_basic_map_free(bmap);
|
||||
|
||||
eq = isl_mat_sub_alloc6(ctx, bmap->eq, 0, bmap->n_eq, 0, 1 + total);
|
||||
T = isl_mat_variable_compression(eq, &T2);
|
||||
if (!T || !T2)
|
||||
goto error;
|
||||
if (T->n_col == 0) {
|
||||
isl_mat_free(T);
|
||||
isl_mat_free(T2);
|
||||
isl_vec_free(v);
|
||||
return isl_basic_map_set_to_empty(bmap);
|
||||
}
|
||||
|
||||
tightened = 0;
|
||||
for (i = 0; i < bmap->n_ineq; ++i) {
|
||||
isl_seq_cpy(v->el, bmap->ineq[i], 1 + total);
|
||||
v = isl_vec_mat_product(v, isl_mat_copy(T));
|
||||
v = normalize_constraint(v, &tightened);
|
||||
v = isl_vec_mat_product(v, isl_mat_copy(T2));
|
||||
if (!v)
|
||||
goto error;
|
||||
isl_seq_cpy(bmap->ineq[i], v->el, 1 + total);
|
||||
}
|
||||
|
||||
isl_mat_free(T);
|
||||
isl_mat_free(T2);
|
||||
isl_vec_free(v);
|
||||
|
||||
ISL_F_SET(bmap, ISL_BASIC_MAP_REDUCED_COEFFICIENTS);
|
||||
|
||||
if (tightened) {
|
||||
int progress = 0;
|
||||
|
||||
bmap = isl_basic_map_detect_inequality_pairs(bmap, &progress);
|
||||
if (progress)
|
||||
bmap = eliminate_divs_eq(bmap, &progress);
|
||||
}
|
||||
|
||||
return bmap;
|
||||
error:
|
||||
isl_mat_free(T);
|
||||
isl_mat_free(T2);
|
||||
isl_vec_free(v);
|
||||
return isl_basic_map_free(bmap);
|
||||
}
|
||||
|
||||
/* Shift the integer division at position "div" of "bmap" by "shift".
|
||||
*
|
||||
* That is, if the integer division has the form
|
||||
*
|
||||
* floor(f(x)/d)
|
||||
*
|
||||
* then replace it by
|
||||
*
|
||||
* floor((f(x) + shift * d)/d) - shift
|
||||
*/
|
||||
__isl_give isl_basic_map *isl_basic_map_shift_div(
|
||||
__isl_take isl_basic_map *bmap, int div, isl_int shift)
|
||||
{
|
||||
int i;
|
||||
unsigned total;
|
||||
|
||||
if (!bmap)
|
||||
return NULL;
|
||||
|
||||
total = isl_basic_map_dim(bmap, isl_dim_all);
|
||||
total -= isl_basic_map_dim(bmap, isl_dim_div);
|
||||
|
||||
isl_int_addmul(bmap->div[div][1], shift, bmap->div[div][0]);
|
||||
|
||||
for (i = 0; i < bmap->n_eq; ++i) {
|
||||
if (isl_int_is_zero(bmap->eq[i][1 + total + div]))
|
||||
continue;
|
||||
isl_int_submul(bmap->eq[i][0],
|
||||
shift, bmap->eq[i][1 + total + div]);
|
||||
}
|
||||
for (i = 0; i < bmap->n_ineq; ++i) {
|
||||
if (isl_int_is_zero(bmap->ineq[i][1 + total + div]))
|
||||
continue;
|
||||
isl_int_submul(bmap->ineq[i][0],
|
||||
shift, bmap->ineq[i][1 + total + div]);
|
||||
}
|
||||
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 + 1 + total + div]))
|
||||
continue;
|
||||
isl_int_submul(bmap->div[i][1],
|
||||
shift, bmap->div[i][1 + 1 + total + div]);
|
||||
}
|
||||
|
||||
return bmap;
|
||||
}
|
||||
|
|
|
@ -304,8 +304,8 @@ void isl_morph_print_internal(__isl_take isl_morph *morph, FILE *out)
|
|||
if (!morph)
|
||||
return;
|
||||
|
||||
isl_basic_set_print(morph->dom, out, 0, "", "", ISL_FORMAT_ISL);
|
||||
isl_basic_set_print(morph->ran, out, 0, "", "", ISL_FORMAT_ISL);
|
||||
isl_basic_set_dump(morph->dom);
|
||||
isl_basic_set_dump(morph->ran);
|
||||
isl_mat_print_internal(morph->map, out, 4);
|
||||
isl_mat_print_internal(morph->inv, out, 4);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#define APPLY_DOMBASE set
|
||||
#define APPLY_DOM isl_set
|
||||
|
||||
#include <isl_multi_apply_templ.c>
|
||||
|
||||
#undef APPLY_DOMBASE
|
||||
#undef APPLY_DOM
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright 2011 Sven Verdoolaege
|
||||
* Copyright 2012-2013 Ecole Normale Superieure
|
||||
*
|
||||
* Use of this software is governed by the MIT license
|
||||
*
|
||||
* Written by Sven Verdoolaege,
|
||||
* Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
|
||||
*/
|
||||
|
||||
#include <isl_multi_macro.h>
|
||||
|
||||
/* Transform the elements of "multi" by applying "fn" to them
|
||||
* with extra argument "set".
|
||||
*
|
||||
* The parameters of "multi" and "set" are assumed to have been aligned.
|
||||
*/
|
||||
__isl_give MULTI(BASE) *FN(FN(MULTI(BASE),apply_aligned),APPLY_DOMBASE)(
|
||||
__isl_take MULTI(BASE) *multi, __isl_take APPLY_DOM *set,
|
||||
__isl_give EL *(*fn)(EL *el, __isl_take APPLY_DOM *set))
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!multi || !set)
|
||||
goto error;
|
||||
|
||||
if (multi->n == 0) {
|
||||
FN(APPLY_DOM,free)(set);
|
||||
return multi;
|
||||
}
|
||||
|
||||
multi = FN(MULTI(BASE),cow)(multi);
|
||||
if (!multi)
|
||||
goto error;
|
||||
|
||||
for (i = 0; i < multi->n; ++i) {
|
||||
multi->p[i] = fn(multi->p[i], FN(APPLY_DOM,copy)(set));
|
||||
if (!multi->p[i])
|
||||
goto error;
|
||||
}
|
||||
|
||||
FN(APPLY_DOM,free)(set);
|
||||
return multi;
|
||||
error:
|
||||
FN(APPLY_DOM,free)(set);
|
||||
FN(MULTI(BASE),free)(multi);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Transform the elements of "multi" by applying "fn" to them
|
||||
* with extra argument "set".
|
||||
*
|
||||
* Align the parameters if needed and call apply_set_aligned.
|
||||
*/
|
||||
static __isl_give MULTI(BASE) *FN(FN(MULTI(BASE),apply),APPLY_DOMBASE)(
|
||||
__isl_take MULTI(BASE) *multi, __isl_take APPLY_DOM *set,
|
||||
__isl_give EL *(*fn)(EL *el, __isl_take APPLY_DOM *set))
|
||||
{
|
||||
isl_ctx *ctx;
|
||||
|
||||
if (!multi || !set)
|
||||
goto error;
|
||||
|
||||
if (isl_space_match(multi->space, isl_dim_param,
|
||||
set->dim, isl_dim_param))
|
||||
return FN(FN(MULTI(BASE),apply_aligned),APPLY_DOMBASE)(multi,
|
||||
set, fn);
|
||||
ctx = FN(MULTI(BASE),get_ctx)(multi);
|
||||
if (!isl_space_has_named_params(multi->space) ||
|
||||
!isl_space_has_named_params(set->dim))
|
||||
isl_die(ctx, isl_error_invalid,
|
||||
"unaligned unnamed parameters", goto error);
|
||||
multi = FN(MULTI(BASE),align_params)(multi,
|
||||
FN(APPLY_DOM,get_space)(set));
|
||||
set = FN(APPLY_DOM,align_params)(set, FN(MULTI(BASE),get_space)(multi));
|
||||
return FN(FN(MULTI(BASE),apply_aligned),APPLY_DOMBASE)(multi, set, fn);
|
||||
error:
|
||||
FN(MULTI(BASE),free)(multi);
|
||||
FN(APPLY_DOM,free)(set);
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#define APPLY_DOMBASE union_set
|
||||
#define APPLY_DOM isl_union_set
|
||||
|
||||
#include <isl_multi_apply_templ.c>
|
||||
|
||||
#undef APPLY_DOMBASE
|
||||
#undef APPLY_DOM
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2014 Ecole Normale Superieure
|
||||
*
|
||||
* Use of this software is governed by the MIT license
|
||||
*
|
||||
* Written by Sven Verdoolaege,
|
||||
* Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
|
||||
*/
|
||||
|
||||
#include <isl_multi_macro.h>
|
||||
|
||||
/* Given f, return floor(f).
|
||||
*/
|
||||
__isl_give MULTI(BASE) *FN(MULTI(BASE),floor)(__isl_take MULTI(BASE) *multi)
|
||||
{
|
||||
int i;
|
||||
|
||||
multi = FN(MULTI(BASE),cow)(multi);
|
||||
if (!multi)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < multi->n; ++i) {
|
||||
multi->p[i] = FN(EL,floor)(multi->p[i]);
|
||||
if (!multi->p[i])
|
||||
return FN(MULTI(BASE),free)(multi);
|
||||
}
|
||||
|
||||
return multi;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2011 Sven Verdoolaege
|
||||
* Copyright 2012-2013 Ecole Normale Superieure
|
||||
*
|
||||
* Use of this software is governed by the MIT license
|
||||
*
|
||||
* Written by Sven Verdoolaege,
|
||||
* Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
|
||||
*/
|
||||
|
||||
#include <isl_multi_macro.h>
|
||||
|
||||
/* Compute the gist of "multi" with respect to the domain constraints
|
||||
* of "context".
|
||||
*/
|
||||
__isl_give MULTI(BASE) *FN(MULTI(BASE),gist)(__isl_take MULTI(BASE) *multi,
|
||||
__isl_take DOM *context)
|
||||
{
|
||||
return FN(FN(MULTI(BASE),apply),DOMBASE)(multi, context, &FN(EL,gist));
|
||||
}
|
||||
|
||||
/* Compute the gist of "multi" with respect to the parameter constraints
|
||||
* of "context".
|
||||
*/
|
||||
__isl_give MULTI(BASE) *FN(MULTI(BASE),gist_params)(
|
||||
__isl_take MULTI(BASE) *multi, __isl_take isl_set *context)
|
||||
{
|
||||
return FN(MULTI(BASE),apply_set)(multi, context, &FN(EL,gist_params));
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2011 Sven Verdoolaege
|
||||
* Copyright 2012-2013 Ecole Normale Superieure
|
||||
*
|
||||
* Use of this software is governed by the MIT license
|
||||
*
|
||||
* Written by Sven Verdoolaege,
|
||||
* Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
|
||||
*/
|
||||
|
||||
#include <isl_multi_macro.h>
|
||||
|
||||
/* Intersect the domain of "multi" with "domain".
|
||||
*/
|
||||
__isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_domain)(
|
||||
__isl_take MULTI(BASE) *multi, __isl_take DOM *domain)
|
||||
{
|
||||
return FN(FN(MULTI(BASE),apply),DOMBASE)(multi, domain,
|
||||
&FN(EL,intersect_domain));
|
||||
}
|
||||
|
||||
/* Intersect the parameter domain of "multi" with "domain".
|
||||
*/
|
||||
__isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_params)(
|
||||
__isl_take MULTI(BASE) *multi, __isl_take isl_set *domain)
|
||||
{
|
||||
return FN(MULTI(BASE),apply_set)(multi, domain,
|
||||
&FN(EL,intersect_params));
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#define xCAT(A,B) A ## B
|
||||
#define CAT(A,B) xCAT(A,B)
|
||||
#undef EL
|
||||
#define EL CAT(isl_,BASE)
|
||||
#define xFN(TYPE,NAME) TYPE ## _ ## NAME
|
||||
#define FN(TYPE,NAME) xFN(TYPE,NAME)
|
||||
#define xMULTI(BASE) isl_multi_ ## BASE
|
||||
#define MULTI(BASE) xMULTI(BASE)
|
||||
#undef DOM
|
||||
#define DOM CAT(isl_,DOMBASE)
|
|
@ -12,14 +12,8 @@
|
|||
#include <isl/set.h>
|
||||
#include <isl_reordering.h>
|
||||
|
||||
#define xCAT(A,B) A ## B
|
||||
#define CAT(A,B) xCAT(A,B)
|
||||
#undef EL
|
||||
#define EL CAT(isl_,BASE)
|
||||
#define xFN(TYPE,NAME) TYPE ## _ ## NAME
|
||||
#define FN(TYPE,NAME) xFN(TYPE,NAME)
|
||||
#define xMULTI(BASE) isl_multi_ ## BASE
|
||||
#define MULTI(BASE) xMULTI(BASE)
|
||||
#include <isl_multi_macro.h>
|
||||
|
||||
#define MULTI_NAME(BASE) "isl_multi_" #BASE
|
||||
#define xLIST(EL) EL ## _list
|
||||
#define LIST(EL) xLIST(EL)
|
||||
|
@ -135,6 +129,7 @@ __isl_null MULTI(BASE) *FN(MULTI(BASE),free)(__isl_take MULTI(BASE) *multi)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef NO_DIMS
|
||||
/* Check whether "multi" has non-zero coefficients for any dimension
|
||||
* in the given range or if any of these dimensions appear
|
||||
* with non-zero coefficients in any of the integer divisions involved.
|
||||
|
@ -201,6 +196,7 @@ __isl_give MULTI(BASE) *FN(MULTI(BASE),add_dims)(__isl_take MULTI(BASE) *multi,
|
|||
|
||||
return FN(MULTI(BASE),insert_dims)(multi, type, pos, n);
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned FN(MULTI(BASE),dim)(__isl_keep MULTI(BASE) *multi,
|
||||
enum isl_dim_type type)
|
||||
|
@ -544,154 +540,6 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if !defined(NO_GIST) || !defined(NO_INTERSECT_DOMAIN)
|
||||
static __isl_give MULTI(BASE) *FN(MULTI(BASE),align_params_multi_set_and)(
|
||||
__isl_take MULTI(BASE) *multi, __isl_take isl_set *set,
|
||||
__isl_give MULTI(BASE) *(*fn)(__isl_take MULTI(BASE) *multi,
|
||||
__isl_take isl_set *set))
|
||||
{
|
||||
isl_ctx *ctx;
|
||||
|
||||
if (!multi || !set)
|
||||
goto error;
|
||||
if (isl_space_match(multi->space, isl_dim_param,
|
||||
set->dim, isl_dim_param))
|
||||
return fn(multi, set);
|
||||
ctx = FN(MULTI(BASE),get_ctx)(multi);
|
||||
if (!isl_space_has_named_params(multi->space) ||
|
||||
!isl_space_has_named_params(set->dim))
|
||||
isl_die(ctx, isl_error_invalid,
|
||||
"unaligned unnamed parameters", goto error);
|
||||
multi = FN(MULTI(BASE),align_params)(multi, isl_set_get_space(set));
|
||||
set = isl_set_align_params(set, FN(MULTI(BASE),get_space)(multi));
|
||||
return fn(multi, set);
|
||||
error:
|
||||
FN(MULTI(BASE),free)(multi);
|
||||
isl_set_free(set);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NO_GIST
|
||||
__isl_give MULTI(BASE) *FN(MULTI(BASE),gist_aligned)(
|
||||
__isl_take MULTI(BASE) *multi, __isl_take isl_set *context)
|
||||
{
|
||||
int i;
|
||||
|
||||
multi = FN(MULTI(BASE),cow)(multi);
|
||||
if (!multi || !context)
|
||||
goto error;
|
||||
|
||||
for (i = 0; i < multi->n; ++i) {
|
||||
multi->p[i] = FN(EL,gist)(multi->p[i], isl_set_copy(context));
|
||||
if (!multi->p[i])
|
||||
goto error;
|
||||
}
|
||||
|
||||
isl_set_free(context);
|
||||
return multi;
|
||||
error:
|
||||
isl_set_free(context);
|
||||
FN(MULTI(BASE),free)(multi);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__isl_give MULTI(BASE) *FN(MULTI(BASE),gist)(__isl_take MULTI(BASE) *multi,
|
||||
__isl_take isl_set *context)
|
||||
{
|
||||
return FN(MULTI(BASE),align_params_multi_set_and)(multi, context,
|
||||
&FN(MULTI(BASE),gist_aligned));
|
||||
}
|
||||
|
||||
__isl_give MULTI(BASE) *FN(MULTI(BASE),gist_params)(
|
||||
__isl_take MULTI(BASE) *multi, __isl_take isl_set *context)
|
||||
{
|
||||
isl_space *space = FN(MULTI(BASE),get_domain_space)(multi);
|
||||
isl_set *dom_context = isl_set_universe(space);
|
||||
dom_context = isl_set_intersect_params(dom_context, context);
|
||||
return FN(MULTI(BASE),gist)(multi, dom_context);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NO_INTERSECT_DOMAIN
|
||||
/* Transform the domain of "multi" by combining it with "domain"
|
||||
* using "fn".
|
||||
*
|
||||
* The parameters of "multi" and "domain" are assumed to have been aligned.
|
||||
*/
|
||||
__isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_aligned)(
|
||||
__isl_take MULTI(BASE) *multi, __isl_take isl_set *domain,
|
||||
__isl_give EL *(*fn)(EL *el, __isl_take isl_set *set2))
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!multi || !domain)
|
||||
goto error;
|
||||
|
||||
if (multi->n == 0) {
|
||||
isl_set_free(domain);
|
||||
return multi;
|
||||
}
|
||||
|
||||
multi = FN(MULTI(BASE),cow)(multi);
|
||||
if (!multi)
|
||||
goto error;
|
||||
|
||||
for (i = 0; i < multi->n; ++i) {
|
||||
multi->p[i] = fn(multi->p[i], isl_set_copy(domain));
|
||||
if (!multi->p[i])
|
||||
goto error;
|
||||
}
|
||||
|
||||
isl_set_free(domain);
|
||||
return multi;
|
||||
error:
|
||||
isl_set_free(domain);
|
||||
FN(MULTI(BASE),free)(multi);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Intersect the domain of "multi" with "domain".
|
||||
*
|
||||
* The parameters of "multi" and "domain" are assumed to have been aligned.
|
||||
*/
|
||||
__isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_domain_aligned)(
|
||||
__isl_take MULTI(BASE) *multi, __isl_take isl_set *domain)
|
||||
{
|
||||
return FN(MULTI(BASE),intersect_aligned)(multi, domain,
|
||||
&FN(EL,intersect_domain));
|
||||
}
|
||||
|
||||
/* Intersect the domain of "multi" with "domain".
|
||||
*/
|
||||
__isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_domain)(
|
||||
__isl_take MULTI(BASE) *multi, __isl_take isl_set *domain)
|
||||
{
|
||||
return FN(MULTI(BASE),align_params_multi_set_and)(multi, domain,
|
||||
&FN(MULTI(BASE),intersect_domain_aligned));
|
||||
}
|
||||
|
||||
/* Intersect the parameter domain of "multi" with "domain".
|
||||
*
|
||||
* The parameters of "multi" and "domain" are assumed to have been aligned.
|
||||
*/
|
||||
__isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_params_aligned)(
|
||||
__isl_take MULTI(BASE) *multi, __isl_take isl_set *domain)
|
||||
{
|
||||
return FN(MULTI(BASE),intersect_aligned)(multi, domain,
|
||||
&FN(EL,intersect_params));
|
||||
}
|
||||
|
||||
/* Intersect the parameter domain of "multi" with "domain".
|
||||
*/
|
||||
__isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_params)(
|
||||
__isl_take MULTI(BASE) *multi, __isl_take isl_set *domain)
|
||||
{
|
||||
return FN(MULTI(BASE),align_params_multi_set_and)(multi, domain,
|
||||
&FN(MULTI(BASE),intersect_params_aligned));
|
||||
}
|
||||
#endif
|
||||
|
||||
__isl_give MULTI(BASE) *FN(FN(MULTI(BASE),from),LIST(BASE))(
|
||||
__isl_take isl_space *space, __isl_take LIST(EL) *list)
|
||||
{
|
||||
|
@ -773,6 +621,7 @@ error:
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef NO_ZERO
|
||||
/* Construct a multi expression in the given space with value zero in
|
||||
* each of the output dimensions.
|
||||
*/
|
||||
|
@ -807,13 +656,29 @@ __isl_give MULTI(BASE) *FN(MULTI(BASE),zero)(__isl_take isl_space *space)
|
|||
|
||||
return multi;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NO_FROM_BASE
|
||||
/* Create a multiple expression with a single output/set dimension
|
||||
* equal to "el".
|
||||
* For most multiple expression types, the base type has a single
|
||||
* output/set dimension and the space of the result is therefore
|
||||
* the same as the space of the input.
|
||||
* In the case of isl_multi_union_pw_aff, however, the base type
|
||||
* lives in a parameter space and we therefore need to add
|
||||
* a single set dimension.
|
||||
*/
|
||||
__isl_give MULTI(BASE) *FN(FN(MULTI(BASE),from),BASE)(__isl_take EL *el)
|
||||
{
|
||||
isl_space *space;
|
||||
MULTI(BASE) *multi;
|
||||
|
||||
multi = FN(MULTI(BASE),alloc)(FN(EL,get_space)(el));
|
||||
space = FN(EL,get_space(el));
|
||||
if (isl_space_is_params(space)) {
|
||||
space = isl_space_set_from_params(space);
|
||||
space = isl_space_add_dims(space, isl_dim_set, 1);
|
||||
}
|
||||
multi = FN(MULTI(BASE),alloc)(space);
|
||||
multi = FN(FN(MULTI(BASE),set),BASE)(multi, 0, el);
|
||||
|
||||
return multi;
|
||||
|
@ -1002,6 +867,7 @@ __isl_give MULTI(BASE) *FN(MULTI(BASE),range_factor_range)(
|
|||
return multi;
|
||||
}
|
||||
|
||||
#ifndef NO_PRODUCT
|
||||
/* Given two MULTI(BASE)s A -> B and C -> D,
|
||||
* construct a MULTI(BASE) [A -> C] -> [B -> D].
|
||||
*
|
||||
|
@ -1054,6 +920,7 @@ __isl_give MULTI(BASE) *FN(MULTI(BASE),product)(
|
|||
return FN(MULTI(BASE),align_params_multi_multi_and)(multi1, multi2,
|
||||
&FN(MULTI(BASE),product_aligned));
|
||||
}
|
||||
#endif
|
||||
|
||||
__isl_give MULTI(BASE) *FN(MULTI(BASE),flatten_range)(
|
||||
__isl_take MULTI(BASE) *multi)
|
||||
|
@ -1129,6 +996,7 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef NO_SPLICE
|
||||
/* Given two multi expressions, "multi1"
|
||||
*
|
||||
* [A1 A2] -> [B1 B2]
|
||||
|
@ -1180,6 +1048,7 @@ error:
|
|||
FN(MULTI(BASE),free)(multi2);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This function is currently only used from isl_aff.c
|
||||
*/
|
||||
|
@ -1221,6 +1090,25 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Subtract "multi2" from "multi1" and return the result.
|
||||
*
|
||||
* The parameters of "multi1" and "multi2" are assumed to have been aligned.
|
||||
*/
|
||||
static __isl_give MULTI(BASE) *FN(MULTI(BASE),sub_aligned)(
|
||||
__isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2)
|
||||
{
|
||||
return FN(MULTI(BASE),bin_op)(multi1, multi2, &FN(EL,sub));
|
||||
}
|
||||
|
||||
/* Subtract "multi2" from "multi1" and return the result.
|
||||
*/
|
||||
__isl_give MULTI(BASE) *FN(MULTI(BASE),sub)(__isl_take MULTI(BASE) *multi1,
|
||||
__isl_take MULTI(BASE) *multi2)
|
||||
{
|
||||
return FN(MULTI(BASE),align_params_multi_multi_and)(multi1, multi2,
|
||||
&FN(MULTI(BASE),sub_aligned));
|
||||
}
|
||||
|
||||
/* Multiply the elements of "multi" by "v" and return the result.
|
||||
*/
|
||||
__isl_give MULTI(BASE) *FN(MULTI(BASE),scale_val)(__isl_take MULTI(BASE) *multi,
|
||||
|
@ -1369,6 +1257,42 @@ error:
|
|||
return FN(MULTI(BASE),free)(multi);
|
||||
}
|
||||
|
||||
/* Compute the residues of the elements of "multi" modulo
|
||||
* the corresponding element of "mv" and return the result.
|
||||
*/
|
||||
__isl_give MULTI(BASE) *FN(MULTI(BASE),mod_multi_val)(
|
||||
__isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!multi || !mv)
|
||||
goto error;
|
||||
|
||||
if (!isl_space_tuple_is_equal(multi->space, isl_dim_out,
|
||||
mv->space, isl_dim_set))
|
||||
isl_die(isl_multi_val_get_ctx(mv), isl_error_invalid,
|
||||
"spaces don't match", goto error);
|
||||
|
||||
multi = FN(MULTI(BASE),cow)(multi);
|
||||
if (!multi)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < multi->n; ++i) {
|
||||
isl_val *v;
|
||||
|
||||
v = isl_multi_val_get_val(mv, i);
|
||||
multi->p[i] = FN(EL,mod_val)(multi->p[i], v);
|
||||
if (!multi->p[i])
|
||||
goto error;
|
||||
}
|
||||
|
||||
isl_multi_val_free(mv);
|
||||
return multi;
|
||||
error:
|
||||
isl_multi_val_free(mv);
|
||||
return FN(MULTI(BASE),free)(multi);
|
||||
}
|
||||
|
||||
#ifndef NO_MOVE_DIMS
|
||||
/* Move the "n" dimensions of "src_type" starting at "src_pos" of "multi"
|
||||
* to dimensions of "dst_type" at "dst_pos".
|
||||
|
@ -1496,3 +1420,24 @@ __isl_give isl_set *FN(MULTI(BASE),domain)(__isl_take MULTI(BASE) *multi)
|
|||
return dom;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NO_NEG
|
||||
/* Return the opposite of "multi".
|
||||
*/
|
||||
__isl_give MULTI(BASE) *FN(MULTI(BASE),neg)(__isl_take MULTI(BASE) *multi)
|
||||
{
|
||||
int i;
|
||||
|
||||
multi = FN(MULTI(BASE),cow)(multi);
|
||||
if (!multi)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < multi->n; ++i) {
|
||||
multi->p[i] = FN(EL,neg)(multi->p[i]);
|
||||
if (!multi->p[i])
|
||||
return FN(MULTI(BASE),free)(multi);
|
||||
}
|
||||
|
||||
return multi;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
#include <isl/space.h>
|
||||
|
||||
#define xCAT(A,B) A ## B
|
||||
#define CAT(A,B) xCAT(A,B)
|
||||
#undef EL
|
||||
#define EL CAT(isl_,BASE)
|
||||
#define xMULTI(BASE) isl_multi_ ## BASE
|
||||
#define MULTI(BASE) xMULTI(BASE)
|
||||
#include <isl_multi_macro.h>
|
||||
|
||||
struct MULTI(BASE) {
|
||||
int ref;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright 2010 INRIA Saclay
|
||||
* Copyright 2014 Ecole Normale Superieure
|
||||
* Copyright 2014 INRIA Rocquencourt
|
||||
*
|
||||
* Use of this software is governed by the MIT license
|
||||
*
|
||||
|
@ -8,12 +9,15 @@
|
|||
* Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
|
||||
* 91893 Orsay, France
|
||||
* and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
|
||||
* and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
|
||||
* B.P. 105 - 78153 Le Chesnay, France
|
||||
*/
|
||||
|
||||
#include <isl/aff.h>
|
||||
#include <isl/set.h>
|
||||
#include <isl/map.h>
|
||||
#include <isl/polynomial.h>
|
||||
#include <isl/schedule.h>
|
||||
#include <isl/obj.h>
|
||||
|
||||
static void *isl_obj_val_copy(void *v)
|
||||
|
@ -333,3 +337,26 @@ struct isl_obj_vtable isl_obj_union_pw_qpolynomial_fold_vtable = {
|
|||
isl_obj_union_pw_qpf_print,
|
||||
isl_obj_union_pw_qpf_free
|
||||
};
|
||||
|
||||
static void *isl_obj_schedule_copy(void *v)
|
||||
{
|
||||
return isl_schedule_copy((isl_schedule *) v);
|
||||
}
|
||||
|
||||
static void isl_obj_schedule_free(void *v)
|
||||
{
|
||||
isl_schedule_free((isl_schedule *) v);
|
||||
}
|
||||
|
||||
static __isl_give isl_printer *isl_obj_schedule_print(
|
||||
__isl_take isl_printer *p, void *v)
|
||||
{
|
||||
return isl_printer_print_schedule(p, (isl_schedule *) v);
|
||||
}
|
||||
|
||||
struct isl_obj_vtable isl_obj_schedule_vtable = {
|
||||
isl_obj_schedule_copy,
|
||||
NULL,
|
||||
isl_obj_schedule_print,
|
||||
isl_obj_schedule_free
|
||||
};
|
||||
|
|
|
@ -1008,24 +1008,6 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void isl_basic_map_print(__isl_keep isl_basic_map *bmap, FILE *out, int indent,
|
||||
const char *prefix, const char *suffix, unsigned output_format)
|
||||
{
|
||||
isl_printer *printer;
|
||||
|
||||
if (!bmap)
|
||||
return;
|
||||
|
||||
printer = isl_printer_to_file(bmap->ctx, out);
|
||||
printer = isl_printer_set_indent(printer, indent);
|
||||
printer = isl_printer_set_prefix(printer, prefix);
|
||||
printer = isl_printer_set_suffix(printer, suffix);
|
||||
printer = isl_printer_set_output_format(printer, output_format);
|
||||
isl_printer_print_basic_map(printer, bmap);
|
||||
|
||||
isl_printer_free(printer);
|
||||
}
|
||||
|
||||
__isl_give isl_printer *isl_printer_print_basic_set(__isl_take isl_printer *p,
|
||||
__isl_keep isl_basic_set *bset)
|
||||
{
|
||||
|
@ -1048,24 +1030,6 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void isl_basic_set_print(struct isl_basic_set *bset, FILE *out, int indent,
|
||||
const char *prefix, const char *suffix, unsigned output_format)
|
||||
{
|
||||
isl_printer *printer;
|
||||
|
||||
if (!bset)
|
||||
return;
|
||||
|
||||
printer = isl_printer_to_file(bset->ctx, out);
|
||||
printer = isl_printer_set_indent(printer, indent);
|
||||
printer = isl_printer_set_prefix(printer, prefix);
|
||||
printer = isl_printer_set_suffix(printer, suffix);
|
||||
printer = isl_printer_set_output_format(printer, output_format);
|
||||
isl_printer_print_basic_set(printer, bset);
|
||||
|
||||
isl_printer_free(printer);
|
||||
}
|
||||
|
||||
__isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *p,
|
||||
__isl_keep isl_set *set)
|
||||
{
|
||||
|
@ -1087,22 +1051,6 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void isl_set_print(struct isl_set *set, FILE *out, int indent,
|
||||
unsigned output_format)
|
||||
{
|
||||
isl_printer *printer;
|
||||
|
||||
if (!set)
|
||||
return;
|
||||
|
||||
printer = isl_printer_to_file(set->ctx, out);
|
||||
printer = isl_printer_set_indent(printer, indent);
|
||||
printer = isl_printer_set_output_format(printer, output_format);
|
||||
printer = isl_printer_print_set(printer, set);
|
||||
|
||||
isl_printer_free(printer);
|
||||
}
|
||||
|
||||
__isl_give isl_printer *isl_printer_print_map(__isl_take isl_printer *p,
|
||||
__isl_keep isl_map *map)
|
||||
{
|
||||
|
@ -1225,22 +1173,6 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void isl_map_print(__isl_keep isl_map *map, FILE *out, int indent,
|
||||
unsigned output_format)
|
||||
{
|
||||
isl_printer *printer;
|
||||
|
||||
if (!map)
|
||||
return;
|
||||
|
||||
printer = isl_printer_to_file(map->ctx, out);
|
||||
printer = isl_printer_set_indent(printer, indent);
|
||||
printer = isl_printer_set_output_format(printer, output_format);
|
||||
printer = isl_printer_print_map(printer, map);
|
||||
|
||||
isl_printer_free(printer);
|
||||
}
|
||||
|
||||
static int upoly_rec_n_non_zero(__isl_keep struct isl_upoly_rec *rec)
|
||||
{
|
||||
int i;
|
||||
|
@ -2161,11 +2093,31 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Print the body of an isl_pw_aff, i.e., a semicolon delimited
|
||||
* sequence of affine expressions, each followed by constraints.
|
||||
*/
|
||||
static __isl_give isl_printer *print_pw_aff_body(
|
||||
__isl_take isl_printer *p, __isl_keep isl_pw_aff *pa)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!pa)
|
||||
return isl_printer_free(p);
|
||||
|
||||
for (i = 0; i < pa->n; ++i) {
|
||||
if (i)
|
||||
p = isl_printer_print_str(p, "; ");
|
||||
p = print_aff(p, pa->p[i].aff);
|
||||
p = print_disjuncts((isl_map *)pa->p[i].set, p, 0);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static __isl_give isl_printer *print_pw_aff_isl(__isl_take isl_printer *p,
|
||||
__isl_keep isl_pw_aff *pwaff)
|
||||
{
|
||||
struct isl_print_space_data data = { 0 };
|
||||
int i;
|
||||
|
||||
if (!pwaff)
|
||||
goto error;
|
||||
|
@ -2175,12 +2127,7 @@ static __isl_give isl_printer *print_pw_aff_isl(__isl_take isl_printer *p,
|
|||
p = isl_printer_print_str(p, " -> ");
|
||||
}
|
||||
p = isl_printer_print_str(p, "{ ");
|
||||
for (i = 0; i < pwaff->n; ++i) {
|
||||
if (i)
|
||||
p = isl_printer_print_str(p, "; ");
|
||||
p = print_aff(p, pwaff->p[i].aff);
|
||||
p = print_disjuncts((isl_map *)pwaff->p[i].set, p, 0);
|
||||
}
|
||||
p = print_pw_aff_body(p, pwaff);
|
||||
p = isl_printer_print_str(p, " }");
|
||||
return p;
|
||||
error:
|
||||
|
@ -2345,6 +2292,84 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Print "pa" in a sequence of isl_pw_affs delimited by semicolons.
|
||||
* Each isl_pw_aff itself is also printed as semicolon delimited
|
||||
* sequence of pieces.
|
||||
* If data->first = 1, then this is the first in the sequence.
|
||||
* Update data->first to tell the next element that it is not the first.
|
||||
*/
|
||||
static int print_pw_aff_body_wrap(__isl_take isl_pw_aff *pa,
|
||||
void *user)
|
||||
{
|
||||
struct isl_union_print_data *data;
|
||||
data = (struct isl_union_print_data *) user;
|
||||
|
||||
if (!data->first)
|
||||
data->p = isl_printer_print_str(data->p, "; ");
|
||||
data->first = 0;
|
||||
|
||||
data->p = print_pw_aff_body(data->p, pa);
|
||||
isl_pw_aff_free(pa);
|
||||
|
||||
return data->p ? 0 : -1;
|
||||
}
|
||||
|
||||
/* Print the body of an isl_union_pw_aff, i.e., a semicolon delimited
|
||||
* sequence of affine expressions, each followed by constraints,
|
||||
* with the sequence enclosed in braces.
|
||||
*/
|
||||
static __isl_give isl_printer *print_union_pw_aff_body(
|
||||
__isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa)
|
||||
{
|
||||
struct isl_union_print_data data = { p, 1 };
|
||||
|
||||
p = isl_printer_print_str(p, s_open_set[0]);
|
||||
data.p = p;
|
||||
if (isl_union_pw_aff_foreach_pw_aff(upa,
|
||||
&print_pw_aff_body_wrap, &data) < 0)
|
||||
data.p = isl_printer_free(p);
|
||||
p = data.p;
|
||||
p = isl_printer_print_str(p, s_close_set[0]);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Print the isl_union_pw_aff "upa" to "p" in isl format.
|
||||
*
|
||||
* The individual isl_pw_affs are delimited by a semicolon.
|
||||
*/
|
||||
static __isl_give isl_printer *print_union_pw_aff_isl(
|
||||
__isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa)
|
||||
{
|
||||
struct isl_print_space_data data = { 0 };
|
||||
isl_space *space;
|
||||
|
||||
space = isl_union_pw_aff_get_space(upa);
|
||||
if (isl_space_dim(space, isl_dim_param) > 0) {
|
||||
p = print_tuple(space, p, isl_dim_param, &data);
|
||||
p = isl_printer_print_str(p, s_to[0]);
|
||||
}
|
||||
isl_space_free(space);
|
||||
p = print_union_pw_aff_body(p, upa);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Print the isl_union_pw_aff "upa" to "p".
|
||||
*
|
||||
* We currently only support an isl format.
|
||||
*/
|
||||
__isl_give isl_printer *isl_printer_print_union_pw_aff(
|
||||
__isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa)
|
||||
{
|
||||
if (!p || !upa)
|
||||
return isl_printer_free(p);
|
||||
|
||||
if (p->output_format == ISL_FORMAT_ISL)
|
||||
return print_union_pw_aff_isl(p, upa);
|
||||
isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
|
||||
"unsupported output format", return isl_printer_free(p));
|
||||
}
|
||||
|
||||
/* Print dimension "pos" of data->space to "p".
|
||||
*
|
||||
* data->user is assumed to be an isl_multi_aff.
|
||||
|
@ -2696,3 +2721,64 @@ __isl_give isl_printer *isl_printer_print_multi_val(
|
|||
isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
|
||||
return isl_printer_free(p));
|
||||
}
|
||||
|
||||
/* Print dimension "pos" of data->space to "p".
|
||||
*
|
||||
* data->user is assumed to be an isl_multi_union_pw_aff.
|
||||
*
|
||||
* The current dimension is necessarily a set dimension, so
|
||||
* we print the corresponding isl_union_pw_aff, including
|
||||
* the braces.
|
||||
*/
|
||||
static __isl_give isl_printer *print_union_pw_aff_dim(__isl_take isl_printer *p,
|
||||
struct isl_print_space_data *data, unsigned pos)
|
||||
{
|
||||
isl_multi_union_pw_aff *mupa = data->user;
|
||||
isl_union_pw_aff *upa;
|
||||
|
||||
upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, pos);
|
||||
p = print_union_pw_aff_body(p, upa);
|
||||
isl_union_pw_aff_free(upa);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Print the isl_multi_union_pw_aff "mupa" to "p" in isl format.
|
||||
*/
|
||||
static __isl_give isl_printer *print_multi_union_pw_aff_isl(
|
||||
__isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa)
|
||||
{
|
||||
struct isl_print_space_data data = { 0 };
|
||||
isl_space *space;
|
||||
|
||||
space = isl_multi_union_pw_aff_get_space(mupa);
|
||||
if (isl_space_dim(space, isl_dim_param) > 0) {
|
||||
struct isl_print_space_data space_data = { 0 };
|
||||
p = print_tuple(space, p, isl_dim_param, &space_data);
|
||||
p = isl_printer_print_str(p, s_to[0]);
|
||||
}
|
||||
|
||||
data.print_dim = &print_union_pw_aff_dim;
|
||||
data.user = mupa;
|
||||
|
||||
p = print_space(space, p, 0, &data);
|
||||
isl_space_free(space);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Print the isl_multi_union_pw_aff "mupa" to "p" in isl format.
|
||||
*
|
||||
* We currently only support an isl format.
|
||||
*/
|
||||
__isl_give isl_printer *isl_printer_print_multi_union_pw_aff(
|
||||
__isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa)
|
||||
{
|
||||
if (!p || !mupa)
|
||||
return isl_printer_free(p);
|
||||
|
||||
if (p->output_format == ISL_FORMAT_ISL)
|
||||
return print_multi_union_pw_aff_isl(p, mupa);
|
||||
isl_die(isl_printer_get_ctx(p), isl_error_unsupported,
|
||||
"unsupported output format", return isl_printer_free(p));
|
||||
}
|
||||
|
|
|
@ -2808,7 +2808,6 @@ __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_from_qpolynomial(
|
|||
#define PART isl_pw_qpolynomial
|
||||
#undef PARTS
|
||||
#define PARTS pw_qpolynomial
|
||||
#define ALIGN_DOMAIN
|
||||
|
||||
#include <isl_union_templ.c>
|
||||
|
||||
|
@ -4060,37 +4059,12 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int neg_entry(void **entry, void *user)
|
||||
{
|
||||
isl_pw_qpolynomial **pwqp = (isl_pw_qpolynomial **)entry;
|
||||
|
||||
*pwqp = isl_pw_qpolynomial_neg(*pwqp);
|
||||
|
||||
return *pwqp ? 0 : -1;
|
||||
}
|
||||
|
||||
__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_neg(
|
||||
__isl_take isl_union_pw_qpolynomial *upwqp)
|
||||
{
|
||||
upwqp = isl_union_pw_qpolynomial_cow(upwqp);
|
||||
if (!upwqp)
|
||||
return NULL;
|
||||
|
||||
if (isl_hash_table_foreach(upwqp->space->ctx, &upwqp->table,
|
||||
&neg_entry, NULL) < 0)
|
||||
goto error;
|
||||
|
||||
return upwqp;
|
||||
error:
|
||||
isl_union_pw_qpolynomial_free(upwqp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_mul(
|
||||
__isl_take isl_union_pw_qpolynomial *upwqp1,
|
||||
__isl_take isl_union_pw_qpolynomial *upwqp2)
|
||||
{
|
||||
return match_bin_op(upwqp1, upwqp2, &isl_pw_qpolynomial_mul);
|
||||
return isl_union_pw_qpolynomial_match_bin_op(upwqp1, upwqp2,
|
||||
&isl_pw_qpolynomial_mul);
|
||||
}
|
||||
|
||||
/* Reorder the columns of the given div definitions according to the
|
||||
|
|
|
@ -118,6 +118,7 @@ static __isl_give isl_printer *str_end_line(__isl_take isl_printer *p)
|
|||
static __isl_give isl_printer *str_flush(__isl_take isl_printer *p)
|
||||
{
|
||||
p->buf_n = 0;
|
||||
p->buf[p->buf_n] = '\0';
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -212,7 +213,7 @@ static struct isl_printer_ops str_ops = {
|
|||
|
||||
__isl_give isl_printer *isl_printer_to_file(isl_ctx *ctx, FILE *file)
|
||||
{
|
||||
struct isl_printer *p = isl_alloc_type(ctx, struct isl_printer);
|
||||
struct isl_printer *p = isl_calloc_type(ctx, struct isl_printer);
|
||||
if (!p)
|
||||
return NULL;
|
||||
p->ctx = ctx;
|
||||
|
@ -228,6 +229,7 @@ __isl_give isl_printer *isl_printer_to_file(isl_ctx *ctx, FILE *file)
|
|||
p->prefix = NULL;
|
||||
p->suffix = NULL;
|
||||
p->width = 0;
|
||||
p->yaml_style = ISL_YAML_STYLE_FLOW;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
@ -253,6 +255,7 @@ __isl_give isl_printer *isl_printer_to_str(isl_ctx *ctx)
|
|||
p->prefix = NULL;
|
||||
p->suffix = NULL;
|
||||
p->width = 0;
|
||||
p->yaml_style = ISL_YAML_STYLE_FLOW;
|
||||
|
||||
return p;
|
||||
error:
|
||||
|
@ -268,6 +271,7 @@ __isl_null isl_printer *isl_printer_free(__isl_take isl_printer *p)
|
|||
free(p->indent_prefix);
|
||||
free(p->prefix);
|
||||
free(p->suffix);
|
||||
free(p->yaml_state);
|
||||
isl_ctx_deref(p->ctx);
|
||||
free(p);
|
||||
|
||||
|
@ -380,6 +384,161 @@ int isl_printer_get_output_format(__isl_keep isl_printer *p)
|
|||
return p->output_format;
|
||||
}
|
||||
|
||||
/* Set the YAML style of "p" to "yaml_style" and return the updated printer.
|
||||
*/
|
||||
__isl_give isl_printer *isl_printer_set_yaml_style(__isl_take isl_printer *p,
|
||||
int yaml_style)
|
||||
{
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
p->yaml_style = yaml_style;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Return the YAML style of "p" or -1 on error.
|
||||
*/
|
||||
int isl_printer_get_yaml_style(__isl_keep isl_printer *p)
|
||||
{
|
||||
if (!p)
|
||||
return -1;
|
||||
return p->yaml_style;
|
||||
}
|
||||
|
||||
/* Push "state" onto the stack of currently active YAML elements and
|
||||
* return the updated printer.
|
||||
*/
|
||||
static __isl_give isl_printer *push_state(__isl_take isl_printer *p,
|
||||
enum isl_yaml_state state)
|
||||
{
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
if (p->yaml_size < p->yaml_depth + 1) {
|
||||
enum isl_yaml_state *state;
|
||||
state = isl_realloc_array(p->ctx, p->yaml_state,
|
||||
enum isl_yaml_state, p->yaml_depth + 1);
|
||||
if (!state)
|
||||
return isl_printer_free(p);
|
||||
p->yaml_state = state;
|
||||
p->yaml_size = p->yaml_depth + 1;
|
||||
}
|
||||
|
||||
p->yaml_state[p->yaml_depth] = state;
|
||||
p->yaml_depth++;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Remove the innermost active YAML element from the stack and
|
||||
* return the updated printer.
|
||||
*/
|
||||
static __isl_give isl_printer *pop_state(__isl_take isl_printer *p)
|
||||
{
|
||||
if (!p)
|
||||
return NULL;
|
||||
p->yaml_depth--;
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Set the state of the innermost active YAML element to "state" and
|
||||
* return the updated printer.
|
||||
*/
|
||||
static __isl_give isl_printer *update_state(__isl_take isl_printer *p,
|
||||
enum isl_yaml_state state)
|
||||
{
|
||||
if (!p)
|
||||
return NULL;
|
||||
if (p->yaml_depth < 1)
|
||||
isl_die(isl_printer_get_ctx(p), isl_error_invalid,
|
||||
"not in YAML construct", return isl_printer_free(p));
|
||||
|
||||
p->yaml_state[p->yaml_depth - 1] = state;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Return the state of the innermost active YAML element.
|
||||
* Return isl_yaml_none if we are not inside any YAML element.
|
||||
*/
|
||||
static enum isl_yaml_state current_state(__isl_keep isl_printer *p)
|
||||
{
|
||||
if (!p)
|
||||
return isl_yaml_none;
|
||||
if (p->yaml_depth < 1)
|
||||
return isl_yaml_none;
|
||||
return p->yaml_state[p->yaml_depth - 1];
|
||||
}
|
||||
|
||||
/* If we are printing a YAML document and we are at the start of an element,
|
||||
* print whatever is needed before we can print the actual element and
|
||||
* keep track of the fact that we are now printing the element.
|
||||
* If "eol" is set, then whatever we print is going to be the last
|
||||
* thing that gets printed on this line.
|
||||
*
|
||||
* If we are about the print the first key of a mapping, then nothing
|
||||
* extra needs to be printed. For any other key, however, we need
|
||||
* to either move to the next line (in block format) or print a comma
|
||||
* (in flow format).
|
||||
* Before printing a value in a mapping, we need to print a colon.
|
||||
*
|
||||
* For sequences, in flow format, we only need to print a comma
|
||||
* for each element except the first.
|
||||
* In block format, before the first element in the sequence,
|
||||
* we move to a new line, print a dash and increase the indentation.
|
||||
* Before any other element, we print a dash on a new line,
|
||||
* temporarily moving the indentation back.
|
||||
*/
|
||||
static __isl_give isl_printer *enter_state(__isl_take isl_printer *p,
|
||||
int eol)
|
||||
{
|
||||
enum isl_yaml_state state;
|
||||
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
state = current_state(p);
|
||||
if (state == isl_yaml_mapping_val_start) {
|
||||
if (eol)
|
||||
p = p->ops->print_str(p, ":");
|
||||
else
|
||||
p = p->ops->print_str(p, ": ");
|
||||
p = update_state(p, isl_yaml_mapping_val);
|
||||
} else if (state == isl_yaml_mapping_first_key_start) {
|
||||
p = update_state(p, isl_yaml_mapping_key);
|
||||
} else if (state == isl_yaml_mapping_key_start) {
|
||||
if (p->yaml_style == ISL_YAML_STYLE_FLOW)
|
||||
p = p->ops->print_str(p, ", ");
|
||||
else {
|
||||
p = p->ops->end_line(p);
|
||||
p = p->ops->start_line(p);
|
||||
}
|
||||
p = update_state(p, isl_yaml_mapping_key);
|
||||
} else if (state == isl_yaml_sequence_first_start) {
|
||||
if (p->yaml_style != ISL_YAML_STYLE_FLOW) {
|
||||
p = p->ops->end_line(p);
|
||||
p = p->ops->start_line(p);
|
||||
p = p->ops->print_str(p, "- ");
|
||||
p = isl_printer_indent(p, 2);
|
||||
}
|
||||
p = update_state(p, isl_yaml_sequence);
|
||||
} else if (state == isl_yaml_sequence_start) {
|
||||
if (p->yaml_style == ISL_YAML_STYLE_FLOW)
|
||||
p = p->ops->print_str(p, ", ");
|
||||
else {
|
||||
p = p->ops->end_line(p);
|
||||
p = isl_printer_indent(p, -2);
|
||||
p = p->ops->start_line(p);
|
||||
p = p->ops->print_str(p, "- ");
|
||||
p = isl_printer_indent(p, 2);
|
||||
}
|
||||
p = update_state(p, isl_yaml_sequence);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
__isl_give isl_printer *isl_printer_print_str(__isl_take isl_printer *p,
|
||||
const char *s)
|
||||
{
|
||||
|
@ -387,13 +546,16 @@ __isl_give isl_printer *isl_printer_print_str(__isl_take isl_printer *p,
|
|||
return NULL;
|
||||
if (!s)
|
||||
return isl_printer_free(p);
|
||||
|
||||
p = enter_state(p, 0);
|
||||
if (!p)
|
||||
return NULL;
|
||||
return p->ops->print_str(p, s);
|
||||
}
|
||||
|
||||
__isl_give isl_printer *isl_printer_print_double(__isl_take isl_printer *p,
|
||||
double d)
|
||||
{
|
||||
p = enter_state(p, 0);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
|
@ -402,6 +564,7 @@ __isl_give isl_printer *isl_printer_print_double(__isl_take isl_printer *p,
|
|||
|
||||
__isl_give isl_printer *isl_printer_print_int(__isl_take isl_printer *p, int i)
|
||||
{
|
||||
p = enter_state(p, 0);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
|
@ -411,6 +574,7 @@ __isl_give isl_printer *isl_printer_print_int(__isl_take isl_printer *p, int i)
|
|||
__isl_give isl_printer *isl_printer_print_isl_int(__isl_take isl_printer *p,
|
||||
isl_int i)
|
||||
{
|
||||
p = enter_state(p, 0);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
|
@ -447,3 +611,154 @@ __isl_give isl_printer *isl_printer_flush(__isl_take isl_printer *p)
|
|||
|
||||
return p->ops->flush(p);
|
||||
}
|
||||
|
||||
/* Start a YAML mapping and push a new state to reflect that we
|
||||
* are about to print the first key in a mapping.
|
||||
*
|
||||
* In flow style, print the opening brace.
|
||||
* In block style, move to the next line with an increased indentation,
|
||||
* except if this is the outer mapping or if we are inside a sequence
|
||||
* (in which case we have already increased the indentation and we want
|
||||
* to print the first key on the same line as the dash).
|
||||
*/
|
||||
__isl_give isl_printer *isl_printer_yaml_start_mapping(
|
||||
__isl_take isl_printer *p)
|
||||
{
|
||||
enum isl_yaml_state state;
|
||||
|
||||
p = enter_state(p, p->yaml_style == ISL_YAML_STYLE_BLOCK);
|
||||
if (!p)
|
||||
return NULL;
|
||||
state = current_state(p);
|
||||
if (p->yaml_style == ISL_YAML_STYLE_FLOW)
|
||||
p = p->ops->print_str(p, "{ ");
|
||||
else if (state != isl_yaml_none && state != isl_yaml_sequence) {
|
||||
p = p->ops->end_line(p);
|
||||
p = isl_printer_indent(p, 2);
|
||||
p = p->ops->start_line(p);
|
||||
}
|
||||
p = push_state(p, isl_yaml_mapping_first_key_start);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Finish a YAML mapping and pop it from the state stack.
|
||||
*
|
||||
* In flow style, print the closing brace.
|
||||
*
|
||||
* In block style, first check if we are still in the
|
||||
* isl_yaml_mapping_first_key_start state. If so, we have not printed
|
||||
* anything yet, so print "{}" to indicate an empty mapping.
|
||||
* If we increased the indentation in isl_printer_yaml_start_mapping,
|
||||
* then decrease it again.
|
||||
* If this is the outer mapping then print a newline.
|
||||
*/
|
||||
__isl_give isl_printer *isl_printer_yaml_end_mapping(
|
||||
__isl_take isl_printer *p)
|
||||
{
|
||||
enum isl_yaml_state state;
|
||||
|
||||
state = current_state(p);
|
||||
p = pop_state(p);
|
||||
if (!p)
|
||||
return NULL;
|
||||
if (p->yaml_style == ISL_YAML_STYLE_FLOW)
|
||||
return p->ops->print_str(p, " }");
|
||||
if (state == isl_yaml_mapping_first_key_start)
|
||||
p = p->ops->print_str(p, "{}");
|
||||
if (!p)
|
||||
return NULL;
|
||||
state = current_state(p);
|
||||
if (state != isl_yaml_none && state != isl_yaml_sequence)
|
||||
p = isl_printer_indent(p, -2);
|
||||
if (state == isl_yaml_none)
|
||||
p = p->ops->end_line(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Start a YAML sequence and push a new state to reflect that we
|
||||
* are about to print the first element in a sequence.
|
||||
*
|
||||
* In flow style, print the opening bracket.
|
||||
*/
|
||||
__isl_give isl_printer *isl_printer_yaml_start_sequence(
|
||||
__isl_take isl_printer *p)
|
||||
{
|
||||
p = enter_state(p, p->yaml_style == ISL_YAML_STYLE_BLOCK);
|
||||
p = push_state(p, isl_yaml_sequence_first_start);
|
||||
if (!p)
|
||||
return NULL;
|
||||
if (p->yaml_style == ISL_YAML_STYLE_FLOW)
|
||||
p = p->ops->print_str(p, "[ ");
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Finish a YAML sequence and pop it from the state stack.
|
||||
*
|
||||
* In flow style, print the closing bracket.
|
||||
*
|
||||
* In block style, check if we are still in the
|
||||
* isl_yaml_sequence_first_start state. If so, we have not printed
|
||||
* anything yet, so print "[]" or " []" to indicate an empty sequence.
|
||||
* We print the extra space when we instructed enter_state not
|
||||
* to print a space at the end of the line.
|
||||
* Otherwise, undo the increase in indentation performed by
|
||||
* enter_state when moving away from the isl_yaml_sequence_first_start
|
||||
* state.
|
||||
* If this is the outer sequence then print a newline.
|
||||
*/
|
||||
__isl_give isl_printer *isl_printer_yaml_end_sequence(
|
||||
__isl_take isl_printer *p)
|
||||
{
|
||||
enum isl_yaml_state state, up;
|
||||
|
||||
state = current_state(p);
|
||||
p = pop_state(p);
|
||||
if (!p)
|
||||
return NULL;
|
||||
if (p->yaml_style == ISL_YAML_STYLE_FLOW)
|
||||
return p->ops->print_str(p, " ]");
|
||||
up = current_state(p);
|
||||
if (state == isl_yaml_sequence_first_start) {
|
||||
if (up == isl_yaml_mapping_val)
|
||||
p = p->ops->print_str(p, " []");
|
||||
else
|
||||
p = p->ops->print_str(p, "[]");
|
||||
} else {
|
||||
p = isl_printer_indent(p, -2);
|
||||
}
|
||||
if (!p)
|
||||
return NULL;
|
||||
state = current_state(p);
|
||||
if (state == isl_yaml_none)
|
||||
p = p->ops->end_line(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Mark the fact that the current element is finished and that
|
||||
* the next output belongs to the next element.
|
||||
* In particular, if we are printing a key, then prepare for
|
||||
* printing the subsequent value. If we are printing a value,
|
||||
* prepare for printing the next key. If we are printing an
|
||||
* element in a sequence, prepare for printing the next element.
|
||||
*/
|
||||
__isl_give isl_printer *isl_printer_yaml_next(__isl_take isl_printer *p)
|
||||
{
|
||||
enum isl_yaml_state state;
|
||||
|
||||
if (!p)
|
||||
return NULL;
|
||||
if (p->yaml_depth < 1)
|
||||
isl_die(isl_printer_get_ctx(p), isl_error_invalid,
|
||||
"not in YAML construct", return isl_printer_free(p));
|
||||
|
||||
state = current_state(p);
|
||||
if (state == isl_yaml_mapping_key)
|
||||
state = isl_yaml_mapping_val_start;
|
||||
else if (state == isl_yaml_mapping_val)
|
||||
state = isl_yaml_mapping_key_start;
|
||||
else if (state == isl_yaml_sequence)
|
||||
state = isl_yaml_sequence_start;
|
||||
p = update_state(p, state);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,18 @@
|
|||
#include <isl/printer.h>
|
||||
#include <isl_yaml.h>
|
||||
|
||||
struct isl_printer_ops;
|
||||
|
||||
/* A printer to a file or a string.
|
||||
*
|
||||
* yaml_style is the YAML style in which the next elements should
|
||||
* be printed and may be either ISL_YAML_STYLE_BLOCK or ISL_YAML_STYLE_FLOW,
|
||||
* with ISL_YAML_STYLE_FLOW being the default.
|
||||
* yaml_state keeps track of the currently active YAML elements.
|
||||
* yaml_size is the size of this arrays, while yaml_depth
|
||||
* is the number of elements currently in use.
|
||||
* yaml_state may be NULL if no YAML printing is being performed.
|
||||
*/
|
||||
struct isl_printer {
|
||||
struct isl_ctx *ctx;
|
||||
struct isl_printer_ops *ops;
|
||||
|
@ -15,4 +26,9 @@ struct isl_printer {
|
|||
char *prefix;
|
||||
char *suffix;
|
||||
int width;
|
||||
|
||||
int yaml_style;
|
||||
int yaml_depth;
|
||||
int yaml_size;
|
||||
enum isl_yaml_state *yaml_state;
|
||||
};
|
||||
|
|
|
@ -644,7 +644,9 @@ __isl_give PW *FN(PW,neg)(__isl_take PW *pw)
|
|||
|
||||
return pw;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NO_SUB
|
||||
__isl_give PW *FN(PW,sub)(__isl_take PW *pw1, __isl_take PW *pw2)
|
||||
{
|
||||
return FN(PW,add)(pw1, FN(PW,neg)(pw2));
|
||||
|
@ -802,9 +804,9 @@ __isl_give PW *FN(PW,fix_si)(__isl_take PW *pw, enum isl_dim_type type,
|
|||
|
||||
/* Restrict the domain of "pw" by combining each cell
|
||||
* with "set" through a call to "fn", where "fn" may be
|
||||
* isl_set_intersect or isl_set_intersect_params.
|
||||
* isl_set_intersect, isl_set_intersect_params or isl_set_subtract.
|
||||
*/
|
||||
static __isl_give PW *FN(PW,intersect_aligned)(__isl_take PW *pw,
|
||||
static __isl_give PW *FN(PW,restrict_domain_aligned)(__isl_take PW *pw,
|
||||
__isl_take isl_set *set,
|
||||
__isl_give isl_set *(*fn)(__isl_take isl_set *set1,
|
||||
__isl_take isl_set *set2))
|
||||
|
@ -840,7 +842,7 @@ error:
|
|||
static __isl_give PW *FN(PW,intersect_domain_aligned)(__isl_take PW *pw,
|
||||
__isl_take isl_set *set)
|
||||
{
|
||||
return FN(PW,intersect_aligned)(pw, set, &isl_set_intersect);
|
||||
return FN(PW,restrict_domain_aligned)(pw, set, &isl_set_intersect);
|
||||
}
|
||||
|
||||
__isl_give PW *FN(PW,intersect_domain)(__isl_take PW *pw,
|
||||
|
@ -853,7 +855,8 @@ __isl_give PW *FN(PW,intersect_domain)(__isl_take PW *pw,
|
|||
static __isl_give PW *FN(PW,intersect_params_aligned)(__isl_take PW *pw,
|
||||
__isl_take isl_set *set)
|
||||
{
|
||||
return FN(PW,intersect_aligned)(pw, set, &isl_set_intersect_params);
|
||||
return FN(PW,restrict_domain_aligned)(pw, set,
|
||||
&isl_set_intersect_params);
|
||||
}
|
||||
|
||||
/* Intersect the domain of "pw" with the parameter domain "context".
|
||||
|
@ -865,6 +868,24 @@ __isl_give PW *FN(PW,intersect_params)(__isl_take PW *pw,
|
|||
&FN(PW,intersect_params_aligned));
|
||||
}
|
||||
|
||||
/* Subtract "domain' from the domain of "pw", assuming their
|
||||
* parameters have been aligned.
|
||||
*/
|
||||
static __isl_give PW *FN(PW,subtract_domain_aligned)(__isl_take PW *pw,
|
||||
__isl_take isl_set *domain)
|
||||
{
|
||||
return FN(PW,restrict_domain_aligned)(pw, domain, &isl_set_subtract);
|
||||
}
|
||||
|
||||
/* Subtract "domain' from the domain of "pw".
|
||||
*/
|
||||
__isl_give PW *FN(PW,subtract_domain)(__isl_take PW *pw,
|
||||
__isl_take isl_set *domain)
|
||||
{
|
||||
return FN(PW,align_params_pw_set_and)(pw, domain,
|
||||
&FN(PW,subtract_domain_aligned));
|
||||
}
|
||||
|
||||
/* Compute the gist of "pw" with respect to the domain constraints
|
||||
* of "context" for the case where the domain of the last element
|
||||
* of "pw" is equal to "context".
|
||||
|
@ -1514,6 +1535,19 @@ error:
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Reset the user pointer on all identifiers of parameters and tuples
|
||||
* of the space of "pw".
|
||||
*/
|
||||
__isl_give PW *FN(PW,reset_user)(__isl_take PW *pw)
|
||||
{
|
||||
isl_space *space;
|
||||
|
||||
space = FN(PW,get_space)(pw);
|
||||
space = isl_space_reset_user(space);
|
||||
|
||||
return FN(PW,reset_space)(pw, space);
|
||||
}
|
||||
|
||||
int FN(PW,has_equal_space)(__isl_keep PW *pw1, __isl_keep PW *pw2)
|
||||
{
|
||||
if (!pw1 || !pw2)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,417 @@
|
|||
/*
|
||||
* Copyright 2013-2014 Ecole Normale Superieure
|
||||
*
|
||||
* Use of this software is governed by the MIT license
|
||||
*
|
||||
* Written by Sven Verdoolaege,
|
||||
* Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
|
||||
*/
|
||||
|
||||
#include <isl/schedule_node.h>
|
||||
#include <isl_schedule_band.h>
|
||||
#include <isl_schedule_private.h>
|
||||
|
||||
isl_ctx *isl_schedule_band_get_ctx(__isl_keep isl_schedule_band *band)
|
||||
{
|
||||
return band ? isl_multi_union_pw_aff_get_ctx(band->mupa) : NULL;
|
||||
}
|
||||
|
||||
/* Return a new uninitialized isl_schedule_band.
|
||||
*/
|
||||
static __isl_give isl_schedule_band *isl_schedule_band_alloc(isl_ctx *ctx)
|
||||
{
|
||||
isl_schedule_band *band;
|
||||
|
||||
band = isl_calloc_type(ctx, isl_schedule_band);
|
||||
if (!band)
|
||||
return NULL;
|
||||
|
||||
band->ref = 1;
|
||||
|
||||
return band;
|
||||
}
|
||||
|
||||
/* Return a new isl_schedule_band with partial schedule "mupa".
|
||||
* First replace "mupa" by its greatest integer part to ensure
|
||||
* that the schedule is always integral.
|
||||
* The band is not marked permutable and the dimensions are not
|
||||
* marked coincident.
|
||||
*/
|
||||
__isl_give isl_schedule_band *isl_schedule_band_from_multi_union_pw_aff(
|
||||
__isl_take isl_multi_union_pw_aff *mupa)
|
||||
{
|
||||
isl_ctx *ctx;
|
||||
isl_schedule_band *band;
|
||||
|
||||
mupa = isl_multi_union_pw_aff_floor(mupa);
|
||||
if (!mupa)
|
||||
return NULL;
|
||||
ctx = isl_multi_union_pw_aff_get_ctx(mupa);
|
||||
band = isl_schedule_band_alloc(ctx);
|
||||
if (!band)
|
||||
goto error;
|
||||
|
||||
band->n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
|
||||
band->coincident = isl_calloc_array(ctx, int, band->n);
|
||||
band->mupa = mupa;
|
||||
|
||||
if (band->n && !band->coincident)
|
||||
return isl_schedule_band_free(band);
|
||||
|
||||
return band;
|
||||
error:
|
||||
isl_multi_union_pw_aff_free(mupa);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create a duplicate of the given isl_schedule_band.
|
||||
*/
|
||||
__isl_give isl_schedule_band *isl_schedule_band_dup(
|
||||
__isl_keep isl_schedule_band *band)
|
||||
{
|
||||
int i;
|
||||
isl_ctx *ctx;
|
||||
isl_schedule_band *dup;
|
||||
|
||||
if (!band)
|
||||
return NULL;
|
||||
|
||||
ctx = isl_schedule_band_get_ctx(band);
|
||||
dup = isl_schedule_band_alloc(ctx);
|
||||
if (!dup)
|
||||
return NULL;
|
||||
|
||||
dup->n = band->n;
|
||||
dup->coincident = isl_alloc_array(ctx, int, band->n);
|
||||
if (band->n && !dup->coincident)
|
||||
return isl_schedule_band_free(dup);
|
||||
|
||||
for (i = 0; i < band->n; ++i)
|
||||
dup->coincident[i] = band->coincident[i];
|
||||
dup->permutable = band->permutable;
|
||||
|
||||
dup->mupa = isl_multi_union_pw_aff_copy(band->mupa);
|
||||
if (!dup->mupa)
|
||||
return isl_schedule_band_free(dup);
|
||||
|
||||
return dup;
|
||||
}
|
||||
|
||||
/* Return an isl_schedule_band that is equal to "band" and that has only
|
||||
* a single reference.
|
||||
*/
|
||||
__isl_give isl_schedule_band *isl_schedule_band_cow(
|
||||
__isl_take isl_schedule_band *band)
|
||||
{
|
||||
if (!band)
|
||||
return NULL;
|
||||
|
||||
if (band->ref == 1)
|
||||
return band;
|
||||
band->ref--;
|
||||
return isl_schedule_band_dup(band);
|
||||
}
|
||||
|
||||
/* Return a new reference to "band".
|
||||
*/
|
||||
__isl_give isl_schedule_band *isl_schedule_band_copy(
|
||||
__isl_keep isl_schedule_band *band)
|
||||
{
|
||||
if (!band)
|
||||
return NULL;
|
||||
|
||||
band->ref++;
|
||||
return band;
|
||||
}
|
||||
|
||||
/* Free a reference to "band" and return NULL.
|
||||
*/
|
||||
__isl_null isl_schedule_band *isl_schedule_band_free(
|
||||
__isl_take isl_schedule_band *band)
|
||||
{
|
||||
if (!band)
|
||||
return NULL;
|
||||
|
||||
if (--band->ref > 0)
|
||||
return NULL;
|
||||
|
||||
isl_multi_union_pw_aff_free(band->mupa);
|
||||
free(band->coincident);
|
||||
free(band);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return the number of scheduling dimensions in the band.
|
||||
*/
|
||||
int isl_schedule_band_n_member(__isl_keep isl_schedule_band *band)
|
||||
{
|
||||
return band ? band->n : 0;
|
||||
}
|
||||
|
||||
/* Is the given scheduling dimension coincident within the band and
|
||||
* with respect to the coincidence constraints?
|
||||
*/
|
||||
int isl_schedule_band_member_get_coincident(__isl_keep isl_schedule_band *band,
|
||||
int pos)
|
||||
{
|
||||
if (!band)
|
||||
return -1;
|
||||
|
||||
if (pos < 0 || pos >= band->n)
|
||||
isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid,
|
||||
"invalid member position", return -1);
|
||||
|
||||
return band->coincident[pos];
|
||||
}
|
||||
|
||||
/* Mark the given scheduling dimension as being coincident or not
|
||||
* according to "coincident".
|
||||
*/
|
||||
__isl_give isl_schedule_band *isl_schedule_band_member_set_coincident(
|
||||
__isl_take isl_schedule_band *band, int pos, int coincident)
|
||||
{
|
||||
if (!band)
|
||||
return NULL;
|
||||
if (isl_schedule_band_member_get_coincident(band, pos) == coincident)
|
||||
return band;
|
||||
band = isl_schedule_band_cow(band);
|
||||
if (!band)
|
||||
return NULL;
|
||||
|
||||
if (pos < 0 || pos >= band->n)
|
||||
isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid,
|
||||
"invalid member position",
|
||||
isl_schedule_band_free(band));
|
||||
|
||||
band->coincident[pos] = coincident;
|
||||
|
||||
return band;
|
||||
}
|
||||
|
||||
/* Is the schedule band mark permutable?
|
||||
*/
|
||||
int isl_schedule_band_get_permutable(__isl_keep isl_schedule_band *band)
|
||||
{
|
||||
if (!band)
|
||||
return -1;
|
||||
return band->permutable;
|
||||
}
|
||||
|
||||
/* Mark the schedule band permutable or not according to "permutable"?
|
||||
*/
|
||||
__isl_give isl_schedule_band *isl_schedule_band_set_permutable(
|
||||
__isl_take isl_schedule_band *band, int permutable)
|
||||
{
|
||||
if (!band)
|
||||
return NULL;
|
||||
if (band->permutable == permutable)
|
||||
return band;
|
||||
band = isl_schedule_band_cow(band);
|
||||
if (!band)
|
||||
return NULL;
|
||||
|
||||
band->permutable = permutable;
|
||||
|
||||
return band;
|
||||
}
|
||||
|
||||
/* Return the schedule space of the band.
|
||||
*/
|
||||
__isl_give isl_space *isl_schedule_band_get_space(
|
||||
__isl_keep isl_schedule_band *band)
|
||||
{
|
||||
if (!band)
|
||||
return NULL;
|
||||
return isl_multi_union_pw_aff_get_space(band->mupa);
|
||||
}
|
||||
|
||||
/* Return the schedule of the band in isolation.
|
||||
*/
|
||||
__isl_give isl_multi_union_pw_aff *isl_schedule_band_get_partial_schedule(
|
||||
__isl_keep isl_schedule_band *band)
|
||||
{
|
||||
return band ? isl_multi_union_pw_aff_copy(band->mupa) : NULL;
|
||||
}
|
||||
|
||||
/* Multiply the partial schedule of "band" with the factors in "mv".
|
||||
* Replace the result by its greatest integer part to ensure
|
||||
* that the schedule is always integral.
|
||||
*/
|
||||
__isl_give isl_schedule_band *isl_schedule_band_scale(
|
||||
__isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv)
|
||||
{
|
||||
band = isl_schedule_band_cow(band);
|
||||
if (!band || !mv)
|
||||
goto error;
|
||||
band->mupa = isl_multi_union_pw_aff_scale_multi_val(band->mupa, mv);
|
||||
band->mupa = isl_multi_union_pw_aff_floor(band->mupa);
|
||||
if (!band->mupa)
|
||||
return isl_schedule_band_free(band);
|
||||
return band;
|
||||
error:
|
||||
isl_schedule_band_free(band);
|
||||
isl_multi_val_free(mv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Divide the partial schedule of "band" by the factors in "mv".
|
||||
* Replace the result by its greatest integer part to ensure
|
||||
* that the schedule is always integral.
|
||||
*/
|
||||
__isl_give isl_schedule_band *isl_schedule_band_scale_down(
|
||||
__isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv)
|
||||
{
|
||||
band = isl_schedule_band_cow(band);
|
||||
if (!band || !mv)
|
||||
goto error;
|
||||
band->mupa = isl_multi_union_pw_aff_scale_down_multi_val(band->mupa,
|
||||
mv);
|
||||
band->mupa = isl_multi_union_pw_aff_floor(band->mupa);
|
||||
if (!band->mupa)
|
||||
return isl_schedule_band_free(band);
|
||||
return band;
|
||||
error:
|
||||
isl_schedule_band_free(band);
|
||||
isl_multi_val_free(mv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Given the schedule of a band, construct the corresponding
|
||||
* schedule for the tile loops based on the given tile sizes
|
||||
* and return the result.
|
||||
*
|
||||
* If the scale tile loops options is set, then the tile loops
|
||||
* are scaled by the tile sizes.
|
||||
*
|
||||
* That is replace each schedule dimension "i" by either
|
||||
* "floor(i/s)" or "s * floor(i/s)".
|
||||
*/
|
||||
static isl_multi_union_pw_aff *isl_multi_union_pw_aff_tile(
|
||||
__isl_take isl_multi_union_pw_aff *sched,
|
||||
__isl_take isl_multi_val *sizes)
|
||||
{
|
||||
isl_ctx *ctx;
|
||||
int i, n;
|
||||
isl_val *v;
|
||||
int scale;
|
||||
|
||||
ctx = isl_multi_val_get_ctx(sizes);
|
||||
scale = isl_options_get_tile_scale_tile_loops(ctx);
|
||||
|
||||
n = isl_multi_union_pw_aff_dim(sched, isl_dim_set);
|
||||
for (i = 0; i < n; ++i) {
|
||||
isl_union_pw_aff *upa;
|
||||
|
||||
upa = isl_multi_union_pw_aff_get_union_pw_aff(sched, i);
|
||||
v = isl_multi_val_get_val(sizes, i);
|
||||
|
||||
upa = isl_union_pw_aff_scale_down_val(upa, isl_val_copy(v));
|
||||
upa = isl_union_pw_aff_floor(upa);
|
||||
if (scale)
|
||||
upa = isl_union_pw_aff_scale_val(upa, isl_val_copy(v));
|
||||
isl_val_free(v);
|
||||
|
||||
sched = isl_multi_union_pw_aff_set_union_pw_aff(sched, i, upa);
|
||||
}
|
||||
|
||||
isl_multi_val_free(sizes);
|
||||
return sched;
|
||||
}
|
||||
|
||||
/* Replace "band" by a band corresponding to the tile loops of a tiling
|
||||
* with the given tile sizes.
|
||||
*/
|
||||
__isl_give isl_schedule_band *isl_schedule_band_tile(
|
||||
__isl_take isl_schedule_band *band, __isl_take isl_multi_val *sizes)
|
||||
{
|
||||
band = isl_schedule_band_cow(band);
|
||||
if (!band || !sizes)
|
||||
goto error;
|
||||
band->mupa = isl_multi_union_pw_aff_tile(band->mupa, sizes);
|
||||
if (!band->mupa)
|
||||
return isl_schedule_band_free(band);
|
||||
return band;
|
||||
error:
|
||||
isl_schedule_band_free(band);
|
||||
isl_multi_val_free(sizes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Replace "band" by a band corresponding to the point loops of a tiling
|
||||
* with the given tile sizes.
|
||||
* "tile" is the corresponding tile loop band.
|
||||
*
|
||||
* If the shift point loops option is set, then the point loops
|
||||
* are shifted to start at zero. That is, each schedule dimension "i"
|
||||
* is replaced by "i - s * floor(i/s)".
|
||||
* The expression "floor(i/s)" (or "s * floor(i/s)") is extracted from
|
||||
* the tile band.
|
||||
*
|
||||
* Otherwise, the band is left untouched.
|
||||
*/
|
||||
__isl_give isl_schedule_band *isl_schedule_band_point(
|
||||
__isl_take isl_schedule_band *band, __isl_keep isl_schedule_band *tile,
|
||||
__isl_take isl_multi_val *sizes)
|
||||
{
|
||||
isl_ctx *ctx;
|
||||
isl_multi_union_pw_aff *scaled;
|
||||
|
||||
if (!band || !sizes)
|
||||
goto error;
|
||||
|
||||
ctx = isl_schedule_band_get_ctx(band);
|
||||
if (!isl_options_get_tile_shift_point_loops(ctx)) {
|
||||
isl_multi_val_free(sizes);
|
||||
return band;
|
||||
}
|
||||
band = isl_schedule_band_cow(band);
|
||||
if (!band)
|
||||
goto error;
|
||||
|
||||
scaled = isl_schedule_band_get_partial_schedule(tile);
|
||||
if (!isl_options_get_tile_scale_tile_loops(ctx))
|
||||
scaled = isl_multi_union_pw_aff_scale_multi_val(scaled, sizes);
|
||||
else
|
||||
isl_multi_val_free(sizes);
|
||||
band->mupa = isl_multi_union_pw_aff_sub(band->mupa, scaled);
|
||||
if (!band->mupa)
|
||||
return isl_schedule_band_free(band);
|
||||
return band;
|
||||
error:
|
||||
isl_schedule_band_free(band);
|
||||
isl_multi_val_free(sizes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Drop the "n" dimensions starting at "pos" from "band".
|
||||
*
|
||||
* We apply the transformation even if "n" is zero to ensure consistent
|
||||
* behavior with respect to changes in the schedule space.
|
||||
*/
|
||||
__isl_give isl_schedule_band *isl_schedule_band_drop(
|
||||
__isl_take isl_schedule_band *band, int pos, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (pos < 0 || n < 0 || pos + n > band->n)
|
||||
isl_die(isl_schedule_band_get_ctx(band), isl_error_internal,
|
||||
"range out of bounds",
|
||||
return isl_schedule_band_free(band));
|
||||
|
||||
band = isl_schedule_band_cow(band);
|
||||
if (!band)
|
||||
return NULL;
|
||||
|
||||
band->mupa = isl_multi_union_pw_aff_drop_dims(band->mupa,
|
||||
isl_dim_set, pos, n);
|
||||
if (!band->mupa)
|
||||
return isl_schedule_band_free(band);
|
||||
|
||||
for (i = pos + n; i < band->n; ++i)
|
||||
band->coincident[i - n] = band->coincident[i];
|
||||
|
||||
band->n -= n;
|
||||
|
||||
return band;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
#ifndef ISL_SCHEDULE_BAND_H
|
||||
#define ISL_SCHEDULE_BAND_H
|
||||
|
||||
#include <isl/aff.h>
|
||||
#include <isl/union_map.h>
|
||||
|
||||
/* Information about a band within a schedule.
|
||||
*
|
||||
* n is the number of scheduling dimensions within the band.
|
||||
* coincident is an array of length n, indicating whether a scheduling dimension
|
||||
* satisfies the coincidence constraints in the sense that
|
||||
* the corresponding dependence distances are zero.
|
||||
* permutable is set if the band is permutable.
|
||||
* mupa is the partial schedule corresponding to this band. The dimension
|
||||
* of mupa is equal to n.
|
||||
*/
|
||||
struct isl_schedule_band {
|
||||
int ref;
|
||||
|
||||
int n;
|
||||
int *coincident;
|
||||
int permutable;
|
||||
|
||||
isl_multi_union_pw_aff *mupa;
|
||||
};
|
||||
typedef struct isl_schedule_band isl_schedule_band;
|
||||
|
||||
__isl_give isl_schedule_band *isl_schedule_band_from_multi_union_pw_aff(
|
||||
__isl_take isl_multi_union_pw_aff *mupa);
|
||||
__isl_give isl_schedule_band *isl_schedule_band_copy(
|
||||
__isl_keep isl_schedule_band *band);
|
||||
__isl_null isl_schedule_band *isl_schedule_band_free(
|
||||
__isl_take isl_schedule_band *band);
|
||||
|
||||
isl_ctx *isl_schedule_band_get_ctx(__isl_keep isl_schedule_band *band);
|
||||
|
||||
__isl_give isl_space *isl_schedule_band_get_space(
|
||||
__isl_keep isl_schedule_band *band);
|
||||
__isl_give isl_multi_union_pw_aff *isl_schedule_band_get_partial_schedule(
|
||||
__isl_keep isl_schedule_band *band);
|
||||
|
||||
int isl_schedule_band_n_member(__isl_keep isl_schedule_band *band);
|
||||
int isl_schedule_band_member_get_coincident(
|
||||
__isl_keep isl_schedule_band *band, int pos);
|
||||
__isl_give isl_schedule_band *isl_schedule_band_member_set_coincident(
|
||||
__isl_take isl_schedule_band *band, int pos, int coincident);
|
||||
int isl_schedule_band_get_permutable(__isl_keep isl_schedule_band *band);
|
||||
__isl_give isl_schedule_band *isl_schedule_band_set_permutable(
|
||||
__isl_take isl_schedule_band *band, int permutable);
|
||||
|
||||
__isl_give isl_schedule_band *isl_schedule_band_scale(
|
||||
__isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv);
|
||||
__isl_give isl_schedule_band *isl_schedule_band_scale_down(
|
||||
__isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv);
|
||||
__isl_give isl_schedule_band *isl_schedule_band_tile(
|
||||
__isl_take isl_schedule_band *band, __isl_take isl_multi_val *sizes);
|
||||
__isl_give isl_schedule_band *isl_schedule_band_point(
|
||||
__isl_take isl_schedule_band *band, __isl_keep isl_schedule_band *tile,
|
||||
__isl_take isl_multi_val *sizes);
|
||||
__isl_give isl_schedule_band *isl_schedule_band_drop(
|
||||
__isl_take isl_schedule_band *band, int pos, int n);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,41 @@
|
|||
#ifndef ISL_SCHEDLUE_NODE_PRIVATE_H
|
||||
#define ISL_SCHEDLUE_NODE_PRIVATE_H
|
||||
|
||||
#include <isl/schedule_node.h>
|
||||
#include <isl_schedule_band.h>
|
||||
|
||||
/* An isl_schedule_node points to a particular location in a schedule tree.
|
||||
*
|
||||
* "schedule" is the schedule that the node is pointing to.
|
||||
* "ancestors" is a list of the n ancestors of the node
|
||||
* that is being pointed to.
|
||||
* The first ancestor is the root of "schedule", while the last ancestor
|
||||
* is the parent of the specified location.
|
||||
* "child_pos" is an array of child positions of the same length as "ancestors",
|
||||
* where ancestor i (i > 0) appears in child_pos[i - 1] of ancestor i - 1 and
|
||||
* "tree" appears in child_pos[n - 1] of ancestor n - 1.
|
||||
* "tree" is the subtree at the specified location.
|
||||
*
|
||||
* Note that the same isl_schedule_tree object may appear several times
|
||||
* in a schedule tree and therefore does not uniquely identify a position
|
||||
* in the schedule tree.
|
||||
*/
|
||||
struct isl_schedule_node {
|
||||
int ref;
|
||||
|
||||
isl_schedule *schedule;
|
||||
isl_schedule_tree_list *ancestors;
|
||||
int *child_pos;
|
||||
isl_schedule_tree *tree;
|
||||
};
|
||||
|
||||
__isl_give isl_schedule_node *isl_schedule_node_alloc(
|
||||
__isl_take isl_schedule *schedule, __isl_take isl_schedule_tree *tree,
|
||||
__isl_take isl_schedule_tree_list *ancestors, int *child_pos);
|
||||
__isl_give isl_schedule_node *isl_schedule_node_graft_tree(
|
||||
__isl_take isl_schedule_node *pos, __isl_take isl_schedule_tree *tree);
|
||||
|
||||
__isl_give isl_schedule_tree *isl_schedule_node_get_tree(
|
||||
__isl_keep isl_schedule_node *node);
|
||||
|
||||
#endif
|
|
@ -3,42 +3,39 @@
|
|||
|
||||
#include <isl/aff.h>
|
||||
#include <isl/schedule.h>
|
||||
#include <isl_schedule_tree.h>
|
||||
|
||||
/* The schedule for an individual domain, plus information about the bands
|
||||
* and scheduling dimensions.
|
||||
* In particular, we keep track of the number of bands and for each
|
||||
* band, the starting position of the next band. The first band starts at
|
||||
* position 0.
|
||||
* For each scheduling dimension, we keep track of whether it satisfies
|
||||
* the coincidence constraints (within its band).
|
||||
*/
|
||||
struct isl_schedule_node {
|
||||
isl_multi_aff *sched;
|
||||
int n_band;
|
||||
int *band_end;
|
||||
int *band_id;
|
||||
int *coincident;
|
||||
};
|
||||
|
||||
/* Information about the computed schedule.
|
||||
* n is the number of nodes/domains/statements.
|
||||
* n_band is the maximal number of bands.
|
||||
* n_total_row is the number of coordinates of the schedule.
|
||||
* dim contains a description of the parameters.
|
||||
/* A complete schedule tree.
|
||||
*
|
||||
* band_forest points to a band forest representation of the schedule
|
||||
* and may be NULL if the forest hasn't been created yet.
|
||||
*
|
||||
* "root" is the root of the schedule tree and may be NULL if we
|
||||
* have created a band forest corresponding to the schedule.
|
||||
*
|
||||
* A pointer to "leaf" may be used to represent a leaf of the schedule.
|
||||
* It should not appear as a child to any other isl_schedule_tree objects,
|
||||
* but an isl_schedule_node may point to "leaf" if it refers to
|
||||
* a leaf of this schedule tree.
|
||||
*/
|
||||
struct isl_schedule {
|
||||
int ref;
|
||||
|
||||
int n;
|
||||
int n_band;
|
||||
int n_total_row;
|
||||
isl_space *dim;
|
||||
|
||||
isl_band_list *band_forest;
|
||||
isl_schedule_tree *root;
|
||||
|
||||
struct isl_schedule_node node[1];
|
||||
struct isl_schedule_tree leaf;
|
||||
};
|
||||
|
||||
__isl_give isl_schedule *isl_schedule_from_schedule_tree(isl_ctx *ctx,
|
||||
__isl_take isl_schedule_tree *tree);
|
||||
__isl_give isl_schedule *isl_schedule_set_root(
|
||||
__isl_take isl_schedule *schedule, __isl_take isl_schedule_tree *tree);
|
||||
__isl_give isl_space *isl_schedule_get_space(
|
||||
__isl_keep isl_schedule *schedule);
|
||||
__isl_give isl_union_set *isl_schedule_get_domain(
|
||||
__isl_keep isl_schedule *schedule);
|
||||
__isl_keep isl_schedule_tree *isl_schedule_peek_leaf(
|
||||
__isl_keep isl_schedule *schedule);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,488 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <isl/schedule.h>
|
||||
#include <isl/stream.h>
|
||||
#include <isl_schedule_private.h>
|
||||
#include <isl_schedule_tree.h>
|
||||
|
||||
/* An enumeration of the various keys that may appear in a YAML mapping
|
||||
* of a schedule.
|
||||
*/
|
||||
enum isl_schedule_key {
|
||||
isl_schedule_key_error = -1,
|
||||
isl_schedule_key_child,
|
||||
isl_schedule_key_coincident,
|
||||
isl_schedule_key_domain,
|
||||
isl_schedule_key_filter,
|
||||
isl_schedule_key_leaf,
|
||||
isl_schedule_key_permutable,
|
||||
isl_schedule_key_schedule,
|
||||
isl_schedule_key_sequence,
|
||||
isl_schedule_key_set
|
||||
};
|
||||
|
||||
/* Extract a mapping key from the token "tok".
|
||||
* Return isl_schedule_key_error on error, i.e., if "tok" does not
|
||||
* correspond to any known key.
|
||||
*/
|
||||
static enum isl_schedule_key extract_key(__isl_keep isl_stream *s,
|
||||
struct isl_token *tok)
|
||||
{
|
||||
int type;
|
||||
char *name;
|
||||
enum isl_schedule_key key;
|
||||
isl_ctx *ctx;
|
||||
|
||||
ctx = isl_stream_get_ctx(s);
|
||||
type = isl_token_get_type(tok);
|
||||
if (type != ISL_TOKEN_IDENT && type != ISL_TOKEN_STRING) {
|
||||
isl_stream_error(s, tok, "expecting key");
|
||||
return isl_schedule_key_error;
|
||||
}
|
||||
name = isl_token_get_str(ctx, tok);
|
||||
if (!strcmp(name, "child"))
|
||||
key = isl_schedule_key_child;
|
||||
else if (!strcmp(name, "coincident"))
|
||||
key = isl_schedule_key_coincident;
|
||||
else if (!strcmp(name, "domain"))
|
||||
key = isl_schedule_key_domain;
|
||||
else if (!strcmp(name, "filter"))
|
||||
key = isl_schedule_key_filter;
|
||||
else if (!strcmp(name, "leaf"))
|
||||
key = isl_schedule_key_leaf;
|
||||
else if (!strcmp(name, "schedule"))
|
||||
key = isl_schedule_key_schedule;
|
||||
else if (!strcmp(name, "sequence"))
|
||||
key = isl_schedule_key_sequence;
|
||||
else if (!strcmp(name, "set"))
|
||||
key = isl_schedule_key_set;
|
||||
else if (!strcmp(name, "permutable"))
|
||||
key = isl_schedule_key_permutable;
|
||||
else
|
||||
isl_die(ctx, isl_error_invalid, "unknown key",
|
||||
key = isl_schedule_key_error);
|
||||
free(name);
|
||||
return key;
|
||||
}
|
||||
|
||||
/* Read a key from "s" and return the corresponding enum.
|
||||
* Return isl_schedule_key_error on error, i.e., if the first token
|
||||
* on the stream does not correspond to any known key.
|
||||
*/
|
||||
static enum isl_schedule_key get_key(__isl_keep isl_stream *s)
|
||||
{
|
||||
struct isl_token *tok;
|
||||
enum isl_schedule_key key;
|
||||
|
||||
tok = isl_stream_next_token(s);
|
||||
key = extract_key(s, tok);
|
||||
isl_token_free(tok);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static __isl_give isl_schedule_tree *isl_stream_read_schedule_tree(
|
||||
__isl_keep isl_stream *s);
|
||||
|
||||
/* Read a subtree with domain root node from "s".
|
||||
*/
|
||||
static __isl_give isl_schedule_tree *read_domain(__isl_keep isl_stream *s)
|
||||
{
|
||||
isl_union_set *domain = NULL;
|
||||
isl_schedule_tree *tree;
|
||||
isl_ctx *ctx;
|
||||
struct isl_token *tok;
|
||||
enum isl_schedule_key key;
|
||||
char *str;
|
||||
int more;
|
||||
|
||||
ctx = isl_stream_get_ctx(s);
|
||||
|
||||
key = get_key(s);
|
||||
|
||||
if (isl_stream_yaml_next(s) < 0)
|
||||
return NULL;
|
||||
|
||||
tok = isl_stream_next_token(s);
|
||||
if (!tok) {
|
||||
isl_stream_error(s, NULL, "unexpected EOF");
|
||||
return NULL;
|
||||
}
|
||||
str = isl_token_get_str(ctx, tok);
|
||||
domain = isl_union_set_read_from_str(ctx, str);
|
||||
free(str);
|
||||
isl_token_free(tok);
|
||||
|
||||
more = isl_stream_yaml_next(s);
|
||||
if (more < 0)
|
||||
goto error;
|
||||
if (!more) {
|
||||
tree = isl_schedule_tree_from_domain(domain);
|
||||
} else {
|
||||
key = get_key(s);
|
||||
if (key != isl_schedule_key_child)
|
||||
isl_die(ctx, isl_error_invalid, "expecting child",
|
||||
goto error);
|
||||
if (isl_stream_yaml_next(s) < 0)
|
||||
goto error;
|
||||
tree = isl_stream_read_schedule_tree(s);
|
||||
tree = isl_schedule_tree_insert_domain(tree, domain);
|
||||
}
|
||||
|
||||
return tree;
|
||||
error:
|
||||
isl_union_set_free(domain);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Read a subtree with filter root node from "s".
|
||||
*/
|
||||
static __isl_give isl_schedule_tree *read_filter(__isl_keep isl_stream *s)
|
||||
{
|
||||
isl_union_set *filter = NULL;
|
||||
isl_schedule_tree *tree;
|
||||
isl_ctx *ctx;
|
||||
struct isl_token *tok;
|
||||
enum isl_schedule_key key;
|
||||
char *str;
|
||||
int more;
|
||||
|
||||
ctx = isl_stream_get_ctx(s);
|
||||
|
||||
key = get_key(s);
|
||||
|
||||
if (isl_stream_yaml_next(s) < 0)
|
||||
return NULL;
|
||||
|
||||
tok = isl_stream_next_token(s);
|
||||
if (!tok) {
|
||||
isl_stream_error(s, NULL, "unexpected EOF");
|
||||
return NULL;
|
||||
}
|
||||
str = isl_token_get_str(ctx, tok);
|
||||
filter = isl_union_set_read_from_str(ctx, str);
|
||||
free(str);
|
||||
isl_token_free(tok);
|
||||
|
||||
more = isl_stream_yaml_next(s);
|
||||
if (more < 0)
|
||||
goto error;
|
||||
if (!more) {
|
||||
tree = isl_schedule_tree_from_filter(filter);
|
||||
} else {
|
||||
key = get_key(s);
|
||||
if (key != isl_schedule_key_child)
|
||||
isl_die(ctx, isl_error_invalid, "expecting child",
|
||||
goto error);
|
||||
if (isl_stream_yaml_next(s) < 0)
|
||||
goto error;
|
||||
tree = isl_stream_read_schedule_tree(s);
|
||||
tree = isl_schedule_tree_insert_filter(tree, filter);
|
||||
}
|
||||
|
||||
return tree;
|
||||
error:
|
||||
isl_union_set_free(filter);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Read a sequence of integers from "s" (representing the coincident
|
||||
* property of a band node).
|
||||
*/
|
||||
static __isl_give isl_val_list *read_coincident(__isl_keep isl_stream *s)
|
||||
{
|
||||
isl_ctx *ctx;
|
||||
isl_val_list *list;
|
||||
int more;
|
||||
|
||||
ctx = isl_stream_get_ctx(s);
|
||||
|
||||
if (isl_stream_yaml_read_start_sequence(s) < 0)
|
||||
return NULL;
|
||||
|
||||
list = isl_val_list_alloc(ctx, 0);
|
||||
while ((more = isl_stream_yaml_next(s)) > 0) {
|
||||
isl_val *val;
|
||||
|
||||
val = isl_stream_read_val(s);
|
||||
list = isl_val_list_add(list, val);
|
||||
}
|
||||
|
||||
if (more < 0 || isl_stream_yaml_read_end_sequence(s))
|
||||
list = isl_val_list_free(list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/* Set the (initial) coincident properties of "band" according to
|
||||
* the (initial) elements of "coincident".
|
||||
*/
|
||||
static __isl_give isl_schedule_band *set_coincident(
|
||||
__isl_take isl_schedule_band *band, __isl_take isl_val_list *coincident)
|
||||
{
|
||||
int i;
|
||||
int n, m;
|
||||
|
||||
n = isl_schedule_band_n_member(band);
|
||||
m = isl_val_list_n_val(coincident);
|
||||
|
||||
for (i = 0; i < n && i < m; ++i) {
|
||||
isl_val *v;
|
||||
|
||||
v = isl_val_list_get_val(coincident, i);
|
||||
if (!v)
|
||||
band = isl_schedule_band_free(band);
|
||||
band = isl_schedule_band_member_set_coincident(band, i,
|
||||
!isl_val_is_zero(v));
|
||||
isl_val_free(v);
|
||||
}
|
||||
isl_val_list_free(coincident);
|
||||
return band;
|
||||
}
|
||||
|
||||
/* Read a subtree with band root node from "s".
|
||||
*/
|
||||
static __isl_give isl_schedule_tree *read_band(isl_stream *s)
|
||||
{
|
||||
isl_multi_union_pw_aff *schedule = NULL;
|
||||
isl_schedule_tree *tree = NULL;
|
||||
isl_val_list *coincident = NULL;
|
||||
isl_ctx *ctx;
|
||||
isl_schedule_band *band;
|
||||
int permutable = 0;
|
||||
int more;
|
||||
|
||||
ctx = isl_stream_get_ctx(s);
|
||||
|
||||
do {
|
||||
struct isl_token *tok;
|
||||
enum isl_schedule_key key;
|
||||
char *str;
|
||||
isl_val *v;
|
||||
|
||||
key = get_key(s);
|
||||
if (isl_stream_yaml_next(s) < 0)
|
||||
goto error;
|
||||
|
||||
switch (key) {
|
||||
case isl_schedule_key_schedule:
|
||||
isl_multi_union_pw_aff_free(schedule);
|
||||
tok = isl_stream_next_token(s);
|
||||
if (!tok) {
|
||||
isl_stream_error(s, NULL, "unexpected EOF");
|
||||
goto error;
|
||||
}
|
||||
str = isl_token_get_str(ctx, tok);
|
||||
schedule = isl_multi_union_pw_aff_read_from_str(ctx,
|
||||
str);
|
||||
free(str);
|
||||
isl_token_free(tok);
|
||||
if (!schedule)
|
||||
goto error;
|
||||
break;
|
||||
case isl_schedule_key_coincident:
|
||||
coincident = read_coincident(s);
|
||||
if (!coincident)
|
||||
goto error;
|
||||
break;
|
||||
case isl_schedule_key_permutable:
|
||||
v = isl_stream_read_val(s);
|
||||
permutable = !isl_val_is_zero(v);
|
||||
isl_val_free(v);
|
||||
break;
|
||||
case isl_schedule_key_child:
|
||||
isl_schedule_tree_free(tree);
|
||||
tree = isl_stream_read_schedule_tree(s);
|
||||
if (!tree)
|
||||
goto error;
|
||||
break;
|
||||
default:
|
||||
isl_die(ctx, isl_error_invalid, "unexpected key",
|
||||
goto error);
|
||||
}
|
||||
} while ((more = isl_stream_yaml_next(s)) > 0);
|
||||
|
||||
if (more < 0)
|
||||
goto error;
|
||||
|
||||
if (!schedule)
|
||||
isl_die(ctx, isl_error_invalid, "missing schedule", goto error);
|
||||
|
||||
band = isl_schedule_band_from_multi_union_pw_aff(schedule);
|
||||
band = isl_schedule_band_set_permutable(band, permutable);
|
||||
if (coincident)
|
||||
band = set_coincident(band, coincident);
|
||||
if (tree)
|
||||
tree = isl_schedule_tree_insert_band(tree, band);
|
||||
else
|
||||
tree = isl_schedule_tree_from_band(band);
|
||||
|
||||
return tree;
|
||||
error:
|
||||
isl_val_list_free(coincident);
|
||||
isl_schedule_tree_free(tree);
|
||||
isl_multi_union_pw_aff_free(schedule);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Read a subtree with root node of type "type" from "s".
|
||||
* The node is represented by a sequence of children.
|
||||
*/
|
||||
static __isl_give isl_schedule_tree *read_children(isl_stream *s,
|
||||
enum isl_schedule_node_type type)
|
||||
{
|
||||
isl_ctx *ctx;
|
||||
isl_schedule_tree_list *list;
|
||||
int more;
|
||||
|
||||
ctx = isl_stream_get_ctx(s);
|
||||
|
||||
isl_token_free(isl_stream_next_token(s));
|
||||
|
||||
if (isl_stream_yaml_next(s) < 0)
|
||||
return NULL;
|
||||
|
||||
if (isl_stream_yaml_read_start_sequence(s))
|
||||
return NULL;
|
||||
|
||||
list = isl_schedule_tree_list_alloc(ctx, 0);
|
||||
while ((more = isl_stream_yaml_next(s)) > 0) {
|
||||
isl_schedule_tree *tree;
|
||||
|
||||
tree = isl_stream_read_schedule_tree(s);
|
||||
list = isl_schedule_tree_list_add(list, tree);
|
||||
}
|
||||
|
||||
if (more < 0 || isl_stream_yaml_read_end_sequence(s))
|
||||
list = isl_schedule_tree_list_free(list);
|
||||
|
||||
return isl_schedule_tree_from_children(type, list);
|
||||
}
|
||||
|
||||
/* Read a subtree with sequence root node from "s".
|
||||
*/
|
||||
static __isl_give isl_schedule_tree *read_sequence(isl_stream *s)
|
||||
{
|
||||
return read_children(s, isl_schedule_node_sequence);
|
||||
}
|
||||
|
||||
/* Read a subtree with set root node from "s".
|
||||
*/
|
||||
static __isl_give isl_schedule_tree *read_set(isl_stream *s)
|
||||
{
|
||||
return read_children(s, isl_schedule_node_set);
|
||||
}
|
||||
|
||||
/* Read a schedule (sub)tree from "s".
|
||||
*
|
||||
* We first determine the type of the root node based on the first
|
||||
* mapping key and then hand over to a function tailored to reading
|
||||
* nodes of this type.
|
||||
*/
|
||||
static __isl_give isl_schedule_tree *isl_stream_read_schedule_tree(
|
||||
struct isl_stream *s)
|
||||
{
|
||||
enum isl_schedule_key key;
|
||||
struct isl_token *tok;
|
||||
isl_schedule_tree *tree = NULL;
|
||||
int more;
|
||||
|
||||
if (isl_stream_yaml_read_start_mapping(s))
|
||||
return NULL;
|
||||
more = isl_stream_yaml_next(s);
|
||||
if (more < 0)
|
||||
return NULL;
|
||||
if (!more) {
|
||||
isl_stream_error(s, NULL, "missing key");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tok = isl_stream_next_token(s);
|
||||
key = extract_key(s, tok);
|
||||
isl_stream_push_token(s, tok);
|
||||
if (key < 0)
|
||||
return NULL;
|
||||
switch (key) {
|
||||
case isl_schedule_key_domain:
|
||||
tree = read_domain(s);
|
||||
break;
|
||||
case isl_schedule_key_filter:
|
||||
tree = read_filter(s);
|
||||
break;
|
||||
case isl_schedule_key_leaf:
|
||||
isl_token_free(isl_stream_next_token(s));
|
||||
tree = isl_schedule_tree_leaf(isl_stream_get_ctx(s));
|
||||
break;
|
||||
case isl_schedule_key_sequence:
|
||||
tree = read_sequence(s);
|
||||
break;
|
||||
case isl_schedule_key_set:
|
||||
tree = read_set(s);
|
||||
break;
|
||||
case isl_schedule_key_schedule:
|
||||
case isl_schedule_key_coincident:
|
||||
case isl_schedule_key_permutable:
|
||||
tree = read_band(s);
|
||||
break;
|
||||
case isl_schedule_key_child:
|
||||
isl_die(isl_stream_get_ctx(s), isl_error_unsupported,
|
||||
"cannot identity node type", return NULL);
|
||||
case isl_schedule_key_error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (isl_stream_yaml_read_end_mapping(s) < 0) {
|
||||
isl_stream_error(s, NULL, "unexpected extra elements");
|
||||
return isl_schedule_tree_free(tree);
|
||||
}
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
/* Read an isl_schedule from "s".
|
||||
*/
|
||||
__isl_give isl_schedule *isl_stream_read_schedule(isl_stream *s)
|
||||
{
|
||||
isl_ctx *ctx;
|
||||
isl_schedule_tree *tree;
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
ctx = isl_stream_get_ctx(s);
|
||||
tree = isl_stream_read_schedule_tree(s);
|
||||
return isl_schedule_from_schedule_tree(ctx, tree);
|
||||
}
|
||||
|
||||
/* Read an isl_schedule from "input".
|
||||
*/
|
||||
__isl_give isl_schedule *isl_schedule_read_from_file(isl_ctx *ctx, FILE *input)
|
||||
{
|
||||
struct isl_stream *s;
|
||||
isl_schedule *schedule;
|
||||
|
||||
s = isl_stream_new_file(ctx, input);
|
||||
if (!s)
|
||||
return NULL;
|
||||
schedule = isl_stream_read_schedule(s);
|
||||
isl_stream_free(s);
|
||||
|
||||
return schedule;
|
||||
}
|
||||
|
||||
/* Read an isl_schedule from "str".
|
||||
*/
|
||||
__isl_give isl_schedule *isl_schedule_read_from_str(isl_ctx *ctx,
|
||||
const char *str)
|
||||
{
|
||||
struct isl_stream *s;
|
||||
isl_schedule *schedule;
|
||||
|
||||
s = isl_stream_new_str(ctx, str);
|
||||
if (!s)
|
||||
return NULL;
|
||||
schedule = isl_stream_read_schedule(s);
|
||||
isl_stream_free(s);
|
||||
|
||||
return schedule;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,134 @@
|
|||
#ifndef ISL_SCHEDLUE_TREE_H
|
||||
#define ISL_SCHEDLUE_TREE_H
|
||||
|
||||
#include <isl_schedule_band.h>
|
||||
#include <isl/schedule.h>
|
||||
#include <isl/set.h>
|
||||
#include <isl/union_set.h>
|
||||
|
||||
struct isl_schedule_tree;
|
||||
typedef struct isl_schedule_tree isl_schedule_tree;
|
||||
|
||||
ISL_DECLARE_LIST(schedule_tree)
|
||||
|
||||
/* A schedule (sub)tree.
|
||||
*
|
||||
* The leaves of a tree are not explicitly represented inside
|
||||
* the isl_schedule_tree. If a tree consists of only a leaf,
|
||||
* then it is equal to the static object isl_schedule_tree_empty.
|
||||
*
|
||||
* ctx may be NULL if type is isl_schedule_node_leaf.
|
||||
* In this case, ref has a negative value.
|
||||
*
|
||||
* The "band" field is valid when type is isl_schedule_node_band.
|
||||
* The "domain" field is valid when type is isl_schedule_node_domain
|
||||
* and introduces the statement instances scheduled by the tree.
|
||||
* The "filter" field is valid when type is isl_schedule_node_filter
|
||||
* and represents the statement instances selected by the node.
|
||||
*
|
||||
* The "children" field is valid for all types except
|
||||
* isl_schedule_node_leaf. This field is NULL if there are
|
||||
* no children (except for the implicit leaves).
|
||||
*/
|
||||
struct isl_schedule_tree {
|
||||
int ref;
|
||||
isl_ctx *ctx;
|
||||
enum isl_schedule_node_type type;
|
||||
union {
|
||||
isl_schedule_band *band;
|
||||
isl_union_set *domain;
|
||||
isl_union_set *filter;
|
||||
};
|
||||
isl_schedule_tree_list *children;
|
||||
};
|
||||
|
||||
isl_ctx *isl_schedule_tree_get_ctx(__isl_keep isl_schedule_tree *tree);
|
||||
enum isl_schedule_node_type isl_schedule_tree_get_type(
|
||||
__isl_keep isl_schedule_tree *tree);
|
||||
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_leaf(isl_ctx *ctx);
|
||||
int isl_schedule_tree_is_leaf(__isl_keep isl_schedule_tree *tree);
|
||||
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_copy(
|
||||
__isl_keep isl_schedule_tree *tree);
|
||||
__isl_null isl_schedule_tree *isl_schedule_tree_free(
|
||||
__isl_take isl_schedule_tree *tree);
|
||||
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_from_band(
|
||||
__isl_take isl_schedule_band *band);
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_from_domain(
|
||||
__isl_take isl_union_set *domain);
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_from_filter(
|
||||
__isl_take isl_union_set *filter);
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_from_children(
|
||||
enum isl_schedule_node_type type,
|
||||
__isl_take isl_schedule_tree_list *list);
|
||||
|
||||
__isl_give isl_space *isl_schedule_tree_band_get_space(
|
||||
__isl_keep isl_schedule_tree *tree);
|
||||
__isl_give isl_multi_union_pw_aff *isl_schedule_tree_band_get_partial_schedule(
|
||||
__isl_keep isl_schedule_tree *tree);
|
||||
__isl_give isl_union_set *isl_schedule_tree_domain_get_domain(
|
||||
__isl_keep isl_schedule_tree *tree);
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_domain_set_domain(
|
||||
__isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain);
|
||||
__isl_give isl_union_set *isl_schedule_tree_filter_get_filter(
|
||||
__isl_keep isl_schedule_tree *tree);
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_filter_set_filter(
|
||||
__isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter);
|
||||
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_first_schedule_descendant(
|
||||
__isl_take isl_schedule_tree *tree, __isl_keep isl_schedule_tree *leaf);
|
||||
__isl_give isl_union_map *isl_schedule_tree_get_subtree_schedule_union_map(
|
||||
__isl_keep isl_schedule_tree *tree);
|
||||
|
||||
unsigned isl_schedule_tree_band_n_member(__isl_keep isl_schedule_tree *tree);
|
||||
|
||||
int isl_schedule_tree_band_member_get_coincident(
|
||||
__isl_keep isl_schedule_tree *tree, int pos);
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_band_member_set_coincident(
|
||||
__isl_take isl_schedule_tree *tree, int pos, int coincident);
|
||||
int isl_schedule_tree_band_get_permutable(__isl_keep isl_schedule_tree *tree);
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_band_set_permutable(
|
||||
__isl_take isl_schedule_tree *tree, int permutable);
|
||||
|
||||
int isl_schedule_tree_has_children(__isl_keep isl_schedule_tree *tree);
|
||||
int isl_schedule_tree_n_children(__isl_keep isl_schedule_tree *tree);
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_get_child(
|
||||
__isl_keep isl_schedule_tree *tree, int pos);
|
||||
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_insert_band(
|
||||
__isl_take isl_schedule_tree *tree, __isl_take isl_schedule_band *band);
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_insert_domain(
|
||||
__isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain);
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_insert_filter(
|
||||
__isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter);
|
||||
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_append_to_leaves(
|
||||
__isl_take isl_schedule_tree *tree1,
|
||||
__isl_take isl_schedule_tree *tree2);
|
||||
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_band_scale(
|
||||
__isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv);
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_band_scale_down(
|
||||
__isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv);
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_band_tile(
|
||||
__isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *sizes);
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_band_split(
|
||||
__isl_take isl_schedule_tree *tree, int pos);
|
||||
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_child(
|
||||
__isl_take isl_schedule_tree *tree, int pos);
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_reset_children(
|
||||
__isl_take isl_schedule_tree *tree);
|
||||
__isl_give isl_schedule_tree *isl_schedule_tree_replace_child(
|
||||
__isl_take isl_schedule_tree *tree, int pos,
|
||||
__isl_take isl_schedule_tree *new_child);
|
||||
|
||||
__isl_give isl_printer *isl_printer_print_schedule_tree(
|
||||
__isl_take isl_printer *p, __isl_keep isl_schedule_tree *tree);
|
||||
__isl_give isl_printer *isl_printer_print_schedule_tree_mark(
|
||||
__isl_take isl_printer *p, __isl_keep isl_schedule_tree *tree,
|
||||
int n_ancestor, int *child_pos);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -10,6 +10,11 @@
|
|||
|
||||
#include <isl_list_templ.h>
|
||||
|
||||
#undef EL
|
||||
#define EL isl_union_set
|
||||
|
||||
#include <isl_list_templ.h>
|
||||
|
||||
#undef BASE
|
||||
#define BASE basic_set
|
||||
|
||||
|
@ -19,3 +24,8 @@
|
|||
#define BASE set
|
||||
|
||||
#include <isl_list_templ.c>
|
||||
|
||||
#undef BASE
|
||||
#define BASE union_set
|
||||
|
||||
#include <isl_list_templ.c>
|
||||
|
|
|
@ -28,7 +28,7 @@ static int same_name(const void *entry, const void *val)
|
|||
return !strcmp(keyword->name, val);
|
||||
}
|
||||
|
||||
enum isl_token_type isl_stream_register_keyword(struct isl_stream *s,
|
||||
enum isl_token_type isl_stream_register_keyword(__isl_keep isl_stream *s,
|
||||
const char *name)
|
||||
{
|
||||
struct isl_hash_table_entry *entry;
|
||||
|
@ -101,14 +101,15 @@ __isl_give isl_val *isl_token_get_val(isl_ctx *ctx, struct isl_token *tok)
|
|||
return isl_val_int_from_isl_int(ctx, tok->u.v);
|
||||
}
|
||||
|
||||
/* Given a token of type ISL_TOKEN_STRING, return the string it represents.
|
||||
/* Given a token with a string representation, return a copy of this string.
|
||||
*/
|
||||
__isl_give char *isl_token_get_str(isl_ctx *ctx, struct isl_token *tok)
|
||||
{
|
||||
if (!tok)
|
||||
return NULL;
|
||||
if (tok->type != ISL_TOKEN_STRING)
|
||||
isl_die(ctx, isl_error_invalid, "not a string token",
|
||||
if (!tok->u.s)
|
||||
isl_die(ctx, isl_error_invalid,
|
||||
"token does not have a string representation",
|
||||
return NULL);
|
||||
|
||||
return strdup(tok->u.s);
|
||||
|
@ -129,7 +130,8 @@ void isl_token_free(struct isl_token *tok)
|
|||
free(tok);
|
||||
}
|
||||
|
||||
void isl_stream_error(struct isl_stream *s, struct isl_token *tok, char *msg)
|
||||
void isl_stream_error(__isl_keep isl_stream *s, struct isl_token *tok,
|
||||
char *msg)
|
||||
{
|
||||
int line = tok ? tok->line : s->line;
|
||||
int col = tok ? tok->col : s->col;
|
||||
|
@ -166,10 +168,10 @@ void isl_stream_error(struct isl_stream *s, struct isl_token *tok, char *msg)
|
|||
}
|
||||
}
|
||||
|
||||
static struct isl_stream* isl_stream_new(struct isl_ctx *ctx)
|
||||
static __isl_give isl_stream* isl_stream_new(struct isl_ctx *ctx)
|
||||
{
|
||||
int i;
|
||||
struct isl_stream *s = isl_alloc_type(ctx, struct isl_stream);
|
||||
isl_stream *s = isl_calloc_type(ctx, struct isl_stream);
|
||||
if (!s)
|
||||
return NULL;
|
||||
s->ctx = ctx;
|
||||
|
@ -178,8 +180,9 @@ static struct isl_stream* isl_stream_new(struct isl_ctx *ctx)
|
|||
s->str = NULL;
|
||||
s->len = 0;
|
||||
s->line = 1;
|
||||
s->col = 0;
|
||||
s->col = 1;
|
||||
s->eof = 0;
|
||||
s->last_line = 0;
|
||||
s->c = -1;
|
||||
s->n_un = 0;
|
||||
for (i = 0; i < 5; ++i)
|
||||
|
@ -196,18 +199,18 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct isl_stream* isl_stream_new_file(struct isl_ctx *ctx, FILE *file)
|
||||
__isl_give isl_stream* isl_stream_new_file(struct isl_ctx *ctx, FILE *file)
|
||||
{
|
||||
struct isl_stream *s = isl_stream_new(ctx);
|
||||
isl_stream *s = isl_stream_new(ctx);
|
||||
if (!s)
|
||||
return NULL;
|
||||
s->file = file;
|
||||
return s;
|
||||
}
|
||||
|
||||
struct isl_stream* isl_stream_new_str(struct isl_ctx *ctx, const char *str)
|
||||
__isl_give isl_stream* isl_stream_new_str(struct isl_ctx *ctx, const char *str)
|
||||
{
|
||||
struct isl_stream *s;
|
||||
isl_stream *s;
|
||||
if (!str)
|
||||
return NULL;
|
||||
s = isl_stream_new(ctx);
|
||||
|
@ -217,7 +220,10 @@ struct isl_stream* isl_stream_new_str(struct isl_ctx *ctx, const char *str)
|
|||
return s;
|
||||
}
|
||||
|
||||
static int stream_getc(struct isl_stream *s)
|
||||
/* Read a character from the stream and advance s->line and s->col
|
||||
* to point to the next character.
|
||||
*/
|
||||
static int stream_getc(__isl_keep isl_stream *s)
|
||||
{
|
||||
int c;
|
||||
if (s->eof)
|
||||
|
@ -233,29 +239,33 @@ static int stream_getc(struct isl_stream *s)
|
|||
}
|
||||
if (c == -1)
|
||||
s->eof = 1;
|
||||
if (!s->eof) {
|
||||
if (s->c == '\n') {
|
||||
s->line++;
|
||||
s->col = 0;
|
||||
} else
|
||||
s->col++;
|
||||
}
|
||||
else if (c == '\n') {
|
||||
s->line++;
|
||||
s->col = 1;
|
||||
} else
|
||||
s->col++;
|
||||
s->c = c;
|
||||
return c;
|
||||
}
|
||||
|
||||
static void isl_stream_ungetc(struct isl_stream *s, int c)
|
||||
static void isl_stream_ungetc(__isl_keep isl_stream *s, int c)
|
||||
{
|
||||
isl_assert(s->ctx, s->n_un < 5, return);
|
||||
s->un[s->n_un++] = c;
|
||||
s->c = -1;
|
||||
}
|
||||
|
||||
static int isl_stream_getc(struct isl_stream *s)
|
||||
/* Read a character from the stream, skipping pairs of '\\' and '\n'.
|
||||
* Set s->start_line and s->start_col to the line and column
|
||||
* of the returned character.
|
||||
*/
|
||||
static int isl_stream_getc(__isl_keep isl_stream *s)
|
||||
{
|
||||
int c;
|
||||
|
||||
do {
|
||||
s->start_line = s->line;
|
||||
s->start_col = s->col;
|
||||
c = stream_getc(s);
|
||||
if (c != '\\')
|
||||
return c;
|
||||
|
@ -267,7 +277,7 @@ static int isl_stream_getc(struct isl_stream *s)
|
|||
return '\\';
|
||||
}
|
||||
|
||||
static int isl_stream_push_char(struct isl_stream *s, int c)
|
||||
static int isl_stream_push_char(__isl_keep isl_stream *s, int c)
|
||||
{
|
||||
if (s->len >= s->size) {
|
||||
char *buffer;
|
||||
|
@ -281,13 +291,13 @@ static int isl_stream_push_char(struct isl_stream *s, int c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void isl_stream_push_token(struct isl_stream *s, struct isl_token *tok)
|
||||
void isl_stream_push_token(__isl_keep isl_stream *s, struct isl_token *tok)
|
||||
{
|
||||
isl_assert(s->ctx, s->n_token < 5, return);
|
||||
s->tokens[s->n_token++] = tok;
|
||||
}
|
||||
|
||||
static enum isl_token_type check_keywords(struct isl_stream *s)
|
||||
static enum isl_token_type check_keywords(__isl_keep isl_stream *s)
|
||||
{
|
||||
struct isl_hash_table_entry *entry;
|
||||
struct isl_keyword *keyword;
|
||||
|
@ -344,7 +354,7 @@ static enum isl_token_type check_keywords(struct isl_stream *s)
|
|||
return ISL_TOKEN_IDENT;
|
||||
}
|
||||
|
||||
int isl_stream_skip_line(struct isl_stream *s)
|
||||
int isl_stream_skip_line(__isl_keep isl_stream *s)
|
||||
{
|
||||
int c;
|
||||
|
||||
|
@ -355,12 +365,12 @@ int isl_stream_skip_line(struct isl_stream *s)
|
|||
return c == -1 ? -1 : 0;
|
||||
}
|
||||
|
||||
static struct isl_token *next_token(struct isl_stream *s, int same_line)
|
||||
static struct isl_token *next_token(__isl_keep isl_stream *s, int same_line)
|
||||
{
|
||||
int c;
|
||||
struct isl_token *tok = NULL;
|
||||
int line, col;
|
||||
int old_line = s->line;
|
||||
int old_line = s->last_line;
|
||||
|
||||
if (s->n_token) {
|
||||
if (same_line && s->tokens[s->n_token - 1]->on_new_line)
|
||||
|
@ -385,11 +395,13 @@ static struct isl_token *next_token(struct isl_stream *s, int same_line)
|
|||
break;
|
||||
}
|
||||
|
||||
line = s->line;
|
||||
col = s->col;
|
||||
line = s->start_line;
|
||||
col = s->start_col;
|
||||
|
||||
if (c == -1 || (same_line && c == '\n'))
|
||||
return NULL;
|
||||
s->last_line = line;
|
||||
|
||||
if (c == '(' ||
|
||||
c == ')' ||
|
||||
c == '+' ||
|
||||
|
@ -655,17 +667,17 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct isl_token *isl_stream_next_token(struct isl_stream *s)
|
||||
struct isl_token *isl_stream_next_token(__isl_keep isl_stream *s)
|
||||
{
|
||||
return next_token(s, 0);
|
||||
}
|
||||
|
||||
struct isl_token *isl_stream_next_token_on_same_line(struct isl_stream *s)
|
||||
struct isl_token *isl_stream_next_token_on_same_line(__isl_keep isl_stream *s)
|
||||
{
|
||||
return next_token(s, 1);
|
||||
}
|
||||
|
||||
int isl_stream_eat_if_available(struct isl_stream *s, int type)
|
||||
int isl_stream_eat_if_available(__isl_keep isl_stream *s, int type)
|
||||
{
|
||||
struct isl_token *tok;
|
||||
|
||||
|
@ -680,7 +692,7 @@ int isl_stream_eat_if_available(struct isl_stream *s, int type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int isl_stream_next_token_is(struct isl_stream *s, int type)
|
||||
int isl_stream_next_token_is(__isl_keep isl_stream *s, int type)
|
||||
{
|
||||
struct isl_token *tok;
|
||||
int r;
|
||||
|
@ -693,7 +705,7 @@ int isl_stream_next_token_is(struct isl_stream *s, int type)
|
|||
return r;
|
||||
}
|
||||
|
||||
char *isl_stream_read_ident_if_available(struct isl_stream *s)
|
||||
char *isl_stream_read_ident_if_available(__isl_keep isl_stream *s)
|
||||
{
|
||||
struct isl_token *tok;
|
||||
|
||||
|
@ -709,7 +721,7 @@ char *isl_stream_read_ident_if_available(struct isl_stream *s)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int isl_stream_eat(struct isl_stream *s, int type)
|
||||
int isl_stream_eat(__isl_keep isl_stream *s, int type)
|
||||
{
|
||||
struct isl_token *tok;
|
||||
|
||||
|
@ -725,7 +737,7 @@ int isl_stream_eat(struct isl_stream *s, int type)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int isl_stream_is_empty(struct isl_stream *s)
|
||||
int isl_stream_is_empty(__isl_keep isl_stream *s)
|
||||
{
|
||||
struct isl_token *tok;
|
||||
|
||||
|
@ -748,7 +760,7 @@ static int free_keyword(void **p, void *user)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void isl_stream_flush_tokens(struct isl_stream *s)
|
||||
void isl_stream_flush_tokens(__isl_keep isl_stream *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -759,7 +771,12 @@ void isl_stream_flush_tokens(struct isl_stream *s)
|
|||
s->n_token = 0;
|
||||
}
|
||||
|
||||
void isl_stream_free(struct isl_stream *s)
|
||||
isl_ctx *isl_stream_get_ctx(__isl_keep isl_stream *s)
|
||||
{
|
||||
return s ? s->ctx : NULL;
|
||||
}
|
||||
|
||||
void isl_stream_free(__isl_take isl_stream *s)
|
||||
{
|
||||
if (!s)
|
||||
return;
|
||||
|
@ -773,6 +790,382 @@ void isl_stream_free(struct isl_stream *s)
|
|||
isl_hash_table_foreach(s->ctx, s->keywords, &free_keyword, NULL);
|
||||
isl_hash_table_free(s->ctx, s->keywords);
|
||||
}
|
||||
free(s->yaml_state);
|
||||
free(s->yaml_indent);
|
||||
isl_ctx_deref(s->ctx);
|
||||
free(s);
|
||||
}
|
||||
|
||||
/* Push "state" onto the stack of currently active YAML elements.
|
||||
* The caller is responsible for setting the corresponding indentation.
|
||||
* Return 0 on success and -1 on failure.
|
||||
*/
|
||||
static int push_state(__isl_keep isl_stream *s, enum isl_yaml_state state)
|
||||
{
|
||||
if (s->yaml_size < s->yaml_depth + 1) {
|
||||
int *indent;
|
||||
enum isl_yaml_state *state;
|
||||
|
||||
state = isl_realloc_array(s->ctx, s->yaml_state,
|
||||
enum isl_yaml_state, s->yaml_depth + 1);
|
||||
if (!state)
|
||||
return -1;
|
||||
s->yaml_state = state;
|
||||
|
||||
indent = isl_realloc_array(s->ctx, s->yaml_indent,
|
||||
int, s->yaml_depth + 1);
|
||||
if (!indent)
|
||||
return -1;
|
||||
s->yaml_indent = indent;
|
||||
|
||||
s->yaml_size = s->yaml_depth + 1;
|
||||
}
|
||||
|
||||
s->yaml_state[s->yaml_depth] = state;
|
||||
s->yaml_depth++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove the innermost active YAML element from the stack.
|
||||
* Return 0 on success and -1 on failure.
|
||||
*/
|
||||
static int pop_state(__isl_keep isl_stream *s)
|
||||
{
|
||||
if (!s)
|
||||
return -1;
|
||||
if (s->yaml_depth < 1)
|
||||
isl_die(isl_stream_get_ctx(s), isl_error_invalid,
|
||||
"not in YAML construct", return -1);
|
||||
|
||||
s->yaml_depth--;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set the state of the innermost active YAML element to "state".
|
||||
* Return 0 on success and -1 on failure.
|
||||
*/
|
||||
static int update_state(__isl_keep isl_stream *s, enum isl_yaml_state state)
|
||||
{
|
||||
if (!s)
|
||||
return -1;
|
||||
if (s->yaml_depth < 1)
|
||||
isl_die(isl_stream_get_ctx(s), isl_error_invalid,
|
||||
"not in YAML construct", return -1);
|
||||
|
||||
s->yaml_state[s->yaml_depth - 1] = state;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return the state of the innermost active YAML element.
|
||||
* Return isl_yaml_none if we are not inside any YAML element.
|
||||
*/
|
||||
static enum isl_yaml_state current_state(__isl_keep isl_stream *s)
|
||||
{
|
||||
if (!s)
|
||||
return isl_yaml_none;
|
||||
if (s->yaml_depth < 1)
|
||||
return isl_yaml_none;
|
||||
return s->yaml_state[s->yaml_depth - 1];
|
||||
}
|
||||
|
||||
/* Set the indentation of the innermost active YAML element to "indent".
|
||||
* If "indent" is equal to ISL_YAML_INDENT_FLOW, then this means
|
||||
* that the current elemient is in flow format.
|
||||
*/
|
||||
static int set_yaml_indent(__isl_keep isl_stream *s, int indent)
|
||||
{
|
||||
if (s->yaml_depth < 1)
|
||||
isl_die(s->ctx, isl_error_internal,
|
||||
"not in YAML element", return -1);
|
||||
|
||||
s->yaml_indent[s->yaml_depth - 1] = indent;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return the indentation of the innermost active YAML element
|
||||
* of -1 on error.
|
||||
*/
|
||||
static int get_yaml_indent(__isl_keep isl_stream *s)
|
||||
{
|
||||
if (s->yaml_depth < 1)
|
||||
isl_die(s->ctx, isl_error_internal,
|
||||
"not in YAML element", return -1);
|
||||
|
||||
return s->yaml_indent[s->yaml_depth - 1];
|
||||
}
|
||||
|
||||
/* Move to the next state at the innermost level.
|
||||
* Return 1 if successful.
|
||||
* Return 0 if we are at the end of the innermost level.
|
||||
* Return -1 on error.
|
||||
*
|
||||
* If we are in state isl_yaml_mapping_key_start, then we have just
|
||||
* started a mapping and we are expecting a key. If the mapping started
|
||||
* with a '{', then we check if the next token is a '}'. If so,
|
||||
* then the mapping is empty and there is no next state at this level.
|
||||
* Otherwise, we assume that there is at least one key (the one from
|
||||
* which we derived the indentation in isl_stream_yaml_read_start_mapping.
|
||||
*
|
||||
* If we are in state isl_yaml_mapping_key, then the we expect a colon
|
||||
* followed by a value, so there is always a next state unless
|
||||
* some error occurs.
|
||||
*
|
||||
* If we are in state isl_yaml_mapping_val, then there may or may
|
||||
* not be a subsequent key in the same mapping.
|
||||
* In flow format, the next key is preceded by a comma.
|
||||
* In block format, the next key has the same indentation as the first key.
|
||||
* If the first token has a smaller indentation, then we have reached
|
||||
* the end of the current mapping.
|
||||
*
|
||||
* If we are in state isl_yaml_sequence_start, then we have just
|
||||
* started a sequence. If the sequence started with a '[',
|
||||
* then we check if the next token is a ']'. If so, then the sequence
|
||||
* is empty and there is no next state at this level.
|
||||
* Otherwise, we assume that there is at least one element in the sequence
|
||||
* (the one from which we derived the indentation in
|
||||
* isl_stream_yaml_read_start_sequence.
|
||||
*
|
||||
* If we are in state isl_yaml_sequence, then there may or may
|
||||
* not be a subsequent element in the same sequence.
|
||||
* In flow format, the next element is preceded by a comma.
|
||||
* In block format, the next element is introduced by a dash with
|
||||
* the same indentation as that of the first element.
|
||||
* If the first token is not a dash or if it has a smaller indentation,
|
||||
* then we have reached the end of the current sequence.
|
||||
*/
|
||||
int isl_stream_yaml_next(__isl_keep isl_stream *s)
|
||||
{
|
||||
struct isl_token *tok;
|
||||
enum isl_yaml_state state;
|
||||
int indent;
|
||||
|
||||
state = current_state(s);
|
||||
if (state == isl_yaml_none)
|
||||
isl_die(s->ctx, isl_error_invalid,
|
||||
"not in YAML element", return -1);
|
||||
switch (state) {
|
||||
case isl_yaml_mapping_key_start:
|
||||
if (get_yaml_indent(s) == ISL_YAML_INDENT_FLOW &&
|
||||
isl_stream_next_token_is(s, '}'))
|
||||
return 0;
|
||||
if (update_state(s, isl_yaml_mapping_key) < 0)
|
||||
return -1;
|
||||
return 1;
|
||||
case isl_yaml_mapping_key:
|
||||
tok = isl_stream_next_token(s);
|
||||
if (!tok) {
|
||||
if (s->eof)
|
||||
isl_stream_error(s, NULL, "unexpected EOF");
|
||||
return -1;
|
||||
}
|
||||
if (tok->type == ':') {
|
||||
isl_token_free(tok);
|
||||
if (update_state(s, isl_yaml_mapping_val) < 0)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
isl_stream_error(s, tok, "expecting ':'");
|
||||
isl_stream_push_token(s, tok);
|
||||
return -1;
|
||||
case isl_yaml_mapping_val:
|
||||
if (get_yaml_indent(s) == ISL_YAML_INDENT_FLOW) {
|
||||
if (!isl_stream_eat_if_available(s, ','))
|
||||
return 0;
|
||||
if (update_state(s, isl_yaml_mapping_key) < 0)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
tok = isl_stream_next_token(s);
|
||||
if (!tok)
|
||||
return 0;
|
||||
indent = tok->col - 1;
|
||||
isl_stream_push_token(s, tok);
|
||||
if (indent < get_yaml_indent(s))
|
||||
return 0;
|
||||
if (update_state(s, isl_yaml_mapping_key) < 0)
|
||||
return -1;
|
||||
return 1;
|
||||
case isl_yaml_sequence_start:
|
||||
if (get_yaml_indent(s) == ISL_YAML_INDENT_FLOW) {
|
||||
if (isl_stream_next_token_is(s, ']'))
|
||||
return 0;
|
||||
if (update_state(s, isl_yaml_sequence) < 0)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
tok = isl_stream_next_token(s);
|
||||
if (!tok) {
|
||||
if (s->eof)
|
||||
isl_stream_error(s, NULL, "unexpected EOF");
|
||||
return -1;
|
||||
}
|
||||
if (tok->type == '-') {
|
||||
isl_token_free(tok);
|
||||
if (update_state(s, isl_yaml_sequence) < 0)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
isl_stream_error(s, tok, "expecting '-'");
|
||||
isl_stream_push_token(s, tok);
|
||||
return 0;
|
||||
case isl_yaml_sequence:
|
||||
if (get_yaml_indent(s) == ISL_YAML_INDENT_FLOW)
|
||||
return isl_stream_eat_if_available(s, ',');
|
||||
tok = isl_stream_next_token(s);
|
||||
if (!tok)
|
||||
return 0;
|
||||
indent = tok->col - 1;
|
||||
if (indent < get_yaml_indent(s) || tok->type != '-') {
|
||||
isl_stream_push_token(s, tok);
|
||||
return 0;
|
||||
}
|
||||
isl_token_free(tok);
|
||||
return 1;
|
||||
default:
|
||||
isl_die(s->ctx, isl_error_internal,
|
||||
"unexpected state", return 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Start reading a YAML mapping.
|
||||
* Return 0 on success and -1 on error.
|
||||
*
|
||||
* If the first token on the stream is a '{' then we remove this token
|
||||
* from the stream and keep track of the fact that the mapping
|
||||
* is given in flow format.
|
||||
* Otherwise, we assume the first token is the first key of the mapping and
|
||||
* keep track of its indentation, but keep the token on the stream.
|
||||
* In both cases, the next token we expect is the first key of the mapping.
|
||||
*/
|
||||
int isl_stream_yaml_read_start_mapping(__isl_keep isl_stream *s)
|
||||
{
|
||||
struct isl_token *tok;
|
||||
int indent;
|
||||
|
||||
if (push_state(s, isl_yaml_mapping_key_start) < 0)
|
||||
return -1;
|
||||
|
||||
tok = isl_stream_next_token(s);
|
||||
if (!tok) {
|
||||
if (s->eof)
|
||||
isl_stream_error(s, NULL, "unexpected EOF");
|
||||
return -1;
|
||||
}
|
||||
if (isl_token_get_type(tok) == '{') {
|
||||
isl_token_free(tok);
|
||||
return set_yaml_indent(s, ISL_YAML_INDENT_FLOW);
|
||||
}
|
||||
indent = tok->col - 1;
|
||||
isl_stream_push_token(s, tok);
|
||||
|
||||
return set_yaml_indent(s, indent);
|
||||
}
|
||||
|
||||
/* Finish reading a YAML mapping.
|
||||
* Return 0 on success and -1 on error.
|
||||
*
|
||||
* If the mapping started with a '{', then we expect a '}' to close
|
||||
* the mapping.
|
||||
* Otherwise, we double-check that the next token (if any)
|
||||
* has a smaller indentation than that of the current mapping.
|
||||
*/
|
||||
int isl_stream_yaml_read_end_mapping(__isl_keep isl_stream *s)
|
||||
{
|
||||
struct isl_token *tok;
|
||||
int indent;
|
||||
|
||||
if (get_yaml_indent(s) == ISL_YAML_INDENT_FLOW) {
|
||||
if (isl_stream_eat(s, '}') < 0)
|
||||
return -1;
|
||||
return pop_state(s);
|
||||
}
|
||||
|
||||
tok = isl_stream_next_token(s);
|
||||
if (!tok)
|
||||
return pop_state(s);
|
||||
|
||||
indent = tok->col - 1;
|
||||
isl_stream_push_token(s, tok);
|
||||
|
||||
if (indent >= get_yaml_indent(s))
|
||||
isl_die(isl_stream_get_ctx(s), isl_error_invalid,
|
||||
"mapping not finished", return -1);
|
||||
|
||||
return pop_state(s);
|
||||
}
|
||||
|
||||
/* Start reading a YAML sequence.
|
||||
* Return 0 on success and -1 on error.
|
||||
*
|
||||
* If the first token on the stream is a '[' then we remove this token
|
||||
* from the stream and keep track of the fact that the sequence
|
||||
* is given in flow format.
|
||||
* Otherwise, we assume the first token is the dash that introduces
|
||||
* the first element of the sequence and keep track of its indentation,
|
||||
* but keep the token on the stream.
|
||||
* In both cases, the next token we expect is the first element
|
||||
* of the sequence.
|
||||
*/
|
||||
int isl_stream_yaml_read_start_sequence(__isl_keep isl_stream *s)
|
||||
{
|
||||
struct isl_token *tok;
|
||||
int indent;
|
||||
|
||||
if (push_state(s, isl_yaml_sequence_start) < 0)
|
||||
return -1;
|
||||
|
||||
tok = isl_stream_next_token(s);
|
||||
if (!tok) {
|
||||
if (s->eof)
|
||||
isl_stream_error(s, NULL, "unexpected EOF");
|
||||
return -1;
|
||||
}
|
||||
if (isl_token_get_type(tok) == '[') {
|
||||
isl_token_free(tok);
|
||||
return set_yaml_indent(s, ISL_YAML_INDENT_FLOW);
|
||||
}
|
||||
indent = tok->col - 1;
|
||||
isl_stream_push_token(s, tok);
|
||||
|
||||
return set_yaml_indent(s, indent);
|
||||
}
|
||||
|
||||
/* Finish reading a YAML sequence.
|
||||
* Return 0 on success and -1 on error.
|
||||
*
|
||||
* If the sequence started with a '[', then we expect a ']' to close
|
||||
* the sequence.
|
||||
* Otherwise, we double-check that the next token (if any)
|
||||
* is not a dash or that it has a smaller indentation than
|
||||
* that of the current sequence.
|
||||
*/
|
||||
int isl_stream_yaml_read_end_sequence(__isl_keep isl_stream *s)
|
||||
{
|
||||
struct isl_token *tok;
|
||||
int indent;
|
||||
int dash;
|
||||
|
||||
if (get_yaml_indent(s) == ISL_YAML_INDENT_FLOW) {
|
||||
if (isl_stream_eat(s, ']') < 0)
|
||||
return -1;
|
||||
return pop_state(s);
|
||||
}
|
||||
|
||||
tok = isl_stream_next_token(s);
|
||||
if (!tok)
|
||||
return pop_state(s);
|
||||
|
||||
indent = tok->col - 1;
|
||||
dash = tok->type == '-';
|
||||
isl_stream_push_token(s, tok);
|
||||
|
||||
if (indent >= get_yaml_indent(s) && dash)
|
||||
isl_die(isl_stream_get_ctx(s), isl_error_invalid,
|
||||
"sequence not finished", return -1);
|
||||
|
||||
return pop_state(s);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <isl_int.h>
|
||||
#include <isl/stream.h>
|
||||
#include <isl_yaml.h>
|
||||
|
||||
struct isl_token {
|
||||
int type;
|
||||
|
@ -19,3 +20,50 @@ struct isl_token {
|
|||
|
||||
struct isl_token *isl_token_new(isl_ctx *ctx,
|
||||
int line, int col, unsigned on_new_line);
|
||||
|
||||
/* An input stream that may be either a file or a string.
|
||||
*
|
||||
* line and col are the line and column number of the next character (1-based).
|
||||
* start_line and start_col are set by isl_stream_getc to point
|
||||
* to the position of the returned character.
|
||||
* last_line is the line number of the previous token.
|
||||
*
|
||||
* yaml_state and yaml_indent keep track of the currently active YAML
|
||||
* elements. yaml_size is the size of these arrays, while yaml_depth
|
||||
* is the number of elements currently in use.
|
||||
* yaml_state and yaml_indent may be NULL if no YAML parsing is being
|
||||
* performed.
|
||||
* yaml_state keeps track of what is expected next at each level.
|
||||
* yaml_indent keeps track of the indentation at each level, with
|
||||
* ISL_YAML_INDENT_FLOW meaning that the element is in flow format
|
||||
* (such that the indentation is not relevant).
|
||||
*/
|
||||
struct isl_stream {
|
||||
struct isl_ctx *ctx;
|
||||
FILE *file;
|
||||
const char *str;
|
||||
int line;
|
||||
int col;
|
||||
int start_line;
|
||||
int start_col;
|
||||
int last_line;
|
||||
int eof;
|
||||
|
||||
char *buffer;
|
||||
size_t size;
|
||||
size_t len;
|
||||
int c;
|
||||
int un[5];
|
||||
int n_un;
|
||||
|
||||
struct isl_token *tokens[5];
|
||||
int n_token;
|
||||
|
||||
struct isl_hash_table *keywords;
|
||||
enum isl_token_type next_type;
|
||||
|
||||
int yaml_depth;
|
||||
int yaml_size;
|
||||
enum isl_yaml_state *yaml_state;
|
||||
int *yaml_indent;
|
||||
};
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
/*
|
||||
* Copyright 2008-2009 Katholieke Universiteit Leuven
|
||||
* Copyright 2013 Ecole Normale Superieure
|
||||
* Copyright 2014 INRIA Rocquencourt
|
||||
*
|
||||
* Use of this software is governed by the MIT license
|
||||
*
|
||||
* Written by Sven Verdoolaege, K.U.Leuven, Departement
|
||||
* Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
|
||||
* and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
|
||||
* and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
|
||||
* B.P. 105 - 78153 Le Chesnay, France
|
||||
*/
|
||||
|
||||
#include <isl_ctx_private.h>
|
||||
|
@ -957,6 +960,22 @@ int isl_tab_mark_redundant(struct isl_tab *tab, int row)
|
|||
}
|
||||
}
|
||||
|
||||
/* Mark "tab" as a rational tableau.
|
||||
* If it wasn't marked as a rational tableau already and if we may
|
||||
* need to undo changes, then arrange for the marking to be undone
|
||||
* during the undo.
|
||||
*/
|
||||
int isl_tab_mark_rational(struct isl_tab *tab)
|
||||
{
|
||||
if (!tab)
|
||||
return -1;
|
||||
if (!tab->rational && tab->need_undo)
|
||||
if (isl_tab_push(tab, isl_tab_undo_rational) < 0)
|
||||
return -1;
|
||||
tab->rational = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int isl_tab_mark_empty(struct isl_tab *tab)
|
||||
{
|
||||
if (!tab)
|
||||
|
@ -1409,7 +1428,8 @@ static int row_at_most_neg_one(struct isl_tab *tab, int row)
|
|||
/* Return 1 if "var" can attain values <= -1.
|
||||
* Return 0 otherwise.
|
||||
*
|
||||
* The sample value of "var" is assumed to be non-negative when the
|
||||
* If the variable "var" is supposed to be non-negative (is_nonneg is set),
|
||||
* then the sample value of "var" is assumed to be non-negative when the
|
||||
* the function is called. If 1 is returned then the constraint
|
||||
* is not redundant and the sample value is made non-negative again before
|
||||
* the function returns.
|
||||
|
@ -1447,7 +1467,7 @@ int isl_tab_min_at_most_neg_one(struct isl_tab *tab, struct isl_tab_var *var)
|
|||
do {
|
||||
find_pivot(tab, var, var, -1, &row, &col);
|
||||
if (row == var->index) {
|
||||
if (restore_row(tab, var) < -1)
|
||||
if (var->is_nonneg && restore_row(tab, var) < -1)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
@ -1643,19 +1663,75 @@ int isl_tab_allocate_con(struct isl_tab *tab)
|
|||
return r;
|
||||
}
|
||||
|
||||
/* Add a variable to the tableau and allocate a column for it.
|
||||
* Return the index into the variable array "var".
|
||||
/* Move the entries in tab->var up one position, starting at "first",
|
||||
* creating room for an extra entry at position "first".
|
||||
* Since some of the entries of tab->row_var and tab->col_var contain
|
||||
* indices into this array, they have to be updated accordingly.
|
||||
*/
|
||||
int isl_tab_allocate_var(struct isl_tab *tab)
|
||||
static int var_insert_entry(struct isl_tab *tab, int first)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (tab->n_var >= tab->max_var)
|
||||
isl_die(isl_tab_get_ctx(tab), isl_error_internal,
|
||||
"not enough room for new variable", return -1);
|
||||
if (first > tab->n_var)
|
||||
isl_die(isl_tab_get_ctx(tab), isl_error_internal,
|
||||
"invalid initial position", return -1);
|
||||
|
||||
for (i = tab->n_var - 1; i >= first; --i) {
|
||||
tab->var[i + 1] = tab->var[i];
|
||||
if (tab->var[i + 1].is_row)
|
||||
tab->row_var[tab->var[i + 1].index]++;
|
||||
else
|
||||
tab->col_var[tab->var[i + 1].index]++;
|
||||
}
|
||||
|
||||
tab->n_var++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Drop the entry at position "first" in tab->var, moving all
|
||||
* subsequent entries down.
|
||||
* Since some of the entries of tab->row_var and tab->col_var contain
|
||||
* indices into this array, they have to be updated accordingly.
|
||||
*/
|
||||
static int var_drop_entry(struct isl_tab *tab, int first)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (first >= tab->n_var)
|
||||
isl_die(isl_tab_get_ctx(tab), isl_error_internal,
|
||||
"invalid initial position", return -1);
|
||||
|
||||
tab->n_var--;
|
||||
|
||||
for (i = first; i < tab->n_var; ++i) {
|
||||
tab->var[i] = tab->var[i + 1];
|
||||
if (tab->var[i + 1].is_row)
|
||||
tab->row_var[tab->var[i].index]--;
|
||||
else
|
||||
tab->col_var[tab->var[i].index]--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Add a variable to the tableau at position "r" and allocate a column for it.
|
||||
* Return the index into the variable array "var", i.e., "r",
|
||||
* or -1 on error.
|
||||
*/
|
||||
int isl_tab_insert_var(struct isl_tab *tab, int r)
|
||||
{
|
||||
int r;
|
||||
int i;
|
||||
unsigned off = 2 + tab->M;
|
||||
|
||||
isl_assert(tab->mat->ctx, tab->n_col < tab->mat->n_col, return -1);
|
||||
isl_assert(tab->mat->ctx, tab->n_var < tab->max_var, return -1);
|
||||
|
||||
r = tab->n_var;
|
||||
if (var_insert_entry(tab, r) < 0)
|
||||
return -1;
|
||||
|
||||
tab->var[r].index = tab->n_col;
|
||||
tab->var[r].is_row = 0;
|
||||
tab->var[r].is_nonneg = 0;
|
||||
|
@ -1668,7 +1744,6 @@ int isl_tab_allocate_var(struct isl_tab *tab)
|
|||
for (i = 0; i < tab->n_row; ++i)
|
||||
isl_int_set_si(tab->mat->row[i][off + tab->n_col], 0);
|
||||
|
||||
tab->n_var++;
|
||||
tab->n_col++;
|
||||
if (isl_tab_push_var(tab, isl_tab_undo_allocate, &tab->var[r]) < 0)
|
||||
return -1;
|
||||
|
@ -1676,6 +1751,17 @@ int isl_tab_allocate_var(struct isl_tab *tab)
|
|||
return r;
|
||||
}
|
||||
|
||||
/* Add a variable to the tableau and allocate a column for it.
|
||||
* Return the index into the variable array "var".
|
||||
*/
|
||||
int isl_tab_allocate_var(struct isl_tab *tab)
|
||||
{
|
||||
if (!tab)
|
||||
return -1;
|
||||
|
||||
return isl_tab_insert_var(tab, tab->n_var);
|
||||
}
|
||||
|
||||
/* Add a row to the tableau. The row is given as an affine combination
|
||||
* of the original variables and needs to be expressed in terms of the
|
||||
* column variables.
|
||||
|
@ -1753,13 +1839,22 @@ static int drop_row(struct isl_tab *tab, int row)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Drop the variable in column "col" along with the column.
|
||||
* The column is removed first because it may need to be moved
|
||||
* into the last position and this process requires
|
||||
* the contents of the col_var array in a state
|
||||
* before the removal of the variable.
|
||||
*/
|
||||
static int drop_col(struct isl_tab *tab, int col)
|
||||
{
|
||||
isl_assert(tab->mat->ctx, tab->col_var[col] == tab->n_var - 1, return -1);
|
||||
int var;
|
||||
|
||||
var = tab->col_var[col];
|
||||
if (col != tab->n_col - 1)
|
||||
swap_cols(tab, col, tab->n_col - 1);
|
||||
tab->n_col--;
|
||||
tab->n_var--;
|
||||
if (var_drop_entry(tab, var) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1982,12 +2077,9 @@ int isl_tab_add_eq(struct isl_tab *tab, isl_int *eq)
|
|||
var = &tab->con[r];
|
||||
row = var->index;
|
||||
if (row_is_manifestly_zero(tab, row)) {
|
||||
if (snap) {
|
||||
if (isl_tab_rollback(tab, snap) < 0)
|
||||
return -1;
|
||||
} else
|
||||
drop_row(tab, row);
|
||||
return 0;
|
||||
if (snap)
|
||||
return isl_tab_rollback(tab, snap);
|
||||
return drop_row(tab, row);
|
||||
}
|
||||
|
||||
if (tab->bmap) {
|
||||
|
@ -2545,37 +2637,37 @@ static int cut_to_hyperplane(struct isl_tab *tab, struct isl_tab_var *var)
|
|||
* even after the relaxation, so we need to restore it.
|
||||
* We therefore prefer to pivot a column up to a row, if possible.
|
||||
*/
|
||||
struct isl_tab *isl_tab_relax(struct isl_tab *tab, int con)
|
||||
int isl_tab_relax(struct isl_tab *tab, int con)
|
||||
{
|
||||
struct isl_tab_var *var;
|
||||
unsigned off = 2 + tab->M;
|
||||
|
||||
if (!tab)
|
||||
return NULL;
|
||||
return -1;
|
||||
|
||||
var = &tab->con[con];
|
||||
|
||||
if (var->is_row && (var->index < 0 || var->index < tab->n_redundant))
|
||||
isl_die(tab->mat->ctx, isl_error_invalid,
|
||||
"cannot relax redundant constraint", goto error);
|
||||
"cannot relax redundant constraint", return -1);
|
||||
if (!var->is_row && (var->index < 0 || var->index < tab->n_dead))
|
||||
isl_die(tab->mat->ctx, isl_error_invalid,
|
||||
"cannot relax dead constraint", goto error);
|
||||
"cannot relax dead constraint", return -1);
|
||||
|
||||
if (!var->is_row && !max_is_manifestly_unbounded(tab, var))
|
||||
if (to_row(tab, var, 1) < 0)
|
||||
goto error;
|
||||
return -1;
|
||||
if (!var->is_row && !min_is_manifestly_unbounded(tab, var))
|
||||
if (to_row(tab, var, -1) < 0)
|
||||
goto error;
|
||||
return -1;
|
||||
|
||||
if (var->is_row) {
|
||||
isl_int_add(tab->mat->row[var->index][1],
|
||||
tab->mat->row[var->index][1], tab->mat->row[var->index][0]);
|
||||
if (restore_row(tab, var) < 0)
|
||||
goto error;
|
||||
return -1;
|
||||
} else {
|
||||
int i;
|
||||
unsigned off = 2 + tab->M;
|
||||
|
||||
for (i = 0; i < tab->n_row; ++i) {
|
||||
if (isl_int_is_zero(tab->mat->row[i][off + var->index]))
|
||||
|
@ -2587,12 +2679,67 @@ struct isl_tab *isl_tab_relax(struct isl_tab *tab, int con)
|
|||
}
|
||||
|
||||
if (isl_tab_push_var(tab, isl_tab_undo_relax, var) < 0)
|
||||
goto error;
|
||||
return -1;
|
||||
|
||||
return tab;
|
||||
error:
|
||||
isl_tab_free(tab);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Replace the variable v at position "pos" in the tableau "tab"
|
||||
* by v' = v + shift.
|
||||
*
|
||||
* If the variable is in a column, then we first check if we can
|
||||
* simply plug in v = v' - shift. The effect on a row with
|
||||
* coefficient f/d for variable v is that the constant term c/d
|
||||
* is replaced by (c - f * shift)/d. If shift is positive and
|
||||
* f is negative for each row that needs to remain non-negative,
|
||||
* then this is clearly safe. In other words, if the minimum of v
|
||||
* is manifestly unbounded, then we can keep v in a column position.
|
||||
* Otherwise, we can pivot it down to a row.
|
||||
* Similarly, if shift is negative, we need to check if the maximum
|
||||
* of is manifestly unbounded.
|
||||
*
|
||||
* If the variable is in a row (from the start or after pivoting),
|
||||
* then the constant term c/d is replaced by (c + d * shift)/d.
|
||||
*/
|
||||
int isl_tab_shift_var(struct isl_tab *tab, int pos, isl_int shift)
|
||||
{
|
||||
struct isl_tab_var *var;
|
||||
|
||||
if (!tab)
|
||||
return -1;
|
||||
if (isl_int_is_zero(shift))
|
||||
return 0;
|
||||
|
||||
var = &tab->var[pos];
|
||||
if (!var->is_row) {
|
||||
if (isl_int_is_neg(shift)) {
|
||||
if (!max_is_manifestly_unbounded(tab, var))
|
||||
if (to_row(tab, var, 1) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
if (!min_is_manifestly_unbounded(tab, var))
|
||||
if (to_row(tab, var, -1) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (var->is_row) {
|
||||
isl_int_addmul(tab->mat->row[var->index][1],
|
||||
shift, tab->mat->row[var->index][0]);
|
||||
} else {
|
||||
int i;
|
||||
unsigned off = 2 + tab->M;
|
||||
|
||||
for (i = 0; i < tab->n_row; ++i) {
|
||||
if (isl_int_is_zero(tab->mat->row[i][off + var->index]))
|
||||
continue;
|
||||
isl_int_submul(tab->mat->row[i][1],
|
||||
shift, tab->mat->row[i][off + var->index]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove the sign constraint from constraint "con".
|
||||
|
@ -3014,10 +3161,21 @@ enum isl_lp_result isl_tab_min(struct isl_tab *tab,
|
|||
return res;
|
||||
}
|
||||
|
||||
/* Is the constraint at position "con" marked as being redundant?
|
||||
* If it is marked as representing an equality, then it is not
|
||||
* considered to be redundant.
|
||||
* Note that isl_tab_mark_redundant marks both the isl_tab_var as
|
||||
* redundant and moves the corresponding row into the first
|
||||
* tab->n_redundant positions (or removes the row, assigning it index -1),
|
||||
* so the final test is actually redundant itself.
|
||||
*/
|
||||
int isl_tab_is_redundant(struct isl_tab *tab, int con)
|
||||
{
|
||||
if (!tab)
|
||||
return -1;
|
||||
if (con < 0 || con >= tab->n_con)
|
||||
isl_die(isl_tab_get_ctx(tab), isl_error_invalid,
|
||||
"position out of bounds", return -1);
|
||||
if (tab->con[con].is_zero)
|
||||
return 0;
|
||||
if (tab->con[con].is_redundant)
|
||||
|
@ -3108,8 +3266,7 @@ static int perform_undo_var(struct isl_tab *tab, struct isl_tab_undo *undo)
|
|||
case isl_tab_undo_allocate:
|
||||
if (undo->u.var_index >= 0) {
|
||||
isl_assert(tab->mat->ctx, !var->is_row, return -1);
|
||||
drop_col(tab, var->index);
|
||||
break;
|
||||
return drop_col(tab, var->index);
|
||||
}
|
||||
if (!var->is_row) {
|
||||
if (!max_is_manifestly_unbounded(tab, var)) {
|
||||
|
@ -3122,8 +3279,7 @@ static int perform_undo_var(struct isl_tab *tab, struct isl_tab_undo *undo)
|
|||
if (to_row(tab, var, 0) < 0)
|
||||
return -1;
|
||||
}
|
||||
drop_row(tab, var->index);
|
||||
break;
|
||||
return drop_row(tab, var->index);
|
||||
case isl_tab_undo_relax:
|
||||
return unrelax(tab, var);
|
||||
case isl_tab_undo_unrestrict:
|
||||
|
@ -3219,6 +3375,9 @@ static int perform_undo(struct isl_tab *tab, struct isl_tab_undo *undo) WARN_UNU
|
|||
static int perform_undo(struct isl_tab *tab, struct isl_tab_undo *undo)
|
||||
{
|
||||
switch (undo->type) {
|
||||
case isl_tab_undo_rational:
|
||||
tab->rational = 0;
|
||||
break;
|
||||
case isl_tab_undo_empty:
|
||||
tab->empty = 0;
|
||||
break;
|
||||
|
|
|
@ -29,6 +29,7 @@ struct isl_tab_var {
|
|||
|
||||
enum isl_tab_undo_type {
|
||||
isl_tab_undo_bottom,
|
||||
isl_tab_undo_rational,
|
||||
isl_tab_undo_empty,
|
||||
isl_tab_undo_nonneg,
|
||||
isl_tab_undo_redundant,
|
||||
|
@ -235,7 +236,7 @@ enum isl_ineq_type isl_tab_ineq_type(struct isl_tab *tab, isl_int *ineq);
|
|||
struct isl_tab_undo *isl_tab_snap(struct isl_tab *tab);
|
||||
int isl_tab_rollback(struct isl_tab *tab, struct isl_tab_undo *snap) WARN_UNUSED;
|
||||
|
||||
struct isl_tab *isl_tab_relax(struct isl_tab *tab, int con) WARN_UNUSED;
|
||||
int isl_tab_relax(struct isl_tab *tab, int con) WARN_UNUSED;
|
||||
int isl_tab_select_facet(struct isl_tab *tab, int con) WARN_UNUSED;
|
||||
int isl_tab_unrestrict(struct isl_tab *tab, int con) WARN_UNUSED;
|
||||
|
||||
|
@ -267,6 +268,7 @@ __isl_give isl_vec *isl_tab_basic_set_non_neg_lexmin(
|
|||
|
||||
struct isl_tab_var *isl_tab_var_from_row(struct isl_tab *tab, int i);
|
||||
int isl_tab_mark_redundant(struct isl_tab *tab, int row) WARN_UNUSED;
|
||||
int isl_tab_mark_rational(struct isl_tab *tab) WARN_UNUSED;
|
||||
int isl_tab_mark_empty(struct isl_tab *tab) WARN_UNUSED;
|
||||
struct isl_tab *isl_tab_dup(struct isl_tab *tab);
|
||||
struct isl_tab *isl_tab_product(struct isl_tab *tab1, struct isl_tab *tab2);
|
||||
|
@ -274,6 +276,7 @@ int isl_tab_extend_cons(struct isl_tab *tab, unsigned n_new) WARN_UNUSED;
|
|||
int isl_tab_allocate_con(struct isl_tab *tab) WARN_UNUSED;
|
||||
int isl_tab_extend_vars(struct isl_tab *tab, unsigned n_new) WARN_UNUSED;
|
||||
int isl_tab_allocate_var(struct isl_tab *tab) WARN_UNUSED;
|
||||
int isl_tab_insert_var(struct isl_tab *tab, int pos) WARN_UNUSED;
|
||||
int isl_tab_pivot(struct isl_tab *tab, int row, int col) WARN_UNUSED;
|
||||
int isl_tab_add_row(struct isl_tab *tab, isl_int *line) WARN_UNUSED;
|
||||
int isl_tab_row_is_redundant(struct isl_tab *tab, int row);
|
||||
|
@ -301,4 +304,6 @@ int isl_tab_push_callback(struct isl_tab *tab,
|
|||
int isl_tab_add_div(struct isl_tab *tab, __isl_keep isl_vec *div,
|
||||
int (*add_ineq)(void *user, isl_int *), void *user);
|
||||
|
||||
int isl_tab_shift_var(struct isl_tab *tab, int pos, isl_int shift) WARN_UNUSED;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <isl/union_map.h>
|
||||
#include <isl_factorization.h>
|
||||
#include <isl/schedule.h>
|
||||
#include <isl/schedule_node.h>
|
||||
#include <isl_options_private.h>
|
||||
#include <isl/vertices.h>
|
||||
#include <isl/ast_build.h>
|
||||
|
@ -104,11 +105,30 @@ static void test_parse_pwaff(isl_ctx *ctx, const char *str)
|
|||
isl_pw_aff_free(pwaff);
|
||||
}
|
||||
|
||||
/* Check that we can read an isl_multi_val from "str" without errors.
|
||||
*/
|
||||
static int test_parse_multi_val(isl_ctx *ctx, const char *str)
|
||||
{
|
||||
isl_multi_val *mv;
|
||||
|
||||
mv = isl_multi_val_read_from_str(ctx, str);
|
||||
isl_multi_val_free(mv);
|
||||
|
||||
return mv ? 0 : -1;
|
||||
}
|
||||
|
||||
int test_parse(struct isl_ctx *ctx)
|
||||
{
|
||||
isl_map *map, *map2;
|
||||
const char *str, *str2;
|
||||
|
||||
if (test_parse_multi_val(ctx, "{ A[B[2] -> C[5, 7]] }") < 0)
|
||||
return -1;
|
||||
if (test_parse_multi_val(ctx, "[n] -> { [2] }") < 0)
|
||||
return -1;
|
||||
if (test_parse_multi_val(ctx, "{ A[4, infty, NaN, -1/2, 2/3] }") < 0)
|
||||
return -1;
|
||||
|
||||
str = "{ [i] -> [-i] }";
|
||||
map = isl_map_read_from_str(ctx, str);
|
||||
assert(map);
|
||||
|
@ -1167,6 +1187,12 @@ struct {
|
|||
{ "{ : 1 = 0 }", "{ : 1 = 0 }", "{ : }" },
|
||||
{ "[M] -> { [x] : exists (e0 = floor((-2 + x)/3): 3e0 = -2 + x) }",
|
||||
"[M] -> { [3M] }" , "[M] -> { [x] : 1 = 0 }" },
|
||||
{ "{ [m, n, a, b] : a <= 2147 + n }",
|
||||
"{ [m, n, a, b] : (m >= 1 and n >= 1 and a <= 2148 - m and "
|
||||
"b <= 2148 - n and b >= 0 and b >= 2149 - n - a) or "
|
||||
"(n >= 1 and a >= 0 and b <= 2148 - n - a and "
|
||||
"b >= 0) }",
|
||||
"{ [m, n, ku, kl] }" },
|
||||
};
|
||||
|
||||
static int test_gist(struct isl_ctx *ctx)
|
||||
|
@ -1179,20 +1205,20 @@ static int test_gist(struct isl_ctx *ctx)
|
|||
|
||||
for (i = 0; i < ARRAY_SIZE(gist_tests); ++i) {
|
||||
int equal_input;
|
||||
isl_basic_set *copy;
|
||||
isl_set *set1, *set2, *copy;
|
||||
|
||||
bset1 = isl_basic_set_read_from_str(ctx, gist_tests[i].set);
|
||||
bset2 = isl_basic_set_read_from_str(ctx, gist_tests[i].context);
|
||||
copy = isl_basic_set_copy(bset1);
|
||||
bset1 = isl_basic_set_gist(bset1, bset2);
|
||||
bset2 = isl_basic_set_read_from_str(ctx, gist_tests[i].gist);
|
||||
equal = isl_basic_set_is_equal(bset1, bset2);
|
||||
isl_basic_set_free(bset1);
|
||||
isl_basic_set_free(bset2);
|
||||
bset1 = isl_basic_set_read_from_str(ctx, gist_tests[i].set);
|
||||
equal_input = isl_basic_set_is_equal(bset1, copy);
|
||||
isl_basic_set_free(bset1);
|
||||
isl_basic_set_free(copy);
|
||||
set1 = isl_set_read_from_str(ctx, gist_tests[i].set);
|
||||
set2 = isl_set_read_from_str(ctx, gist_tests[i].context);
|
||||
copy = isl_set_copy(set1);
|
||||
set1 = isl_set_gist(set1, set2);
|
||||
set2 = isl_set_read_from_str(ctx, gist_tests[i].gist);
|
||||
equal = isl_set_is_equal(set1, set2);
|
||||
isl_set_free(set1);
|
||||
isl_set_free(set2);
|
||||
set1 = isl_set_read_from_str(ctx, gist_tests[i].set);
|
||||
equal_input = isl_set_is_equal(set1, copy);
|
||||
isl_set_free(set1);
|
||||
isl_set_free(copy);
|
||||
if (equal < 0 || equal_input < 0)
|
||||
return -1;
|
||||
if (!equal)
|
||||
|
@ -1281,31 +1307,45 @@ int test_coalesce_set(isl_ctx *ctx, const char *str, int check_one)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Inputs for coalescing tests with unbounded wrapping.
|
||||
* "str" is a string representation of the input set.
|
||||
* "single_disjunct" is set if we expect the result to consist of
|
||||
* a single disjunct.
|
||||
*/
|
||||
struct {
|
||||
int single_disjunct;
|
||||
const char *str;
|
||||
} coalesce_unbounded_tests[] = {
|
||||
{ 1, "{ [x,y,z] : y + 2 >= 0 and x - y + 1 >= 0 and "
|
||||
"-x - y + 1 >= 0 and -3 <= z <= 3;"
|
||||
"[x,y,z] : -x+z + 20 >= 0 and -x-z + 20 >= 0 and "
|
||||
"x-z + 20 >= 0 and x+z + 20 >= 0 and "
|
||||
"-10 <= y <= 0}" },
|
||||
{ 1, "{ [x,y] : 0 <= x,y <= 10; [5,y]: 4 <= y <= 11 }" },
|
||||
{ 1, "{ [x,0,0] : -5 <= x <= 5; [0,y,1] : -5 <= y <= 5 }" },
|
||||
{ 1, "{ [x,y] : 0 <= x <= 10 and 0 >= y >= -1 and x+y >= 0; [0,1] }" },
|
||||
{ 1, "{ [x,y] : (0 <= x,y <= 4) or (2 <= x,y <= 5 and x + y <= 9) }" },
|
||||
};
|
||||
|
||||
/* Test the functionality of isl_set_coalesce with the bounded wrapping
|
||||
* option turned off.
|
||||
*/
|
||||
int test_coalesce_unbounded_wrapping(isl_ctx *ctx)
|
||||
{
|
||||
int i;
|
||||
int r = 0;
|
||||
int bounded;
|
||||
|
||||
bounded = isl_options_get_coalesce_bounded_wrapping(ctx);
|
||||
isl_options_set_coalesce_bounded_wrapping(ctx, 0);
|
||||
|
||||
if (test_coalesce_set(ctx,
|
||||
"{[x,y,z] : y + 2 >= 0 and x - y + 1 >= 0 and "
|
||||
"-x - y + 1 >= 0 and -3 <= z <= 3;"
|
||||
"[x,y,z] : -x+z + 20 >= 0 and -x-z + 20 >= 0 and "
|
||||
"x-z + 20 >= 0 and x+z + 20 >= 0 and "
|
||||
"-10 <= y <= 0}", 1) < 0)
|
||||
goto error;
|
||||
if (test_coalesce_set(ctx,
|
||||
"{[x,y] : 0 <= x,y <= 10; [5,y]: 4 <=y <= 11}", 1) < 0)
|
||||
goto error;
|
||||
if (test_coalesce_set(ctx,
|
||||
"{[x,0,0] : -5 <= x <= 5; [0,y,1] : -5 <= y <= 5 }", 1) < 0)
|
||||
goto error;
|
||||
|
||||
if (0) {
|
||||
error:
|
||||
for (i = 0; i < ARRAY_SIZE(coalesce_unbounded_tests); ++i) {
|
||||
const char *str = coalesce_unbounded_tests[i].str;
|
||||
int check_one = coalesce_unbounded_tests[i].single_disjunct;
|
||||
if (test_coalesce_set(ctx, str, check_one) >= 0)
|
||||
continue;
|
||||
r = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
isl_options_set_coalesce_bounded_wrapping(ctx, bounded);
|
||||
|
@ -1431,11 +1471,106 @@ struct {
|
|||
"[x,0] : 3 <= x <= 5 }" },
|
||||
{ 0, "{ [x,y] : 0 <= x <= 2 and y >= 0 and x + y <= 4; "
|
||||
"[x,0] : 3 <= x <= 4 }" },
|
||||
{ 1 , "{ [i0, i1] : i0 <= 122 and i0 >= 1 and 128i1 >= -249 + i0 and "
|
||||
{ 1, "{ [i0, i1] : i0 <= 122 and i0 >= 1 and 128i1 >= -249 + i0 and "
|
||||
"i1 <= 0; "
|
||||
"[i0, 0] : i0 >= 123 and i0 <= 124 }" },
|
||||
{ 1, "{ [0,0]; [1,1] }" },
|
||||
{ 1, "[n] -> { [k] : 16k <= -1 + n and k >= 1; [0] : n >= 2 }" },
|
||||
{ 1, "{ [k, ii, k - ii] : ii >= -6 + k and ii <= 6 and ii >= 1 and "
|
||||
"ii <= k;"
|
||||
"[k, 0, k] : k <= 6 and k >= 1 }" },
|
||||
{ 1, "{ [i,j] : i = 4 j and 0 <= i <= 100;"
|
||||
"[i,j] : 1 <= i <= 100 and i >= 4j + 1 and i <= 4j + 2 }" },
|
||||
{ 1, "{ [x,y] : x % 2 = 0 and y % 2 = 0; [x,x] : x % 2 = 0 }" },
|
||||
{ 1, "[n] -> { [1] : n >= 0;"
|
||||
"[x] : exists (e0 = floor((x)/2): x >= 2 and "
|
||||
"2e0 >= -1 + x and 2e0 <= x and 2e0 <= n) }" },
|
||||
{ 1, "[n] -> { [x, y] : exists (e0 = floor((x)/2), e1 = floor((y)/3): "
|
||||
"3e1 = y and x >= 2 and 2e0 >= -1 + x and "
|
||||
"2e0 <= x and 2e0 <= n);"
|
||||
"[1, y] : exists (e0 = floor((y)/3): 3e0 = y and "
|
||||
"n >= 0) }" },
|
||||
{ 1, "[t1] -> { [i0] : (exists (e0 = floor((63t1)/64): "
|
||||
"128e0 >= -134 + 127t1 and t1 >= 2 and "
|
||||
"64e0 <= 63t1 and 64e0 >= -63 + 63t1)) or "
|
||||
"t1 = 1 }" },
|
||||
{ 1, "{ [i, i] : exists (e0 = floor((1 + 2i)/3): 3e0 <= 2i and "
|
||||
"3e0 >= -1 + 2i and i <= 9 and i >= 1);"
|
||||
"[0, 0] }" },
|
||||
{ 1, "{ [t1] : exists (e0 = floor((-11 + t1)/2): 2e0 = -11 + t1 and "
|
||||
"t1 >= 13 and t1 <= 16);"
|
||||
"[t1] : t1 <= 15 and t1 >= 12 }" },
|
||||
{ 1, "{ [x,y] : x = 3y and 0 <= y <= 2; [-3,-1] }" },
|
||||
{ 1, "{ [x,y] : 2x = 3y and 0 <= y <= 4; [-3,-2] }" },
|
||||
{ 0, "{ [x,y] : 2x = 3y and 0 <= y <= 4; [-2,-2] }" },
|
||||
{ 0, "{ [x,y] : 2x = 3y and 0 <= y <= 4; [-3,-1] }" },
|
||||
{ 1, "{ [i] : exists j : i = 4 j and 0 <= i <= 100;"
|
||||
"[i] : exists j : 1 <= i <= 100 and i >= 4j + 1 and "
|
||||
"i <= 4j + 2 }" },
|
||||
{ 1, "{ [c0] : (exists (e0 : c0 - 1 <= 3e0 <= c0)) or "
|
||||
"(exists (e0 : 3e0 = -2 + c0)) }" },
|
||||
{ 0, "[n, b0, t0] -> "
|
||||
"{ [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12] : "
|
||||
"(exists (e0 = floor((-32b0 + i4)/1048576), "
|
||||
"e1 = floor((i8)/32): 1048576e0 = -32b0 + i4 and 32e1 = i8 and "
|
||||
"n <= 2147483647 and b0 <= 32767 and b0 >= 0 and "
|
||||
"32b0 <= -2 + n and t0 <= 31 and t0 >= 0 and i0 >= 8 + n and "
|
||||
"3i4 <= -96 + 3t0 + i0 and 3i4 >= -95 - n + 3t0 + i0 and "
|
||||
"i8 >= -157 + i0 - 4i4 and i8 >= 0 and "
|
||||
"i8 <= -33 + i0 - 4i4 and 3i8 <= -91 + 4n - i0)) or "
|
||||
"(exists (e0 = floor((-32b0 + i4)/1048576), "
|
||||
"e1 = floor((i8)/32): 1048576e0 = -32b0 + i4 and 32e1 = i8 and "
|
||||
"n <= 2147483647 and b0 <= 32767 and b0 >= 0 and "
|
||||
"32b0 <= -2 + n and t0 <= 31 and t0 >= 0 and i0 <= 7 + n and "
|
||||
"4i4 <= -3 + i0 and 3i4 <= -96 + 3t0 + i0 and "
|
||||
"3i4 >= -95 - n + 3t0 + i0 and i8 >= -157 + i0 - 4i4 and "
|
||||
"i8 >= 0 and i8 <= -4 + i0 - 3i4 and i8 <= -41 + i0));"
|
||||
"[i0, i1, i2, i3, 0, i5, i6, i7, i8, i9, i10, i11, i12] : "
|
||||
"(exists (e0 = floor((i8)/32): b0 = 0 and 32e0 = i8 and "
|
||||
"n <= 2147483647 and t0 <= 31 and t0 >= 0 and i0 >= 11 and "
|
||||
"i0 >= 96 - 3t0 and i0 <= 95 + n - 3t0 and i0 <= 7 + n and "
|
||||
"i8 >= -40 + i0 and i8 <= -10 + i0)) }" },
|
||||
};
|
||||
|
||||
/* A specialized coalescing test case that would result
|
||||
* in a segmentation fault or a failed assertion in earlier versions of isl.
|
||||
*/
|
||||
static int test_coalesce_special(struct isl_ctx *ctx)
|
||||
{
|
||||
const char *str;
|
||||
isl_map *map1, *map2;
|
||||
|
||||
str = "[y] -> { [S_L220_OUT[] -> T7[]] -> "
|
||||
"[[S_L309_IN[] -> T11[]] -> ce_imag2[1, o1]] : "
|
||||
"(y = 201 and o1 <= 239 and o1 >= 212) or "
|
||||
"(exists (e0 = [(y)/3]: 3e0 = y and y <= 198 and y >= 3 and "
|
||||
"o1 <= 239 and o1 >= 212)) or "
|
||||
"(exists (e0 = [(y)/3]: 3e0 = y and y <= 201 and y >= 3 and "
|
||||
"o1 <= 241 and o1 >= 240));"
|
||||
"[S_L220_OUT[] -> T7[]] -> "
|
||||
"[[S_L309_IN[] -> T11[]] -> ce_imag2[0, o1]] : "
|
||||
"(y = 2 and o1 <= 241 and o1 >= 212) or "
|
||||
"(exists (e0 = [(-2 + y)/3]: 3e0 = -2 + y and y <= 200 and "
|
||||
"y >= 5 and o1 <= 241 and o1 >= 212)) }";
|
||||
map1 = isl_map_read_from_str(ctx, str);
|
||||
map1 = isl_map_align_divs(map1);
|
||||
map1 = isl_map_coalesce(map1);
|
||||
str = "[y] -> { [S_L220_OUT[] -> T7[]] -> "
|
||||
"[[S_L309_IN[] -> T11[]] -> ce_imag2[o0, o1]] : "
|
||||
"exists (e0 = [(-1 - y + o0)/3]: 3e0 = -1 - y + o0 and "
|
||||
"y <= 201 and o0 <= 2 and o1 >= 212 and o1 <= 241 and "
|
||||
"o0 >= 3 - y and o0 <= -2 + y and o0 >= 0) }";
|
||||
map2 = isl_map_read_from_str(ctx, str);
|
||||
map2 = isl_map_union(map2, map1);
|
||||
map2 = isl_map_align_divs(map2);
|
||||
map2 = isl_map_coalesce(map2);
|
||||
isl_map_free(map2);
|
||||
if (!map2)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Test the functionality of isl_set_coalesce.
|
||||
* That is, check that the output is always equal to the input
|
||||
* and in some cases that the result consists of a single disjunct.
|
||||
|
@ -1453,6 +1588,8 @@ static int test_coalesce(struct isl_ctx *ctx)
|
|||
|
||||
if (test_coalesce_unbounded_wrapping(ctx) < 0)
|
||||
return -1;
|
||||
if (test_coalesce_special(ctx) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2461,6 +2598,7 @@ static int test_subtract(isl_ctx *ctx)
|
|||
{
|
||||
int i;
|
||||
isl_union_map *umap1, *umap2;
|
||||
isl_union_pw_multi_aff *upma1, *upma2;
|
||||
isl_union_set *uset;
|
||||
int equal;
|
||||
|
||||
|
@ -2482,6 +2620,24 @@ static int test_subtract(isl_ctx *ctx)
|
|||
"incorrect subtract domain result", return -1);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(subtract_domain_tests); ++i) {
|
||||
upma1 = isl_union_pw_multi_aff_read_from_str(ctx,
|
||||
subtract_domain_tests[i].minuend);
|
||||
uset = isl_union_set_read_from_str(ctx,
|
||||
subtract_domain_tests[i].subtrahend);
|
||||
upma2 = isl_union_pw_multi_aff_read_from_str(ctx,
|
||||
subtract_domain_tests[i].difference);
|
||||
upma1 = isl_union_pw_multi_aff_subtract_domain(upma1, uset);
|
||||
equal = isl_union_pw_multi_aff_plain_is_equal(upma1, upma2);
|
||||
isl_union_pw_multi_aff_free(upma1);
|
||||
isl_union_pw_multi_aff_free(upma2);
|
||||
if (equal < 0)
|
||||
return -1;
|
||||
if (!equal)
|
||||
isl_die(ctx, isl_error_unknown,
|
||||
"incorrect subtract domain result", return -1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2857,7 +3013,7 @@ struct {
|
|||
};
|
||||
|
||||
/* Test schedule construction based on conditional constraints.
|
||||
* In particular, check the number of members in the outer band
|
||||
* In particular, check the number of members in the outer band node
|
||||
* as an indication of whether tiling is possible or not.
|
||||
*/
|
||||
static int test_conditional_schedule_constraints(isl_ctx *ctx)
|
||||
|
@ -2869,8 +3025,7 @@ static int test_conditional_schedule_constraints(isl_ctx *ctx)
|
|||
isl_union_map *validity;
|
||||
isl_schedule_constraints *sc;
|
||||
isl_schedule *schedule;
|
||||
isl_band_list *list;
|
||||
isl_band *band;
|
||||
isl_schedule_node *node;
|
||||
int n_member;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(live_range_tests); ++i) {
|
||||
|
@ -2889,11 +3044,12 @@ static int test_conditional_schedule_constraints(isl_ctx *ctx)
|
|||
sc = isl_schedule_constraints_set_conditional_validity(sc,
|
||||
condition, validity);
|
||||
schedule = isl_schedule_constraints_compute_schedule(sc);
|
||||
list = isl_schedule_get_band_forest(schedule);
|
||||
band = isl_band_list_get_band(list, 0);
|
||||
n_member = isl_band_n_member(band);
|
||||
isl_band_free(band);
|
||||
isl_band_list_free(list);
|
||||
node = isl_schedule_get_root(schedule);
|
||||
while (node &&
|
||||
isl_schedule_node_get_type(node) != isl_schedule_node_band)
|
||||
node = isl_schedule_node_first_child(node);
|
||||
n_member = isl_schedule_node_band_n_member(node);
|
||||
isl_schedule_node_free(node);
|
||||
isl_schedule_free(schedule);
|
||||
|
||||
if (!schedule)
|
||||
|
@ -5084,6 +5240,112 @@ static int test_dual(isl_ctx *ctx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct {
|
||||
int scale_tile;
|
||||
int shift_point;
|
||||
const char *domain;
|
||||
const char *schedule;
|
||||
const char *sizes;
|
||||
const char *tile;
|
||||
const char *point;
|
||||
} tile_tests[] = {
|
||||
{ 0, 0, "[n] -> { S[i,j] : 0 <= i,j < n }",
|
||||
"[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]",
|
||||
"{ [32,32] }",
|
||||
"[{ S[i,j] -> [floor(i/32)] }, { S[i,j] -> [floor(j/32)] }]",
|
||||
"[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]",
|
||||
},
|
||||
{ 1, 0, "[n] -> { S[i,j] : 0 <= i,j < n }",
|
||||
"[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]",
|
||||
"{ [32,32] }",
|
||||
"[{ S[i,j] -> [32*floor(i/32)] }, { S[i,j] -> [32*floor(j/32)] }]",
|
||||
"[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]",
|
||||
},
|
||||
{ 0, 1, "[n] -> { S[i,j] : 0 <= i,j < n }",
|
||||
"[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]",
|
||||
"{ [32,32] }",
|
||||
"[{ S[i,j] -> [floor(i/32)] }, { S[i,j] -> [floor(j/32)] }]",
|
||||
"[{ S[i,j] -> [i%32] }, { S[i,j] -> [j%32] }]",
|
||||
},
|
||||
{ 1, 1, "[n] -> { S[i,j] : 0 <= i,j < n }",
|
||||
"[{ S[i,j] -> [i] }, { S[i,j] -> [j] }]",
|
||||
"{ [32,32] }",
|
||||
"[{ S[i,j] -> [32*floor(i/32)] }, { S[i,j] -> [32*floor(j/32)] }]",
|
||||
"[{ S[i,j] -> [i%32] }, { S[i,j] -> [j%32] }]",
|
||||
},
|
||||
};
|
||||
|
||||
/* Basic tiling tests. Create a schedule tree with a domain and a band node,
|
||||
* tile the band and then check if the tile and point bands have the
|
||||
* expected partial schedule.
|
||||
*/
|
||||
static int test_tile(isl_ctx *ctx)
|
||||
{
|
||||
int i;
|
||||
int scale;
|
||||
int shift;
|
||||
|
||||
scale = isl_options_get_tile_scale_tile_loops(ctx);
|
||||
shift = isl_options_get_tile_shift_point_loops(ctx);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tile_tests); ++i) {
|
||||
int opt;
|
||||
int equal;
|
||||
const char *str;
|
||||
isl_union_set *domain;
|
||||
isl_multi_union_pw_aff *mupa, *mupa2;
|
||||
isl_schedule_node *node;
|
||||
isl_multi_val *sizes;
|
||||
|
||||
opt = tile_tests[i].scale_tile;
|
||||
isl_options_set_tile_scale_tile_loops(ctx, opt);
|
||||
opt = tile_tests[i].shift_point;
|
||||
isl_options_set_tile_shift_point_loops(ctx, opt);
|
||||
|
||||
str = tile_tests[i].domain;
|
||||
domain = isl_union_set_read_from_str(ctx, str);
|
||||
node = isl_schedule_node_from_domain(domain);
|
||||
node = isl_schedule_node_child(node, 0);
|
||||
str = tile_tests[i].schedule;
|
||||
mupa = isl_multi_union_pw_aff_read_from_str(ctx, str);
|
||||
node = isl_schedule_node_insert_partial_schedule(node, mupa);
|
||||
str = tile_tests[i].sizes;
|
||||
sizes = isl_multi_val_read_from_str(ctx, str);
|
||||
node = isl_schedule_node_band_tile(node, sizes);
|
||||
|
||||
str = tile_tests[i].tile;
|
||||
mupa = isl_multi_union_pw_aff_read_from_str(ctx, str);
|
||||
mupa2 = isl_schedule_node_band_get_partial_schedule(node);
|
||||
equal = isl_multi_union_pw_aff_plain_is_equal(mupa, mupa2);
|
||||
isl_multi_union_pw_aff_free(mupa);
|
||||
isl_multi_union_pw_aff_free(mupa2);
|
||||
|
||||
node = isl_schedule_node_child(node, 0);
|
||||
|
||||
str = tile_tests[i].point;
|
||||
mupa = isl_multi_union_pw_aff_read_from_str(ctx, str);
|
||||
mupa2 = isl_schedule_node_band_get_partial_schedule(node);
|
||||
if (equal >= 0 && equal)
|
||||
equal = isl_multi_union_pw_aff_plain_is_equal(mupa,
|
||||
mupa2);
|
||||
isl_multi_union_pw_aff_free(mupa);
|
||||
isl_multi_union_pw_aff_free(mupa2);
|
||||
|
||||
isl_schedule_node_free(node);
|
||||
|
||||
if (equal < 0)
|
||||
return -1;
|
||||
if (!equal)
|
||||
isl_die(ctx, isl_error_unknown,
|
||||
"unexpected result", return -1);
|
||||
}
|
||||
|
||||
isl_options_set_tile_scale_tile_loops(ctx, scale);
|
||||
isl_options_set_tile_shift_point_loops(ctx, shift);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct {
|
||||
const char *name;
|
||||
int (*fn)(isl_ctx *ctx);
|
||||
|
@ -5121,6 +5383,7 @@ struct {
|
|||
{ "affine", &test_aff },
|
||||
{ "injective", &test_injective },
|
||||
{ "schedule", &test_schedule },
|
||||
{ "tile", &test_tile },
|
||||
{ "union_pw", &test_union_pw },
|
||||
{ "parse", &test_parse },
|
||||
{ "single-valued", &test_sv },
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
|
||||
#define ISL_DIM_H
|
||||
#include <isl_map_private.h>
|
||||
#include <isl_union_map_private.h>
|
||||
#include <isl/ctx.h>
|
||||
#include <isl/hash.h>
|
||||
#include <isl/aff.h>
|
||||
#include <isl/map.h>
|
||||
#include <isl/set.h>
|
||||
#include <isl_space_private.h>
|
||||
#include <isl_union_map_private.h>
|
||||
#include <isl/union_set.h>
|
||||
#include <isl/deprecated/union_map_int.h>
|
||||
|
||||
|
@ -705,10 +705,28 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Intersect "umap" with the parameter domain "set".
|
||||
*
|
||||
* If "set" does not have any constraints, then we can return immediately.
|
||||
*/
|
||||
__isl_give isl_union_map *isl_union_map_intersect_params(
|
||||
__isl_take isl_union_map *umap, __isl_take isl_set *set)
|
||||
{
|
||||
int is_universe;
|
||||
|
||||
is_universe = isl_set_plain_is_universe(set);
|
||||
if (is_universe < 0)
|
||||
goto error;
|
||||
if (is_universe) {
|
||||
isl_set_free(set);
|
||||
return umap;
|
||||
}
|
||||
|
||||
return gen_bin_set_op(umap, set, &intersect_params_entry);
|
||||
error:
|
||||
isl_union_map_free(umap);
|
||||
isl_set_free(set);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__isl_give isl_union_set *isl_union_set_intersect_params(
|
||||
|
@ -1421,6 +1439,34 @@ __isl_give isl_union_map *isl_union_map_range_product(
|
|||
return bin_op(umap1, umap2, &range_product_entry);
|
||||
}
|
||||
|
||||
/* If data->map A -> B and "map2" C -> D have the same range space,
|
||||
* then add (A, C) -> (B * D) to data->res.
|
||||
*/
|
||||
static int flat_domain_product_entry(void **entry, void *user)
|
||||
{
|
||||
struct isl_union_map_bin_data *data = user;
|
||||
isl_map *map2 = *entry;
|
||||
|
||||
if (!isl_space_tuple_is_equal(data->map->dim, isl_dim_out,
|
||||
map2->dim, isl_dim_out))
|
||||
return 0;
|
||||
|
||||
map2 = isl_map_flat_domain_product(isl_map_copy(data->map),
|
||||
isl_map_copy(map2));
|
||||
|
||||
data->res = isl_union_map_add_map(data->res, map2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Given two maps A -> B and C -> D, construct a map (A, C) -> (B * D).
|
||||
*/
|
||||
__isl_give isl_union_map *isl_union_map_flat_domain_product(
|
||||
__isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
|
||||
{
|
||||
return bin_op(umap1, umap2, &flat_domain_product_entry);
|
||||
}
|
||||
|
||||
static int flat_range_product_entry(void **entry, void *user)
|
||||
{
|
||||
struct isl_union_map_bin_data *data = user;
|
||||
|
@ -1606,6 +1652,24 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Remove redundant constraints in each of the basic maps of "umap".
|
||||
* Since removing redundant constraints does not change the meaning
|
||||
* or the space, the operation can be performed in-place.
|
||||
*/
|
||||
__isl_give isl_union_map *isl_union_map_remove_redundancies(
|
||||
__isl_take isl_union_map *umap)
|
||||
{
|
||||
return inplace(umap, &isl_map_remove_redundancies);
|
||||
}
|
||||
|
||||
/* Remove redundant constraints in each of the basic sets of "uset".
|
||||
*/
|
||||
__isl_give isl_union_set *isl_union_set_remove_redundancies(
|
||||
__isl_take isl_union_set *uset)
|
||||
{
|
||||
return isl_union_map_remove_redundancies(uset);
|
||||
}
|
||||
|
||||
__isl_give isl_union_map *isl_union_map_coalesce(
|
||||
__isl_take isl_union_map *umap)
|
||||
{
|
||||
|
@ -1805,6 +1869,39 @@ __isl_give isl_union_map *isl_union_map_domain_map(
|
|||
return cond_un_op(umap, &domain_map_entry);
|
||||
}
|
||||
|
||||
/* Construct an isl_pw_multi_aff that maps "map" to its domain and
|
||||
* add the result to "res".
|
||||
*/
|
||||
static int domain_map_upma(__isl_take isl_map *map, void *user)
|
||||
{
|
||||
isl_union_pw_multi_aff **res = user;
|
||||
isl_multi_aff *ma;
|
||||
isl_pw_multi_aff *pma;
|
||||
|
||||
ma = isl_multi_aff_domain_map(isl_map_get_space(map));
|
||||
pma = isl_pw_multi_aff_alloc(isl_map_wrap(map), ma);
|
||||
*res = isl_union_pw_multi_aff_add_pw_multi_aff(*res, pma);
|
||||
|
||||
return *res ? 0 : -1;
|
||||
|
||||
}
|
||||
|
||||
/* Return an isl_union_pw_multi_aff that maps a wrapped copy of "umap"
|
||||
* to its domain.
|
||||
*/
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_map_domain_map_union_pw_multi_aff(
|
||||
__isl_take isl_union_map *umap)
|
||||
{
|
||||
isl_union_pw_multi_aff *res;
|
||||
|
||||
res = isl_union_pw_multi_aff_empty(isl_union_map_get_space(umap));
|
||||
if (isl_union_map_foreach_map(umap, &domain_map_upma, &res) < 0)
|
||||
res = isl_union_pw_multi_aff_free(res);
|
||||
|
||||
isl_union_map_free(umap);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int range_map_entry(void **entry, void *user)
|
||||
{
|
||||
isl_map *map = *entry;
|
||||
|
@ -1907,6 +2004,38 @@ __isl_give isl_union_map *isl_union_set_identity(__isl_take isl_union_set *uset)
|
|||
return cond_un_op(uset, &identity_entry);
|
||||
}
|
||||
|
||||
/* Construct an identity isl_pw_multi_aff on "set" and add it to *res.
|
||||
*/
|
||||
static int identity_upma(__isl_take isl_set *set, void *user)
|
||||
{
|
||||
isl_union_pw_multi_aff **res = user;
|
||||
isl_space *space;
|
||||
isl_pw_multi_aff *pma;
|
||||
|
||||
space = isl_space_map_from_set(isl_set_get_space(set));
|
||||
pma = isl_pw_multi_aff_identity(space);
|
||||
pma = isl_pw_multi_aff_intersect_domain(pma, set);
|
||||
*res = isl_union_pw_multi_aff_add_pw_multi_aff(*res, pma);
|
||||
|
||||
return *res ? 0 : -1;
|
||||
}
|
||||
|
||||
/* Return an identity function on "uset" in the form
|
||||
* of an isl_union_pw_multi_aff.
|
||||
*/
|
||||
__isl_give isl_union_pw_multi_aff *isl_union_set_identity_union_pw_multi_aff(
|
||||
__isl_take isl_union_set *uset)
|
||||
{
|
||||
isl_union_pw_multi_aff *res;
|
||||
|
||||
res = isl_union_pw_multi_aff_empty(isl_union_set_get_space(uset));
|
||||
if (isl_union_set_foreach_set(uset, &identity_upma, &res) < 0)
|
||||
res = isl_union_pw_multi_aff_free(res);
|
||||
|
||||
isl_union_set_free(uset);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* If "map" is of the form [A -> B] -> C, then add A -> C to "res".
|
||||
*/
|
||||
static int domain_factor_domain_entry(void **entry, void *user)
|
||||
|
@ -2174,6 +2303,80 @@ int isl_union_set_is_strict_subset(__isl_keep isl_union_set *uset1,
|
|||
return isl_union_map_is_strict_subset(uset1, uset2);
|
||||
}
|
||||
|
||||
/* Internal data structure for isl_union_map_is_disjoint.
|
||||
* umap2 is the union map with which we are comparing.
|
||||
* is_disjoint is initialized to 1 and is set to 0 as soon
|
||||
* as the union maps turn out not to be disjoint.
|
||||
*/
|
||||
struct isl_union_map_is_disjoint_data {
|
||||
isl_union_map *umap2;
|
||||
int is_disjoint;
|
||||
};
|
||||
|
||||
/* Check if "map" is disjoint from data->umap2 and abort
|
||||
* the search if it is not.
|
||||
*/
|
||||
static int is_disjoint_entry(void **entry, void *user)
|
||||
{
|
||||
struct isl_union_map_is_disjoint_data *data = user;
|
||||
uint32_t hash;
|
||||
struct isl_hash_table_entry *entry2;
|
||||
isl_map *map = *entry;
|
||||
|
||||
hash = isl_space_get_hash(map->dim);
|
||||
entry2 = isl_hash_table_find(data->umap2->dim->ctx, &data->umap2->table,
|
||||
hash, &has_dim, map->dim, 0);
|
||||
if (!entry2)
|
||||
return 0;
|
||||
|
||||
data->is_disjoint = isl_map_is_disjoint(map, entry2->data);
|
||||
if (data->is_disjoint < 0 || !data->is_disjoint)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Are "umap1" and "umap2" disjoint?
|
||||
*/
|
||||
int isl_union_map_is_disjoint(__isl_keep isl_union_map *umap1,
|
||||
__isl_keep isl_union_map *umap2)
|
||||
{
|
||||
struct isl_union_map_is_disjoint_data data = { NULL, 1 };
|
||||
|
||||
umap1 = isl_union_map_copy(umap1);
|
||||
umap2 = isl_union_map_copy(umap2);
|
||||
umap1 = isl_union_map_align_params(umap1,
|
||||
isl_union_map_get_space(umap2));
|
||||
umap2 = isl_union_map_align_params(umap2,
|
||||
isl_union_map_get_space(umap1));
|
||||
|
||||
if (!umap1 || !umap2)
|
||||
goto error;
|
||||
|
||||
data.umap2 = umap2;
|
||||
if (isl_hash_table_foreach(umap1->dim->ctx, &umap1->table,
|
||||
&is_disjoint_entry, &data) < 0 &&
|
||||
data.is_disjoint)
|
||||
goto error;
|
||||
|
||||
isl_union_map_free(umap1);
|
||||
isl_union_map_free(umap2);
|
||||
|
||||
return data.is_disjoint;
|
||||
error:
|
||||
isl_union_map_free(umap1);
|
||||
isl_union_map_free(umap2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Are "uset1" and "uset2" disjoint?
|
||||
*/
|
||||
int isl_union_set_is_disjoint(__isl_keep isl_union_set *uset1,
|
||||
__isl_keep isl_union_set *uset2)
|
||||
{
|
||||
return isl_union_map_is_disjoint(uset1, uset2);
|
||||
}
|
||||
|
||||
static int sample_entry(void **entry, void *user)
|
||||
{
|
||||
isl_basic_map **sample = (isl_basic_map **)user;
|
||||
|
@ -3324,6 +3527,18 @@ __isl_give isl_union_map *isl_union_map_project_out(
|
|||
return data.res;
|
||||
}
|
||||
|
||||
/* Turn the "n" dimensions of type "type", starting at "first"
|
||||
* into existentially quantified variables.
|
||||
* Since the space of an isl_union_set only contains parameters,
|
||||
* "type" is required to be equal to isl_dim_param.
|
||||
*/
|
||||
__isl_give isl_union_set *isl_union_set_project_out(
|
||||
__isl_take isl_union_set *uset,
|
||||
enum isl_dim_type type, unsigned first, unsigned n)
|
||||
{
|
||||
return isl_union_map_project_out(uset, type, first, n);
|
||||
}
|
||||
|
||||
/* Internal data structure for isl_union_map_involves_dims.
|
||||
* "first" and "n" are the arguments for the isl_map_involves_dims calls.
|
||||
*/
|
||||
|
@ -3371,3 +3586,176 @@ int isl_union_map_involves_dims(__isl_keep isl_union_map *umap,
|
|||
|
||||
return !excludes;
|
||||
}
|
||||
|
||||
/* Internal data structure for isl_union_map_reset_range_space.
|
||||
* "range" is the space from which to set the range space.
|
||||
* "res" collects the results.
|
||||
*/
|
||||
struct isl_union_map_reset_range_space_data {
|
||||
isl_space *range;
|
||||
isl_union_map *res;
|
||||
};
|
||||
|
||||
/* Replace the range space of "map" by the range space of data->range and
|
||||
* add the result to data->res.
|
||||
*/
|
||||
static int reset_range_space(__isl_take isl_map *map, void *user)
|
||||
{
|
||||
struct isl_union_map_reset_range_space_data *data = user;
|
||||
isl_space *space;
|
||||
|
||||
space = isl_map_get_space(map);
|
||||
space = isl_space_domain(space);
|
||||
space = isl_space_extend_domain_with_range(space,
|
||||
isl_space_copy(data->range));
|
||||
map = isl_map_reset_space(map, space);
|
||||
data->res = isl_union_map_add_map(data->res, map);
|
||||
|
||||
return data->res ? 0 : -1;
|
||||
}
|
||||
|
||||
/* Replace the range space of all the maps in "umap" by
|
||||
* the range space of "space".
|
||||
*
|
||||
* This assumes that all maps have the same output dimension.
|
||||
* This function should therefore not be made publicly available.
|
||||
*
|
||||
* Since the spaces of the maps change, so do their hash value.
|
||||
* We therefore need to create a new isl_union_map.
|
||||
*/
|
||||
__isl_give isl_union_map *isl_union_map_reset_range_space(
|
||||
__isl_take isl_union_map *umap, __isl_take isl_space *space)
|
||||
{
|
||||
struct isl_union_map_reset_range_space_data data = { space };
|
||||
|
||||
data.res = isl_union_map_empty(isl_union_map_get_space(umap));
|
||||
if (isl_union_map_foreach_map(umap, &reset_range_space, &data) < 0)
|
||||
data.res = isl_union_map_free(data.res);
|
||||
|
||||
isl_space_free(space);
|
||||
isl_union_map_free(umap);
|
||||
return data.res;
|
||||
}
|
||||
|
||||
/* Internal data structure for isl_union_map_order_at_multi_union_pw_aff.
|
||||
* "mupa" is the function from which the isl_multi_pw_affs are extracted.
|
||||
* "order" is applied to the extracted isl_multi_pw_affs that correspond
|
||||
* to the domain and the range of each map.
|
||||
* "res" collects the results.
|
||||
*/
|
||||
struct isl_union_order_at_data {
|
||||
isl_multi_union_pw_aff *mupa;
|
||||
__isl_give isl_map *(*order)(__isl_take isl_multi_pw_aff *mpa1,
|
||||
__isl_take isl_multi_pw_aff *mpa2);
|
||||
isl_union_map *res;
|
||||
};
|
||||
|
||||
/* Intersect "map" with the result of applying data->order to
|
||||
* the functions in data->mupa that apply to the domain and the range
|
||||
* of "map" and add the result to data->res.
|
||||
*/
|
||||
static int order_at(__isl_take isl_map *map, void *user)
|
||||
{
|
||||
struct isl_union_order_at_data *data = user;
|
||||
isl_space *space;
|
||||
isl_multi_pw_aff *mpa1, *mpa2;
|
||||
isl_map *order;
|
||||
|
||||
space = isl_space_domain(isl_map_get_space(map));
|
||||
mpa1 = isl_multi_union_pw_aff_extract_multi_pw_aff(data->mupa, space);
|
||||
space = isl_space_range(isl_map_get_space(map));
|
||||
mpa2 = isl_multi_union_pw_aff_extract_multi_pw_aff(data->mupa, space);
|
||||
order = data->order(mpa1, mpa2);
|
||||
map = isl_map_intersect(map, order);
|
||||
data->res = isl_union_map_add_map(data->res, map);
|
||||
|
||||
return data->res ? 0 : -1;
|
||||
}
|
||||
|
||||
/* Intersect each map in "umap" with the result of calling "order"
|
||||
* on the functions is "mupa" that apply to the domain and the range
|
||||
* of the map.
|
||||
*/
|
||||
static __isl_give isl_union_map *isl_union_map_order_at_multi_union_pw_aff(
|
||||
__isl_take isl_union_map *umap, __isl_take isl_multi_union_pw_aff *mupa,
|
||||
__isl_give isl_map *(*order)(__isl_take isl_multi_pw_aff *mpa1,
|
||||
__isl_take isl_multi_pw_aff *mpa2))
|
||||
{
|
||||
struct isl_union_order_at_data data;
|
||||
|
||||
umap = isl_union_map_align_params(umap,
|
||||
isl_multi_union_pw_aff_get_space(mupa));
|
||||
mupa = isl_multi_union_pw_aff_align_params(mupa,
|
||||
isl_union_map_get_space(umap));
|
||||
data.mupa = mupa;
|
||||
data.order = order;
|
||||
data.res = isl_union_map_empty(isl_union_map_get_space(umap));
|
||||
if (isl_union_map_foreach_map(umap, &order_at, &data) < 0)
|
||||
data.res = isl_union_map_free(data.res);
|
||||
|
||||
isl_multi_union_pw_aff_free(mupa);
|
||||
isl_union_map_free(umap);
|
||||
return data.res;
|
||||
}
|
||||
|
||||
/* Return the subset of "umap" where the domain and the range
|
||||
* have equal "mupa" values.
|
||||
*/
|
||||
__isl_give isl_union_map *isl_union_map_eq_at_multi_union_pw_aff(
|
||||
__isl_take isl_union_map *umap,
|
||||
__isl_take isl_multi_union_pw_aff *mupa)
|
||||
{
|
||||
return isl_union_map_order_at_multi_union_pw_aff(umap, mupa,
|
||||
&isl_multi_pw_aff_eq_map);
|
||||
}
|
||||
|
||||
/* Return the subset of "umap" where the domain has a lexicographically
|
||||
* smaller "mupa" value than the range.
|
||||
*/
|
||||
__isl_give isl_union_map *isl_union_map_lex_lt_at_multi_union_pw_aff(
|
||||
__isl_take isl_union_map *umap,
|
||||
__isl_take isl_multi_union_pw_aff *mupa)
|
||||
{
|
||||
return isl_union_map_order_at_multi_union_pw_aff(umap, mupa,
|
||||
&isl_multi_pw_aff_lex_lt_map);
|
||||
}
|
||||
|
||||
/* Return the subset of "umap" where the domain has a lexicographically
|
||||
* greater "mupa" value than the range.
|
||||
*/
|
||||
__isl_give isl_union_map *isl_union_map_lex_gt_at_multi_union_pw_aff(
|
||||
__isl_take isl_union_map *umap,
|
||||
__isl_take isl_multi_union_pw_aff *mupa)
|
||||
{
|
||||
return isl_union_map_order_at_multi_union_pw_aff(umap, mupa,
|
||||
&isl_multi_pw_aff_lex_gt_map);
|
||||
}
|
||||
|
||||
/* Return the union of the elements in the list "list".
|
||||
*/
|
||||
__isl_give isl_union_set *isl_union_set_list_union(
|
||||
__isl_take isl_union_set_list *list)
|
||||
{
|
||||
int i, n;
|
||||
isl_ctx *ctx;
|
||||
isl_space *space;
|
||||
isl_union_set *res;
|
||||
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
ctx = isl_union_set_list_get_ctx(list);
|
||||
space = isl_space_params_alloc(ctx, 0);
|
||||
res = isl_union_set_empty(space);
|
||||
|
||||
n = isl_union_set_list_n_union_set(list);
|
||||
for (i = 0; i < n; ++i) {
|
||||
isl_union_set *uset_i;
|
||||
|
||||
uset_i = isl_union_set_list_get_union_set(list, i);
|
||||
res = isl_union_set_union(res, uset_i);
|
||||
}
|
||||
|
||||
isl_union_set_list_free(list);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#define isl_union_set_list isl_union_map_list
|
||||
#define isl_union_set isl_union_map
|
||||
#include <isl/union_map.h>
|
||||
#include <isl/union_set.h>
|
||||
|
@ -8,3 +9,6 @@ struct isl_union_map {
|
|||
|
||||
struct isl_hash_table table;
|
||||
};
|
||||
|
||||
__isl_give isl_union_map *isl_union_map_reset_range_space(
|
||||
__isl_take isl_union_map *umap, __isl_take isl_space *space);
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
/*
|
||||
* Copyright 2010 INRIA Saclay
|
||||
* Copyright 2013 Ecole Normale Superieure
|
||||
*
|
||||
* Use of this software is governed by the MIT license
|
||||
*
|
||||
* Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
|
||||
* Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
|
||||
* 91893 Orsay, France
|
||||
* and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
|
||||
*/
|
||||
|
||||
#define xFN(TYPE,NAME) TYPE ## _ ## NAME
|
||||
|
@ -116,13 +118,20 @@ __isl_give UNION *FN(UNION,copy)(__isl_keep UNION *u)
|
|||
return u;
|
||||
}
|
||||
|
||||
/* Return the number of base expressions in "u".
|
||||
*/
|
||||
int FN(FN(UNION,n),PARTS)(__isl_keep UNION *u)
|
||||
{
|
||||
return u ? u->table.n : 0;
|
||||
}
|
||||
|
||||
S(UNION,foreach_data)
|
||||
{
|
||||
int (*fn)(__isl_take PART *part, void *user);
|
||||
void *user;
|
||||
};
|
||||
|
||||
static int call_on_copy(void **entry, void *user)
|
||||
static int FN(UNION,call_on_copy)(void **entry, void *user)
|
||||
{
|
||||
PART *part = *entry;
|
||||
S(UNION,foreach_data) *data = (S(UNION,foreach_data) *)user;
|
||||
|
@ -139,12 +148,12 @@ int FN(FN(UNION,foreach),PARTS)(__isl_keep UNION *u,
|
|||
return -1;
|
||||
|
||||
return isl_hash_table_foreach(u->space->ctx, &u->table,
|
||||
&call_on_copy, &data);
|
||||
&FN(UNION,call_on_copy), &data);
|
||||
}
|
||||
|
||||
/* Is the space of "entry" equal to "space"?
|
||||
*/
|
||||
static int has_space(const void *entry, const void *val)
|
||||
static int FN(UNION,has_space)(const void *entry, const void *val)
|
||||
{
|
||||
PART *part = (PART *)entry;
|
||||
isl_space *space = (isl_space *) val;
|
||||
|
@ -154,12 +163,12 @@ static int has_space(const void *entry, const void *val)
|
|||
|
||||
/* This function is not currently used by isl_aff.c.
|
||||
*/
|
||||
static int has_domain_space(const void *entry, const void *val)
|
||||
static int FN(UNION,has_domain_space)(const void *entry, const void *val)
|
||||
__attribute__ ((unused));
|
||||
|
||||
/* Is the domain space of "entry" equal to "space"?
|
||||
*/
|
||||
static int has_domain_space(const void *entry, const void *val)
|
||||
static int FN(UNION,has_domain_space)(const void *entry, const void *val)
|
||||
{
|
||||
PART *part = (PART *)entry;
|
||||
isl_space *space = (isl_space *) val;
|
||||
|
@ -173,7 +182,7 @@ static int has_domain_space(const void *entry, const void *val)
|
|||
|
||||
/* Is the domain space of "entry" equal to the domain of "space"?
|
||||
*/
|
||||
static int has_same_domain_space(const void *entry, const void *val)
|
||||
static int FN(UNION,has_same_domain_space)(const void *entry, const void *val)
|
||||
{
|
||||
PART *part = (PART *)entry;
|
||||
isl_space *space = (isl_space *) val;
|
||||
|
@ -209,7 +218,7 @@ __isl_give PART *FN(FN(UNION,extract),PARTS)(__isl_keep UNION *u,
|
|||
|
||||
hash = isl_space_get_hash(space);
|
||||
entry = isl_hash_table_find(u->space->ctx, &u->table, hash,
|
||||
&has_space, space, 0);
|
||||
&FN(UNION,has_space), space, 0);
|
||||
if (!entry)
|
||||
#ifdef HAS_TYPE
|
||||
return FN(PART,ZERO)(space, u->type);
|
||||
|
@ -257,7 +266,8 @@ static __isl_give UNION *FN(UNION,add_part_generic)(__isl_take UNION *u,
|
|||
|
||||
hash = isl_space_get_hash(part->dim);
|
||||
entry = isl_hash_table_find(u->space->ctx, &u->table, hash,
|
||||
&has_same_domain_space, part->dim, 1);
|
||||
&FN(UNION,has_same_domain_space),
|
||||
part->dim, 1);
|
||||
if (!entry)
|
||||
goto error;
|
||||
|
||||
|
@ -304,7 +314,7 @@ __isl_give UNION *FN(FN(UNION,add),PARTS)(__isl_take UNION *u,
|
|||
return FN(UNION,add_part_generic)(u, part, 1);
|
||||
}
|
||||
|
||||
static int add_part(__isl_take PART *part, void *user)
|
||||
static int FN(UNION,add_part)(__isl_take PART *part, void *user)
|
||||
{
|
||||
UNION **u = (UNION **)user;
|
||||
|
||||
|
@ -325,7 +335,7 @@ __isl_give UNION *FN(UNION,dup)(__isl_keep UNION *u)
|
|||
#else
|
||||
dup = FN(UNION,ZERO)(isl_space_copy(u->space));
|
||||
#endif
|
||||
if (FN(FN(UNION,foreach),PARTS)(u, &add_part, &dup) < 0)
|
||||
if (FN(FN(UNION,foreach),PARTS)(u, &FN(UNION,add_part), &dup) < 0)
|
||||
goto error;
|
||||
return dup;
|
||||
error:
|
||||
|
@ -344,7 +354,7 @@ __isl_give UNION *FN(UNION,cow)(__isl_take UNION *u)
|
|||
return FN(UNION,dup)(u);
|
||||
}
|
||||
|
||||
static int free_u_entry(void **entry, void *user)
|
||||
static int FN(UNION,free_u_entry)(void **entry, void *user)
|
||||
{
|
||||
PART *part = *entry;
|
||||
FN(PART,free)(part);
|
||||
|
@ -359,7 +369,8 @@ __isl_null UNION *FN(UNION,free)(__isl_take UNION *u)
|
|||
if (--u->ref > 0)
|
||||
return NULL;
|
||||
|
||||
isl_hash_table_foreach(u->space->ctx, &u->table, &free_u_entry, NULL);
|
||||
isl_hash_table_foreach(u->space->ctx, &u->table,
|
||||
&FN(UNION,free_u_entry), NULL);
|
||||
isl_hash_table_clear(&u->table);
|
||||
isl_space_free(u->space);
|
||||
free(u);
|
||||
|
@ -371,8 +382,7 @@ S(UNION,align) {
|
|||
UNION *res;
|
||||
};
|
||||
|
||||
#ifdef ALIGN_DOMAIN
|
||||
static int align_entry(__isl_take PART *part, void *user)
|
||||
static int FN(UNION,align_entry)(__isl_take PART *part, void *user)
|
||||
{
|
||||
isl_reordering *exp;
|
||||
S(UNION,align) *data = user;
|
||||
|
@ -385,26 +395,41 @@ static int align_entry(__isl_take PART *part, void *user)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int align_entry(__isl_take PART *part, void *user)
|
||||
|
||||
/* Reorder the parameters of "u" according to the given reordering.
|
||||
*/
|
||||
static __isl_give UNION *FN(UNION,realign_domain)(__isl_take UNION *u,
|
||||
__isl_take isl_reordering *r)
|
||||
{
|
||||
isl_reordering *exp;
|
||||
S(UNION,align) *data = user;
|
||||
S(UNION,align) data = { NULL, NULL };
|
||||
|
||||
exp = isl_reordering_extend_space(isl_reordering_copy(data->exp),
|
||||
FN(PART,get_space)(part));
|
||||
if (!u || !r)
|
||||
goto error;
|
||||
|
||||
data->res = FN(FN(UNION,add),PARTS)(data->res,
|
||||
FN(PART,realign)(part, exp));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#ifdef HAS_TYPE
|
||||
data.res = FN(UNION,alloc)(isl_space_copy(r->dim), u->type, u->table.n);
|
||||
#else
|
||||
data.res = FN(UNION,alloc)(isl_space_copy(r->dim), u->table.n);
|
||||
#endif
|
||||
data.exp = r;
|
||||
if (FN(FN(UNION,foreach),PARTS)(u, &FN(UNION,align_entry), &data) < 0)
|
||||
data.res = FN(UNION,free)(data.res);
|
||||
|
||||
isl_reordering_free(data.exp);
|
||||
FN(UNION,free)(u);
|
||||
return data.res;
|
||||
error:
|
||||
FN(UNION,free)(u);
|
||||
isl_reordering_free(r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Align the parameters of "u" to those of "model".
|
||||
*/
|
||||
__isl_give UNION *FN(UNION,align_params)(__isl_take UNION *u,
|
||||
__isl_take isl_space *model)
|
||||
{
|
||||
S(UNION,align) data = { NULL, NULL };
|
||||
isl_reordering *r;
|
||||
|
||||
if (!u || !model)
|
||||
goto error;
|
||||
|
@ -415,35 +440,20 @@ __isl_give UNION *FN(UNION,align_params)(__isl_take UNION *u,
|
|||
}
|
||||
|
||||
model = isl_space_params(model);
|
||||
data.exp = isl_parameter_alignment_reordering(u->space, model);
|
||||
if (!data.exp)
|
||||
goto error;
|
||||
|
||||
#ifdef HAS_TYPE
|
||||
data.res = FN(UNION,alloc)(isl_space_copy(data.exp->dim),
|
||||
u->type, u->table.n);
|
||||
#else
|
||||
data.res = FN(UNION,alloc)(isl_space_copy(data.exp->dim), u->table.n);
|
||||
#endif
|
||||
if (FN(FN(UNION,foreach),PARTS)(u, &align_entry, &data) < 0)
|
||||
goto error;
|
||||
|
||||
isl_reordering_free(data.exp);
|
||||
FN(UNION,free)(u);
|
||||
r = isl_parameter_alignment_reordering(u->space, model);
|
||||
isl_space_free(model);
|
||||
return data.res;
|
||||
|
||||
return FN(UNION,realign_domain)(u, r);
|
||||
error:
|
||||
isl_reordering_free(data.exp);
|
||||
FN(UNION,free)(u);
|
||||
FN(UNION,free)(data.res);
|
||||
isl_space_free(model);
|
||||
FN(UNION,free)(u);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add "part" to *u, taking the union sum if "u" already has
|
||||
* a part defined on the same space as "part".
|
||||
*/
|
||||
static int union_add_part(__isl_take PART *part, void *user)
|
||||
static int FN(UNION,union_add_part)(__isl_take PART *part, void *user)
|
||||
{
|
||||
UNION **u = (UNION **)user;
|
||||
|
||||
|
@ -473,7 +483,7 @@ static __isl_give UNION *FN(UNION,union_add_)(__isl_take UNION *u1,
|
|||
if (!u1 || !u2)
|
||||
goto error;
|
||||
|
||||
if (FN(FN(UNION,foreach),PARTS)(u2, &union_add_part, &u1) < 0)
|
||||
if (FN(FN(UNION,foreach),PARTS)(u2, &FN(UNION,union_add_part), &u1) < 0)
|
||||
goto error;
|
||||
|
||||
FN(UNION,free)(u2);
|
||||
|
@ -516,7 +526,7 @@ S(UNION,match_bin_data) {
|
|||
* If so, call data->fn on the two elements and add the result to
|
||||
* data->res.
|
||||
*/
|
||||
static int match_bin_entry(void **entry, void *user)
|
||||
static int FN(UNION,match_bin_entry)(void **entry, void *user)
|
||||
{
|
||||
S(UNION,match_bin_data) *data = user;
|
||||
uint32_t hash;
|
||||
|
@ -528,7 +538,8 @@ static int match_bin_entry(void **entry, void *user)
|
|||
space = FN(PART,get_space)(part);
|
||||
hash = isl_space_get_hash(space);
|
||||
entry2 = isl_hash_table_find(data->u2->space->ctx, &data->u2->table,
|
||||
hash, &has_same_domain_space, space, 0);
|
||||
hash, &FN(UNION,has_same_domain_space),
|
||||
space, 0);
|
||||
isl_space_free(space);
|
||||
if (!entry2)
|
||||
return 0;
|
||||
|
@ -553,14 +564,14 @@ static int match_bin_entry(void **entry, void *user)
|
|||
/* This function is currently only used from isl_polynomial.c
|
||||
* and not from isl_fold.c.
|
||||
*/
|
||||
static __isl_give UNION *match_bin_op(__isl_take UNION *u1,
|
||||
static __isl_give UNION *FN(UNION,match_bin_op)(__isl_take UNION *u1,
|
||||
__isl_take UNION *u2,
|
||||
__isl_give PART *(*fn)(__isl_take PART *, __isl_take PART *))
|
||||
__attribute__ ((unused));
|
||||
/* For each pair of elements in "u1" and "u2" living in the same space,
|
||||
* call "fn" and collect the results.
|
||||
*/
|
||||
static __isl_give UNION *match_bin_op(__isl_take UNION *u1,
|
||||
static __isl_give UNION *FN(UNION,match_bin_op)(__isl_take UNION *u1,
|
||||
__isl_take UNION *u2,
|
||||
__isl_give PART *(*fn)(__isl_take PART *, __isl_take PART *))
|
||||
{
|
||||
|
@ -580,7 +591,7 @@ static __isl_give UNION *match_bin_op(__isl_take UNION *u1,
|
|||
data.res = FN(UNION,alloc)(isl_space_copy(u1->space), u1->table.n);
|
||||
#endif
|
||||
if (isl_hash_table_foreach(u1->space->ctx, &u1->table,
|
||||
&match_bin_entry, &data) < 0)
|
||||
&FN(UNION,match_bin_entry), &data) < 0)
|
||||
goto error;
|
||||
|
||||
FN(UNION,free)(u1);
|
||||
|
@ -604,7 +615,7 @@ __isl_give UNION *FN(UNION,add)(__isl_take UNION *u1, __isl_take UNION *u2)
|
|||
#if DEFAULT_IS_ZERO
|
||||
return FN(UNION,union_add_)(u1, u2);
|
||||
#else
|
||||
return match_bin_op(u1, u2, &FN(PART,add));
|
||||
return FN(UNION,match_bin_op)(u1, u2, &FN(PART,add));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -613,7 +624,7 @@ __isl_give UNION *FN(UNION,add)(__isl_take UNION *u1, __isl_take UNION *u2)
|
|||
*/
|
||||
__isl_give UNION *FN(UNION,sub)(__isl_take UNION *u1, __isl_take UNION *u2)
|
||||
{
|
||||
return match_bin_op(u1, u2, &FN(PART,sub));
|
||||
return FN(UNION,match_bin_op)(u1, u2, &FN(PART,sub));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -623,7 +634,7 @@ S(UNION,any_set_data) {
|
|||
__isl_give PW *(*fn)(__isl_take PW*, __isl_take isl_set*);
|
||||
};
|
||||
|
||||
static int any_set_entry(void **entry, void *user)
|
||||
static int FN(UNION,any_set_entry)(void **entry, void *user)
|
||||
{
|
||||
S(UNION,any_set_data) *data = user;
|
||||
PW *pw = *entry;
|
||||
|
@ -640,7 +651,7 @@ static int any_set_entry(void **entry, void *user)
|
|||
|
||||
/* Update each element of "u" by calling "fn" on the element and "set".
|
||||
*/
|
||||
static __isl_give UNION *any_set_op(__isl_take UNION *u,
|
||||
static __isl_give UNION *FN(UNION,any_set_op)(__isl_take UNION *u,
|
||||
__isl_take isl_set *set,
|
||||
__isl_give PW *(*fn)(__isl_take PW*, __isl_take isl_set*))
|
||||
{
|
||||
|
@ -660,7 +671,7 @@ static __isl_give UNION *any_set_op(__isl_take UNION *u,
|
|||
data.res = FN(UNION,alloc)(isl_space_copy(u->space), u->table.n);
|
||||
#endif
|
||||
if (isl_hash_table_foreach(u->space->ctx, &u->table,
|
||||
&any_set_entry, &data) < 0)
|
||||
&FN(UNION,any_set_entry), &data) < 0)
|
||||
goto error;
|
||||
|
||||
FN(UNION,free)(u);
|
||||
|
@ -678,7 +689,7 @@ error:
|
|||
__isl_give UNION *FN(UNION,intersect_params)(__isl_take UNION *u,
|
||||
__isl_take isl_set *set)
|
||||
{
|
||||
return any_set_op(u, set, &FN(PW,intersect_params));
|
||||
return FN(UNION,any_set_op)(u, set, &FN(PW,intersect_params));
|
||||
}
|
||||
|
||||
/* Compute the gist of the domain of "u" with respect to
|
||||
|
@ -687,7 +698,7 @@ __isl_give UNION *FN(UNION,intersect_params)(__isl_take UNION *u,
|
|||
__isl_give UNION *FN(UNION,gist_params)(__isl_take UNION *u,
|
||||
__isl_take isl_set *set)
|
||||
{
|
||||
return any_set_op(u, set, &FN(PW,gist_params));
|
||||
return FN(UNION,any_set_op)(u, set, &FN(PW,gist_params));
|
||||
}
|
||||
|
||||
S(UNION,match_domain_data) {
|
||||
|
@ -696,7 +707,7 @@ S(UNION,match_domain_data) {
|
|||
__isl_give PW *(*fn)(__isl_take PW*, __isl_take isl_set*);
|
||||
};
|
||||
|
||||
static int set_has_dim(const void *entry, const void *val)
|
||||
static int FN(UNION,set_has_dim)(const void *entry, const void *val)
|
||||
{
|
||||
isl_set *set = (isl_set *)entry;
|
||||
isl_space *dim = (isl_space *)val;
|
||||
|
@ -708,7 +719,7 @@ static int set_has_dim(const void *entry, const void *val)
|
|||
* of *entry, apply data->fn to *entry and this set (if any), and add
|
||||
* the result to data->res.
|
||||
*/
|
||||
static int match_domain_entry(void **entry, void *user)
|
||||
static int FN(UNION,match_domain_entry)(void **entry, void *user)
|
||||
{
|
||||
S(UNION,match_domain_data) *data = user;
|
||||
uint32_t hash;
|
||||
|
@ -719,7 +730,7 @@ static int match_domain_entry(void **entry, void *user)
|
|||
space = FN(PW,get_domain_space)(pw);
|
||||
hash = isl_space_get_hash(space);
|
||||
entry2 = isl_hash_table_find(data->uset->dim->ctx, &data->uset->table,
|
||||
hash, &set_has_dim, space, 0);
|
||||
hash, &FN(UNION,set_has_dim), space, 0);
|
||||
isl_space_free(space);
|
||||
if (!entry2)
|
||||
return 0;
|
||||
|
@ -738,7 +749,7 @@ static int match_domain_entry(void **entry, void *user)
|
|||
* the set lives in the same space as the domain of PW
|
||||
* and collect the results.
|
||||
*/
|
||||
static __isl_give UNION *match_domain_op(__isl_take UNION *u,
|
||||
static __isl_give UNION *FN(UNION,match_domain_op)(__isl_take UNION *u,
|
||||
__isl_take isl_union_set *uset,
|
||||
__isl_give PW *(*fn)(__isl_take PW*, __isl_take isl_set*))
|
||||
{
|
||||
|
@ -758,7 +769,7 @@ static __isl_give UNION *match_domain_op(__isl_take UNION *u,
|
|||
data.res = FN(UNION,alloc)(isl_space_copy(u->space), u->table.n);
|
||||
#endif
|
||||
if (isl_hash_table_foreach(u->space->ctx, &u->table,
|
||||
&match_domain_entry, &data) < 0)
|
||||
&FN(UNION,match_domain_entry), &data) < 0)
|
||||
goto error;
|
||||
|
||||
FN(UNION,free)(u);
|
||||
|
@ -781,7 +792,64 @@ __isl_give UNION *FN(UNION,intersect_domain)(__isl_take UNION *u,
|
|||
if (isl_union_set_is_params(uset))
|
||||
return FN(UNION,intersect_params)(u,
|
||||
isl_set_from_union_set(uset));
|
||||
return match_domain_op(u, uset, &FN(PW,intersect_domain));
|
||||
return FN(UNION,match_domain_op)(u, uset, &FN(PW,intersect_domain));
|
||||
}
|
||||
|
||||
/* Internal data structure for isl_union_*_subtract_domain.
|
||||
* uset is the set that needs to be removed from the domain.
|
||||
* res collects the results.
|
||||
*/
|
||||
S(UNION,subtract_domain_data) {
|
||||
isl_union_set *uset;
|
||||
UNION *res;
|
||||
};
|
||||
|
||||
/* Take the set (which may be empty) in data->uset that lives
|
||||
* in the same space as the domain of "pw", subtract it from the domain
|
||||
* of "pw" and add the result to data->res.
|
||||
*/
|
||||
static int FN(UNION,subtract_domain_entry)(__isl_take PW *pw, void *user)
|
||||
{
|
||||
S(UNION,subtract_domain_data) *data = user;
|
||||
isl_space *space;
|
||||
isl_set *set;
|
||||
|
||||
space = FN(PW,get_domain_space)(pw);
|
||||
set = isl_union_set_extract_set(data->uset, space);
|
||||
pw = FN(PW,subtract_domain)(pw, set);
|
||||
data->res = FN(FN(UNION,add),PARTS)(data->res, pw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Subtract "uset' from the domain of "u".
|
||||
*/
|
||||
__isl_give UNION *FN(UNION,subtract_domain)(__isl_take UNION *u,
|
||||
__isl_take isl_union_set *uset)
|
||||
{
|
||||
S(UNION,subtract_domain_data) data;
|
||||
|
||||
if (!u || !uset)
|
||||
goto error;
|
||||
|
||||
data.uset = uset;
|
||||
#ifdef HAS_TYPE
|
||||
data.res = FN(UNION,alloc)(isl_space_copy(u->space), u->type,
|
||||
u->table.n);
|
||||
#else
|
||||
data.res = FN(UNION,alloc)(isl_space_copy(u->space), u->table.n);
|
||||
#endif
|
||||
if (FN(FN(UNION,foreach),PARTS)(u,
|
||||
&FN(UNION,subtract_domain_entry), &data) < 0)
|
||||
data.res = FN(UNION,free)(data.res);
|
||||
|
||||
FN(UNION,free)(u);
|
||||
isl_union_set_free(uset);
|
||||
return data.res;
|
||||
error:
|
||||
FN(UNION,free)(u);
|
||||
isl_union_set_free(uset);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__isl_give UNION *FN(UNION,gist)(__isl_take UNION *u,
|
||||
|
@ -789,7 +857,7 @@ __isl_give UNION *FN(UNION,gist)(__isl_take UNION *u,
|
|||
{
|
||||
if (isl_union_set_is_params(uset))
|
||||
return FN(UNION,gist_params)(u, isl_set_from_union_set(uset));
|
||||
return match_domain_op(u, uset, &FN(PW,gist));
|
||||
return FN(UNION,match_domain_op)(u, uset, &FN(PW,gist));
|
||||
}
|
||||
|
||||
#ifndef NO_EVAL
|
||||
|
@ -809,7 +877,8 @@ __isl_give isl_val *FN(UNION,eval)(__isl_take UNION *u,
|
|||
goto error;
|
||||
hash = isl_space_get_hash(space);
|
||||
entry = isl_hash_table_find(u->space->ctx, &u->table,
|
||||
hash, &has_domain_space, space, 0);
|
||||
hash, &FN(UNION,has_domain_space),
|
||||
space, 0);
|
||||
isl_space_free(space);
|
||||
if (!entry) {
|
||||
v = isl_val_zero(isl_point_get_ctx(pnt));
|
||||
|
@ -826,7 +895,7 @@ error:
|
|||
}
|
||||
#endif
|
||||
|
||||
static int coalesce_entry(void **entry, void *user)
|
||||
static int FN(UNION,coalesce_entry)(void **entry, void *user)
|
||||
{
|
||||
PW **pw = (PW **)entry;
|
||||
|
||||
|
@ -843,7 +912,7 @@ __isl_give UNION *FN(UNION,coalesce)(__isl_take UNION *u)
|
|||
return NULL;
|
||||
|
||||
if (isl_hash_table_foreach(u->space->ctx, &u->table,
|
||||
&coalesce_entry, NULL) < 0)
|
||||
&FN(UNION,coalesce_entry), NULL) < 0)
|
||||
goto error;
|
||||
|
||||
return u;
|
||||
|
@ -852,7 +921,7 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int domain(__isl_take PART *part, void *user)
|
||||
static int FN(UNION,domain_entry)(__isl_take PART *part, void *user)
|
||||
{
|
||||
isl_union_set **uset = (isl_union_set **)user;
|
||||
|
||||
|
@ -866,7 +935,7 @@ __isl_give isl_union_set *FN(UNION,domain)(__isl_take UNION *u)
|
|||
isl_union_set *uset;
|
||||
|
||||
uset = isl_union_set_empty(FN(UNION,get_space)(u));
|
||||
if (FN(FN(UNION,foreach),PARTS)(u, &domain, &uset) < 0)
|
||||
if (FN(FN(UNION,foreach),PARTS)(u, &FN(UNION,domain_entry), &uset) < 0)
|
||||
goto error;
|
||||
|
||||
FN(UNION,free)(u);
|
||||
|
@ -878,7 +947,7 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int mul_isl_int(void **entry, void *user)
|
||||
static int FN(UNION,mul_isl_int_entry)(void **entry, void *user)
|
||||
{
|
||||
PW **pw = (PW **)entry;
|
||||
isl_int *v = user;
|
||||
|
@ -916,7 +985,7 @@ __isl_give UNION *FN(UNION,mul_isl_int)(__isl_take UNION *u, isl_int v)
|
|||
u->type = isl_fold_type_negate(u->type);
|
||||
#endif
|
||||
if (isl_hash_table_foreach(u->space->ctx, &u->table,
|
||||
&mul_isl_int, &v) < 0)
|
||||
&FN(UNION,mul_isl_int_entry), v) < 0)
|
||||
goto error;
|
||||
|
||||
return u;
|
||||
|
@ -929,7 +998,7 @@ error:
|
|||
*
|
||||
* Return 0 on success and -1 on error.
|
||||
*/
|
||||
static int scale_val(void **entry, void *user)
|
||||
static int FN(UNION,scale_val_entry)(void **entry, void *user)
|
||||
{
|
||||
PW **pw = (PW **)entry;
|
||||
isl_val *v = user;
|
||||
|
@ -978,7 +1047,8 @@ __isl_give UNION *FN(UNION,scale_val)(__isl_take UNION *u,
|
|||
if (isl_val_is_neg(v))
|
||||
u->type = isl_fold_type_negate(u->type);
|
||||
#endif
|
||||
if (isl_hash_table_foreach(u->space->ctx, &u->table, &scale_val, v) < 0)
|
||||
if (isl_hash_table_foreach(u->space->ctx, &u->table,
|
||||
&FN(UNION,scale_val_entry), v) < 0)
|
||||
goto error;
|
||||
|
||||
isl_val_free(v);
|
||||
|
@ -1050,7 +1120,7 @@ S(UNION,plain_is_equal_data)
|
|||
int is_equal;
|
||||
};
|
||||
|
||||
static int plain_is_equal_entry(void **entry, void *user)
|
||||
static int FN(UNION,plain_is_equal_entry)(void **entry, void *user)
|
||||
{
|
||||
S(UNION,plain_is_equal_data) *data = user;
|
||||
uint32_t hash;
|
||||
|
@ -1059,7 +1129,8 @@ static int plain_is_equal_entry(void **entry, void *user)
|
|||
|
||||
hash = isl_space_get_hash(pw->dim);
|
||||
entry2 = isl_hash_table_find(data->u2->space->ctx, &data->u2->table,
|
||||
hash, &has_same_domain_space, pw->dim, 0);
|
||||
hash, &FN(UNION,has_same_domain_space),
|
||||
pw->dim, 0);
|
||||
if (!entry2) {
|
||||
data->is_equal = 0;
|
||||
return -1;
|
||||
|
@ -1092,7 +1163,7 @@ int FN(UNION,plain_is_equal)(__isl_keep UNION *u1, __isl_keep UNION *u2)
|
|||
|
||||
data.u2 = u2;
|
||||
if (isl_hash_table_foreach(u1->space->ctx, &u1->table,
|
||||
&plain_is_equal_entry, &data) < 0 &&
|
||||
&FN(UNION,plain_is_equal_entry), &data) < 0 &&
|
||||
data.is_equal)
|
||||
goto error;
|
||||
|
||||
|
@ -1105,3 +1176,196 @@ error:
|
|||
FN(UNION,free)(u2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifndef NO_NEG
|
||||
/* Replace *entry by its opposite.
|
||||
*
|
||||
* Return 0 on success and -1 on error.
|
||||
*/
|
||||
static int FN(UNION,neg_entry)(void **entry, void *user)
|
||||
{
|
||||
PW **pw = (PW **) entry;
|
||||
|
||||
*pw = FN(PW,neg)(*pw);
|
||||
|
||||
return *pw ? 0 : -1;
|
||||
}
|
||||
|
||||
/* Return the opposite of "u".
|
||||
*/
|
||||
__isl_give UNION *FN(UNION,neg)(__isl_take UNION *u)
|
||||
{
|
||||
u = FN(UNION,cow)(u);
|
||||
if (!u)
|
||||
return NULL;
|
||||
|
||||
if (isl_hash_table_foreach(u->space->ctx, &u->table,
|
||||
&FN(UNION,neg_entry), NULL) < 0)
|
||||
return FN(UNION,free)(u);
|
||||
|
||||
return u;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Internal data structure for isl_union_*_drop_dims.
|
||||
* type, first and n are passed to isl_*_drop_dims.
|
||||
* res collects the results.
|
||||
*/
|
||||
S(UNION,drop_dims_data) {
|
||||
enum isl_dim_type type;
|
||||
unsigned first;
|
||||
unsigned n;
|
||||
|
||||
UNION *res;
|
||||
};
|
||||
|
||||
/* Drop the parameters specified by "data" from "part" and
|
||||
* add the results to data->res.
|
||||
*/
|
||||
static int FN(UNION,drop_dims_entry)(__isl_take PART *part, void *user)
|
||||
{
|
||||
S(UNION,drop_dims_data) *data = user;
|
||||
|
||||
part = FN(PART,drop_dims)(part, data->type, data->first, data->n);
|
||||
data->res = FN(FN(UNION,add),PARTS)(data->res, part);
|
||||
if (!data->res)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Drop the specified parameters from "u".
|
||||
* That is, type is required to be isl_dim_param.
|
||||
*/
|
||||
__isl_give UNION *FN(UNION,drop_dims)( __isl_take UNION *u,
|
||||
enum isl_dim_type type, unsigned first, unsigned n)
|
||||
{
|
||||
isl_space *space;
|
||||
S(UNION,drop_dims_data) data = { type, first, n };
|
||||
|
||||
if (!u)
|
||||
return NULL;
|
||||
|
||||
if (type != isl_dim_param)
|
||||
isl_die(FN(UNION,get_ctx)(u), isl_error_invalid,
|
||||
"can only project out parameters",
|
||||
return FN(UNION,free)(u));
|
||||
|
||||
space = FN(UNION,get_space)(u);
|
||||
space = isl_space_drop_dims(space, type, first, n);
|
||||
#ifdef HAS_TYPE
|
||||
data.res = FN(UNION,alloc)(space, u->type, u->table.n);
|
||||
#else
|
||||
data.res = FN(UNION,alloc)(space, u->table.n);
|
||||
#endif
|
||||
if (FN(FN(UNION,foreach),PARTS)(u,
|
||||
&FN(UNION,drop_dims_entry), &data) < 0)
|
||||
data.res = FN(UNION,free)(data.res);
|
||||
|
||||
FN(UNION,free)(u);
|
||||
|
||||
return data.res;
|
||||
}
|
||||
|
||||
/* Internal data structure for isl_union_*_set_dim_name.
|
||||
* pos is the position of the parameter that needs to be renamed.
|
||||
* s is the new name.
|
||||
* res collects the results.
|
||||
*/
|
||||
S(UNION,set_dim_name_data) {
|
||||
unsigned pos;
|
||||
const char *s;
|
||||
|
||||
UNION *res;
|
||||
};
|
||||
|
||||
/* Change the name of the parameter at position data->pos of "part" to data->s
|
||||
* and add the result to data->res.
|
||||
*/
|
||||
static int FN(UNION,set_dim_name_entry)(__isl_take PART *part, void *user)
|
||||
{
|
||||
S(UNION,set_dim_name_data) *data = user;
|
||||
|
||||
part = FN(PART,set_dim_name)(part, isl_dim_param, data->pos, data->s);
|
||||
data->res = FN(FN(UNION,add),PARTS)(data->res, part);
|
||||
if (!data->res)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Change the name of the parameter at position "pos" to "s".
|
||||
* That is, type is required to be isl_dim_param.
|
||||
*/
|
||||
__isl_give UNION *FN(UNION,set_dim_name)(__isl_take UNION *u,
|
||||
enum isl_dim_type type, unsigned pos, const char *s)
|
||||
{
|
||||
S(UNION,set_dim_name_data) data = { pos, s };
|
||||
isl_space *space;
|
||||
|
||||
if (!u)
|
||||
return NULL;
|
||||
|
||||
if (type != isl_dim_param)
|
||||
isl_die(FN(UNION,get_ctx)(u), isl_error_invalid,
|
||||
"can only set parameter names",
|
||||
return FN(UNION,free)(u));
|
||||
|
||||
space = FN(UNION,get_space)(u);
|
||||
space = isl_space_set_dim_name(space, type, pos, s);
|
||||
#ifdef HAS_TYPE
|
||||
data.res = FN(UNION,alloc)(space, u->type, u->table.n);
|
||||
#else
|
||||
data.res = FN(UNION,alloc)(space, u->table.n);
|
||||
#endif
|
||||
|
||||
if (FN(FN(UNION,foreach),PARTS)(u,
|
||||
&FN(UNION,set_dim_name_entry), &data) < 0)
|
||||
data.res = FN(UNION,free)(data.res);
|
||||
|
||||
FN(UNION,free)(u);
|
||||
|
||||
return data.res;
|
||||
}
|
||||
|
||||
/* Reset the user pointer on all identifiers of parameters and tuples
|
||||
* of the space of "part" and add the result to *res.
|
||||
*/
|
||||
static int FN(UNION,reset_user_entry)(__isl_take PART *part, void *user)
|
||||
{
|
||||
UNION **res = user;
|
||||
|
||||
part = FN(PART,reset_user)(part);
|
||||
*res = FN(FN(UNION,add),PARTS)(*res, part);
|
||||
if (!*res)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Reset the user pointer on all identifiers of parameters and tuples
|
||||
* of the spaces of "u".
|
||||
*/
|
||||
__isl_give UNION *FN(UNION,reset_user)(__isl_take UNION *u)
|
||||
{
|
||||
isl_space *space;
|
||||
UNION *res;
|
||||
|
||||
if (!u)
|
||||
return NULL;
|
||||
|
||||
space = FN(UNION,get_space)(u);
|
||||
space = isl_space_reset_user(space);
|
||||
#ifdef HAS_TYPE
|
||||
res = FN(UNION,alloc)(space, u->type, u->table.n);
|
||||
#else
|
||||
res = FN(UNION,alloc)(space, u->table.n);
|
||||
#endif
|
||||
if (FN(FN(UNION,foreach),PARTS)(u,
|
||||
&FN(UNION,reset_user_entry), &res) < 0)
|
||||
res = FN(UNION,free)(res);
|
||||
|
||||
FN(UNION,free)(u);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -936,6 +936,18 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Given two integer values "v1" and "v2", return the residue of "v1"
|
||||
* modulo "v2".
|
||||
*
|
||||
* This is a private copy of isl_val_mod for use in the generic
|
||||
* isl_multi_*_mod_multi_val instantiated for isl_val.
|
||||
*/
|
||||
__isl_give isl_val *isl_val_mod_val(__isl_take isl_val *v1,
|
||||
__isl_take isl_val *v2)
|
||||
{
|
||||
return isl_val_mod(v1, v2);
|
||||
}
|
||||
|
||||
/* Given two integer values, return their greatest common divisor.
|
||||
*/
|
||||
__isl_give isl_val *isl_val_gcd(__isl_take isl_val *v1, __isl_take isl_val *v2)
|
||||
|
@ -1566,8 +1578,6 @@ int isl_val_check_match_domain_space(__isl_keep isl_val *v,
|
|||
#define BASE val
|
||||
|
||||
#define NO_DOMAIN
|
||||
#define NO_INTERSECT_DOMAIN
|
||||
#define NO_GIST
|
||||
#define NO_IDENTITY
|
||||
#define NO_FROM_BASE
|
||||
#define NO_MOVE_DIMS
|
||||
|
|
|
@ -55,6 +55,8 @@ __isl_give isl_val *isl_val_scale_val(__isl_take isl_val *v1,
|
|||
__isl_take isl_val *v2);
|
||||
__isl_give isl_val *isl_val_scale_down_val(__isl_take isl_val *v1,
|
||||
__isl_take isl_val *v2);
|
||||
__isl_give isl_val *isl_val_mod_val(__isl_take isl_val *v1,
|
||||
__isl_take isl_val *v2);
|
||||
|
||||
int isl_val_plain_is_equal(__isl_keep isl_val *val1, __isl_keep isl_val *val2);
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef ISL_YAML_H
|
||||
#define ISL_YAML_H
|
||||
|
||||
#define ISL_YAML_INDENT_FLOW -1
|
||||
|
||||
enum isl_yaml_state {
|
||||
isl_yaml_none,
|
||||
isl_yaml_mapping_first_key_start,
|
||||
isl_yaml_mapping_key_start,
|
||||
isl_yaml_mapping_key,
|
||||
isl_yaml_mapping_val_start,
|
||||
isl_yaml_mapping_val,
|
||||
isl_yaml_sequence_first_start,
|
||||
isl_yaml_sequence_start,
|
||||
isl_yaml_sequence
|
||||
};
|
||||
|
||||
#endif
|
|
@ -13,10 +13,16 @@ int main(int argc, char **argv)
|
|||
{
|
||||
struct isl_ctx *ctx = isl_ctx_alloc();
|
||||
struct isl_basic_set *bset;
|
||||
isl_printer *p;
|
||||
|
||||
bset = isl_basic_set_read_from_file(ctx, stdin);
|
||||
bset = isl_basic_set_detect_equalities(bset);
|
||||
isl_basic_set_print(bset, stdout, 0, "", "", ISL_FORMAT_POLYLIB);
|
||||
|
||||
p = isl_printer_to_file(ctx, stdout);
|
||||
p = isl_printer_set_output_format(p, ISL_FORMAT_POLYLIB);
|
||||
p = isl_printer_print_basic_set(p, bset);
|
||||
isl_printer_free(p);
|
||||
|
||||
isl_basic_set_free(bset);
|
||||
isl_ctx_free(ctx);
|
||||
|
||||
|
|
|
@ -90,6 +90,12 @@
|
|||
#define BASE multi_pw_aff
|
||||
#include <print_templ.c>
|
||||
#undef BASE
|
||||
#define BASE union_pw_aff
|
||||
#include <print_templ.c>
|
||||
#undef BASE
|
||||
#define BASE multi_union_pw_aff
|
||||
#include <print_templ.c>
|
||||
#undef BASE
|
||||
#define BASE point
|
||||
#include <print_templ.c>
|
||||
#undef BASE
|
||||
|
|
|
@ -6,14 +6,11 @@
|
|||
}
|
||||
for (int c0 = 1; c0 < 3 * M - 1; c0 += 3) {
|
||||
S3((c0 + 2) / 3);
|
||||
if (3 * M >= c0 + 8) {
|
||||
for (int c1 = (c0 + 5) / 3; c1 <= M; c1 += 1) {
|
||||
S6((c0 + 2) / 3, c1);
|
||||
for (int c4 = (c0 + 5) / 3; c4 < c1; c4 += 1)
|
||||
S5(c4, c1, (c0 + 2) / 3);
|
||||
}
|
||||
} else if (c0 + 5 == 3 * M)
|
||||
S6(M - 1, M);
|
||||
for (int c1 = (c0 + 5) / 3; c1 <= M; c1 += 1) {
|
||||
S6((c0 + 2) / 3, c1);
|
||||
for (int c4 = (c0 + 5) / 3; c4 < c1; c4 += 1)
|
||||
S5(c4, c1, (c0 + 2) / 3);
|
||||
}
|
||||
for (int c1 = (c0 + 5) / 3; c1 <= M; c1 += 1)
|
||||
S2(c1, (c0 + 2) / 3);
|
||||
}
|
||||
|
|
|
@ -1,30 +1,20 @@
|
|||
{
|
||||
if (m == 1) {
|
||||
S1(0, 1, 1, 1);
|
||||
S8(0, 1);
|
||||
} else if (m >= 2) {
|
||||
S1(0, 1, 1, 1);
|
||||
S3(0, 1, 1, 2, 1, 1, 1, 2);
|
||||
S4(0, 1, 2, 2, 1, 1, 2, 2);
|
||||
S2(0, 1, 1, 1, 1, 1, 2, 1);
|
||||
S8(0, 1);
|
||||
}
|
||||
for (int c0 = 1; c0 < 2 * m - 3; c0 += 1) {
|
||||
for (int c0 = 0; c0 < 2 * m - 1; c0 += 1) {
|
||||
if (2 * m >= c0 + 3 && c0 >= 1) {
|
||||
if (c0 + 1 == m) {
|
||||
S5(m - 2, 1, m - 1, 1, m - 1, 1, m, 1);
|
||||
S1(m - 1, 1, m, 1);
|
||||
S3(m - 1, 1, m, 2, m, 1, m, 2);
|
||||
} else if (m >= c0 + 2) {
|
||||
} else if (c0 >= m) {
|
||||
S5(c0 - 1, -m + c0 + 2, c0, -m + c0 + 2, m - 1, -m + c0 + 2, m, -m + c0 + 2);
|
||||
S6(c0 - 1, -m + c0 + 1, c0, -m + c0 + 2, m, -m + c0 + 1, m, -m + c0 + 2);
|
||||
S1(c0, -m + c0 + 2, m, -m + c0 + 2);
|
||||
S3(c0, -m + c0 + 2, c0 + 1, -m + c0 + 3, m, -m + c0 + 2, m, -m + c0 + 3);
|
||||
} else {
|
||||
S5(c0 - 1, 1, c0, 1, c0, 1, c0 + 1, 1);
|
||||
S1(c0, 1, c0 + 1, 1);
|
||||
S3(c0, 1, c0 + 1, 2, c0 + 1, 1, c0 + 1, 2);
|
||||
S4(c0, 1, c0 + 2, 2, c0 + 1, 1, c0 + 2, 2);
|
||||
S2(c0, 1, c0 + 1, 1, c0 + 1, 1, c0 + 2, 1);
|
||||
} else {
|
||||
S5(c0 - 1, -m + c0 + 2, c0, -m + c0 + 2, m - 1, -m + c0 + 2, m, -m + c0 + 2);
|
||||
S6(c0 - 1, -m + c0 + 1, c0, -m + c0 + 2, m, -m + c0 + 1, m, -m + c0 + 2);
|
||||
S1(c0, -m + c0 + 2, m, -m + c0 + 2);
|
||||
S3(c0, -m + c0 + 2, c0 + 1, -m + c0 + 3, m, -m + c0 + 2, m, -m + c0 + 3);
|
||||
}
|
||||
for (int c2 = max(2, -m + c0 + 3); c2 <= min(m - 1, c0); c2 += 1) {
|
||||
S5(c0 - 1, c2, c0, c2, c0 - c2 + 1, c2, c0 - c2 + 2, c2);
|
||||
|
@ -54,33 +44,17 @@
|
|||
S4(c0, c0 + 1, c0 + 2, c0 + 2, 1, c0 + 1, 2, c0 + 2);
|
||||
S2(c0, c0 + 1, c0 + 1, c0 + 1, 1, c0 + 1, 2, c0 + 1);
|
||||
}
|
||||
for (int c8 = max(1, -m + c0 + 2); c8 <= min(m, c0 + 1); c8 += 1)
|
||||
S8(c0, c8);
|
||||
}
|
||||
if (m >= 2) {
|
||||
if (m >= 3) {
|
||||
S5(2 * m - 4, m - 1, 2 * m - 3, m - 1, m - 1, m - 1, m, m - 1);
|
||||
S6(2 * m - 4, m - 2, 2 * m - 3, m - 1, m, m - 2, m, m - 1);
|
||||
S1(2 * m - 3, m - 1, m, m - 1);
|
||||
S3(2 * m - 3, m - 1, 2 * m - 2, m, m, m - 1, m, m);
|
||||
S5(2 * m - 4, m, 2 * m - 3, m, m - 2, m, m - 1, m);
|
||||
S7(2 * m - 4, m - 1, 2 * m - 2, m, m - 1, m - 1, m, m);
|
||||
S6(2 * m - 4, m - 1, 2 * m - 3, m, m - 1, m - 1, m - 1, m);
|
||||
S1(2 * m - 3, m, m - 1, m);
|
||||
} else {
|
||||
S5(0, 1, 1, 1, 1, 1, 2, 1);
|
||||
S1(1, 1, 2, 1);
|
||||
S3(1, 1, 2, 2, 2, 1, 2, 2);
|
||||
S7(0, 1, 2, 2, 1, 1, 2, 2);
|
||||
S6(0, 1, 1, 2, 1, 1, 1, 2);
|
||||
S1(1, 2, 1, 2);
|
||||
}
|
||||
S2(2 * m - 3, m, 2 * m - 2, m, m - 1, m, m, m);
|
||||
for (int c8 = m - 1; c8 <= m; c8 += 1)
|
||||
S8(2 * m - 3, c8);
|
||||
} else if (m >= 2 && c0 == 0) {
|
||||
S1(0, 1, 1, 1);
|
||||
S3(0, 1, 1, 2, 1, 1, 1, 2);
|
||||
S4(0, 1, 2, 2, 1, 1, 2, 2);
|
||||
S2(0, 1, 1, 1, 1, 1, 2, 1);
|
||||
} else if (m >= 2) {
|
||||
S5(2 * m - 3, m, 2 * m - 2, m, m - 1, m, m, m);
|
||||
S6(2 * m - 3, m - 1, 2 * m - 2, m, m, m - 1, m, m);
|
||||
S1(2 * m - 2, m, m, m);
|
||||
S8(2 * m - 2, m);
|
||||
}
|
||||
} else
|
||||
S1(0, 1, 1, 1);
|
||||
for (int c8 = max(1, -m + c0 + 2); c8 <= min(m, c0 + 1); c8 += 1)
|
||||
S8(c0, c8);
|
||||
}
|
||||
|
|
|
@ -67,32 +67,25 @@
|
|||
}
|
||||
}
|
||||
for (int c0 = 37; c0 <= 218; c0 += 1) {
|
||||
for (int c1 = (c0 + 5) / 14 - 8; c1 < min(0, c0 / 14 - 5); c1 += 1) {
|
||||
if (c0 <= 46 && c1 == -3)
|
||||
S7(c0, -3, 6);
|
||||
if (-77 * ((-3 * c1 + 1) / 5) + 447 >= 6 * c0)
|
||||
S6(c0, c1, -((-2 * c1 + 3) / 5) + 9);
|
||||
for (int c2 = c1 + 24; c2 <= -2 * c1 + 24; c2 += 1)
|
||||
S2(c0, c1, c2);
|
||||
for (int c2 = -2 * c1 + 30; c2 <= c1 - (3 * c0 + 17) / 14 + 56; c2 += 1)
|
||||
S1(c0, c1, c2);
|
||||
}
|
||||
if (c0 <= 148)
|
||||
for (int c1 = max(0, (c0 + 5) / 14 - 8); c1 < c0 / 14 - 5; c1 += 1) {
|
||||
if (c1 == 0)
|
||||
S2(c0, 0, 24);
|
||||
if (c0 <= 148) {
|
||||
for (int c1 = (c0 + 5) / 14 - 8; c1 < c0 / 14 - 5; c1 += 1) {
|
||||
if (c0 <= 46 && c1 == -3)
|
||||
S7(c0, -3, 6);
|
||||
if (77 * ((3 * c1 + 18) / 5) + 216 >= 6 * c0)
|
||||
S6(c0, c1, -((-2 * c1 + 3) / 5) + 9);
|
||||
for (int c2 = c1 + 24; c2 <= -2 * c1 + 24; c2 += 1)
|
||||
S2(c0, c1, c2);
|
||||
for (int c2 = max(c1 + 24, -2 * c1 + 30); c2 <= c1 - (3 * c0 + 17) / 14 + 56; c2 += 1)
|
||||
S1(c0, c1, c2);
|
||||
}
|
||||
if (c0 >= 79 && c0 % 14 >= 9) {
|
||||
for (int c2 = max((c0 - 70) / 14 + 24, (c0 - 70) / 14 - (3 * c0 + 14) / 14 + 49); c2 <= (c0 - 70) / 14 - (3 * c0 + 17) / 14 + 56; c2 += 1)
|
||||
S1(c0, c0 / 14 - 5, c2);
|
||||
} else if (c0 <= 69 && c0 % 14 >= 9) {
|
||||
if (c0 <= 41)
|
||||
S7(c0, -3, 6);
|
||||
S6(c0, c0 / 14 - 5, 8);
|
||||
for (int c2 = -((-c0 + 83) / 14) - (3 * c0 + 14) / 14 + 49; c2 <= -((-c0 + 83) / 14) - (3 * c0 + 17) / 14 + 56; c2 += 1)
|
||||
S1(c0, c0 / 14 - 5, c2);
|
||||
if (c0 % 14 >= 9) {
|
||||
if (c0 <= 41)
|
||||
S7(c0, -3, 6);
|
||||
if (c0 <= 69)
|
||||
S6(c0, c0 / 14 - 5, 8);
|
||||
for (int c2 = max((c0 - 28) / 14 + 21, (c0 - 28) / 14 - (3 * c0 + 14) / 14 + 46); c2 <= (c0 - 28) / 14 - (3 * c0 + 17) / 14 + 53; c2 += 1)
|
||||
S1(c0, c0 / 14 - 5, c2);
|
||||
}
|
||||
}
|
||||
for (int c1 = (c0 + 5) / 14 - 5; c1 < 0; c1 += 1) {
|
||||
if (7 * c1 + 114 >= 2 * c0)
|
||||
|
@ -125,7 +118,7 @@
|
|||
S1(c0, c1, c2);
|
||||
}
|
||||
for (int c1 = c0 / 14 - 2; c1 <= 18; c1 += 1) {
|
||||
for (int c2 = c1 + 6; c2 <= min((2 * c1 + 1) / 5 + 7, floord(2 * c0 - 7 * c1, 21) + 4); c2 += 1)
|
||||
for (int c2 = c1 + 6; c2 <= min((2 * c1 + 1) / 5 + 7, (2 * c0 - 7 * c1 + 63) / 21 + 1); c2 += 1)
|
||||
S7(c0, c1, c2);
|
||||
for (int c2 = max(6, (c0 + 5) / 14 + 1); c2 <= min(min(c1, c0 / 14 + 3), -c1 + c1 / 2 + 18); c2 += 1)
|
||||
S5(c0, c1, c2);
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
if (g4 == 0 && N >= g0 + t1 + 1 && t1 <= 7) {
|
||||
for (int c0 = t0; c0 <= min(127, N - g1 - 1); c0 += 16)
|
||||
S1(g0 + t1, g1 + c0);
|
||||
} else if (g4 >= 4 && N >= g0 + t1 + 1 && t1 <= 7 && g4 % 4 == 0)
|
||||
if (N >= g0 + t1 + 1 && t1 <= 7 && g4 % 4 == 0)
|
||||
for (int c0 = t0; c0 <= min(127, N - g1 - 1); c0 += 16)
|
||||
S1(g0 + t1, g1 + c0);
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
for (int c0 = 0; c0 <= 5 * n; c0 += 1)
|
||||
for (int c1 = max(-((5 * n - c0 + 1) % 2) - n + c0 + 1, 2 * floord(c0 - 1, 3) + 2); c1 <= min(c0, n + c0 - (n + c0 + 2) / 3); c1 += 2)
|
||||
for (int c1 = max(-((5 * n - c0 + 1) % 2) - n + c0 + 1, 2 * ((c0 + 2) / 3)); c1 <= min(c0, n + c0 - (n + c0 + 2) / 3); c1 += 2)
|
||||
S1((3 * c1 / 2) - c0, c0 - c1);
|
||||
|
|
|
@ -2,50 +2,50 @@
|
|||
for (int c0 = -27 * n + 2; c0 <= 1; c0 += 1)
|
||||
S1(c0 - 1);
|
||||
for (int c0 = 2; c0 <= min(2 * n, n + 29); c0 += 1) {
|
||||
if (c0 >= 3) {
|
||||
if (2 * n >= c0 + 1) {
|
||||
S4(c0 - c0 / 2 - 1, c0 / 2 + 1);
|
||||
if (c0 + 2 >= 2 * n) {
|
||||
for (int c2 = 1; c2 < -n + c0; c2 += 1)
|
||||
S5(-n + c0, n, c2);
|
||||
} else if (c0 >= 5) {
|
||||
S4(c0 - c0 / 2 - 2, c0 / 2 + 2);
|
||||
for (int c2 = 1; c2 < c0 - c0 / 2 - 1; c2 += 1)
|
||||
S5(c0 - c0 / 2 - 1, c0 / 2 + 1, c2);
|
||||
}
|
||||
if (c0 >= 3 && 2 * n >= c0 + 1) {
|
||||
S4(c0 - c0 / 2 - 1, c0 / 2 + 1);
|
||||
if (c0 >= 5 && 2 * n >= c0 + 3) {
|
||||
S4(c0 - c0 / 2 - 2, c0 / 2 + 2);
|
||||
for (int c2 = 1; c2 < c0 - c0 / 2 - 1; c2 += 1)
|
||||
S5(c0 - c0 / 2 - 1, c0 / 2 + 1, c2);
|
||||
}
|
||||
for (int c1 = -c0 + c0 / 2 + 3; c1 <= min(-1, n - c0); c1 += 1) {
|
||||
S4(-c1, c0 + c1);
|
||||
S6(-c1 + 2, c0 + c1 - 2);
|
||||
for (int c2 = 1; c2 <= -c1; c2 += 1)
|
||||
S5(-c1 + 1, c0 + c1 - 1, c2);
|
||||
}
|
||||
if (2 * n >= c0 + 3 && c0 >= n + 2) {
|
||||
S6(-n + c0 + 1, n - 1);
|
||||
for (int c2 = 1; c2 < -n + c0; c2 += 1)
|
||||
S5(-n + c0, n, c2);
|
||||
}
|
||||
if (c0 >= n + 3 && 2 * n >= c0 + 1) {
|
||||
S6(-n + c0, n);
|
||||
} else {
|
||||
if (c0 >= 5 && n + 1 >= c0) {
|
||||
S6(2, c0 - 2);
|
||||
S1(c0 - 1);
|
||||
} else if (n + 1 >= c0 && c0 <= 4)
|
||||
S1(c0 - 1);
|
||||
if (n + 1 >= c0) {
|
||||
S6(1, c0 - 1);
|
||||
} else if (n >= 3 && c0 == n + 2) {
|
||||
S6(2, n);
|
||||
S1(n + 1);
|
||||
}
|
||||
}
|
||||
if (c0 >= n + 3)
|
||||
S1(c0 - 1);
|
||||
if (n == 2 && c0 == 4)
|
||||
S1(3);
|
||||
} else
|
||||
}
|
||||
for (int c1 = -c0 + c0 / 2 + 3; c1 <= min(-1, n - c0); c1 += 1) {
|
||||
S4(-c1, c0 + c1);
|
||||
S6(-c1 + 2, c0 + c1 - 2);
|
||||
for (int c2 = 1; c2 <= -c1; c2 += 1)
|
||||
S5(-c1 + 1, c0 + c1 - 1, c2);
|
||||
}
|
||||
if (c0 >= 3 && n + 1 >= c0 && c0 <= 4) {
|
||||
S1(c0 - 1);
|
||||
} else if (c0 >= 5 && n + 1 >= c0) {
|
||||
S6(2, c0 - 2);
|
||||
S1(c0 - 1);
|
||||
}
|
||||
if (n >= 2 && c0 == n + 1) {
|
||||
S6(1, n);
|
||||
} else if (2 * n >= c0 + 3 && c0 >= n + 2) {
|
||||
S6(-n + c0 + 1, n - 1);
|
||||
for (int c2 = 1; c2 < -n + c0; c2 += 1)
|
||||
S5(-n + c0, n, c2);
|
||||
}
|
||||
if (2 * n >= c0 + 1 && c0 + 2 >= 2 * n)
|
||||
for (int c2 = 1; c2 < -n + c0; c2 += 1)
|
||||
S5(-n + c0, n, c2);
|
||||
if (c0 >= n + 3 && 2 * n >= c0 + 1) {
|
||||
S6(-n + c0, n);
|
||||
} else if (c0 >= 3 && n >= c0) {
|
||||
S6(1, c0 - 1);
|
||||
} else if (c0 == 2) {
|
||||
S1(1);
|
||||
} else if (n >= 3 && c0 == n + 2) {
|
||||
S6(2, n);
|
||||
S1(n + 1);
|
||||
}
|
||||
if (c0 >= n + 3)
|
||||
S1(c0 - 1);
|
||||
if (n == 2 && c0 == 4)
|
||||
S1(3);
|
||||
if (c0 % 2 == 0)
|
||||
S3(c0 / 2);
|
||||
for (int c1 = max(1, -n + c0); c1 < (c0 + 1) / 2; c1 += 1)
|
||||
|
|
|
@ -9,37 +9,40 @@
|
|||
for (int c2 = 1; c2 < c0 - c0 / 2 - 1; c2 += 1)
|
||||
S5(c0 - c0 / 2 - 1, c0 / 2 + 1, c2);
|
||||
}
|
||||
for (int c1 = -c0 + c0 / 2 + 3; c1 <= min(-1, n - c0); c1 += 1) {
|
||||
S4(-c1, c0 + c1);
|
||||
S6(-c1 + 2, c0 + c1 - 2);
|
||||
for (int c2 = 1; c2 <= -c1; c2 += 1)
|
||||
S5(-c1 + 1, c0 + c1 - 1, c2);
|
||||
}
|
||||
if (2 * n >= c0 + 3 && c0 >= n + 2) {
|
||||
S6(-n + c0 + 1, n - 1);
|
||||
for (int c2 = 1; c2 < -n + c0; c2 += 1)
|
||||
S5(-n + c0, n, c2);
|
||||
} else if (c0 + 2 >= 2 * n)
|
||||
}
|
||||
for (int c1 = -c0 + c0 / 2 + 3; c1 <= min(-1, n - c0); c1 += 1) {
|
||||
S4(-c1, c0 + c1);
|
||||
S6(-c1 + 2, c0 + c1 - 2);
|
||||
for (int c2 = 1; c2 <= -c1; c2 += 1)
|
||||
S5(-c1 + 1, c0 + c1 - 1, c2);
|
||||
}
|
||||
if (c0 >= 5 && n + 1 >= c0) {
|
||||
S6(2, c0 - 2);
|
||||
S1(c0 - 1);
|
||||
if (c0 == n + 1)
|
||||
S6(1, n);
|
||||
} else if (c0 == 2) {
|
||||
S1(1);
|
||||
} else if (2 * n >= c0 + 3 && c0 >= n + 2) {
|
||||
S6(-n + c0 + 1, n - 1);
|
||||
for (int c2 = 1; c2 < -n + c0; c2 += 1)
|
||||
S5(-n + c0, n, c2);
|
||||
} else if (c0 <= 4)
|
||||
S1(c0 - 1);
|
||||
if (c0 >= 3 && n >= c0) {
|
||||
S6(1, c0 - 1);
|
||||
} else {
|
||||
if (c0 + 2 >= 2 * n)
|
||||
for (int c2 = 1; c2 < -n + c0; c2 += 1)
|
||||
S5(-n + c0, n, c2);
|
||||
if (c0 >= n + 3) {
|
||||
S6(-n + c0, n);
|
||||
S1(c0 - 1);
|
||||
} else {
|
||||
if (c0 >= 5 && n + 1 >= c0) {
|
||||
S6(2, c0 - 2);
|
||||
S1(c0 - 1);
|
||||
} else if (c0 <= 4)
|
||||
S1(c0 - 1);
|
||||
if (n + 1 >= c0) {
|
||||
S6(1, c0 - 1);
|
||||
} else {
|
||||
S6(2, n);
|
||||
S1(n + 1);
|
||||
}
|
||||
} else if (c0 == n + 2) {
|
||||
S6(2, n);
|
||||
S1(n + 1);
|
||||
}
|
||||
} else
|
||||
S1(1);
|
||||
}
|
||||
if (c0 % 2 == 0)
|
||||
S3(c0 / 2);
|
||||
for (int c1 = max(1, -n + c0); c1 < (c0 + 1) / 2; c1 += 1)
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
{
|
||||
for (int c0 = 1; c0 < n; c0 += 1) {
|
||||
for (int c2 = c0 + 1; c2 <= n; c2 += 1)
|
||||
S1(c0, c2);
|
||||
for (int c1 = 1; c1 < c0; c1 += 1)
|
||||
for (int c2 = c1 + 1; c2 <= n; c2 += 1)
|
||||
S2(c1, c2, c0);
|
||||
}
|
||||
for (int c1 = 1; c1 < n; c1 += 1)
|
||||
for (int c0 = 1; c0 <= n; c0 += 1) {
|
||||
for (int c2 = c0 + 1; c2 <= n; c2 += 1)
|
||||
S1(c0, c2);
|
||||
for (int c1 = 1; c1 < c0; c1 += 1)
|
||||
for (int c2 = c1 + 1; c2 <= n; c2 += 1)
|
||||
S2(c1, c2, n);
|
||||
S2(c1, c2, c0);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
for (int c0 = 0; c0 <= 15; c0 += 1)
|
||||
for (int c1 = max(2 * c0 - 15, c0 / 2); c1 <= min(15, c0 + 1); c1 += 1)
|
||||
for (int c2 = max(max(max(1, 67 * c0 - (c0 + 1) / 3), 67 * c1 - (c1 + 2) / 3), 133 * c0 - 67 * c1 + (c0 + c1 + 1) / 3 - 66); c2 <= min(min(1000, 100 * c0 + 99), 133 * c0 - 67 * c1 + floord(c0 + c1 - 1, 3) + 133); c2 += 1)
|
||||
for (int c2 = max(max(max(1, 67 * c0 - (c0 + 1) / 3), 67 * c1 - (c1 + 2) / 3), 133 * c0 - 67 * c1 + (c0 + c1 + 1) / 3 - 66); c2 <= min(min(1000, 100 * c0 + 99), 133 * c0 - 67 * c1 + (c0 + c1 + 2) / 3 + 132); c2 += 1)
|
||||
for (int c3 = max(max(c2, 200 * c0 - c2), 100 * c1 + (c2 + 1) / 2); c3 <= min(min(2 * c2 + 1, 200 * c0 - c2 + 199), 100 * c1 + (c2 + 1) / 2 + 99); c3 += 1)
|
||||
s0(c0, c1, c2, c3);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
for (int c0 = 0; c0 <= 15; c0 += 1)
|
||||
for (int c1 = max(2 * c0 - 15, c0 / 2); c1 <= min(15, c0 + 1); c1 += 1)
|
||||
for (int c2 = max(max(max(1, 67 * c0 - (c0 + 1) / 3), 67 * c1 - (c1 + 2) / 3), 133 * c0 - 67 * c1 + (c0 + c1 + 1) / 3 - 66); c2 <= min(min(1000, 100 * c0 + 99), 133 * c0 - 67 * c1 + floord(c0 + c1 - 1, 3) + 133); c2 += 1)
|
||||
for (int c2 = max(max(max(1, 67 * c0 - (c0 + 1) / 3), 67 * c1 - (c1 + 2) / 3), 133 * c0 - 67 * c1 + (c0 + c1 + 1) / 3 - 66); c2 <= min(min(1000, 100 * c0 + 99), 133 * c0 - 67 * c1 + (c0 + c1 + 2) / 3 + 132); c2 += 1)
|
||||
for (int c3 = max(max(c2, 200 * c0 - c2), 100 * c1 + (c2 + 1) / 2); c3 <= min(min(2 * c2 + 1, 200 * c0 - c2 + 199), 100 * c1 + (c2 + 1) / 2 + 99); c3 += 1)
|
||||
s0(c0, c1, c2, c3);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
for (int c0 = 0; c0 <= 15; c0 += 1)
|
||||
for (int c1 = max(2 * c0 - 15, c0 / 2); c1 <= min(15, c0 + 1); c1 += 1)
|
||||
for (int c2 = max(max(max(1, 67 * c0 - (c0 + 1) / 3), 67 * c1 - (c1 + 2) / 3), 133 * c0 - 67 * c1 + (c0 + c1 + 1) / 3 - 66); c2 <= min(min(1000, 100 * c0 + 99), 133 * c0 - 67 * c1 + floord(c0 + c1 - 1, 3) + 133); c2 += 1)
|
||||
for (int c2 = max(max(max(1, 67 * c0 - (c0 + 1) / 3), 67 * c1 - (c1 + 2) / 3), 133 * c0 - 67 * c1 + (c0 + c1 + 1) / 3 - 66); c2 <= min(min(1000, 100 * c0 + 99), 133 * c0 - 67 * c1 + (c0 + c1 + 2) / 3 + 132); c2 += 1)
|
||||
for (int c3 = max(max(c2, 200 * c0 - c2), 100 * c1 + (c2 + 1) / 2); c3 <= min(min(2 * c2 + 1, 200 * c0 - c2 + 199), 100 * c1 + (c2 + 1) / 2 + 99); c3 += 1)
|
||||
s0(c0, c1, c2, c3);
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
for (int c0 = 0; c0 <= 14; c0 += 1)
|
||||
for (int c1 = max(2 * c0 - 12, -c0 + 3 * floord(c0 - 1, 2) + 3); c1 <= min(2 * c0, c0 / 2 + 9); c1 += 3)
|
||||
for (int c1 = max(2 * c0 - 12, -c0 + 3 * ((c0 + 1) / 2)); c1 <= min(2 * c0, c0 / 2 + 9); c1 += 3)
|
||||
s0((2 * c0 - c1) / 3, (-c0 + 2 * c1) / 3);
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
if (t1 >= 126)
|
||||
S(0, t1 - 384);
|
||||
S(0, t1 - 256);
|
||||
if (t1 >= 126)
|
||||
S(1, t1 - 384);
|
||||
S(1, t1 - 256);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
# Check that the most appropriate lower bound is selected
|
||||
[t1,t2]->{ S[i,j] -> [i,j] : exists (alpha, beta :
|
||||
0 <= i <= 1 &&
|
||||
t1 = j+128alpha &&
|
||||
0 <= j+2beta < 128 &&
|
||||
510 <= t2+2beta <= 514 &&
|
||||
0 <= 2beta - t2 <= 5
|
||||
)}
|
||||
[t1,t2] -> {: 125 <= t1 <= 127 and 254 <= t2 < 257}
|
||||
{[i,j] -> unroll[x]}
|
|
@ -8,7 +8,7 @@
|
|||
; CHECK: WAR dependences:
|
||||
; CHECK: { }
|
||||
; CHECK: WAW dependences:
|
||||
; CHECK: { Stmt_for_body[i0] -> Stmt_for_body[1 + i0] : i0 >= 0 and i0 <= 1022 }
|
||||
; CHECK: { Stmt_for_body[i0] -> Stmt_for_body[1 + i0] : i0 <= 1022 and i0 >= 0 }
|
||||
; CHECK: Reduction dependences:
|
||||
; CHECK: { Stmt_for_body[i0] -> Stmt_for_body[1 + i0] : i0 <= 1022 and i0 >= 0 }
|
||||
;
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
; RUN: opt %loadPolly -polly-dependences -analyze < %s | FileCheck %s
|
||||
;
|
||||
; CHECK: RAW dependences:
|
||||
; CHECK-DAG: Stmt_for_body3[i0, 1] -> Stmt_for_body3[1 + i0, o1] : i0 <= 1022 and i0 >= 0 and o1 <= 511 and o1 >= 1
|
||||
; CHECK-DAG: Stmt_for_body3[i0, 0] -> Stmt_for_body3[i0, o1] : i0 <= 1023 and i0 >= 0 and o1 <= 511 and o1 >= 1
|
||||
; CHECK-DAG: Stmt_for_body3[i0, i1] -> Stmt_for_body3[i0 + i1, o1] : i1 <= 1023 - i0 and i1 >= 0 and i1 <= 1 and i0 >= 0 and o1 <= 511 and o1 >= 1
|
||||
; CHECK: WAR dependences:
|
||||
; CHECK: { }
|
||||
; CHECK: WAW dependences:
|
||||
|
|
|
@ -2,13 +2,10 @@
|
|||
;
|
||||
; CHECK: RAW dependences:
|
||||
; CHECK-DAG: Stmt_S0[i0] -> Stmt_S1[o0, i0 - o0] : i0 <= 1023 and o0 >= 0 and o0 <= i0
|
||||
; CHECK-DAG: Stmt_S1[i0, i1] -> Stmt_S2[-1 + i0 + i1] : i0 >= 0 and i1 >= 1 and i0 <= 1022 and i1 <= 1024 - i0 and i1 <= 1023
|
||||
; CHECK-DAG: Stmt_S1[1023, i1] -> Stmt_S2[1022 + i1] : i1 <= 1 and i1 >= 0
|
||||
; CHECK-DAG: Stmt_S1[i0, 0] -> Stmt_S2[-1 + i0] : i0 <= 1022 and i0 >= 1
|
||||
; CHECK-DAG: Stmt_S1[i0, i1] -> Stmt_S2[-1 + i0 + i1] : i1 <= 1023 and i1 >= 0 and i1 >= 1 - i0 and i0 >= 0 and i0 <= 1023 and i1 <= 1024 - i0
|
||||
; CHECK: WAR dependences:
|
||||
; CHECK-DAG: Stmt_S2[i0] -> Stmt_S2[1 + i0] : i0 <= 1022 and i0 >= 0
|
||||
; CHECK-DAG: Stmt_S1[i0, i1] -> Stmt_S2[i0 + i1] : i0 >= 0 and i1 <= 1023 - i0 and i1 >= 1
|
||||
; CHECK-DAG: Stmt_S1[i0, 0] -> Stmt_S2[i0] : i0 <= 1023 and i0 >= 1
|
||||
; CHECK-DAG: Stmt_S1[i0, i1] -> Stmt_S2[i0 + i1] : i1 <= 1023 - i0 and i1 >= 0 and i1 >= 1 - i0 and i0 >= 0 }
|
||||
; CHECK: WAW dependences:
|
||||
; CHECK-DAG: Stmt_S0[i0] -> Stmt_S1[o0, i0 - o0] : i0 <= 1023 and o0 >= 0 and o0 <= i0
|
||||
; CHECK-DAG: Stmt_S1[0, 0] -> Stmt_S2[0]
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
; RUN: opt %loadPolly -polly-dependences -analyze < %s | FileCheck %s
|
||||
;
|
||||
; CHECK: RAW dependences:
|
||||
; CHECK-DAG: Stmt_S2[0, 0] -> Stmt_S3[1]
|
||||
; CHECK-DAG: Stmt_S2[i0, 1 - i0] -> Stmt_S3[i0] : i0 <= 1 and i0 >= 0
|
||||
; CHECK-DAG: Stmt_S2[i0, i1] -> Stmt_S3[o0] : o0 <= 1 and i1 <= 1 - i0 and o0 <= 1 + i0 - i1 and o0 >= 1 - i1
|
||||
; CHECK-DAG: Stmt_S3[i0] -> Stmt_S2[o0, 1 - i0] : i0 <= 1 and i0 >= 0 and o0 >= 1 + i0 and o0 <= 98
|
||||
; CHECK-DAG: Stmt_S1[i0] -> Stmt_S3[2 + i0] : i0 >= 0 and i0 <= 96
|
||||
; CHECK: WAR dependences:
|
||||
; CHECK: { }
|
||||
; CHECK: WAW dependences:
|
||||
; CHECK-DAG: Stmt_S2[0, 0] -> Stmt_S3[1]
|
||||
; CHECK-DAG: Stmt_S2[i0, 1 - i0] -> Stmt_S3[i0] : i0 <= 1 and i0 >= 0
|
||||
; CHECK-DAG: Stmt_S2[i0, i1] -> Stmt_S3[o0] : o0 <= 1 and i1 <= 1 - i0 and o0 <= 1 + i0 - i1 and o0 >= 1 - i1
|
||||
; CHECK-DAG: Stmt_S3[i0] -> Stmt_S2[o0, 1 - i0] : i0 <= 1 and i0 >= 0 and o0 >= 1 + i0 and o0 <= 98
|
||||
; CHECK-DAG: Stmt_S1[i0] -> Stmt_S3[2 + i0] : i0 >= 0 and i0 <= 96
|
||||
; CHECK: Reduction dependences:
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
; CHECK: WAW dependences:
|
||||
; CHECK: { }
|
||||
; CHECK: Reduction dependences:
|
||||
; CHECK-DAG: Stmt_for_body3[i0, i1] -> Stmt_for_body3[i0, 1 + i1] : i0 <= 1023 and i0 >= 0 and i1 <= 1022 and i1 >= 0
|
||||
; CHECK-DAG: Stmt_for_body3[i0, i1] -> Stmt_for_body3[1 + i0, i1] : i0 <= 1022 and i0 >= 0 and i1 <= 1023 and i1 >= 0
|
||||
; CHECK-DAG: Stmt_for_body3[i0, i1] -> Stmt_for_body3[o0, 1 + i0 + i1 - o0] : o0 <= 1 + i0 and o0 >= i0 and o0 <= 1023 and i0 >= 0 and i1 >= 0 and o0 >= -1022 + i0 + i1
|
||||
;
|
||||
; void f(int *restrict A, int *restrict B, int *restrict Values) {
|
||||
; for (int i = 0; i < 1024; i++) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue