From 6f87ceab1c00e2b7020071f3adf3fdf35faf4662 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 1 Sep 2011 11:58:50 +0200 Subject: [PATCH] add isl_pw_multi_aff Signed-off-by: Sven Verdoolaege --- doc/user.pod | 69 ++++++++++++++++++++++++++++++++++++-- include/isl/aff.h | 56 +++++++++++++++++++++++++++++++ include/isl/aff_type.h | 3 ++ isl_aff.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++ isl_aff_private.h | 29 ++++++++++++++++ isl_output.c | 41 +++++++++++++++++++++++ print.c | 3 ++ 7 files changed, 290 insertions(+), 2 deletions(-) diff --git a/doc/user.pod b/doc/user.pod index 1c79aca2..d0e41ae6 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -600,6 +600,10 @@ of the original object. __isl_keep isl_pw_aff *pwaff); __isl_give isl_space *isl_multi_aff_get_space( __isl_keep isl_multi_aff *maff); + __isl_give isl_space *isl_pw_multi_aff_get_domain_space( + __isl_keep isl_pw_multi_aff *pma); + __isl_give isl_space *isl_pw_multi_aff_get_space( + __isl_keep isl_pw_multi_aff *pma); #include __isl_give isl_space *isl_point_get_space( @@ -1204,7 +1208,7 @@ A (basic) set or relation can also be constructed from a (piecewise) (multiple) affine expression or a list of affine expressions (See L<"Piecewise Quasi Affine Expressions"> and -L<"Multiple Quasi Affine Expressions">). +L<"Piecewise Multiple Quasi Affine Expressions">). __isl_give isl_basic_map *isl_basic_map_from_aff( __isl_take isl_aff *aff); @@ -1217,6 +1221,10 @@ L<"Multiple Quasi Affine Expressions">). __isl_take isl_aff_list *list); __isl_give isl_basic_map *isl_basic_map_from_multi_aff( __isl_take isl_multi_aff *maff) + __isl_give isl_set *isl_set_from_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma); + __isl_give isl_map *isl_map_from_pw_multi_aff( + __isl_take isl_pw_multi_aff *pma); The C argument describes the domain of the resulting basic relation. It is required because the C may consist @@ -2893,7 +2901,7 @@ An expression can be printed using __isl_take isl_printer *p, __isl_keep isl_pw_aff *pwaff); -=head2 Multiple Quasi Affine Expressions +=head2 Piecewise Multiple Quasi Affine Expressions An C object represents a sequence of zero or more affine expressions, all defined on the same domain space. @@ -2906,6 +2914,17 @@ following function. __isl_take isl_space *space, __isl_take isl_aff_list *list); +An empty piecewise multiple quasi affine expression (one with no cells) or +a piecewise multiple quasi affine expression with a single cell can +be created using the following functions. + + #include + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_empty( + __isl_take isl_space *space); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_alloc( + __isl_take isl_set *set, + __isl_take isl_multi_aff *maff); + Multiple quasi affine expressions can be copied and freed using #include @@ -2913,18 +2932,49 @@ Multiple quasi affine expressions can be copied and freed using __isl_keep isl_multi_aff *maff); void *isl_multi_aff_free(__isl_take isl_multi_aff *maff); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_copy( + __isl_keep isl_pw_multi_aff *pma); + void *isl_pw_multi_aff_free( + __isl_take isl_pw_multi_aff *pma); + The expression can be inspected using #include isl_ctx *isl_multi_aff_get_ctx( __isl_keep isl_multi_aff *maff); + isl_ctx *isl_pw_multi_aff_get_ctx( + __isl_keep isl_pw_multi_aff *pma); unsigned isl_multi_aff_dim(__isl_keep isl_multi_aff *maff, enum isl_dim_type type); + unsigned isl_pw_multi_aff_dim( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); __isl_give isl_aff *isl_multi_aff_get_aff( __isl_keep isl_multi_aff *multi, int pos); + const char *isl_pw_multi_aff_get_dim_name( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type, unsigned pos); + __isl_give isl_id *isl_pw_multi_aff_get_dim_id( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type, unsigned pos); const char *isl_multi_aff_get_tuple_name( __isl_keep isl_multi_aff *multi, enum isl_dim_type type); + const char *isl_pw_multi_aff_get_tuple_name( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); + int isl_pw_multi_aff_has_tuple_id( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); + __isl_give isl_id *isl_pw_multi_aff_get_tuple_id( + __isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); + + int isl_pw_multi_aff_foreach_piece( + __isl_keep isl_pw_multi_aff *pma, + int (*fn)(__isl_take isl_set *set, + __isl_take isl_multi_aff *maff, + void *user), void *user); It can be modified using @@ -2932,12 +2982,18 @@ It can be modified using __isl_give isl_multi_aff *isl_multi_aff_set_dim_name( __isl_take isl_multi_aff *maff, enum isl_dim_type type, unsigned pos, const char *s); + __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_tuple_id( + __isl_take isl_pw_multi_aff *pma, + enum isl_dim_type type, __isl_take isl_id *id); To check whether two multiple affine expressions are obviously equal to each other, use int isl_multi_aff_plain_is_equal(__isl_keep isl_multi_aff *maff1, __isl_keep isl_multi_aff *maff2); + int isl_pw_multi_aff_plain_is_equal( + __isl_keep isl_pw_multi_aff *pma1, + __isl_keep isl_pw_multi_aff *pma2); Operations include @@ -2945,9 +3001,15 @@ Operations include __isl_give isl_multi_aff *isl_multi_aff_add( __isl_take isl_multi_aff *maff1, __isl_take isl_multi_aff *maff2); + __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_multi_aff *isl_multi_aff_scale( __isl_take isl_multi_aff *maff, isl_int f); + __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_multi_aff *isl_multi_aff_gist( __isl_take isl_multi_aff *maff, __isl_take isl_set *context); @@ -2958,6 +3020,9 @@ An expression can be printed using __isl_give isl_printer *isl_printer_print_multi_aff( __isl_take isl_printer *p, __isl_keep isl_multi_aff *maff); + __isl_give isl_printer *isl_printer_print_pw_multi_aff( + __isl_take isl_printer *p, + __isl_keep isl_pw_multi_aff *pma); =head2 Points diff --git a/include/isl/aff.h b/include/isl/aff.h index 08f6ae94..2bc50375 100644 --- a/include/isl/aff.h +++ b/include/isl/aff.h @@ -251,6 +251,62 @@ __isl_give isl_printer *isl_printer_print_multi_aff(__isl_take isl_printer *p, void isl_multi_aff_dump(__isl_keep isl_multi_aff *maff); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_alloc(__isl_take isl_set *set, + __isl_take isl_multi_aff *maff); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_copy( + __isl_keep isl_pw_multi_aff *pma); +void *isl_pw_multi_aff_free(__isl_take isl_pw_multi_aff *pma); + +unsigned isl_pw_multi_aff_dim(__isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); + +isl_ctx *isl_pw_multi_aff_get_ctx(__isl_keep isl_pw_multi_aff *pma); +__isl_give isl_space *isl_pw_multi_aff_get_domain_space( + __isl_keep isl_pw_multi_aff *pma); +__isl_give isl_space *isl_pw_multi_aff_get_space( + __isl_keep isl_pw_multi_aff *pma); +const char *isl_pw_multi_aff_get_tuple_name(__isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); +__isl_give isl_id *isl_pw_multi_aff_get_tuple_id( + __isl_keep isl_pw_multi_aff *pma, enum isl_dim_type type); +int isl_pw_multi_aff_has_tuple_id(__isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_tuple_id( + __isl_take isl_pw_multi_aff *pma, + enum isl_dim_type type, __isl_take isl_id *id); + +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_empty(__isl_take isl_space *space); + +const char *isl_pw_multi_aff_get_dim_name(__isl_keep isl_pw_multi_aff *pma, + enum isl_dim_type type, unsigned pos); +__isl_give isl_id *isl_pw_multi_aff_get_dim_id( + __isl_keep isl_pw_multi_aff *pma, enum isl_dim_type type, + unsigned pos); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_dim_id( + __isl_take isl_pw_multi_aff *pma, + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id); + +int isl_pw_multi_aff_plain_is_equal(__isl_keep isl_pw_multi_aff *pma1, + __isl_keep isl_pw_multi_aff *pma2); + +__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_intersect_domain( + __isl_take isl_pw_multi_aff *pma, __isl_take isl_set *set); + +int isl_pw_multi_aff_foreach_piece(__isl_keep isl_pw_multi_aff *pma, + int (*fn)(__isl_take isl_set *set, __isl_take isl_multi_aff *maff, + void *user), void *user); + +__isl_give isl_map *isl_map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma); +__isl_give isl_set *isl_set_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma); + +__isl_give isl_printer *isl_printer_print_pw_multi_aff(__isl_take isl_printer *p, + __isl_keep isl_pw_multi_aff *pma); + +void isl_pw_multi_aff_dump(__isl_keep isl_pw_multi_aff *pma); + #if defined(__cplusplus) } #endif diff --git a/include/isl/aff_type.h b/include/isl/aff_type.h index 5bcfffb2..152eeb55 100644 --- a/include/isl/aff_type.h +++ b/include/isl/aff_type.h @@ -10,4 +10,7 @@ typedef struct isl_pw_aff isl_pw_aff; struct isl_multi_aff; typedef struct isl_multi_aff isl_multi_aff; +struct isl_pw_multi_aff; +typedef struct isl_pw_multi_aff isl_pw_multi_aff; + #endif diff --git a/isl_aff.c b/isl_aff.c index 73aff169..bed9e4ac 100644 --- a/isl_aff.c +++ b/isl_aff.c @@ -1968,6 +1968,32 @@ error: return NULL; } +/* Exploit the equalities in "eq" to simplify the affine expressions. + */ +static __isl_give isl_multi_aff *isl_multi_aff_substitute_equalities( + __isl_take isl_multi_aff *maff, __isl_take isl_basic_set *eq) +{ + int i; + + maff = isl_multi_aff_cow(maff); + if (!maff || !eq) + goto error; + + for (i = 0; i < maff->n; ++i) { + maff->p[i] = isl_aff_substitute_equalities(maff->p[i], + isl_basic_set_copy(eq)); + if (!maff->p[i]) + goto error; + } + + isl_basic_set_free(eq); + return maff; +error: + isl_basic_set_free(eq); + isl_multi_aff_free(maff); + return NULL; +} + __isl_give isl_multi_aff *isl_multi_aff_scale(__isl_take isl_multi_aff *maff, isl_int f) { @@ -2067,3 +2093,68 @@ __isl_give isl_multi_aff *isl_multi_aff_drop_dims(__isl_take isl_multi_aff *maff return maff; } + +#undef PW +#define PW isl_pw_multi_aff +#undef EL +#define EL isl_multi_aff +#undef EL_IS_ZERO +#define EL_IS_ZERO is_empty +#undef ZERO +#define ZERO empty +#undef IS_ZERO +#define IS_ZERO is_empty +#undef FIELD +#define FIELD maff + +#define NO_NEG +#define NO_EVAL +#define NO_OPT +#define NO_INVOLVES_DIMS +#define NO_MOVE_DIMS +#define NO_INSERT_DIMS +#define NO_LIFT +#define NO_MORPH + +#include + +/* Construct a map mapping the domain the piecewise multi-affine expression + * to its range, with each dimension in the range equated to the + * corresponding affine expression on its cell. + */ +__isl_give isl_map *isl_map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma) +{ + int i; + isl_map *map; + + if (!pma) + return NULL; + + map = isl_map_empty(isl_pw_multi_aff_get_space(pma)); + + for (i = 0; i < pma->n; ++i) { + isl_multi_aff *maff; + isl_basic_map *bmap; + isl_map *map_i; + + maff = isl_multi_aff_copy(pma->p[i].maff); + bmap = isl_basic_map_from_multi_aff(maff); + map_i = isl_map_from_basic_map(bmap); + map_i = isl_map_intersect_domain(map_i, + isl_set_copy(pma->p[i].set)); + map = isl_map_union_disjoint(map, map_i); + } + + isl_pw_multi_aff_free(pma); + return map; +} + +__isl_give isl_set *isl_set_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma) +{ + if (!isl_space_is_set(pma->dim)) + isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid, + "isl_pw_multi_aff cannot be converted into an isl_set", + return isl_pw_multi_aff_free(pma)); + + return isl_map_from_pw_multi_aff(pma); +} diff --git a/isl_aff_private.h b/isl_aff_private.h index 1b5ab709..aaedc8b8 100644 --- a/isl_aff_private.h +++ b/isl_aff_private.h @@ -31,6 +31,22 @@ struct isl_pw_aff { struct isl_pw_aff_piece p[1]; }; +struct isl_pw_multi_aff_piece { + isl_set *set; + isl_multi_aff *maff; +}; + +struct isl_pw_multi_aff { + int ref; + + isl_space *dim; + + int n; + + size_t size; + struct isl_pw_multi_aff_piece p[1]; +}; + __isl_give isl_aff *isl_aff_alloc(__isl_take isl_local_space *ls); __isl_give isl_aff *isl_aff_reset_space_and_domain(__isl_take isl_aff *aff, @@ -43,6 +59,8 @@ __isl_give isl_aff *isl_aff_realign_domain(__isl_take isl_aff *aff, __isl_give isl_aff *isl_aff_expand_divs( __isl_take isl_aff *aff, __isl_take isl_mat *div, int *exp); +__isl_give isl_pw_aff *isl_pw_aff_alloc_size(__isl_take isl_space *space, + int n); __isl_give isl_pw_aff *isl_pw_aff_reset_space(__isl_take isl_pw_aff *pwaff, __isl_take isl_space *dim); __isl_give isl_pw_aff *isl_pw_aff_reset_domain_space( @@ -66,4 +84,15 @@ __isl_give isl_multi_aff *isl_multi_aff_drop_dims( __isl_take isl_multi_aff *maff, enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_domain_space( + __isl_take isl_pw_multi_aff *pwmaff, __isl_take isl_space *space); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_space( + __isl_take isl_pw_multi_aff *pwmaff, __isl_take isl_space *space); +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_add_disjoint( + __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2); + +__isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_out( + __isl_take isl_pw_multi_aff *pma, + enum isl_dim_type type, unsigned first, unsigned n); + #endif diff --git a/isl_output.c b/isl_output.c index 98c26477..1451b1d1 100644 --- a/isl_output.c +++ b/isl_output.c @@ -2296,3 +2296,44 @@ error: isl_printer_free(p); return NULL; } + +static __isl_give isl_printer *print_pw_multi_aff_isl(__isl_take isl_printer *p, + __isl_keep isl_pw_multi_aff *pma) +{ + int i; + + if (!pma) + goto error; + + if (isl_space_dim(pma->dim, isl_dim_param) > 0) { + p = print_tuple(pma->dim, p, isl_dim_param, 0, NULL, NULL); + p = isl_printer_print_str(p, " -> "); + } + p = isl_printer_print_str(p, "{ "); + for (i = 0; i < pma->n; ++i) { + if (i) + p = isl_printer_print_str(p, "; "); + p = print_multi_aff(p, pma->p[i].maff); + p = print_disjuncts((isl_map *)pma->p[i].set, p, 0); + } + p = isl_printer_print_str(p, " }"); + return p; +error: + isl_printer_free(p); + return NULL; +} + +__isl_give isl_printer *isl_printer_print_pw_multi_aff( + __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma) +{ + if (!p || !pma) + goto error; + + if (p->output_format == ISL_FORMAT_ISL) + return print_pw_multi_aff_isl(p, pma); + isl_die(p->ctx, isl_error_unsupported, "unsupported output format", + goto error); +error: + isl_printer_free(p); + return NULL; +} diff --git a/print.c b/print.c index 5db00f62..4e0aecd4 100644 --- a/print.c +++ b/print.c @@ -72,3 +72,6 @@ #undef BASE #define BASE multi_aff #include +#undef BASE +#define BASE pw_multi_aff +#include -- 2.11.4.GIT