diff options
Diffstat (limited to 'isl_multi_templ.c')
-rw-r--r-- | isl_multi_templ.c | 567 |
1 files changed, 551 insertions, 16 deletions
diff --git a/isl_multi_templ.c b/isl_multi_templ.c index d73eb500..c0291862 100644 --- a/isl_multi_templ.c +++ b/isl_multi_templ.c @@ -1,6 +1,6 @@ /* * Copyright 2011 Sven Verdoolaege - * Copyright 2012 Ecole Normale Superieure + * Copyright 2012-2013 Ecole Normale Superieure * * Use of this software is governed by the MIT license * @@ -105,7 +105,7 @@ __isl_give MULTI(BASE) *FN(MULTI(BASE),copy)(__isl_keep MULTI(BASE) *multi) return multi; } -void *FN(MULTI(BASE),free)(__isl_take MULTI(BASE) *multi) +__isl_null MULTI(BASE) *FN(MULTI(BASE),free)(__isl_take MULTI(BASE) *multi) { int i; @@ -123,6 +123,31 @@ void *FN(MULTI(BASE),free)(__isl_take MULTI(BASE) *multi) return NULL; } +/* 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. + */ +int FN(MULTI(BASE),involves_dims)(__isl_keep MULTI(BASE) *multi, + enum isl_dim_type type, unsigned first, unsigned n) +{ + int i; + + if (!multi) + return -1; + if (multi->n == 0 || n == 0) + return 0; + + for (i = 0; i < multi->n; ++i) { + int involves; + + involves = FN(EL,involves_dims)(multi->p[i], type, first, n); + if (involves < 0 || involves) + return involves; + } + + return 0; +} + __isl_give MULTI(BASE) *FN(MULTI(BASE),insert_dims)( __isl_take MULTI(BASE) *multi, enum isl_dim_type type, unsigned first, unsigned n) @@ -171,6 +196,25 @@ unsigned FN(MULTI(BASE),dim)(__isl_keep MULTI(BASE) *multi, return multi ? isl_space_dim(multi->space, type) : 0; } +/* Return the position of the first dimension of "type" with id "id". + * Return -1 if there is no such dimension. + */ +int FN(MULTI(BASE),find_dim_by_id)(__isl_keep MULTI(BASE) *multi, + enum isl_dim_type type, __isl_keep isl_id *id) +{ + if (!multi) + return -1; + return isl_space_find_dim_by_id(multi->space, type, id); +} + +/* Return the id of the given dimension. + */ +__isl_give isl_id *FN(MULTI(BASE),get_dim_id)(__isl_keep MULTI(BASE) *multi, + enum isl_dim_type type, unsigned pos) +{ + return multi ? isl_space_get_dim_id(multi->space, type, pos) : NULL; +} + __isl_give MULTI(BASE) *FN(MULTI(BASE),set_dim_name)( __isl_take MULTI(BASE) *multi, enum isl_dim_type type, unsigned pos, const char *s) @@ -202,6 +246,22 @@ const char *FN(MULTI(BASE),get_tuple_name)(__isl_keep MULTI(BASE) *multi, return multi ? isl_space_get_tuple_name(multi->space, type) : NULL; } +/* Does the specified tuple have an id? + */ +int FN(MULTI(BASE),has_tuple_id)(__isl_keep MULTI(BASE) *multi, + enum isl_dim_type type) +{ + return multi ? isl_space_has_tuple_id(multi->space, type) : -1; +} + +/* Return the id of the specified tuple. + */ +__isl_give isl_id *FN(MULTI(BASE),get_tuple_id)(__isl_keep MULTI(BASE) *multi, + enum isl_dim_type type) +{ + return multi ? isl_space_get_tuple_id(multi->space, type) : NULL; +} + __isl_give EL *FN(FN(MULTI(BASE),get),BASE)(__isl_keep MULTI(BASE) *multi, int pos) { @@ -221,12 +281,23 @@ __isl_give MULTI(BASE) *FN(FN(MULTI(BASE),set),BASE)( { isl_space *multi_space = NULL; isl_space *el_space = NULL; + int match; multi = FN(MULTI(BASE),cow)(multi); if (!multi || !el) goto error; multi_space = FN(MULTI(BASE),get_space)(multi); + match = FN(EL,matching_params)(el, multi_space); + if (match < 0) + goto error; + if (!match) { + multi = FN(MULTI(BASE),align_params)(multi, + FN(EL,get_space)(el)); + isl_space_free(multi_space); + multi_space = FN(MULTI(BASE),get_space)(multi); + el = FN(EL,align_params)(el, isl_space_copy(multi_space)); + } if (FN(EL,check_match_domain_space)(el, multi_space) < 0) goto error; @@ -302,6 +373,28 @@ __isl_give MULTI(BASE) *FN(MULTI(BASE),reset_space)( return FN(MULTI(BASE),reset_space_and_domain)(multi, space, domain); } +/* Set the id of the given dimension of "multi" to "id". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),set_dim_id)( + __isl_take MULTI(BASE) *multi, + enum isl_dim_type type, unsigned pos, __isl_take isl_id *id) +{ + isl_space *space; + + multi = FN(MULTI(BASE),cow)(multi); + if (!multi || !id) + goto error; + + space = FN(MULTI(BASE),get_space)(multi); + space = isl_space_set_dim_id(space, type, pos, id); + + return FN(MULTI(BASE),reset_space)(multi, space); +error: + isl_id_free(id); + FN(MULTI(BASE),free)(multi); + return NULL; +} + __isl_give MULTI(BASE) *FN(MULTI(BASE),set_tuple_name)( __isl_keep MULTI(BASE) *multi, enum isl_dim_type type, const char *s) @@ -319,19 +412,58 @@ __isl_give MULTI(BASE) *FN(MULTI(BASE),set_tuple_name)( } __isl_give MULTI(BASE) *FN(MULTI(BASE),set_tuple_id)( - __isl_keep MULTI(BASE) *multi, enum isl_dim_type type, + __isl_take MULTI(BASE) *multi, enum isl_dim_type type, __isl_take isl_id *id) { isl_space *space; multi = FN(MULTI(BASE),cow)(multi); if (!multi) - return isl_id_free(id); + goto error; space = FN(MULTI(BASE),get_space)(multi); space = isl_space_set_tuple_id(space, type, id); return FN(MULTI(BASE),reset_space)(multi, space); +error: + isl_id_free(id); + return NULL; +} + +/* Drop the id on the specified tuple. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),reset_tuple_id)( + __isl_take MULTI(BASE) *multi, enum isl_dim_type type) +{ + isl_space *space; + + if (!multi) + return NULL; + if (!FN(MULTI(BASE),has_tuple_id)(multi, type)) + return multi; + + multi = FN(MULTI(BASE),cow)(multi); + if (!multi) + return NULL; + + space = FN(MULTI(BASE),get_space)(multi); + space = isl_space_reset_tuple_id(space, type); + + return FN(MULTI(BASE),reset_space)(multi, space); +} + +/* Reset the user pointer on all identifiers of parameters and tuples + * of the space of "multi". + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),reset_user)( + __isl_take MULTI(BASE) *multi) +{ + isl_space *space; + + space = FN(MULTI(BASE),get_space)(multi); + space = isl_space_reset_user(space); + + return FN(MULTI(BASE),reset_space)(multi, space); } __isl_give MULTI(BASE) *FN(MULTI(BASE),realign_domain)( @@ -367,10 +499,17 @@ __isl_give MULTI(BASE) *FN(MULTI(BASE),align_params)( __isl_take MULTI(BASE) *multi, __isl_take isl_space *model) { isl_ctx *ctx; + isl_reordering *exp; if (!multi || !model) goto error; + if (isl_space_match(multi->space, isl_dim_param, + model, isl_dim_param)) { + isl_space_free(model); + return multi; + } + ctx = isl_space_get_ctx(model); if (!isl_space_has_named_params(model)) isl_die(ctx, isl_error_invalid, @@ -378,16 +517,12 @@ __isl_give MULTI(BASE) *FN(MULTI(BASE),align_params)( if (!isl_space_has_named_params(multi->space)) isl_die(ctx, isl_error_invalid, "input has unnamed parameters", goto error); - if (!isl_space_match(multi->space, isl_dim_param, - model, isl_dim_param)) { - isl_reordering *exp; - model = isl_space_params(model); - exp = isl_parameter_alignment_reordering(multi->space, model); - exp = isl_reordering_extend_space(exp, + model = isl_space_params(model); + exp = isl_parameter_alignment_reordering(multi->space, model); + exp = isl_reordering_extend_space(exp, FN(MULTI(BASE),get_domain_space)(multi)); - multi = FN(MULTI(BASE),realign_domain)(multi, exp); - } + multi = FN(MULTI(BASE),realign_domain)(multi, exp); isl_space_free(model); return multi; @@ -397,7 +532,7 @@ error: return NULL; } -#ifndef NO_GIST +#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, @@ -423,7 +558,9 @@ error: 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) { @@ -464,6 +601,85 @@ __isl_give MULTI(BASE) *FN(MULTI(BASE),gist_params)( } #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) { @@ -632,10 +848,42 @@ __isl_give MULTI(BASE) *FN(MULTI(BASE),drop_dims)( return multi; } +/* Align the parameters of "multi1" and "multi2" (if needed) and call "fn". + */ +static __isl_give MULTI(BASE) *FN(MULTI(BASE),align_params_multi_multi_and)( + __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2, + __isl_give MULTI(BASE) *(*fn)(__isl_take MULTI(BASE) *multi1, + __isl_take MULTI(BASE) *multi2)) +{ + isl_ctx *ctx; + + if (!multi1 || !multi2) + goto error; + if (isl_space_match(multi1->space, isl_dim_param, + multi2->space, isl_dim_param)) + return fn(multi1, multi2); + ctx = FN(MULTI(BASE),get_ctx)(multi1); + if (!isl_space_has_named_params(multi1->space) || + !isl_space_has_named_params(multi2->space)) + isl_die(ctx, isl_error_invalid, + "unaligned unnamed parameters", goto error); + multi1 = FN(MULTI(BASE),align_params)(multi1, + FN(MULTI(BASE),get_space)(multi2)); + multi2 = FN(MULTI(BASE),align_params)(multi2, + FN(MULTI(BASE),get_space)(multi1)); + return fn(multi1, multi2); +error: + FN(MULTI(BASE),free)(multi1); + FN(MULTI(BASE),free)(multi2); + return NULL; +} + /* Given two MULTI(BASE)s A -> B and C -> D, - * construct a MULTI(BASE) (A * C) -> (B, D). + * construct a MULTI(BASE) (A * C) -> [B -> D]. + * + * The parameters are assumed to have been aligned. */ -__isl_give MULTI(BASE) *FN(MULTI(BASE),range_product)( +static __isl_give MULTI(BASE) *FN(MULTI(BASE),range_product_aligned)( __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2) { int i, n1, n2; @@ -672,6 +920,129 @@ error: return NULL; } +/* Given two MULTI(BASE)s A -> B and C -> D, + * construct a MULTI(BASE) (A * C) -> [B -> D]. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),range_product)( + __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2) +{ + return FN(MULTI(BASE),align_params_multi_multi_and)(multi1, multi2, + &FN(MULTI(BASE),range_product_aligned)); +} + +/* Is the range of "multi" a wrapped relation? + */ +int FN(MULTI(BASE),range_is_wrapping)(__isl_keep MULTI(BASE) *multi) +{ + if (!multi) + return -1; + return isl_space_range_is_wrapping(multi->space); +} + +/* Given a function A -> [B -> C], extract the function A -> B. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),range_factor_domain)( + __isl_take MULTI(BASE) *multi) +{ + isl_space *space; + int total, keep; + + if (!multi) + return NULL; + if (!isl_space_range_is_wrapping(multi->space)) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid, + "range is not a product", + return FN(MULTI(BASE),free)(multi)); + + space = FN(MULTI(BASE),get_space)(multi); + total = isl_space_dim(space, isl_dim_out); + space = isl_space_range_factor_domain(space); + keep = isl_space_dim(space, isl_dim_out); + multi = FN(MULTI(BASE),drop_dims)(multi, + isl_dim_out, keep, total - keep); + multi = FN(MULTI(BASE),reset_space)(multi, space); + + return multi; +} + +/* Given a function A -> [B -> C], extract the function A -> C. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),range_factor_range)( + __isl_take MULTI(BASE) *multi) +{ + isl_space *space; + int total, keep; + + if (!multi) + return NULL; + if (!isl_space_range_is_wrapping(multi->space)) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid, + "range is not a product", + return FN(MULTI(BASE),free)(multi)); + + space = FN(MULTI(BASE),get_space)(multi); + total = isl_space_dim(space, isl_dim_out); + space = isl_space_range_factor_range(space); + keep = isl_space_dim(space, isl_dim_out); + multi = FN(MULTI(BASE),drop_dims)(multi, isl_dim_out, 0, total - keep); + multi = FN(MULTI(BASE),reset_space)(multi, space); + + return multi; +} + +/* Given two MULTI(BASE)s A -> B and C -> D, + * construct a MULTI(BASE) [A -> C] -> [B -> D]. + * + * The parameters are assumed to have been aligned. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),product_aligned)( + __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2) +{ + int i; + EL *el; + isl_space *space; + MULTI(BASE) *res; + int in1, in2, out1, out2; + + in1 = FN(MULTI(BASE),dim)(multi1, isl_dim_in); + in2 = FN(MULTI(BASE),dim)(multi2, isl_dim_in); + out1 = FN(MULTI(BASE),dim)(multi1, isl_dim_out); + out2 = FN(MULTI(BASE),dim)(multi2, isl_dim_out); + space = isl_space_product(FN(MULTI(BASE),get_space)(multi1), + FN(MULTI(BASE),get_space)(multi2)); + res = FN(MULTI(BASE),alloc)(isl_space_copy(space)); + space = isl_space_domain(space); + + for (i = 0; i < out1; ++i) { + el = FN(FN(MULTI(BASE),get),BASE)(multi1, i); + el = FN(EL,insert_dims)(el, isl_dim_in, in1, in2); + el = FN(EL,reset_domain_space)(el, isl_space_copy(space)); + res = FN(FN(MULTI(BASE),set),BASE)(res, i, el); + } + + for (i = 0; i < out2; ++i) { + el = FN(FN(MULTI(BASE),get),BASE)(multi2, i); + el = FN(EL,insert_dims)(el, isl_dim_in, 0, in1); + el = FN(EL,reset_domain_space)(el, isl_space_copy(space)); + res = FN(FN(MULTI(BASE),set),BASE)(res, out1 + i, el); + } + + isl_space_free(space); + FN(MULTI(BASE),free)(multi1); + FN(MULTI(BASE),free)(multi2); + return res; +} + +/* Given two MULTI(BASE)s A -> B and C -> D, + * construct a MULTI(BASE) [A -> C] -> [B -> D]. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),product)( + __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2) +{ + return FN(MULTI(BASE),align_params_multi_multi_and)(multi1, multi2, + &FN(MULTI(BASE),product_aligned)); +} + __isl_give MULTI(BASE) *FN(MULTI(BASE),flatten_range)( __isl_take MULTI(BASE) *multi) { @@ -693,7 +1064,7 @@ __isl_give MULTI(BASE) *FN(MULTI(BASE),flatten_range)( } /* Given two MULTI(BASE)s A -> B and C -> D, - * construct a MULTI(BASE) (A * C) -> [B -> D]. + * construct a MULTI(BASE) (A * C) -> (B, D). */ __isl_give MULTI(BASE) *FN(MULTI(BASE),flat_range_product)( __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2) @@ -909,3 +1280,167 @@ error: isl_multi_val_free(mv); return FN(MULTI(BASE),free)(multi); } + +/* Divide the elements of "multi" by the corresponding element of "mv" + * and return the result. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),scale_down_multi_val)( + __isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv) +{ + int i; + + if (!multi || !mv) + goto error; + + if (!isl_space_tuple_match(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,scale_down_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". + * + * We only support moving input dimensions to parameters and vice versa. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),move_dims)(__isl_take MULTI(BASE) *multi, + enum isl_dim_type dst_type, unsigned dst_pos, + enum isl_dim_type src_type, unsigned src_pos, unsigned n) +{ + int i; + + if (!multi) + return NULL; + + if (n == 0 && + !isl_space_is_named_or_nested(multi->space, src_type) && + !isl_space_is_named_or_nested(multi->space, dst_type)) + return multi; + + if (dst_type == isl_dim_out || src_type == isl_dim_out) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid, + "cannot move output/set dimension", + return FN(MULTI(BASE),free)(multi)); + if (dst_type == isl_dim_div || src_type == isl_dim_div) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid, + "cannot move divs", + return FN(MULTI(BASE),free)(multi)); + if (src_pos + n > isl_space_dim(multi->space, src_type)) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid, + "range out of bounds", + return FN(MULTI(BASE),free)(multi)); + if (dst_type == src_type) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_unsupported, + "moving dims within the same type not supported", + return FN(MULTI(BASE),free)(multi)); + + multi = FN(MULTI(BASE),cow)(multi); + if (!multi) + return NULL; + + multi->space = isl_space_move_dims(multi->space, dst_type, dst_pos, + src_type, src_pos, n); + if (!multi->space) + return FN(MULTI(BASE),free)(multi); + + for (i = 0; i < multi->n; ++i) { + multi->p[i] = FN(EL,move_dims)(multi->p[i], dst_type, dst_pos, + src_type, src_pos, n); + if (!multi->p[i]) + return FN(MULTI(BASE),free)(multi); + } + + return multi; +} +#endif + +/* Convert a multiple expression defined over a parameter domain + * into one that is defined over a zero-dimensional set. + */ +__isl_give MULTI(BASE) *FN(MULTI(BASE),from_range)( + __isl_take MULTI(BASE) *multi) +{ + isl_space *space; + + if (!multi) + return NULL; + if (!isl_space_is_set(multi->space)) + isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid, + "not living in a set space", + return FN(MULTI(BASE),free)(multi)); + + space = FN(MULTI(BASE),get_space)(multi); + space = isl_space_from_range(space); + multi = FN(MULTI(BASE),reset_space)(multi, space); + + return multi; +} + +/* Are "multi1" and "multi2" obviously equal? + */ +int FN(MULTI(BASE),plain_is_equal)(__isl_keep MULTI(BASE) *multi1, + __isl_keep MULTI(BASE) *multi2) +{ + int i; + int equal; + + if (!multi1 || !multi2) + return -1; + if (multi1->n != multi2->n) + return 0; + equal = isl_space_is_equal(multi1->space, multi2->space); + if (equal < 0 || !equal) + return equal; + + for (i = 0; i < multi1->n; ++i) { + equal = FN(EL,plain_is_equal)(multi1->p[i], multi2->p[i]); + if (equal < 0 || !equal) + return equal; + } + + return 1; +} + +#ifndef NO_DOMAIN +/* Return the shared domain of the elements of "multi". + */ +__isl_give isl_set *FN(MULTI(BASE),domain)(__isl_take MULTI(BASE) *multi) +{ + int i; + isl_set *dom; + + if (!multi) + return NULL; + + dom = isl_set_universe(FN(MULTI(BASE),get_domain_space)(multi)); + for (i = 0; i < multi->n; ++i) { + isl_set *dom_i; + + dom_i = FN(EL,domain)(FN(FN(MULTI(BASE),get),BASE)(multi, i)); + dom = isl_set_intersect(dom, dom_i); + } + + FN(MULTI(BASE),free)(multi); + return dom; +} +#endif |