| /* |
| * Copyright 2017 Sven Verdoolaege |
| * |
| * Use of this software is governed by the MIT license |
| * |
| * Written by Sven Verdoolaege. |
| */ |
| |
| /* These versions of the explicit domain functions are used |
| * when the multi expression may have an explicit domain. |
| */ |
| |
| #include <isl_multi_macro.h> |
| |
| __isl_give MULTI(BASE) *FN(MULTI(BASE),cow)(__isl_take MULTI(BASE) *multi); |
| |
| /* Does "multi" have an explicit domain? |
| * |
| * An explicit domain is only available if "multi" is zero-dimensional. |
| */ |
| static int FN(MULTI(BASE),has_explicit_domain)(__isl_keep MULTI(BASE) *multi) |
| { |
| return multi && multi->n == 0; |
| } |
| |
| /* Check that "multi" has an explicit domain. |
| */ |
| static isl_stat FN(MULTI(BASE),check_has_explicit_domain)( |
| __isl_keep MULTI(BASE) *multi) |
| { |
| if (!multi) |
| return isl_stat_error; |
| if (!FN(MULTI(BASE),has_explicit_domain)(multi)) |
| isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_internal, |
| "expression does not have an explicit domain", |
| return isl_stat_error); |
| return isl_stat_ok; |
| } |
| |
| /* Return the explicit domain of "multi", assuming it has one. |
| */ |
| static __isl_keep DOM *FN(MULTI(BASE),peek_explicit_domain)( |
| __isl_keep MULTI(BASE) *multi) |
| { |
| if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0) |
| return NULL; |
| return multi->u.dom; |
| } |
| |
| /* Return a copy of the explicit domain of "multi", assuming it has one. |
| */ |
| static __isl_give DOM *FN(MULTI(BASE),get_explicit_domain)( |
| __isl_keep MULTI(BASE) *multi) |
| { |
| return FN(DOM,copy)(FN(MULTI(BASE),peek_explicit_domain)(multi)); |
| } |
| |
| /* Replace the explicit domain of "multi" by "dom", assuming it has one. |
| */ |
| static __isl_give MULTI(BASE) *FN(MULTI(BASE),set_explicit_domain)( |
| __isl_take MULTI(BASE) *multi, __isl_take DOM *dom) |
| { |
| if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0) |
| goto error; |
| multi = FN(MULTI(BASE),cow)(multi); |
| if (!multi || !dom) |
| goto error; |
| FN(DOM,free)(multi->u.dom); |
| multi->u.dom = dom; |
| if (!multi->u.dom) |
| return FN(MULTI(BASE),free)(multi); |
| return multi; |
| error: |
| FN(MULTI(BASE),free)(multi); |
| FN(DOM,free)(dom); |
| return NULL; |
| } |
| |
| /* Intersect the domain of "dst" with the explicit domain of "src". |
| * |
| * In the case of isl_multi_union_pw_aff objects, the explicit domain |
| * of "src" is allowed to have only constraints on the parameters, even |
| * if the domain of "dst" contains actual domain elements. In this case, |
| * the domain of "dst" is intersected with those parameter constraints. |
| */ |
| static __isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_explicit_domain)( |
| __isl_take MULTI(BASE) *dst, __isl_keep MULTI(BASE) *src) |
| { |
| isl_bool is_params; |
| DOM *dom; |
| |
| dom = FN(MULTI(BASE),peek_explicit_domain)(src); |
| is_params = FN(DOM,is_params)(dom); |
| if (is_params < 0) |
| return FN(MULTI(BASE),free)(dst); |
| |
| dom = FN(DOM,copy)(dom); |
| if (!is_params) { |
| dst = FN(MULTI(BASE),intersect_domain)(dst, dom); |
| } else { |
| isl_set *params; |
| |
| params = FN(DOM,params)(dom); |
| dst = FN(MULTI(BASE),intersect_params)(dst, params); |
| } |
| |
| return dst; |
| } |
| |
| /* Set the explicit domain of "dst" to that of "src". |
| */ |
| static __isl_give MULTI(BASE) *FN(MULTI(BASE),copy_explicit_domain)( |
| __isl_take MULTI(BASE) *dst, __isl_keep MULTI(BASE) *src) |
| { |
| DOM *dom; |
| |
| dom = FN(MULTI(BASE),get_explicit_domain)(src); |
| dst = FN(MULTI(BASE),set_explicit_domain)(dst, dom); |
| |
| return dst; |
| } |
| |
| /* Align the parameters of the explicit domain of "multi" to those of "space". |
| */ |
| static __isl_give MULTI(BASE) *FN(MULTI(BASE),align_explicit_domain_params)( |
| __isl_take MULTI(BASE) *multi, __isl_take isl_space *space) |
| { |
| DOM *dom; |
| |
| dom = FN(MULTI(BASE),get_explicit_domain)(multi); |
| dom = FN(DOM,align_params)(dom, space); |
| multi = FN(MULTI(BASE),set_explicit_domain)(multi, dom); |
| |
| return multi; |
| } |
| |
| /* Replace the space of the explicit domain of "multi" by "space", |
| * without modifying its dimension. |
| */ |
| static __isl_give MULTI(BASE) *FN(MULTI(BASE),reset_explicit_domain_space)( |
| __isl_take MULTI(BASE) *multi, __isl_take isl_space *space) |
| { |
| DOM *dom; |
| |
| dom = FN(MULTI(BASE),get_explicit_domain)(multi); |
| dom = FN(DOM,reset_equal_dim_space)(dom, space); |
| multi = FN(MULTI(BASE),set_explicit_domain)(multi, dom); |
| |
| return multi; |
| } |
| |
| /* Free the explicit domain of "multi". |
| */ |
| static void FN(MULTI(BASE),free_explicit_domain)(__isl_keep MULTI(BASE) *multi) |
| { |
| if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0) |
| return; |
| FN(DOM,free)(multi->u.dom); |
| } |
| |
| /* Do "multi1" and "multi2" have the same explicit domain? |
| */ |
| static isl_bool FN(MULTI(BASE),equal_explicit_domain)( |
| __isl_keep MULTI(BASE) *multi1, __isl_keep MULTI(BASE) *multi2) |
| { |
| DOM *dom1, *dom2; |
| isl_bool equal; |
| |
| if (FN(MULTI(BASE),check_has_explicit_domain)(multi1) < 0 || |
| FN(MULTI(BASE),check_has_explicit_domain)(multi2) < 0) |
| return isl_bool_error; |
| dom1 = FN(MULTI(BASE),get_explicit_domain)(multi1); |
| dom2 = FN(MULTI(BASE),get_explicit_domain)(multi2); |
| equal = FN(DOM,is_equal)(dom1, dom2); |
| FN(DOM,free)(dom1); |
| FN(DOM,free)(dom2); |
| |
| return equal; |
| } |
| |
| static isl_stat FN(MULTI(BASE),check_explicit_domain)( |
| __isl_keep MULTI(BASE) *multi) __attribute__ ((unused)); |
| |
| /* Debugging function to check that the explicit domain of "multi" |
| * has the correct space. |
| */ |
| isl_stat FN(MULTI(BASE),check_explicit_domain)(__isl_keep MULTI(BASE) *multi) |
| { |
| isl_space *space1, *space2; |
| isl_bool equal; |
| |
| if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0) |
| return isl_stat_error; |
| space1 = isl_space_domain(isl_space_copy(multi->space)); |
| space2 = FN(DOM,get_space)(multi->u.dom); |
| equal = isl_space_is_equal(space1, space2); |
| isl_space_free(space1); |
| isl_space_free(space2); |
| if (equal < 0) |
| return isl_stat_error; |
| if (!equal) |
| isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_internal, |
| "check failed", return isl_stat_error); |
| return isl_stat_ok; |
| } |