/* * 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_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; }