16135b0feSTobias Grosser /*
26135b0feSTobias Grosser * Copyright 2017 Sven Verdoolaege
36135b0feSTobias Grosser *
46135b0feSTobias Grosser * Use of this software is governed by the MIT license
56135b0feSTobias Grosser *
66135b0feSTobias Grosser * Written by Sven Verdoolaege.
76135b0feSTobias Grosser */
86135b0feSTobias Grosser
96135b0feSTobias Grosser /* These versions of the explicit domain functions are used
106135b0feSTobias Grosser * when the multi expression may have an explicit domain.
116135b0feSTobias Grosser */
126135b0feSTobias Grosser
136135b0feSTobias Grosser #include <isl_multi_macro.h>
146135b0feSTobias Grosser
156135b0feSTobias Grosser __isl_give MULTI(BASE) *FN(MULTI(BASE),cow)(__isl_take MULTI(BASE) *multi);
166135b0feSTobias Grosser
176135b0feSTobias Grosser /* Does "multi" have an explicit domain?
186135b0feSTobias Grosser *
196135b0feSTobias Grosser * An explicit domain is only available if "multi" is zero-dimensional.
206135b0feSTobias Grosser */
FN(MULTI (BASE),has_explicit_domain)216135b0feSTobias Grosser static int FN(MULTI(BASE),has_explicit_domain)(__isl_keep MULTI(BASE) *multi)
226135b0feSTobias Grosser {
236135b0feSTobias Grosser return multi && multi->n == 0;
246135b0feSTobias Grosser }
256135b0feSTobias Grosser
266135b0feSTobias Grosser /* Check that "multi" has an explicit domain.
276135b0feSTobias Grosser */
FN(MULTI (BASE),check_has_explicit_domain)286135b0feSTobias Grosser static isl_stat FN(MULTI(BASE),check_has_explicit_domain)(
296135b0feSTobias Grosser __isl_keep MULTI(BASE) *multi)
306135b0feSTobias Grosser {
316135b0feSTobias Grosser if (!multi)
326135b0feSTobias Grosser return isl_stat_error;
336135b0feSTobias Grosser if (!FN(MULTI(BASE),has_explicit_domain)(multi))
346135b0feSTobias Grosser isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_internal,
356135b0feSTobias Grosser "expression does not have an explicit domain",
366135b0feSTobias Grosser return isl_stat_error);
376135b0feSTobias Grosser return isl_stat_ok;
386135b0feSTobias Grosser }
396135b0feSTobias Grosser
406135b0feSTobias Grosser /* Return the explicit domain of "multi", assuming it has one.
416135b0feSTobias Grosser */
FN(MULTI (BASE),peek_explicit_domain)42*79e3f2c6STobias Grosser static __isl_keep DOM *FN(MULTI(BASE),peek_explicit_domain)(
436135b0feSTobias Grosser __isl_keep MULTI(BASE) *multi)
446135b0feSTobias Grosser {
456135b0feSTobias Grosser if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0)
466135b0feSTobias Grosser return NULL;
47*79e3f2c6STobias Grosser return multi->u.dom;
48*79e3f2c6STobias Grosser }
49*79e3f2c6STobias Grosser
50*79e3f2c6STobias Grosser /* Return a copy of the explicit domain of "multi", assuming it has one.
51*79e3f2c6STobias Grosser */
FN(MULTI (BASE),get_explicit_domain)52*79e3f2c6STobias Grosser static __isl_give DOM *FN(MULTI(BASE),get_explicit_domain)(
53*79e3f2c6STobias Grosser __isl_keep MULTI(BASE) *multi)
54*79e3f2c6STobias Grosser {
55*79e3f2c6STobias Grosser return FN(DOM,copy)(FN(MULTI(BASE),peek_explicit_domain)(multi));
566135b0feSTobias Grosser }
576135b0feSTobias Grosser
586135b0feSTobias Grosser /* Replace the explicit domain of "multi" by "dom", assuming it has one.
596135b0feSTobias Grosser */
MULTI(BASE)606135b0feSTobias Grosser static __isl_give MULTI(BASE) *FN(MULTI(BASE),set_explicit_domain)(
616135b0feSTobias Grosser __isl_take MULTI(BASE) *multi, __isl_take DOM *dom)
626135b0feSTobias Grosser {
636135b0feSTobias Grosser if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0)
646135b0feSTobias Grosser goto error;
656135b0feSTobias Grosser multi = FN(MULTI(BASE),cow)(multi);
666135b0feSTobias Grosser if (!multi || !dom)
676135b0feSTobias Grosser goto error;
686135b0feSTobias Grosser FN(DOM,free)(multi->u.dom);
696135b0feSTobias Grosser multi->u.dom = dom;
706135b0feSTobias Grosser if (!multi->u.dom)
716135b0feSTobias Grosser return FN(MULTI(BASE),free)(multi);
726135b0feSTobias Grosser return multi;
736135b0feSTobias Grosser error:
746135b0feSTobias Grosser FN(MULTI(BASE),free)(multi);
756135b0feSTobias Grosser FN(DOM,free)(dom);
766135b0feSTobias Grosser return NULL;
776135b0feSTobias Grosser }
786135b0feSTobias Grosser
796135b0feSTobias Grosser /* Intersect the domain of "dst" with the explicit domain of "src".
80*79e3f2c6STobias Grosser *
81*79e3f2c6STobias Grosser * In the case of isl_multi_union_pw_aff objects, the explicit domain
82*79e3f2c6STobias Grosser * of "src" is allowed to have only constraints on the parameters, even
83*79e3f2c6STobias Grosser * if the domain of "dst" contains actual domain elements. In this case,
84*79e3f2c6STobias Grosser * the domain of "dst" is intersected with those parameter constraints.
856135b0feSTobias Grosser */
MULTI(BASE)866135b0feSTobias Grosser static __isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_explicit_domain)(
876135b0feSTobias Grosser __isl_take MULTI(BASE) *dst, __isl_keep MULTI(BASE) *src)
886135b0feSTobias Grosser {
89*79e3f2c6STobias Grosser isl_bool is_params;
906135b0feSTobias Grosser DOM *dom;
916135b0feSTobias Grosser
92*79e3f2c6STobias Grosser dom = FN(MULTI(BASE),peek_explicit_domain)(src);
93*79e3f2c6STobias Grosser is_params = FN(DOM,is_params)(dom);
94*79e3f2c6STobias Grosser if (is_params < 0)
95*79e3f2c6STobias Grosser return FN(MULTI(BASE),free)(dst);
96*79e3f2c6STobias Grosser
97*79e3f2c6STobias Grosser dom = FN(DOM,copy)(dom);
98*79e3f2c6STobias Grosser if (!is_params) {
996135b0feSTobias Grosser dst = FN(MULTI(BASE),intersect_domain)(dst, dom);
100*79e3f2c6STobias Grosser } else {
101*79e3f2c6STobias Grosser isl_set *params;
102*79e3f2c6STobias Grosser
103*79e3f2c6STobias Grosser params = FN(DOM,params)(dom);
104*79e3f2c6STobias Grosser dst = FN(MULTI(BASE),intersect_params)(dst, params);
105*79e3f2c6STobias Grosser }
1066135b0feSTobias Grosser
1076135b0feSTobias Grosser return dst;
1086135b0feSTobias Grosser }
1096135b0feSTobias Grosser
1106135b0feSTobias Grosser /* Set the explicit domain of "dst" to that of "src".
1116135b0feSTobias Grosser */
MULTI(BASE)1126135b0feSTobias Grosser static __isl_give MULTI(BASE) *FN(MULTI(BASE),copy_explicit_domain)(
1136135b0feSTobias Grosser __isl_take MULTI(BASE) *dst, __isl_keep MULTI(BASE) *src)
1146135b0feSTobias Grosser {
1156135b0feSTobias Grosser DOM *dom;
1166135b0feSTobias Grosser
1176135b0feSTobias Grosser dom = FN(MULTI(BASE),get_explicit_domain)(src);
1186135b0feSTobias Grosser dst = FN(MULTI(BASE),set_explicit_domain)(dst, dom);
1196135b0feSTobias Grosser
1206135b0feSTobias Grosser return dst;
1216135b0feSTobias Grosser }
1226135b0feSTobias Grosser
1236135b0feSTobias Grosser /* Align the parameters of the explicit domain of "multi" to those of "space".
1246135b0feSTobias Grosser */
MULTI(BASE)1256135b0feSTobias Grosser static __isl_give MULTI(BASE) *FN(MULTI(BASE),align_explicit_domain_params)(
1266135b0feSTobias Grosser __isl_take MULTI(BASE) *multi, __isl_take isl_space *space)
1276135b0feSTobias Grosser {
1286135b0feSTobias Grosser DOM *dom;
1296135b0feSTobias Grosser
1306135b0feSTobias Grosser dom = FN(MULTI(BASE),get_explicit_domain)(multi);
1316135b0feSTobias Grosser dom = FN(DOM,align_params)(dom, space);
1326135b0feSTobias Grosser multi = FN(MULTI(BASE),set_explicit_domain)(multi, dom);
1336135b0feSTobias Grosser
1346135b0feSTobias Grosser return multi;
1356135b0feSTobias Grosser }
1366135b0feSTobias Grosser
1376135b0feSTobias Grosser /* Replace the space of the explicit domain of "multi" by "space",
1386135b0feSTobias Grosser * without modifying its dimension.
1396135b0feSTobias Grosser */
MULTI(BASE)1406135b0feSTobias Grosser static __isl_give MULTI(BASE) *FN(MULTI(BASE),reset_explicit_domain_space)(
1416135b0feSTobias Grosser __isl_take MULTI(BASE) *multi, __isl_take isl_space *space)
1426135b0feSTobias Grosser {
1436135b0feSTobias Grosser DOM *dom;
1446135b0feSTobias Grosser
1456135b0feSTobias Grosser dom = FN(MULTI(BASE),get_explicit_domain)(multi);
1466135b0feSTobias Grosser dom = FN(DOM,reset_equal_dim_space)(dom, space);
1476135b0feSTobias Grosser multi = FN(MULTI(BASE),set_explicit_domain)(multi, dom);
1486135b0feSTobias Grosser
1496135b0feSTobias Grosser return multi;
1506135b0feSTobias Grosser }
1516135b0feSTobias Grosser
1526135b0feSTobias Grosser /* Free the explicit domain of "multi".
1536135b0feSTobias Grosser */
FN(MULTI (BASE),free_explicit_domain)1546135b0feSTobias Grosser static void FN(MULTI(BASE),free_explicit_domain)(__isl_keep MULTI(BASE) *multi)
1556135b0feSTobias Grosser {
1566135b0feSTobias Grosser if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0)
1576135b0feSTobias Grosser return;
1586135b0feSTobias Grosser FN(DOM,free)(multi->u.dom);
1596135b0feSTobias Grosser }
1606135b0feSTobias Grosser
1616135b0feSTobias Grosser /* Do "multi1" and "multi2" have the same explicit domain?
1626135b0feSTobias Grosser */
FN(MULTI (BASE),equal_explicit_domain)1636135b0feSTobias Grosser static isl_bool FN(MULTI(BASE),equal_explicit_domain)(
1646135b0feSTobias Grosser __isl_keep MULTI(BASE) *multi1, __isl_keep MULTI(BASE) *multi2)
1656135b0feSTobias Grosser {
1666135b0feSTobias Grosser DOM *dom1, *dom2;
1676135b0feSTobias Grosser isl_bool equal;
1686135b0feSTobias Grosser
1696135b0feSTobias Grosser if (FN(MULTI(BASE),check_has_explicit_domain)(multi1) < 0 ||
1706135b0feSTobias Grosser FN(MULTI(BASE),check_has_explicit_domain)(multi2) < 0)
1716135b0feSTobias Grosser return isl_bool_error;
1726135b0feSTobias Grosser dom1 = FN(MULTI(BASE),get_explicit_domain)(multi1);
1736135b0feSTobias Grosser dom2 = FN(MULTI(BASE),get_explicit_domain)(multi2);
1746135b0feSTobias Grosser equal = FN(DOM,is_equal)(dom1, dom2);
1756135b0feSTobias Grosser FN(DOM,free)(dom1);
1766135b0feSTobias Grosser FN(DOM,free)(dom2);
1776135b0feSTobias Grosser
1786135b0feSTobias Grosser return equal;
1796135b0feSTobias Grosser }
1806135b0feSTobias Grosser
1816135b0feSTobias Grosser static isl_stat FN(MULTI(BASE),check_explicit_domain)(
1826135b0feSTobias Grosser __isl_keep MULTI(BASE) *multi) __attribute__ ((unused));
1836135b0feSTobias Grosser
1846135b0feSTobias Grosser /* Debugging function to check that the explicit domain of "multi"
1856135b0feSTobias Grosser * has the correct space.
1866135b0feSTobias Grosser */
FN(MULTI (BASE),check_explicit_domain)1876135b0feSTobias Grosser isl_stat FN(MULTI(BASE),check_explicit_domain)(__isl_keep MULTI(BASE) *multi)
1886135b0feSTobias Grosser {
1896135b0feSTobias Grosser isl_space *space1, *space2;
1906135b0feSTobias Grosser isl_bool equal;
1916135b0feSTobias Grosser
1926135b0feSTobias Grosser if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0)
1936135b0feSTobias Grosser return isl_stat_error;
1946135b0feSTobias Grosser space1 = isl_space_domain(isl_space_copy(multi->space));
1956135b0feSTobias Grosser space2 = FN(DOM,get_space)(multi->u.dom);
1966135b0feSTobias Grosser equal = isl_space_is_equal(space1, space2);
1976135b0feSTobias Grosser isl_space_free(space1);
1986135b0feSTobias Grosser isl_space_free(space2);
1996135b0feSTobias Grosser if (equal < 0)
2006135b0feSTobias Grosser return isl_stat_error;
2016135b0feSTobias Grosser if (!equal)
2026135b0feSTobias Grosser isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_internal,
2036135b0feSTobias Grosser "check failed", return isl_stat_error);
2046135b0feSTobias Grosser return isl_stat_ok;
2056135b0feSTobias Grosser }
206