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