isl_multi_explicit_domain.c revision 1.1 1 1.1 mrg /*
2 1.1 mrg * Copyright 2017 Sven Verdoolaege
3 1.1 mrg *
4 1.1 mrg * Use of this software is governed by the MIT license
5 1.1 mrg *
6 1.1 mrg * Written by Sven Verdoolaege.
7 1.1 mrg */
8 1.1 mrg
9 1.1 mrg /* These versions of the explicit domain functions are used
10 1.1 mrg * when the multi expression may have an explicit domain.
11 1.1 mrg */
12 1.1 mrg
13 1.1 mrg #include <isl_multi_macro.h>
14 1.1 mrg
15 1.1 mrg __isl_give MULTI(BASE) *FN(MULTI(BASE),cow)(__isl_take MULTI(BASE) *multi);
16 1.1 mrg
17 1.1 mrg /* Does "multi" have an explicit domain?
18 1.1 mrg *
19 1.1 mrg * An explicit domain is only available if "multi" is zero-dimensional.
20 1.1 mrg */
21 1.1 mrg static int FN(MULTI(BASE),has_explicit_domain)(__isl_keep MULTI(BASE) *multi)
22 1.1 mrg {
23 1.1 mrg return multi && multi->n == 0;
24 1.1 mrg }
25 1.1 mrg
26 1.1 mrg /* Check that "multi" has an explicit domain.
27 1.1 mrg */
28 1.1 mrg static isl_stat FN(MULTI(BASE),check_has_explicit_domain)(
29 1.1 mrg __isl_keep MULTI(BASE) *multi)
30 1.1 mrg {
31 1.1 mrg if (!multi)
32 1.1 mrg return isl_stat_error;
33 1.1 mrg if (!FN(MULTI(BASE),has_explicit_domain)(multi))
34 1.1 mrg isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_internal,
35 1.1 mrg "expression does not have an explicit domain",
36 1.1 mrg return isl_stat_error);
37 1.1 mrg return isl_stat_ok;
38 1.1 mrg }
39 1.1 mrg
40 1.1 mrg /* Return the explicit domain of "multi", assuming it has one.
41 1.1 mrg */
42 1.1 mrg static __isl_keep DOM *FN(MULTI(BASE),peek_explicit_domain)(
43 1.1 mrg __isl_keep MULTI(BASE) *multi)
44 1.1 mrg {
45 1.1 mrg if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0)
46 1.1 mrg return NULL;
47 1.1 mrg return multi->u.dom;
48 1.1 mrg }
49 1.1 mrg
50 1.1 mrg /* Return a copy of the explicit domain of "multi", assuming it has one.
51 1.1 mrg */
52 1.1 mrg static __isl_give DOM *FN(MULTI(BASE),get_explicit_domain)(
53 1.1 mrg __isl_keep MULTI(BASE) *multi)
54 1.1 mrg {
55 1.1 mrg return FN(DOM,copy)(FN(MULTI(BASE),peek_explicit_domain)(multi));
56 1.1 mrg }
57 1.1 mrg
58 1.1 mrg /* Replace the explicit domain of "multi" by "dom", assuming it has one.
59 1.1 mrg */
60 1.1 mrg static __isl_give MULTI(BASE) *FN(MULTI(BASE),set_explicit_domain)(
61 1.1 mrg __isl_take MULTI(BASE) *multi, __isl_take DOM *dom)
62 1.1 mrg {
63 1.1 mrg if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0)
64 1.1 mrg goto error;
65 1.1 mrg multi = FN(MULTI(BASE),cow)(multi);
66 1.1 mrg if (!multi || !dom)
67 1.1 mrg goto error;
68 1.1 mrg FN(DOM,free)(multi->u.dom);
69 1.1 mrg multi->u.dom = dom;
70 1.1 mrg if (!multi->u.dom)
71 1.1 mrg return FN(MULTI(BASE),free)(multi);
72 1.1 mrg return multi;
73 1.1 mrg error:
74 1.1 mrg FN(MULTI(BASE),free)(multi);
75 1.1 mrg FN(DOM,free)(dom);
76 1.1 mrg return NULL;
77 1.1 mrg }
78 1.1 mrg
79 1.1 mrg /* Intersect the domain of "dst" with the explicit domain of "src".
80 1.1 mrg *
81 1.1 mrg * In the case of isl_multi_union_pw_aff objects, the explicit domain
82 1.1 mrg * of "src" is allowed to have only constraints on the parameters, even
83 1.1 mrg * if the domain of "dst" contains actual domain elements. In this case,
84 1.1 mrg * the domain of "dst" is intersected with those parameter constraints.
85 1.1 mrg */
86 1.1 mrg static __isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_explicit_domain)(
87 1.1 mrg __isl_take MULTI(BASE) *dst, __isl_keep MULTI(BASE) *src)
88 1.1 mrg {
89 1.1 mrg isl_bool is_params;
90 1.1 mrg DOM *dom;
91 1.1 mrg
92 1.1 mrg dom = FN(MULTI(BASE),peek_explicit_domain)(src);
93 1.1 mrg is_params = FN(DOM,is_params)(dom);
94 1.1 mrg if (is_params < 0)
95 1.1 mrg return FN(MULTI(BASE),free)(dst);
96 1.1 mrg
97 1.1 mrg dom = FN(DOM,copy)(dom);
98 1.1 mrg if (!is_params) {
99 1.1 mrg dst = FN(MULTI(BASE),intersect_domain)(dst, dom);
100 1.1 mrg } else {
101 1.1 mrg isl_set *params;
102 1.1 mrg
103 1.1 mrg params = FN(DOM,params)(dom);
104 1.1 mrg dst = FN(MULTI(BASE),intersect_params)(dst, params);
105 1.1 mrg }
106 1.1 mrg
107 1.1 mrg return dst;
108 1.1 mrg }
109 1.1 mrg
110 1.1 mrg /* Set the explicit domain of "dst" to that of "src".
111 1.1 mrg */
112 1.1 mrg static __isl_give MULTI(BASE) *FN(MULTI(BASE),copy_explicit_domain)(
113 1.1 mrg __isl_take MULTI(BASE) *dst, __isl_keep MULTI(BASE) *src)
114 1.1 mrg {
115 1.1 mrg DOM *dom;
116 1.1 mrg
117 1.1 mrg dom = FN(MULTI(BASE),get_explicit_domain)(src);
118 1.1 mrg dst = FN(MULTI(BASE),set_explicit_domain)(dst, dom);
119 1.1 mrg
120 1.1 mrg return dst;
121 1.1 mrg }
122 1.1 mrg
123 1.1 mrg /* Align the parameters of the explicit domain of "multi" to those of "space".
124 1.1 mrg */
125 1.1 mrg static __isl_give MULTI(BASE) *FN(MULTI(BASE),align_explicit_domain_params)(
126 1.1 mrg __isl_take MULTI(BASE) *multi, __isl_take isl_space *space)
127 1.1 mrg {
128 1.1 mrg DOM *dom;
129 1.1 mrg
130 1.1 mrg dom = FN(MULTI(BASE),get_explicit_domain)(multi);
131 1.1 mrg dom = FN(DOM,align_params)(dom, space);
132 1.1 mrg multi = FN(MULTI(BASE),set_explicit_domain)(multi, dom);
133 1.1 mrg
134 1.1 mrg return multi;
135 1.1 mrg }
136 1.1 mrg
137 1.1 mrg /* Replace the space of the explicit domain of "multi" by "space",
138 1.1 mrg * without modifying its dimension.
139 1.1 mrg */
140 1.1 mrg static __isl_give MULTI(BASE) *FN(MULTI(BASE),reset_explicit_domain_space)(
141 1.1 mrg __isl_take MULTI(BASE) *multi, __isl_take isl_space *space)
142 1.1 mrg {
143 1.1 mrg DOM *dom;
144 1.1 mrg
145 1.1 mrg dom = FN(MULTI(BASE),get_explicit_domain)(multi);
146 1.1 mrg dom = FN(DOM,reset_equal_dim_space)(dom, space);
147 1.1 mrg multi = FN(MULTI(BASE),set_explicit_domain)(multi, dom);
148 1.1 mrg
149 1.1 mrg return multi;
150 1.1 mrg }
151 1.1 mrg
152 1.1 mrg /* Free the explicit domain of "multi".
153 1.1 mrg */
154 1.1 mrg static void FN(MULTI(BASE),free_explicit_domain)(__isl_keep MULTI(BASE) *multi)
155 1.1 mrg {
156 1.1 mrg if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0)
157 1.1 mrg return;
158 1.1 mrg FN(DOM,free)(multi->u.dom);
159 1.1 mrg }
160 1.1 mrg
161 1.1 mrg /* Do "multi1" and "multi2" have the same explicit domain?
162 1.1 mrg */
163 1.1 mrg static isl_bool FN(MULTI(BASE),equal_explicit_domain)(
164 1.1 mrg __isl_keep MULTI(BASE) *multi1, __isl_keep MULTI(BASE) *multi2)
165 1.1 mrg {
166 1.1 mrg DOM *dom1, *dom2;
167 1.1 mrg isl_bool equal;
168 1.1 mrg
169 1.1 mrg if (FN(MULTI(BASE),check_has_explicit_domain)(multi1) < 0 ||
170 1.1 mrg FN(MULTI(BASE),check_has_explicit_domain)(multi2) < 0)
171 1.1 mrg return isl_bool_error;
172 1.1 mrg dom1 = FN(MULTI(BASE),get_explicit_domain)(multi1);
173 1.1 mrg dom2 = FN(MULTI(BASE),get_explicit_domain)(multi2);
174 1.1 mrg equal = FN(DOM,is_equal)(dom1, dom2);
175 1.1 mrg FN(DOM,free)(dom1);
176 1.1 mrg FN(DOM,free)(dom2);
177 1.1 mrg
178 1.1 mrg return equal;
179 1.1 mrg }
180 1.1 mrg
181 1.1 mrg static isl_stat FN(MULTI(BASE),check_explicit_domain)(
182 1.1 mrg __isl_keep MULTI(BASE) *multi) __attribute__ ((unused));
183 1.1 mrg
184 1.1 mrg /* Debugging function to check that the explicit domain of "multi"
185 1.1 mrg * has the correct space.
186 1.1 mrg */
187 1.1 mrg isl_stat FN(MULTI(BASE),check_explicit_domain)(__isl_keep MULTI(BASE) *multi)
188 1.1 mrg {
189 1.1 mrg isl_space *space1, *space2;
190 1.1 mrg isl_bool equal;
191 1.1 mrg
192 1.1 mrg if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0)
193 1.1 mrg return isl_stat_error;
194 1.1 mrg space1 = isl_space_domain(isl_space_copy(multi->space));
195 1.1 mrg space2 = FN(DOM,get_space)(multi->u.dom);
196 1.1 mrg equal = isl_space_is_equal(space1, space2);
197 1.1 mrg isl_space_free(space1);
198 1.1 mrg isl_space_free(space2);
199 1.1 mrg if (equal < 0)
200 1.1 mrg return isl_stat_error;
201 1.1 mrg if (!equal)
202 1.1 mrg isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_internal,
203 1.1 mrg "check failed", return isl_stat_error);
204 1.1 mrg return isl_stat_ok;
205 1.1 mrg }
206