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:
Tobias Grosser 2015-02-16 19:33:40 +00:00
parent 97a59fb464
commit 1fa7b972c0
104 changed files with 14847 additions and 2852 deletions

View File

@ -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

View File

@ -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 \

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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)
}

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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.

View File

@ -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 dUlm, 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

View File

@ -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

View File

@ -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".

View File

@ -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

View File

@ -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;
}

View File

@ -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(

31
polly/lib/External/isl/isl_map_list.c vendored Normal file
View File

@ -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>

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -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 dUlm, 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;
}

View File

@ -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

View File

@ -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;
}

29
polly/lib/External/isl/isl_multi_gist.c vendored Normal file
View File

@ -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 dUlm, 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));
}

View File

@ -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 dUlm, 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));
}

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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
};

View File

@ -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));
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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

View File

@ -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;
}

View File

@ -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

1535
polly/lib/External/isl/isl_schedule_node.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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;
}

1423
polly/lib/External/isl/isl_schedule_tree.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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>

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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;

View File

@ -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

View File

@ -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 },

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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);

18
polly/lib/External/isl/isl_yaml.h vendored Normal file
View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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]}

View File

@ -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 }
;

View File

@ -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:

View File

@ -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]

View File

@ -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:

View File

@ -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