xref: /llvm-project/polly/lib/External/isl/isl_multi_explicit_domain.c (revision 79e3f2c6e2234bad7e53b892fc07105b3c3e539f)
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