From 68bc0409a868d331f033be5fed23e2a9fec91a36 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 17 Jun 2014 12:20:59 +0200 Subject: [PATCH] add isl_multi_union_pw_aff_read_from_str Signed-off-by: Sven Verdoolaege --- doc/user.pod | 3 + include/isl/aff.h | 2 + isl_input.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+) diff --git a/doc/user.pod b/doc/user.pod index 05e7a1d2..77f7ef6f 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -3287,6 +3287,9 @@ Objects can be read from input using the following functions. __isl_give isl_union_pw_multi_aff * isl_union_pw_multi_aff_read_from_str( isl_ctx *ctx, const char *str); + __isl_give isl_multi_union_pw_aff * + isl_multi_union_pw_aff_read_from_str( + isl_ctx *ctx, const char *str); #include __isl_give isl_union_pw_qpolynomial * diff --git a/include/isl/aff.h b/include/isl/aff.h index c83d09e4..f0d02584 100644 --- a/include/isl/aff.h +++ b/include/isl/aff.h @@ -849,6 +849,8 @@ __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_map( __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_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( diff --git a/isl_input.c b/isl_input.c index 771d437a..1393258f 100644 --- a/isl_input.c +++ b/isl_input.c @@ -3479,6 +3479,200 @@ __isl_give isl_multi_pw_aff *isl_multi_pw_aff_read_from_str(isl_ctx *ctx, return mpa; } +/* Read the body of an isl_union_pw_aff from "s" with parameter domain "dom". + */ +static __isl_give isl_union_pw_aff *read_union_pw_aff_with_dom( + struct isl_stream *s, __isl_take isl_set *dom, struct vars *v) +{ + isl_pw_aff *pa; + isl_union_pw_aff *upa = NULL; + isl_set *aff_dom; + int n; + + n = v->n; + aff_dom = read_aff_domain(s, isl_set_copy(dom), v); + pa = read_pw_aff_with_dom(s, aff_dom, v); + vars_drop(v, v->n - n); + + upa = isl_union_pw_aff_from_pw_aff(pa); + + while (isl_stream_eat_if_available(s, ';')) { + isl_pw_aff *pa_i; + isl_union_pw_aff *upa_i; + + n = v->n; + aff_dom = read_aff_domain(s, isl_set_copy(dom), v); + pa_i = read_pw_aff_with_dom(s, aff_dom, v); + vars_drop(v, v->n - n); + + upa_i = isl_union_pw_aff_from_pw_aff(pa_i); + upa = isl_union_pw_aff_union_add(upa, upa_i); + } + + isl_set_free(dom); + return upa; +} + +/* This function is called for each element in a tuple inside + * isl_stream_read_multi_union_pw_aff. + * + * Read a '{', the union piecewise affine expression body and a '}' and + * add the isl_union_pw_aff to *list. + */ +static __isl_give isl_space *read_union_pw_aff_el(struct isl_stream *s, + struct vars *v, __isl_take isl_space *space, int rational, void *user) +{ + isl_set *dom; + isl_union_pw_aff *upa; + isl_union_pw_aff_list **list = (isl_union_pw_aff_list **) user; + + dom = isl_set_universe(isl_space_params(isl_space_copy(space))); + if (isl_stream_eat(s, '{')) + goto error; + upa = read_union_pw_aff_with_dom(s, dom, v); + *list = isl_union_pw_aff_list_add(*list, upa); + if (isl_stream_eat(s, '}')) + return isl_space_free(space); + if (!*list) + return isl_space_free(space); + return space; +error: + isl_set_free(dom); + return isl_space_free(space); +} + +/* Do the next tokens in "s" correspond to an empty tuple? + * In particular, does the stream start with a '[', followed by a ']', + * not followed by a "->"? + */ +static int next_is_empty_tuple(struct isl_stream *s) +{ + struct isl_token *tok, *tok2, *tok3; + int is_empty_tuple = 0; + + tok = isl_stream_next_token(s); + if (!tok) + return 0; + if (tok->type != '[') { + isl_stream_push_token(s, tok); + return 0; + } + + tok2 = isl_stream_next_token(s); + if (tok2 && tok2->type == ']') { + tok3 = isl_stream_next_token(s); + is_empty_tuple = !tok || tok->type != ISL_TOKEN_TO; + if (tok3) + isl_stream_push_token(s, tok3); + } + if (tok2) + isl_stream_push_token(s, tok2); + isl_stream_push_token(s, tok); + + return is_empty_tuple; +} + +/* Do the next tokens in "s" correspond to a tuple of parameters? + * In particular, does the stream start with a '[' that is not + * followed by a '{' or a nested tuple? + */ +static int next_is_param_tuple(struct isl_stream *s) +{ + struct isl_token *tok, *tok2; + int is_tuple; + + tok = isl_stream_next_token(s); + if (!tok) + return 0; + if (tok->type != '[' || next_is_tuple(s)) { + isl_stream_push_token(s, tok); + return 0; + } + + tok2 = isl_stream_next_token(s); + is_tuple = tok2 && tok2->type != '{'; + if (tok2) + isl_stream_push_token(s, tok2); + isl_stream_push_token(s, tok); + + return is_tuple; +} + +/* Read an isl_multi_union_pw_aff from "s". + * + * The input has the form + * + * [{ [..] : ... ; [..] : ... }, { [..] : ... ; [..] : ... }] + * + * or + * + * [..] -> [{ [..] : ... ; [..] : ... }, { [..] : ... ; [..] : ... }] + * + * We first check for the special case of an empty tuple "[]". + * Then we check if there are any parameters. + * Finally, we read the tuple, collecting the individual isl_union_pw_aff + * elements in a list and construct the result from the tuple space and + * the list. + */ +__isl_give isl_multi_union_pw_aff *isl_stream_read_multi_union_pw_aff( + struct isl_stream *s) +{ + struct vars *v; + isl_set *dom = NULL; + isl_space *space; + isl_multi_union_pw_aff *mupa = NULL; + isl_union_pw_aff_list *list; + + if (next_is_empty_tuple(s)) { + if (isl_stream_eat(s, '[')) + return NULL; + if (isl_stream_eat(s, ']')) + return NULL; + space = isl_space_set_alloc(s->ctx, 0, 0); + return isl_multi_union_pw_aff_zero(space); + } + + v = vars_new(s->ctx); + if (!v) + return NULL; + + dom = isl_set_universe(isl_space_params_alloc(s->ctx, 0)); + if (next_is_param_tuple(s)) { + dom = read_map_tuple(s, dom, isl_dim_param, v, 1, 0); + if (isl_stream_eat(s, ISL_TOKEN_TO)) + goto error; + } + space = isl_set_get_space(dom); + isl_set_free(dom); + list = isl_union_pw_aff_list_alloc(s->ctx, 0); + space = read_tuple_space(s, v, space, 1, 0, + &read_union_pw_aff_el, &list); + mupa = isl_multi_union_pw_aff_from_union_pw_aff_list(space, list); + + vars_free(v); + + return mupa; +error: + vars_free(v); + isl_set_free(dom); + isl_multi_union_pw_aff_free(mupa); + return NULL; +} + +/* Read an isl_multi_union_pw_aff from "str". + */ +__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_read_from_str( + isl_ctx *ctx, const char *str) +{ + isl_multi_union_pw_aff *mupa; + struct isl_stream *s = isl_stream_new_str(ctx, str); + if (!s) + return NULL; + mupa = isl_stream_read_multi_union_pw_aff(s); + isl_stream_free(s); + return mupa; +} + __isl_give isl_union_pw_qpolynomial *isl_stream_read_union_pw_qpolynomial( struct isl_stream *s) { -- 2.11.4.GIT