File: | polly/lib/External/isl/isl_aff.c |
Warning: | line 5493, column 3 Value stored to 'o_src' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * Copyright 2011 INRIA Saclay |
3 | * Copyright 2011 Sven Verdoolaege |
4 | * Copyright 2012-2014 Ecole Normale Superieure |
5 | * Copyright 2014 INRIA Rocquencourt |
6 | * |
7 | * Use of this software is governed by the MIT license |
8 | * |
9 | * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France, |
10 | * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod, |
11 | * 91893 Orsay, France |
12 | * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France |
13 | * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt, |
14 | * B.P. 105 - 78153 Le Chesnay, France |
15 | */ |
16 | |
17 | #include <isl_ctx_private.h> |
18 | #include <isl_map_private.h> |
19 | #include <isl_union_map_private.h> |
20 | #include <isl_aff_private.h> |
21 | #include <isl_space_private.h> |
22 | #include <isl_local_space_private.h> |
23 | #include <isl_vec_private.h> |
24 | #include <isl_mat_private.h> |
25 | #include <isl/id.h> |
26 | #include <isl/constraint.h> |
27 | #include <isl_seq.h> |
28 | #include <isl/set.h> |
29 | #include <isl_val_private.h> |
30 | #include <isl_point_private.h> |
31 | #include <isl_config.h> |
32 | |
33 | #undef BASEunion_pw_aff |
34 | #define BASEunion_pw_aff aff |
35 | |
36 | #include <isl_list_templ.c> |
37 | |
38 | #undef BASEunion_pw_aff |
39 | #define BASEunion_pw_aff pw_aff |
40 | |
41 | #include <isl_list_templ.c> |
42 | |
43 | #undef BASEunion_pw_aff |
44 | #define BASEunion_pw_aff pw_multi_aff |
45 | |
46 | #include <isl_list_templ.c> |
47 | |
48 | #undef BASEunion_pw_aff |
49 | #define BASEunion_pw_aff union_pw_aff |
50 | |
51 | #include <isl_list_templ.c> |
52 | |
53 | #undef BASEunion_pw_aff |
54 | #define BASEunion_pw_aff union_pw_multi_aff |
55 | |
56 | #include <isl_list_templ.c> |
57 | |
58 | __isl_give isl_aff *isl_aff_alloc_vec(__isl_take isl_local_space *ls, |
59 | __isl_take isl_vec *v) |
60 | { |
61 | isl_aff *aff; |
62 | |
63 | if (!ls || !v) |
64 | goto error; |
65 | |
66 | aff = isl_calloc_type(v->ctx, struct isl_aff)((struct isl_aff *)isl_calloc_or_die(v->ctx, 1, sizeof(struct isl_aff))); |
67 | if (!aff) |
68 | goto error; |
69 | |
70 | aff->ref = 1; |
71 | aff->ls = ls; |
72 | aff->v = v; |
73 | |
74 | return aff; |
75 | error: |
76 | isl_local_space_free(ls); |
77 | isl_vec_free(v); |
78 | return NULL((void*)0); |
79 | } |
80 | |
81 | __isl_give isl_aff *isl_aff_alloc(__isl_take isl_local_space *ls) |
82 | { |
83 | isl_ctx *ctx; |
84 | isl_vec *v; |
85 | unsigned total; |
86 | |
87 | if (!ls) |
88 | return NULL((void*)0); |
89 | |
90 | ctx = isl_local_space_get_ctx(ls); |
91 | if (!isl_local_space_divs_known(ls)) |
92 | isl_die(ctx, isl_error_invalid, "local space has unknown divs",do { isl_handle_error(ctx, isl_error_invalid, "local space has unknown divs" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 93); goto error; } while (0) |
93 | goto error)do { isl_handle_error(ctx, isl_error_invalid, "local space has unknown divs" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 93); goto error; } while (0); |
94 | if (!isl_local_space_is_set(ls)) |
95 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "domain of affine expression should be a set" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 97); goto error; } while (0) |
96 | "domain of affine expression should be a set",do { isl_handle_error(ctx, isl_error_invalid, "domain of affine expression should be a set" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 97); goto error; } while (0) |
97 | goto error)do { isl_handle_error(ctx, isl_error_invalid, "domain of affine expression should be a set" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 97); goto error; } while (0); |
98 | |
99 | total = isl_local_space_dim(ls, isl_dim_all); |
100 | v = isl_vec_alloc(ctx, 1 + 1 + total); |
101 | return isl_aff_alloc_vec(ls, v); |
102 | error: |
103 | isl_local_space_free(ls); |
104 | return NULL((void*)0); |
105 | } |
106 | |
107 | __isl_give isl_aff *isl_aff_zero_on_domain(__isl_take isl_local_space *ls) |
108 | { |
109 | isl_aff *aff; |
110 | |
111 | aff = isl_aff_alloc(ls); |
112 | if (!aff) |
113 | return NULL((void*)0); |
114 | |
115 | isl_int_set_si(aff->v->el[0], 1)isl_sioimath_set_si((aff->v->el[0]), 1); |
116 | isl_seq_clr(aff->v->el + 1, aff->v->size - 1); |
117 | |
118 | return aff; |
119 | } |
120 | |
121 | /* Return a piecewise affine expression defined on the specified domain |
122 | * that is equal to zero. |
123 | */ |
124 | __isl_give isl_pw_aff *isl_pw_aff_zero_on_domain(__isl_take isl_local_space *ls) |
125 | { |
126 | return isl_pw_aff_from_aff(isl_aff_zero_on_domain(ls)); |
127 | } |
128 | |
129 | /* Return an affine expression defined on the specified domain |
130 | * that represents NaN. |
131 | */ |
132 | __isl_give isl_aff *isl_aff_nan_on_domain(__isl_take isl_local_space *ls) |
133 | { |
134 | isl_aff *aff; |
135 | |
136 | aff = isl_aff_alloc(ls); |
137 | if (!aff) |
138 | return NULL((void*)0); |
139 | |
140 | isl_seq_clr(aff->v->el, aff->v->size); |
141 | |
142 | return aff; |
143 | } |
144 | |
145 | /* Return a piecewise affine expression defined on the specified domain |
146 | * that represents NaN. |
147 | */ |
148 | __isl_give isl_pw_aff *isl_pw_aff_nan_on_domain(__isl_take isl_local_space *ls) |
149 | { |
150 | return isl_pw_aff_from_aff(isl_aff_nan_on_domain(ls)); |
151 | } |
152 | |
153 | /* Return an affine expression that is equal to "val" on |
154 | * domain local space "ls". |
155 | */ |
156 | __isl_give isl_aff *isl_aff_val_on_domain(__isl_take isl_local_space *ls, |
157 | __isl_take isl_val *val) |
158 | { |
159 | isl_aff *aff; |
160 | |
161 | if (!ls || !val) |
162 | goto error; |
163 | if (!isl_val_is_rat(val)) |
164 | isl_die(isl_val_get_ctx(val), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(val), isl_error_invalid , "expecting rational value", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 165); goto error; } while (0) |
165 | "expecting rational value", goto error)do { isl_handle_error(isl_val_get_ctx(val), isl_error_invalid , "expecting rational value", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 165); goto error; } while (0); |
166 | |
167 | aff = isl_aff_alloc(isl_local_space_copy(ls)); |
168 | if (!aff) |
169 | goto error; |
170 | |
171 | isl_seq_clr(aff->v->el + 2, aff->v->size - 2); |
172 | isl_int_set(aff->v->el[1], val->n)isl_sioimath_set((aff->v->el[1]), *(val->n)); |
173 | isl_int_set(aff->v->el[0], val->d)isl_sioimath_set((aff->v->el[0]), *(val->d)); |
174 | |
175 | isl_local_space_free(ls); |
176 | isl_val_free(val); |
177 | return aff; |
178 | error: |
179 | isl_local_space_free(ls); |
180 | isl_val_free(val); |
181 | return NULL((void*)0); |
182 | } |
183 | |
184 | /* Return an affine expression that is equal to the specified dimension |
185 | * in "ls". |
186 | */ |
187 | __isl_give isl_aff *isl_aff_var_on_domain(__isl_take isl_local_space *ls, |
188 | enum isl_dim_type type, unsigned pos) |
189 | { |
190 | isl_space *space; |
191 | isl_aff *aff; |
192 | |
193 | if (!ls) |
194 | return NULL((void*)0); |
195 | |
196 | space = isl_local_space_get_space(ls); |
197 | if (!space) |
198 | goto error; |
199 | if (isl_space_is_map(space)) |
200 | isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "expecting (parameter) set space", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 201); goto error; } while (0) |
201 | "expecting (parameter) set space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "expecting (parameter) set space", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 201); goto error; } while (0); |
202 | if (pos >= isl_local_space_dim(ls, type)) |
203 | isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "position out of bounds", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 204); goto error; } while (0) |
204 | "position out of bounds", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "position out of bounds", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 204); goto error; } while (0); |
205 | |
206 | isl_space_free(space); |
207 | aff = isl_aff_alloc(ls); |
208 | if (!aff) |
209 | return NULL((void*)0); |
210 | |
211 | pos += isl_local_space_offset(aff->ls, type); |
212 | |
213 | isl_int_set_si(aff->v->el[0], 1)isl_sioimath_set_si((aff->v->el[0]), 1); |
214 | isl_seq_clr(aff->v->el + 1, aff->v->size - 1); |
215 | isl_int_set_si(aff->v->el[1 + pos], 1)isl_sioimath_set_si((aff->v->el[1 + pos]), 1); |
216 | |
217 | return aff; |
218 | error: |
219 | isl_local_space_free(ls); |
220 | isl_space_free(space); |
221 | return NULL((void*)0); |
222 | } |
223 | |
224 | /* Return a piecewise affine expression that is equal to |
225 | * the specified dimension in "ls". |
226 | */ |
227 | __isl_give isl_pw_aff *isl_pw_aff_var_on_domain(__isl_take isl_local_space *ls, |
228 | enum isl_dim_type type, unsigned pos) |
229 | { |
230 | return isl_pw_aff_from_aff(isl_aff_var_on_domain(ls, type, pos)); |
231 | } |
232 | |
233 | /* Return an affine expression that is equal to the parameter |
234 | * in the domain space "space" with identifier "id". |
235 | */ |
236 | __isl_give isl_aff *isl_aff_param_on_domain_space_id( |
237 | __isl_take isl_space *space, __isl_take isl_id *id) |
238 | { |
239 | int pos; |
240 | isl_local_space *ls; |
241 | |
242 | if (!space || !id) |
243 | goto error; |
244 | pos = isl_space_find_dim_by_id(space, isl_dim_param, id); |
245 | if (pos < 0) |
246 | isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "parameter not found in space", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 247); goto error; } while (0) |
247 | "parameter not found in space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "parameter not found in space", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 247); goto error; } while (0); |
248 | isl_id_free(id); |
249 | ls = isl_local_space_from_space(space); |
250 | return isl_aff_var_on_domain(ls, isl_dim_param, pos); |
251 | error: |
252 | isl_space_free(space); |
253 | isl_id_free(id); |
254 | return NULL((void*)0); |
255 | } |
256 | |
257 | __isl_give isl_aff *isl_aff_copy(__isl_keep isl_aff *aff) |
258 | { |
259 | if (!aff) |
260 | return NULL((void*)0); |
261 | |
262 | aff->ref++; |
263 | return aff; |
264 | } |
265 | |
266 | __isl_give isl_aff *isl_aff_dup(__isl_keep isl_aff *aff) |
267 | { |
268 | if (!aff) |
269 | return NULL((void*)0); |
270 | |
271 | return isl_aff_alloc_vec(isl_local_space_copy(aff->ls), |
272 | isl_vec_copy(aff->v)); |
273 | } |
274 | |
275 | __isl_give isl_aff *isl_aff_cow(__isl_take isl_aff *aff) |
276 | { |
277 | if (!aff) |
278 | return NULL((void*)0); |
279 | |
280 | if (aff->ref == 1) |
281 | return aff; |
282 | aff->ref--; |
283 | return isl_aff_dup(aff); |
284 | } |
285 | |
286 | __isl_null isl_aff *isl_aff_free(__isl_take isl_aff *aff) |
287 | { |
288 | if (!aff) |
289 | return NULL((void*)0); |
290 | |
291 | if (--aff->ref > 0) |
292 | return NULL((void*)0); |
293 | |
294 | isl_local_space_free(aff->ls); |
295 | isl_vec_free(aff->v); |
296 | |
297 | free(aff); |
298 | |
299 | return NULL((void*)0); |
300 | } |
301 | |
302 | isl_ctx *isl_aff_get_ctx(__isl_keep isl_aff *aff) |
303 | { |
304 | return aff ? isl_local_space_get_ctx(aff->ls) : NULL((void*)0); |
305 | } |
306 | |
307 | /* Return a hash value that digests "aff". |
308 | */ |
309 | uint32_t isl_aff_get_hash(__isl_keep isl_aff *aff) |
310 | { |
311 | uint32_t hash, ls_hash, v_hash; |
312 | |
313 | if (!aff) |
314 | return 0; |
315 | |
316 | hash = isl_hash_init()(2166136261u); |
317 | ls_hash = isl_local_space_get_hash(aff->ls); |
318 | isl_hash_hash(hash, ls_hash)do { do { hash *= 16777619; hash ^= (ls_hash) & 0xFF; } while (0); do { hash *= 16777619; hash ^= ((ls_hash) >> 8) & 0xFF; } while(0); do { hash *= 16777619; hash ^= ((ls_hash) >> 16) & 0xFF; } while(0); do { hash *= 16777619; hash ^= ( (ls_hash) >> 24) & 0xFF; } while(0); } while(0); |
319 | v_hash = isl_vec_get_hash(aff->v); |
320 | isl_hash_hash(hash, v_hash)do { do { hash *= 16777619; hash ^= (v_hash) & 0xFF; } while (0); do { hash *= 16777619; hash ^= ((v_hash) >> 8) & 0xFF; } while(0); do { hash *= 16777619; hash ^= ((v_hash) >> 16) & 0xFF; } while(0); do { hash *= 16777619; hash ^= ( (v_hash) >> 24) & 0xFF; } while(0); } while(0); |
321 | |
322 | return hash; |
323 | } |
324 | |
325 | /* Externally, an isl_aff has a map space, but internally, the |
326 | * ls field corresponds to the domain of that space. |
327 | */ |
328 | int isl_aff_dim(__isl_keep isl_aff *aff, enum isl_dim_type type) |
329 | { |
330 | if (!aff) |
331 | return 0; |
332 | if (type == isl_dim_out) |
333 | return 1; |
334 | if (type == isl_dim_in) |
335 | type = isl_dim_set; |
336 | return isl_local_space_dim(aff->ls, type); |
337 | } |
338 | |
339 | /* Return the position of the dimension of the given type and name |
340 | * in "aff". |
341 | * Return -1 if no such dimension can be found. |
342 | */ |
343 | int isl_aff_find_dim_by_name(__isl_keep isl_aff *aff, enum isl_dim_type type, |
344 | const char *name) |
345 | { |
346 | if (!aff) |
347 | return -1; |
348 | if (type == isl_dim_out) |
349 | return -1; |
350 | if (type == isl_dim_in) |
351 | type = isl_dim_set; |
352 | return isl_local_space_find_dim_by_name(aff->ls, type, name); |
353 | } |
354 | |
355 | /* Return the domain space of "aff". |
356 | */ |
357 | static __isl_keep isl_space *isl_aff_peek_domain_space(__isl_keep isl_aff *aff) |
358 | { |
359 | return aff ? isl_local_space_peek_space(aff->ls) : NULL((void*)0); |
360 | } |
361 | |
362 | __isl_give isl_space *isl_aff_get_domain_space(__isl_keep isl_aff *aff) |
363 | { |
364 | return isl_space_copy(isl_aff_peek_domain_space(aff)); |
365 | } |
366 | |
367 | __isl_give isl_space *isl_aff_get_space(__isl_keep isl_aff *aff) |
368 | { |
369 | isl_space *space; |
370 | if (!aff) |
371 | return NULL((void*)0); |
372 | space = isl_local_space_get_space(aff->ls); |
373 | space = isl_space_from_domain(space); |
374 | space = isl_space_add_dims(space, isl_dim_out, 1); |
375 | return space; |
376 | } |
377 | |
378 | __isl_give isl_local_space *isl_aff_get_domain_local_space( |
379 | __isl_keep isl_aff *aff) |
380 | { |
381 | return aff ? isl_local_space_copy(aff->ls) : NULL((void*)0); |
382 | } |
383 | |
384 | __isl_give isl_local_space *isl_aff_get_local_space(__isl_keep isl_aff *aff) |
385 | { |
386 | isl_local_space *ls; |
387 | if (!aff) |
388 | return NULL((void*)0); |
389 | ls = isl_local_space_copy(aff->ls); |
390 | ls = isl_local_space_from_domain(ls); |
391 | ls = isl_local_space_add_dims(ls, isl_dim_out, 1); |
392 | return ls; |
393 | } |
394 | |
395 | /* Return the local space of the domain of "aff". |
396 | * This may be either a copy or the local space itself |
397 | * if there is only one reference to "aff". |
398 | * This allows the local space to be modified inplace |
399 | * if both the expression and its local space have only a single reference. |
400 | * The caller is not allowed to modify "aff" between this call and |
401 | * a subsequent call to isl_aff_restore_domain_local_space. |
402 | * The only exception is that isl_aff_free can be called instead. |
403 | */ |
404 | __isl_give isl_local_space *isl_aff_take_domain_local_space( |
405 | __isl_keep isl_aff *aff) |
406 | { |
407 | isl_local_space *ls; |
408 | |
409 | if (!aff) |
410 | return NULL((void*)0); |
411 | if (aff->ref != 1) |
412 | return isl_aff_get_domain_local_space(aff); |
413 | ls = aff->ls; |
414 | aff->ls = NULL((void*)0); |
415 | return ls; |
416 | } |
417 | |
418 | /* Set the local space of the domain of "aff" to "ls", |
419 | * where the local space of "aff" may be missing |
420 | * due to a preceding call to isl_aff_take_domain_local_space. |
421 | * However, in this case, "aff" only has a single reference and |
422 | * then the call to isl_aff_cow has no effect. |
423 | */ |
424 | __isl_give isl_aff *isl_aff_restore_domain_local_space( |
425 | __isl_keep isl_aff *aff, __isl_take isl_local_space *ls) |
426 | { |
427 | if (!aff || !ls) |
428 | goto error; |
429 | |
430 | if (aff->ls == ls) { |
431 | isl_local_space_free(ls); |
432 | return aff; |
433 | } |
434 | |
435 | aff = isl_aff_cow(aff); |
436 | if (!aff) |
437 | goto error; |
438 | isl_local_space_free(aff->ls); |
439 | aff->ls = ls; |
440 | |
441 | return aff; |
442 | error: |
443 | isl_aff_free(aff); |
444 | isl_local_space_free(ls); |
445 | return NULL((void*)0); |
446 | } |
447 | |
448 | /* Externally, an isl_aff has a map space, but internally, the |
449 | * ls field corresponds to the domain of that space. |
450 | */ |
451 | const char *isl_aff_get_dim_name(__isl_keep isl_aff *aff, |
452 | enum isl_dim_type type, unsigned pos) |
453 | { |
454 | if (!aff) |
455 | return NULL((void*)0); |
456 | if (type == isl_dim_out) |
457 | return NULL((void*)0); |
458 | if (type == isl_dim_in) |
459 | type = isl_dim_set; |
460 | return isl_local_space_get_dim_name(aff->ls, type, pos); |
461 | } |
462 | |
463 | __isl_give isl_aff *isl_aff_reset_domain_space(__isl_take isl_aff *aff, |
464 | __isl_take isl_space *dim) |
465 | { |
466 | aff = isl_aff_cow(aff); |
467 | if (!aff || !dim) |
468 | goto error; |
469 | |
470 | aff->ls = isl_local_space_reset_space(aff->ls, dim); |
471 | if (!aff->ls) |
472 | return isl_aff_free(aff); |
473 | |
474 | return aff; |
475 | error: |
476 | isl_aff_free(aff); |
477 | isl_space_free(dim); |
478 | return NULL((void*)0); |
479 | } |
480 | |
481 | /* Reset the space of "aff". This function is called from isl_pw_templ.c |
482 | * and doesn't know if the space of an element object is represented |
483 | * directly or through its domain. It therefore passes along both. |
484 | */ |
485 | __isl_give isl_aff *isl_aff_reset_space_and_domain(__isl_take isl_aff *aff, |
486 | __isl_take isl_space *space, __isl_take isl_space *domain) |
487 | { |
488 | isl_space_free(space); |
489 | return isl_aff_reset_domain_space(aff, domain); |
490 | } |
491 | |
492 | /* Reorder the coefficients of the affine expression based |
493 | * on the given reordering. |
494 | * The reordering r is assumed to have been extended with the local |
495 | * variables. |
496 | */ |
497 | static __isl_give isl_vec *vec_reorder(__isl_take isl_vec *vec, |
498 | __isl_take isl_reordering *r, int n_div) |
499 | { |
500 | isl_space *space; |
501 | isl_vec *res; |
502 | int i; |
503 | |
504 | if (!vec || !r) |
505 | goto error; |
506 | |
507 | space = isl_reordering_peek_space(r); |
508 | res = isl_vec_alloc(vec->ctx, |
509 | 2 + isl_space_dim(space, isl_dim_all) + n_div); |
510 | if (!res) |
511 | goto error; |
512 | isl_seq_cpy(res->el, vec->el, 2); |
513 | isl_seq_clr(res->el + 2, res->size - 2); |
514 | for (i = 0; i < r->len; ++i) |
515 | isl_int_set(res->el[2 + r->pos[i]], vec->el[2 + i])isl_sioimath_set((res->el[2 + r->pos[i]]), *(vec->el [2 + i])); |
516 | |
517 | isl_reordering_free(r); |
518 | isl_vec_free(vec); |
519 | return res; |
520 | error: |
521 | isl_vec_free(vec); |
522 | isl_reordering_free(r); |
523 | return NULL((void*)0); |
524 | } |
525 | |
526 | /* Reorder the dimensions of the domain of "aff" according |
527 | * to the given reordering. |
528 | */ |
529 | __isl_give isl_aff *isl_aff_realign_domain(__isl_take isl_aff *aff, |
530 | __isl_take isl_reordering *r) |
531 | { |
532 | aff = isl_aff_cow(aff); |
533 | if (!aff) |
534 | goto error; |
535 | |
536 | r = isl_reordering_extend(r, aff->ls->div->n_row); |
537 | aff->v = vec_reorder(aff->v, isl_reordering_copy(r), |
538 | aff->ls->div->n_row); |
539 | aff->ls = isl_local_space_realign(aff->ls, r); |
540 | |
541 | if (!aff->v || !aff->ls) |
542 | return isl_aff_free(aff); |
543 | |
544 | return aff; |
545 | error: |
546 | isl_aff_free(aff); |
547 | isl_reordering_free(r); |
548 | return NULL((void*)0); |
549 | } |
550 | |
551 | __isl_give isl_aff *isl_aff_align_params(__isl_take isl_aff *aff, |
552 | __isl_take isl_space *model) |
553 | { |
554 | isl_bool equal_params; |
555 | |
556 | if (!aff || !model) |
557 | goto error; |
558 | |
559 | equal_params = isl_space_has_equal_params(aff->ls->dim, model); |
560 | if (equal_params < 0) |
561 | goto error; |
562 | if (!equal_params) { |
563 | isl_reordering *exp; |
564 | |
565 | exp = isl_parameter_alignment_reordering(aff->ls->dim, model); |
566 | exp = isl_reordering_extend_space(exp, |
567 | isl_aff_get_domain_space(aff)); |
568 | aff = isl_aff_realign_domain(aff, exp); |
569 | } |
570 | |
571 | isl_space_free(model); |
572 | return aff; |
573 | error: |
574 | isl_space_free(model); |
575 | isl_aff_free(aff); |
576 | return NULL((void*)0); |
577 | } |
578 | |
579 | /* Is "aff" obviously equal to zero? |
580 | * |
581 | * If the denominator is zero, then "aff" is not equal to zero. |
582 | */ |
583 | isl_bool isl_aff_plain_is_zero(__isl_keep isl_aff *aff) |
584 | { |
585 | if (!aff) |
586 | return isl_bool_error; |
587 | |
588 | if (isl_int_is_zero(aff->v->el[0])(isl_sioimath_sgn(*(aff->v->el[0])) == 0)) |
589 | return isl_bool_false; |
590 | return isl_seq_first_non_zero(aff->v->el + 1, aff->v->size - 1) < 0; |
591 | } |
592 | |
593 | /* Does "aff" represent NaN? |
594 | */ |
595 | isl_bool isl_aff_is_nan(__isl_keep isl_aff *aff) |
596 | { |
597 | if (!aff) |
598 | return isl_bool_error; |
599 | |
600 | return isl_seq_first_non_zero(aff->v->el, 2) < 0; |
601 | } |
602 | |
603 | /* Are "aff1" and "aff2" obviously equal? |
604 | * |
605 | * NaN is not equal to anything, not even to another NaN. |
606 | */ |
607 | isl_bool isl_aff_plain_is_equal(__isl_keep isl_aff *aff1, |
608 | __isl_keep isl_aff *aff2) |
609 | { |
610 | isl_bool equal; |
611 | |
612 | if (!aff1 || !aff2) |
613 | return isl_bool_error; |
614 | |
615 | if (isl_aff_is_nan(aff1) || isl_aff_is_nan(aff2)) |
616 | return isl_bool_false; |
617 | |
618 | equal = isl_local_space_is_equal(aff1->ls, aff2->ls); |
619 | if (equal < 0 || !equal) |
620 | return equal; |
621 | |
622 | return isl_vec_is_equal(aff1->v, aff2->v); |
623 | } |
624 | |
625 | /* Return the common denominator of "aff" in "v". |
626 | * |
627 | * We cannot return anything meaningful in case of a NaN. |
628 | */ |
629 | isl_stat isl_aff_get_denominator(__isl_keep isl_aff *aff, isl_int *v) |
630 | { |
631 | if (!aff) |
632 | return isl_stat_error; |
633 | if (isl_aff_is_nan(aff)) |
634 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "cannot get denominator of NaN", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 635); return isl_stat_error; } while (0) |
635 | "cannot get denominator of NaN", return isl_stat_error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "cannot get denominator of NaN", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 635); return isl_stat_error; } while (0); |
636 | isl_int_set(*v, aff->v->el[0])isl_sioimath_set((*v), *(aff->v->el[0])); |
637 | return isl_stat_ok; |
638 | } |
639 | |
640 | /* Return the common denominator of "aff". |
641 | */ |
642 | __isl_give isl_val *isl_aff_get_denominator_val(__isl_keep isl_aff *aff) |
643 | { |
644 | isl_ctx *ctx; |
645 | |
646 | if (!aff) |
647 | return NULL((void*)0); |
648 | |
649 | ctx = isl_aff_get_ctx(aff); |
650 | if (isl_aff_is_nan(aff)) |
651 | return isl_val_nan(ctx); |
652 | return isl_val_int_from_isl_int(ctx, aff->v->el[0]); |
653 | } |
654 | |
655 | /* Return the constant term of "aff". |
656 | */ |
657 | __isl_give isl_val *isl_aff_get_constant_val(__isl_keep isl_aff *aff) |
658 | { |
659 | isl_ctx *ctx; |
660 | isl_val *v; |
661 | |
662 | if (!aff) |
663 | return NULL((void*)0); |
664 | |
665 | ctx = isl_aff_get_ctx(aff); |
666 | if (isl_aff_is_nan(aff)) |
667 | return isl_val_nan(ctx); |
668 | v = isl_val_rat_from_isl_int(ctx, aff->v->el[1], aff->v->el[0]); |
669 | return isl_val_normalize(v); |
670 | } |
671 | |
672 | /* Return the coefficient of the variable of type "type" at position "pos" |
673 | * of "aff". |
674 | */ |
675 | __isl_give isl_val *isl_aff_get_coefficient_val(__isl_keep isl_aff *aff, |
676 | enum isl_dim_type type, int pos) |
677 | { |
678 | isl_ctx *ctx; |
679 | isl_val *v; |
680 | |
681 | if (!aff) |
682 | return NULL((void*)0); |
683 | |
684 | ctx = isl_aff_get_ctx(aff); |
685 | if (type == isl_dim_out) |
686 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 688); return ((void*)0); } while (0) |
687 | "output/set dimension does not have a coefficient",do { isl_handle_error(ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 688); return ((void*)0); } while (0) |
688 | return NULL)do { isl_handle_error(ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 688); return ((void*)0); } while (0); |
689 | if (type == isl_dim_in) |
690 | type = isl_dim_set; |
691 | |
692 | if (pos >= isl_local_space_dim(aff->ls, type)) |
693 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "position out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 694); return ((void*)0); } while (0) |
694 | "position out of bounds", return NULL)do { isl_handle_error(ctx, isl_error_invalid, "position out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 694); return ((void*)0); } while (0); |
695 | |
696 | if (isl_aff_is_nan(aff)) |
697 | return isl_val_nan(ctx); |
698 | pos += isl_local_space_offset(aff->ls, type); |
699 | v = isl_val_rat_from_isl_int(ctx, aff->v->el[1 + pos], aff->v->el[0]); |
700 | return isl_val_normalize(v); |
701 | } |
702 | |
703 | /* Return the sign of the coefficient of the variable of type "type" |
704 | * at position "pos" of "aff". |
705 | */ |
706 | int isl_aff_coefficient_sgn(__isl_keep isl_aff *aff, enum isl_dim_type type, |
707 | int pos) |
708 | { |
709 | isl_ctx *ctx; |
710 | |
711 | if (!aff) |
712 | return 0; |
713 | |
714 | ctx = isl_aff_get_ctx(aff); |
715 | if (type == isl_dim_out) |
716 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 718); return 0; } while (0) |
717 | "output/set dimension does not have a coefficient",do { isl_handle_error(ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 718); return 0; } while (0) |
718 | return 0)do { isl_handle_error(ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 718); return 0; } while (0); |
719 | if (type == isl_dim_in) |
720 | type = isl_dim_set; |
721 | |
722 | if (pos >= isl_local_space_dim(aff->ls, type)) |
723 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "position out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 724); return 0; } while (0) |
724 | "position out of bounds", return 0)do { isl_handle_error(ctx, isl_error_invalid, "position out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 724); return 0; } while (0); |
725 | |
726 | pos += isl_local_space_offset(aff->ls, type); |
727 | return isl_int_sgn(aff->v->el[1 + pos])isl_sioimath_sgn(*(aff->v->el[1 + pos])); |
728 | } |
729 | |
730 | /* Replace the numerator of the constant term of "aff" by "v". |
731 | * |
732 | * A NaN is unaffected by this operation. |
733 | */ |
734 | __isl_give isl_aff *isl_aff_set_constant(__isl_take isl_aff *aff, isl_int v) |
735 | { |
736 | if (!aff) |
737 | return NULL((void*)0); |
738 | if (isl_aff_is_nan(aff)) |
739 | return aff; |
740 | aff = isl_aff_cow(aff); |
741 | if (!aff) |
742 | return NULL((void*)0); |
743 | |
744 | aff->v = isl_vec_cow(aff->v); |
745 | if (!aff->v) |
746 | return isl_aff_free(aff); |
747 | |
748 | isl_int_set(aff->v->el[1], v)isl_sioimath_set((aff->v->el[1]), *(v)); |
749 | |
750 | return aff; |
751 | } |
752 | |
753 | /* Replace the constant term of "aff" by "v". |
754 | * |
755 | * A NaN is unaffected by this operation. |
756 | */ |
757 | __isl_give isl_aff *isl_aff_set_constant_val(__isl_take isl_aff *aff, |
758 | __isl_take isl_val *v) |
759 | { |
760 | if (!aff || !v) |
761 | goto error; |
762 | |
763 | if (isl_aff_is_nan(aff)) { |
764 | isl_val_free(v); |
765 | return aff; |
766 | } |
767 | |
768 | if (!isl_val_is_rat(v)) |
769 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "expecting rational value", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 770); goto error; } while (0) |
770 | "expecting rational value", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "expecting rational value", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 770); goto error; } while (0); |
771 | |
772 | if (isl_int_eq(aff->v->el[1], v->n)(isl_sioimath_cmp(*(aff->v->el[1]), *(v->n)) == 0) && |
773 | isl_int_eq(aff->v->el[0], v->d)(isl_sioimath_cmp(*(aff->v->el[0]), *(v->d)) == 0)) { |
774 | isl_val_free(v); |
775 | return aff; |
776 | } |
777 | |
778 | aff = isl_aff_cow(aff); |
779 | if (!aff) |
780 | goto error; |
781 | aff->v = isl_vec_cow(aff->v); |
782 | if (!aff->v) |
783 | goto error; |
784 | |
785 | if (isl_int_eq(aff->v->el[0], v->d)(isl_sioimath_cmp(*(aff->v->el[0]), *(v->d)) == 0)) { |
786 | isl_int_set(aff->v->el[1], v->n)isl_sioimath_set((aff->v->el[1]), *(v->n)); |
787 | } else if (isl_int_is_one(v->d)(isl_sioimath_cmp_si(*(v->d), 1) == 0)) { |
788 | isl_int_mul(aff->v->el[1], aff->v->el[0], v->n)isl_sioimath_mul((aff->v->el[1]), *(aff->v->el[0] ), *(v->n)); |
789 | } else { |
790 | isl_seq_scale(aff->v->el + 1, |
791 | aff->v->el + 1, v->d, aff->v->size - 1); |
792 | isl_int_mul(aff->v->el[1], aff->v->el[0], v->n)isl_sioimath_mul((aff->v->el[1]), *(aff->v->el[0] ), *(v->n)); |
793 | isl_int_mul(aff->v->el[0], aff->v->el[0], v->d)isl_sioimath_mul((aff->v->el[0]), *(aff->v->el[0] ), *(v->d)); |
794 | aff->v = isl_vec_normalize(aff->v); |
795 | if (!aff->v) |
796 | goto error; |
797 | } |
798 | |
799 | isl_val_free(v); |
800 | return aff; |
801 | error: |
802 | isl_aff_free(aff); |
803 | isl_val_free(v); |
804 | return NULL((void*)0); |
805 | } |
806 | |
807 | /* Add "v" to the constant term of "aff". |
808 | * |
809 | * A NaN is unaffected by this operation. |
810 | */ |
811 | __isl_give isl_aff *isl_aff_add_constant(__isl_take isl_aff *aff, isl_int v) |
812 | { |
813 | if (isl_int_is_zero(v)(isl_sioimath_sgn(*(v)) == 0)) |
814 | return aff; |
815 | |
816 | if (!aff) |
817 | return NULL((void*)0); |
818 | if (isl_aff_is_nan(aff)) |
819 | return aff; |
820 | aff = isl_aff_cow(aff); |
821 | if (!aff) |
822 | return NULL((void*)0); |
823 | |
824 | aff->v = isl_vec_cow(aff->v); |
825 | if (!aff->v) |
826 | return isl_aff_free(aff); |
827 | |
828 | isl_int_addmul(aff->v->el[1], aff->v->el[0], v)isl_sioimath_addmul((aff->v->el[1]), *(aff->v->el [0]), *(v)); |
829 | |
830 | return aff; |
831 | } |
832 | |
833 | /* Add "v" to the constant term of "aff". |
834 | * |
835 | * A NaN is unaffected by this operation. |
836 | */ |
837 | __isl_give isl_aff *isl_aff_add_constant_val(__isl_take isl_aff *aff, |
838 | __isl_take isl_val *v) |
839 | { |
840 | if (!aff || !v) |
841 | goto error; |
842 | |
843 | if (isl_aff_is_nan(aff) || isl_val_is_zero(v)) { |
844 | isl_val_free(v); |
845 | return aff; |
846 | } |
847 | |
848 | if (!isl_val_is_rat(v)) |
849 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "expecting rational value", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 850); goto error; } while (0) |
850 | "expecting rational value", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "expecting rational value", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 850); goto error; } while (0); |
851 | |
852 | aff = isl_aff_cow(aff); |
853 | if (!aff) |
854 | goto error; |
855 | |
856 | aff->v = isl_vec_cow(aff->v); |
857 | if (!aff->v) |
858 | goto error; |
859 | |
860 | if (isl_int_is_one(v->d)(isl_sioimath_cmp_si(*(v->d), 1) == 0)) { |
861 | isl_int_addmul(aff->v->el[1], aff->v->el[0], v->n)isl_sioimath_addmul((aff->v->el[1]), *(aff->v->el [0]), *(v->n)); |
862 | } else if (isl_int_eq(aff->v->el[0], v->d)(isl_sioimath_cmp(*(aff->v->el[0]), *(v->d)) == 0)) { |
863 | isl_int_add(aff->v->el[1], aff->v->el[1], v->n)isl_sioimath_add((aff->v->el[1]), *(aff->v->el[1] ), *(v->n)); |
864 | aff->v = isl_vec_normalize(aff->v); |
865 | if (!aff->v) |
866 | goto error; |
867 | } else { |
868 | isl_seq_scale(aff->v->el + 1, |
869 | aff->v->el + 1, v->d, aff->v->size - 1); |
870 | isl_int_addmul(aff->v->el[1], aff->v->el[0], v->n)isl_sioimath_addmul((aff->v->el[1]), *(aff->v->el [0]), *(v->n)); |
871 | isl_int_mul(aff->v->el[0], aff->v->el[0], v->d)isl_sioimath_mul((aff->v->el[0]), *(aff->v->el[0] ), *(v->d)); |
872 | aff->v = isl_vec_normalize(aff->v); |
873 | if (!aff->v) |
874 | goto error; |
875 | } |
876 | |
877 | isl_val_free(v); |
878 | return aff; |
879 | error: |
880 | isl_aff_free(aff); |
881 | isl_val_free(v); |
882 | return NULL((void*)0); |
883 | } |
884 | |
885 | __isl_give isl_aff *isl_aff_add_constant_si(__isl_take isl_aff *aff, int v) |
886 | { |
887 | isl_int t; |
888 | |
889 | isl_int_init(t)isl_sioimath_init((t)); |
890 | isl_int_set_si(t, v)isl_sioimath_set_si((t), v); |
891 | aff = isl_aff_add_constant(aff, t); |
892 | isl_int_clear(t)isl_sioimath_clear((t)); |
893 | |
894 | return aff; |
895 | } |
896 | |
897 | /* Add "v" to the numerator of the constant term of "aff". |
898 | * |
899 | * A NaN is unaffected by this operation. |
900 | */ |
901 | __isl_give isl_aff *isl_aff_add_constant_num(__isl_take isl_aff *aff, isl_int v) |
902 | { |
903 | if (isl_int_is_zero(v)(isl_sioimath_sgn(*(v)) == 0)) |
904 | return aff; |
905 | |
906 | if (!aff) |
907 | return NULL((void*)0); |
908 | if (isl_aff_is_nan(aff)) |
909 | return aff; |
910 | aff = isl_aff_cow(aff); |
911 | if (!aff) |
912 | return NULL((void*)0); |
913 | |
914 | aff->v = isl_vec_cow(aff->v); |
915 | if (!aff->v) |
916 | return isl_aff_free(aff); |
917 | |
918 | isl_int_add(aff->v->el[1], aff->v->el[1], v)isl_sioimath_add((aff->v->el[1]), *(aff->v->el[1] ), *(v)); |
919 | |
920 | return aff; |
921 | } |
922 | |
923 | /* Add "v" to the numerator of the constant term of "aff". |
924 | * |
925 | * A NaN is unaffected by this operation. |
926 | */ |
927 | __isl_give isl_aff *isl_aff_add_constant_num_si(__isl_take isl_aff *aff, int v) |
928 | { |
929 | isl_int t; |
930 | |
931 | if (v == 0) |
932 | return aff; |
933 | |
934 | isl_int_init(t)isl_sioimath_init((t)); |
935 | isl_int_set_si(t, v)isl_sioimath_set_si((t), v); |
936 | aff = isl_aff_add_constant_num(aff, t); |
937 | isl_int_clear(t)isl_sioimath_clear((t)); |
938 | |
939 | return aff; |
940 | } |
941 | |
942 | /* Replace the numerator of the constant term of "aff" by "v". |
943 | * |
944 | * A NaN is unaffected by this operation. |
945 | */ |
946 | __isl_give isl_aff *isl_aff_set_constant_si(__isl_take isl_aff *aff, int v) |
947 | { |
948 | if (!aff) |
949 | return NULL((void*)0); |
950 | if (isl_aff_is_nan(aff)) |
951 | return aff; |
952 | aff = isl_aff_cow(aff); |
953 | if (!aff) |
954 | return NULL((void*)0); |
955 | |
956 | aff->v = isl_vec_cow(aff->v); |
957 | if (!aff->v) |
958 | return isl_aff_free(aff); |
959 | |
960 | isl_int_set_si(aff->v->el[1], v)isl_sioimath_set_si((aff->v->el[1]), v); |
961 | |
962 | return aff; |
963 | } |
964 | |
965 | /* Replace the numerator of the coefficient of the variable of type "type" |
966 | * at position "pos" of "aff" by "v". |
967 | * |
968 | * A NaN is unaffected by this operation. |
969 | */ |
970 | __isl_give isl_aff *isl_aff_set_coefficient(__isl_take isl_aff *aff, |
971 | enum isl_dim_type type, int pos, isl_int v) |
972 | { |
973 | if (!aff) |
974 | return NULL((void*)0); |
975 | |
976 | if (type == isl_dim_out) |
977 | isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 979); return isl_aff_free(aff); } while (0) |
978 | "output/set dimension does not have a coefficient",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 979); return isl_aff_free(aff); } while (0) |
979 | return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 979); return isl_aff_free(aff); } while (0); |
980 | if (type == isl_dim_in) |
981 | type = isl_dim_set; |
982 | |
983 | if (pos >= isl_local_space_dim(aff->ls, type)) |
984 | isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 985); return isl_aff_free(aff); } while (0) |
985 | "position out of bounds", return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 985); return isl_aff_free(aff); } while (0); |
986 | |
987 | if (isl_aff_is_nan(aff)) |
988 | return aff; |
989 | aff = isl_aff_cow(aff); |
990 | if (!aff) |
991 | return NULL((void*)0); |
992 | |
993 | aff->v = isl_vec_cow(aff->v); |
994 | if (!aff->v) |
995 | return isl_aff_free(aff); |
996 | |
997 | pos += isl_local_space_offset(aff->ls, type); |
998 | isl_int_set(aff->v->el[1 + pos], v)isl_sioimath_set((aff->v->el[1 + pos]), *(v)); |
999 | |
1000 | return aff; |
1001 | } |
1002 | |
1003 | /* Replace the numerator of the coefficient of the variable of type "type" |
1004 | * at position "pos" of "aff" by "v". |
1005 | * |
1006 | * A NaN is unaffected by this operation. |
1007 | */ |
1008 | __isl_give isl_aff *isl_aff_set_coefficient_si(__isl_take isl_aff *aff, |
1009 | enum isl_dim_type type, int pos, int v) |
1010 | { |
1011 | if (!aff) |
1012 | return NULL((void*)0); |
1013 | |
1014 | if (type == isl_dim_out) |
1015 | isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1017); return isl_aff_free(aff); } while (0) |
1016 | "output/set dimension does not have a coefficient",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1017); return isl_aff_free(aff); } while (0) |
1017 | return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1017); return isl_aff_free(aff); } while (0); |
1018 | if (type == isl_dim_in) |
1019 | type = isl_dim_set; |
1020 | |
1021 | if (pos < 0 || pos >= isl_local_space_dim(aff->ls, type)) |
1022 | isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1023); return isl_aff_free(aff); } while (0) |
1023 | "position out of bounds", return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1023); return isl_aff_free(aff); } while (0); |
1024 | |
1025 | if (isl_aff_is_nan(aff)) |
1026 | return aff; |
1027 | pos += isl_local_space_offset(aff->ls, type); |
1028 | if (isl_int_cmp_si(aff->v->el[1 + pos], v)isl_sioimath_cmp_si(*(aff->v->el[1 + pos]), v) == 0) |
1029 | return aff; |
1030 | |
1031 | aff = isl_aff_cow(aff); |
1032 | if (!aff) |
1033 | return NULL((void*)0); |
1034 | |
1035 | aff->v = isl_vec_cow(aff->v); |
1036 | if (!aff->v) |
1037 | return isl_aff_free(aff); |
1038 | |
1039 | isl_int_set_si(aff->v->el[1 + pos], v)isl_sioimath_set_si((aff->v->el[1 + pos]), v); |
1040 | |
1041 | return aff; |
1042 | } |
1043 | |
1044 | /* Replace the coefficient of the variable of type "type" at position "pos" |
1045 | * of "aff" by "v". |
1046 | * |
1047 | * A NaN is unaffected by this operation. |
1048 | */ |
1049 | __isl_give isl_aff *isl_aff_set_coefficient_val(__isl_take isl_aff *aff, |
1050 | enum isl_dim_type type, int pos, __isl_take isl_val *v) |
1051 | { |
1052 | if (!aff || !v) |
1053 | goto error; |
1054 | |
1055 | if (type == isl_dim_out) |
1056 | isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1058); goto error; } while (0) |
1057 | "output/set dimension does not have a coefficient",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1058); goto error; } while (0) |
1058 | goto error)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1058); goto error; } while (0); |
1059 | if (type == isl_dim_in) |
1060 | type = isl_dim_set; |
1061 | |
1062 | if (pos >= isl_local_space_dim(aff->ls, type)) |
1063 | isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1064); goto error; } while (0) |
1064 | "position out of bounds", goto error)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1064); goto error; } while (0); |
1065 | |
1066 | if (isl_aff_is_nan(aff)) { |
1067 | isl_val_free(v); |
1068 | return aff; |
1069 | } |
1070 | if (!isl_val_is_rat(v)) |
1071 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "expecting rational value", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1072); goto error; } while (0) |
1072 | "expecting rational value", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "expecting rational value", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1072); goto error; } while (0); |
1073 | |
1074 | pos += isl_local_space_offset(aff->ls, type); |
1075 | if (isl_int_eq(aff->v->el[1 + pos], v->n)(isl_sioimath_cmp(*(aff->v->el[1 + pos]), *(v->n)) == 0) && |
1076 | isl_int_eq(aff->v->el[0], v->d)(isl_sioimath_cmp(*(aff->v->el[0]), *(v->d)) == 0)) { |
1077 | isl_val_free(v); |
1078 | return aff; |
1079 | } |
1080 | |
1081 | aff = isl_aff_cow(aff); |
1082 | if (!aff) |
1083 | goto error; |
1084 | aff->v = isl_vec_cow(aff->v); |
1085 | if (!aff->v) |
1086 | goto error; |
1087 | |
1088 | if (isl_int_eq(aff->v->el[0], v->d)(isl_sioimath_cmp(*(aff->v->el[0]), *(v->d)) == 0)) { |
1089 | isl_int_set(aff->v->el[1 + pos], v->n)isl_sioimath_set((aff->v->el[1 + pos]), *(v->n)); |
1090 | } else if (isl_int_is_one(v->d)(isl_sioimath_cmp_si(*(v->d), 1) == 0)) { |
1091 | isl_int_mul(aff->v->el[1 + pos], aff->v->el[0], v->n)isl_sioimath_mul((aff->v->el[1 + pos]), *(aff->v-> el[0]), *(v->n)); |
1092 | } else { |
1093 | isl_seq_scale(aff->v->el + 1, |
1094 | aff->v->el + 1, v->d, aff->v->size - 1); |
1095 | isl_int_mul(aff->v->el[1 + pos], aff->v->el[0], v->n)isl_sioimath_mul((aff->v->el[1 + pos]), *(aff->v-> el[0]), *(v->n)); |
1096 | isl_int_mul(aff->v->el[0], aff->v->el[0], v->d)isl_sioimath_mul((aff->v->el[0]), *(aff->v->el[0] ), *(v->d)); |
1097 | aff->v = isl_vec_normalize(aff->v); |
1098 | if (!aff->v) |
1099 | goto error; |
1100 | } |
1101 | |
1102 | isl_val_free(v); |
1103 | return aff; |
1104 | error: |
1105 | isl_aff_free(aff); |
1106 | isl_val_free(v); |
1107 | return NULL((void*)0); |
1108 | } |
1109 | |
1110 | /* Add "v" to the coefficient of the variable of type "type" |
1111 | * at position "pos" of "aff". |
1112 | * |
1113 | * A NaN is unaffected by this operation. |
1114 | */ |
1115 | __isl_give isl_aff *isl_aff_add_coefficient(__isl_take isl_aff *aff, |
1116 | enum isl_dim_type type, int pos, isl_int v) |
1117 | { |
1118 | if (!aff) |
1119 | return NULL((void*)0); |
1120 | |
1121 | if (type == isl_dim_out) |
1122 | isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1124); return isl_aff_free(aff); } while (0) |
1123 | "output/set dimension does not have a coefficient",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1124); return isl_aff_free(aff); } while (0) |
1124 | return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1124); return isl_aff_free(aff); } while (0); |
1125 | if (type == isl_dim_in) |
1126 | type = isl_dim_set; |
1127 | |
1128 | if (pos >= isl_local_space_dim(aff->ls, type)) |
1129 | isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1130); return isl_aff_free(aff); } while (0) |
1130 | "position out of bounds", return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1130); return isl_aff_free(aff); } while (0); |
1131 | |
1132 | if (isl_aff_is_nan(aff)) |
1133 | return aff; |
1134 | aff = isl_aff_cow(aff); |
1135 | if (!aff) |
1136 | return NULL((void*)0); |
1137 | |
1138 | aff->v = isl_vec_cow(aff->v); |
1139 | if (!aff->v) |
1140 | return isl_aff_free(aff); |
1141 | |
1142 | pos += isl_local_space_offset(aff->ls, type); |
1143 | isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v)isl_sioimath_addmul((aff->v->el[1 + pos]), *(aff->v-> el[0]), *(v)); |
1144 | |
1145 | return aff; |
1146 | } |
1147 | |
1148 | /* Add "v" to the coefficient of the variable of type "type" |
1149 | * at position "pos" of "aff". |
1150 | * |
1151 | * A NaN is unaffected by this operation. |
1152 | */ |
1153 | __isl_give isl_aff *isl_aff_add_coefficient_val(__isl_take isl_aff *aff, |
1154 | enum isl_dim_type type, int pos, __isl_take isl_val *v) |
1155 | { |
1156 | if (!aff || !v) |
1157 | goto error; |
1158 | |
1159 | if (isl_val_is_zero(v)) { |
1160 | isl_val_free(v); |
1161 | return aff; |
1162 | } |
1163 | |
1164 | if (type == isl_dim_out) |
1165 | isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1167); goto error; } while (0) |
1166 | "output/set dimension does not have a coefficient",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1167); goto error; } while (0) |
1167 | goto error)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1167); goto error; } while (0); |
1168 | if (type == isl_dim_in) |
1169 | type = isl_dim_set; |
1170 | |
1171 | if (pos >= isl_local_space_dim(aff->ls, type)) |
1172 | isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1173); goto error; } while (0) |
1173 | "position out of bounds", goto error)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1173); goto error; } while (0); |
1174 | |
1175 | if (isl_aff_is_nan(aff)) { |
1176 | isl_val_free(v); |
1177 | return aff; |
1178 | } |
1179 | if (!isl_val_is_rat(v)) |
1180 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "expecting rational value", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1181); goto error; } while (0) |
1181 | "expecting rational value", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "expecting rational value", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1181); goto error; } while (0); |
1182 | |
1183 | aff = isl_aff_cow(aff); |
1184 | if (!aff) |
1185 | goto error; |
1186 | |
1187 | aff->v = isl_vec_cow(aff->v); |
1188 | if (!aff->v) |
1189 | goto error; |
1190 | |
1191 | pos += isl_local_space_offset(aff->ls, type); |
1192 | if (isl_int_is_one(v->d)(isl_sioimath_cmp_si(*(v->d), 1) == 0)) { |
1193 | isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v->n)isl_sioimath_addmul((aff->v->el[1 + pos]), *(aff->v-> el[0]), *(v->n)); |
1194 | } else if (isl_int_eq(aff->v->el[0], v->d)(isl_sioimath_cmp(*(aff->v->el[0]), *(v->d)) == 0)) { |
1195 | isl_int_add(aff->v->el[1 + pos], aff->v->el[1 + pos], v->n)isl_sioimath_add((aff->v->el[1 + pos]), *(aff->v-> el[1 + pos]), *(v->n)); |
1196 | aff->v = isl_vec_normalize(aff->v); |
1197 | if (!aff->v) |
1198 | goto error; |
1199 | } else { |
1200 | isl_seq_scale(aff->v->el + 1, |
1201 | aff->v->el + 1, v->d, aff->v->size - 1); |
1202 | isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v->n)isl_sioimath_addmul((aff->v->el[1 + pos]), *(aff->v-> el[0]), *(v->n)); |
1203 | isl_int_mul(aff->v->el[0], aff->v->el[0], v->d)isl_sioimath_mul((aff->v->el[0]), *(aff->v->el[0] ), *(v->d)); |
1204 | aff->v = isl_vec_normalize(aff->v); |
1205 | if (!aff->v) |
1206 | goto error; |
1207 | } |
1208 | |
1209 | isl_val_free(v); |
1210 | return aff; |
1211 | error: |
1212 | isl_aff_free(aff); |
1213 | isl_val_free(v); |
1214 | return NULL((void*)0); |
1215 | } |
1216 | |
1217 | __isl_give isl_aff *isl_aff_add_coefficient_si(__isl_take isl_aff *aff, |
1218 | enum isl_dim_type type, int pos, int v) |
1219 | { |
1220 | isl_int t; |
1221 | |
1222 | isl_int_init(t)isl_sioimath_init((t)); |
1223 | isl_int_set_si(t, v)isl_sioimath_set_si((t), v); |
1224 | aff = isl_aff_add_coefficient(aff, type, pos, t); |
1225 | isl_int_clear(t)isl_sioimath_clear((t)); |
1226 | |
1227 | return aff; |
1228 | } |
1229 | |
1230 | __isl_give isl_aff *isl_aff_get_div(__isl_keep isl_aff *aff, int pos) |
1231 | { |
1232 | if (!aff) |
1233 | return NULL((void*)0); |
1234 | |
1235 | return isl_local_space_get_div(aff->ls, pos); |
1236 | } |
1237 | |
1238 | /* Return the negation of "aff". |
1239 | * |
1240 | * As a special case, -NaN = NaN. |
1241 | */ |
1242 | __isl_give isl_aff *isl_aff_neg(__isl_take isl_aff *aff) |
1243 | { |
1244 | if (!aff) |
1245 | return NULL((void*)0); |
1246 | if (isl_aff_is_nan(aff)) |
1247 | return aff; |
1248 | aff = isl_aff_cow(aff); |
1249 | if (!aff) |
1250 | return NULL((void*)0); |
1251 | aff->v = isl_vec_cow(aff->v); |
1252 | if (!aff->v) |
1253 | return isl_aff_free(aff); |
1254 | |
1255 | isl_seq_neg(aff->v->el + 1, aff->v->el + 1, aff->v->size - 1); |
1256 | |
1257 | return aff; |
1258 | } |
1259 | |
1260 | /* Remove divs from the local space that do not appear in the affine |
1261 | * expression. |
1262 | * We currently only remove divs at the end. |
1263 | * Some intermediate divs may also not appear directly in the affine |
1264 | * expression, but we would also need to check that no other divs are |
1265 | * defined in terms of them. |
1266 | */ |
1267 | __isl_give isl_aff *isl_aff_remove_unused_divs(__isl_take isl_aff *aff) |
1268 | { |
1269 | int pos; |
1270 | int off; |
1271 | int n; |
1272 | |
1273 | if (!aff) |
1274 | return NULL((void*)0); |
1275 | |
1276 | n = isl_local_space_dim(aff->ls, isl_dim_div); |
1277 | off = isl_local_space_offset(aff->ls, isl_dim_div); |
1278 | |
1279 | pos = isl_seq_last_non_zero(aff->v->el + 1 + off, n) + 1; |
1280 | if (pos == n) |
1281 | return aff; |
1282 | |
1283 | aff = isl_aff_cow(aff); |
1284 | if (!aff) |
1285 | return NULL((void*)0); |
1286 | |
1287 | aff->ls = isl_local_space_drop_dims(aff->ls, isl_dim_div, pos, n - pos); |
1288 | aff->v = isl_vec_drop_els(aff->v, 1 + off + pos, n - pos); |
1289 | if (!aff->ls || !aff->v) |
1290 | return isl_aff_free(aff); |
1291 | |
1292 | return aff; |
1293 | } |
1294 | |
1295 | /* Look for any divs in the aff->ls with a denominator equal to one |
1296 | * and plug them into the affine expression and any subsequent divs |
1297 | * that may reference the div. |
1298 | */ |
1299 | static __isl_give isl_aff *plug_in_integral_divs(__isl_take isl_aff *aff) |
1300 | { |
1301 | int i, n; |
1302 | int len; |
1303 | isl_int v; |
1304 | isl_vec *vec; |
1305 | isl_local_space *ls; |
1306 | unsigned pos; |
1307 | |
1308 | if (!aff) |
1309 | return NULL((void*)0); |
1310 | |
1311 | n = isl_local_space_dim(aff->ls, isl_dim_div); |
1312 | len = aff->v->size; |
1313 | for (i = 0; i < n; ++i) { |
1314 | if (!isl_int_is_one(aff->ls->div->row[i][0])(isl_sioimath_cmp_si(*(aff->ls->div->row[i][0]), 1) == 0)) |
1315 | continue; |
1316 | ls = isl_local_space_copy(aff->ls); |
1317 | ls = isl_local_space_substitute_seq(ls, isl_dim_div, i, |
1318 | aff->ls->div->row[i], len, i + 1, n - (i + 1)); |
1319 | vec = isl_vec_copy(aff->v); |
1320 | vec = isl_vec_cow(vec); |
1321 | if (!ls || !vec) |
1322 | goto error; |
1323 | |
1324 | isl_int_init(v)isl_sioimath_init((v)); |
1325 | |
1326 | pos = isl_local_space_offset(aff->ls, isl_dim_div) + i; |
1327 | isl_seq_substitute(vec->el, pos, aff->ls->div->row[i], |
1328 | len, len, v); |
1329 | |
1330 | isl_int_clear(v)isl_sioimath_clear((v)); |
1331 | |
1332 | isl_vec_free(aff->v); |
1333 | aff->v = vec; |
1334 | isl_local_space_free(aff->ls); |
1335 | aff->ls = ls; |
1336 | } |
1337 | |
1338 | return aff; |
1339 | error: |
1340 | isl_vec_free(vec); |
1341 | isl_local_space_free(ls); |
1342 | return isl_aff_free(aff); |
1343 | } |
1344 | |
1345 | /* Look for any divs j that appear with a unit coefficient inside |
1346 | * the definitions of other divs i and plug them into the definitions |
1347 | * of the divs i. |
1348 | * |
1349 | * In particular, an expression of the form |
1350 | * |
1351 | * floor((f(..) + floor(g(..)/n))/m) |
1352 | * |
1353 | * is simplified to |
1354 | * |
1355 | * floor((n * f(..) + g(..))/(n * m)) |
1356 | * |
1357 | * This simplification is correct because we can move the expression |
1358 | * f(..) into the inner floor in the original expression to obtain |
1359 | * |
1360 | * floor(floor((n * f(..) + g(..))/n)/m) |
1361 | * |
1362 | * from which we can derive the simplified expression. |
1363 | */ |
1364 | static __isl_give isl_aff *plug_in_unit_divs(__isl_take isl_aff *aff) |
1365 | { |
1366 | int i, j, n; |
1367 | int off; |
1368 | |
1369 | if (!aff) |
1370 | return NULL((void*)0); |
1371 | |
1372 | n = isl_local_space_dim(aff->ls, isl_dim_div); |
1373 | off = isl_local_space_offset(aff->ls, isl_dim_div); |
1374 | for (i = 1; i < n; ++i) { |
1375 | for (j = 0; j < i; ++j) { |
1376 | if (!isl_int_is_one(aff->ls->div->row[i][1 + off + j])(isl_sioimath_cmp_si(*(aff->ls->div->row[i][1 + off + j]), 1) == 0)) |
1377 | continue; |
1378 | aff->ls = isl_local_space_substitute_seq(aff->ls, |
1379 | isl_dim_div, j, aff->ls->div->row[j], |
1380 | aff->v->size, i, 1); |
1381 | if (!aff->ls) |
1382 | return isl_aff_free(aff); |
1383 | } |
1384 | } |
1385 | |
1386 | return aff; |
1387 | } |
1388 | |
1389 | /* Swap divs "a" and "b" in "aff", which is assumed to be non-NULL. |
1390 | * |
1391 | * Even though this function is only called on isl_affs with a single |
1392 | * reference, we are careful to only change aff->v and aff->ls together. |
1393 | */ |
1394 | static __isl_give isl_aff *swap_div(__isl_take isl_aff *aff, int a, int b) |
1395 | { |
1396 | unsigned off = isl_local_space_offset(aff->ls, isl_dim_div); |
1397 | isl_local_space *ls; |
1398 | isl_vec *v; |
1399 | |
1400 | ls = isl_local_space_copy(aff->ls); |
1401 | ls = isl_local_space_swap_div(ls, a, b); |
1402 | v = isl_vec_copy(aff->v); |
1403 | v = isl_vec_cow(v); |
1404 | if (!ls || !v) |
1405 | goto error; |
1406 | |
1407 | isl_int_swap(v->el[1 + off + a], v->el[1 + off + b])isl_sioimath_swap((v->el[1 + off + a]), (v->el[1 + off + b])); |
1408 | isl_vec_free(aff->v); |
1409 | aff->v = v; |
1410 | isl_local_space_free(aff->ls); |
1411 | aff->ls = ls; |
1412 | |
1413 | return aff; |
1414 | error: |
1415 | isl_vec_free(v); |
1416 | isl_local_space_free(ls); |
1417 | return isl_aff_free(aff); |
1418 | } |
1419 | |
1420 | /* Merge divs "a" and "b" in "aff", which is assumed to be non-NULL. |
1421 | * |
1422 | * We currently do not actually remove div "b", but simply add its |
1423 | * coefficient to that of "a" and then zero it out. |
1424 | */ |
1425 | static __isl_give isl_aff *merge_divs(__isl_take isl_aff *aff, int a, int b) |
1426 | { |
1427 | unsigned off = isl_local_space_offset(aff->ls, isl_dim_div); |
1428 | |
1429 | if (isl_int_is_zero(aff->v->el[1 + off + b])(isl_sioimath_sgn(*(aff->v->el[1 + off + b])) == 0)) |
1430 | return aff; |
1431 | |
1432 | aff->v = isl_vec_cow(aff->v); |
1433 | if (!aff->v) |
1434 | return isl_aff_free(aff); |
1435 | |
1436 | isl_int_add(aff->v->el[1 + off + a],isl_sioimath_add((aff->v->el[1 + off + a]), *(aff->v ->el[1 + off + a]), *(aff->v->el[1 + off + b])) |
1437 | aff->v->el[1 + off + a], aff->v->el[1 + off + b])isl_sioimath_add((aff->v->el[1 + off + a]), *(aff->v ->el[1 + off + a]), *(aff->v->el[1 + off + b])); |
1438 | isl_int_set_si(aff->v->el[1 + off + b], 0)isl_sioimath_set_si((aff->v->el[1 + off + b]), 0); |
1439 | |
1440 | return aff; |
1441 | } |
1442 | |
1443 | /* Sort the divs in the local space of "aff" according to |
1444 | * the comparison function "cmp_row" in isl_local_space.c, |
1445 | * combining the coefficients of identical divs. |
1446 | * |
1447 | * Reordering divs does not change the semantics of "aff", |
1448 | * so there is no need to call isl_aff_cow. |
1449 | * Moreover, this function is currently only called on isl_affs |
1450 | * with a single reference. |
1451 | */ |
1452 | static __isl_give isl_aff *sort_divs(__isl_take isl_aff *aff) |
1453 | { |
1454 | int i, j, n; |
1455 | |
1456 | if (!aff) |
1457 | return NULL((void*)0); |
1458 | |
1459 | n = isl_aff_dim(aff, isl_dim_div); |
1460 | for (i = 1; i < n; ++i) { |
1461 | for (j = i - 1; j >= 0; --j) { |
1462 | int cmp = isl_mat_cmp_div(aff->ls->div, j, j + 1); |
1463 | if (cmp < 0) |
1464 | break; |
1465 | if (cmp == 0) |
1466 | aff = merge_divs(aff, j, j + 1); |
1467 | else |
1468 | aff = swap_div(aff, j, j + 1); |
1469 | if (!aff) |
1470 | return NULL((void*)0); |
1471 | } |
1472 | } |
1473 | |
1474 | return aff; |
1475 | } |
1476 | |
1477 | /* Normalize the representation of "aff". |
1478 | * |
1479 | * This function should only be called of "new" isl_affs, i.e., |
1480 | * with only a single reference. We therefore do not need to |
1481 | * worry about affecting other instances. |
1482 | */ |
1483 | __isl_give isl_aff *isl_aff_normalize(__isl_take isl_aff *aff) |
1484 | { |
1485 | if (!aff) |
1486 | return NULL((void*)0); |
1487 | aff->v = isl_vec_normalize(aff->v); |
1488 | if (!aff->v) |
1489 | return isl_aff_free(aff); |
1490 | aff = plug_in_integral_divs(aff); |
1491 | aff = plug_in_unit_divs(aff); |
1492 | aff = sort_divs(aff); |
1493 | aff = isl_aff_remove_unused_divs(aff); |
1494 | return aff; |
1495 | } |
1496 | |
1497 | /* Given f, return floor(f). |
1498 | * If f is an integer expression, then just return f. |
1499 | * If f is a constant, then return the constant floor(f). |
1500 | * Otherwise, if f = g/m, write g = q m + r, |
1501 | * create a new div d = [r/m] and return the expression q + d. |
1502 | * The coefficients in r are taken to lie between -m/2 and m/2. |
1503 | * |
1504 | * reduce_div_coefficients performs the same normalization. |
1505 | * |
1506 | * As a special case, floor(NaN) = NaN. |
1507 | */ |
1508 | __isl_give isl_aff *isl_aff_floor(__isl_take isl_aff *aff) |
1509 | { |
1510 | int i; |
1511 | int size; |
1512 | isl_ctx *ctx; |
1513 | isl_vec *div; |
1514 | |
1515 | if (!aff) |
1516 | return NULL((void*)0); |
1517 | |
1518 | if (isl_aff_is_nan(aff)) |
1519 | return aff; |
1520 | if (isl_int_is_one(aff->v->el[0])(isl_sioimath_cmp_si(*(aff->v->el[0]), 1) == 0)) |
1521 | return aff; |
1522 | |
1523 | aff = isl_aff_cow(aff); |
1524 | if (!aff) |
1525 | return NULL((void*)0); |
1526 | |
1527 | aff->v = isl_vec_cow(aff->v); |
1528 | if (!aff->v) |
1529 | return isl_aff_free(aff); |
1530 | |
1531 | if (isl_aff_is_cst(aff)) { |
1532 | isl_int_fdiv_q(aff->v->el[1], aff->v->el[1], aff->v->el[0])isl_sioimath_fdiv_q((aff->v->el[1]), *(aff->v->el [1]), *(aff->v->el[0])); |
1533 | isl_int_set_si(aff->v->el[0], 1)isl_sioimath_set_si((aff->v->el[0]), 1); |
1534 | return aff; |
1535 | } |
1536 | |
1537 | div = isl_vec_copy(aff->v); |
1538 | div = isl_vec_cow(div); |
1539 | if (!div) |
1540 | return isl_aff_free(aff); |
1541 | |
1542 | ctx = isl_aff_get_ctx(aff); |
1543 | isl_int_fdiv_q(aff->v->el[0], aff->v->el[0], ctx->two)isl_sioimath_fdiv_q((aff->v->el[0]), *(aff->v->el [0]), *(ctx->two)); |
1544 | for (i = 1; i < aff->v->size; ++i) { |
1545 | isl_int_fdiv_r(div->el[i], div->el[i], div->el[0])isl_sioimath_fdiv_r((div->el[i]), *(div->el[i]), *(div-> el[0])); |
1546 | isl_int_fdiv_q(aff->v->el[i], aff->v->el[i], div->el[0])isl_sioimath_fdiv_q((aff->v->el[i]), *(aff->v->el [i]), *(div->el[0])); |
1547 | if (isl_int_gt(div->el[i], aff->v->el[0])(isl_sioimath_cmp(*(div->el[i]), *(aff->v->el[0])) > 0)) { |
1548 | isl_int_sub(div->el[i], div->el[i], div->el[0])isl_sioimath_sub((div->el[i]), *(div->el[i]), *(div-> el[0])); |
1549 | isl_int_add_ui(aff->v->el[i], aff->v->el[i], 1)isl_sioimath_add_ui((aff->v->el[i]), *(aff->v->el [i]), 1); |
1550 | } |
1551 | } |
1552 | |
1553 | aff->ls = isl_local_space_add_div(aff->ls, div); |
1554 | if (!aff->ls) |
1555 | return isl_aff_free(aff); |
1556 | |
1557 | size = aff->v->size; |
1558 | aff->v = isl_vec_extend(aff->v, size + 1); |
1559 | if (!aff->v) |
1560 | return isl_aff_free(aff); |
1561 | isl_int_set_si(aff->v->el[0], 1)isl_sioimath_set_si((aff->v->el[0]), 1); |
1562 | isl_int_set_si(aff->v->el[size], 1)isl_sioimath_set_si((aff->v->el[size]), 1); |
1563 | |
1564 | aff = isl_aff_normalize(aff); |
1565 | |
1566 | return aff; |
1567 | } |
1568 | |
1569 | /* Compute |
1570 | * |
1571 | * aff mod m = aff - m * floor(aff/m) |
1572 | * |
1573 | * with m an integer value. |
1574 | */ |
1575 | __isl_give isl_aff *isl_aff_mod_val(__isl_take isl_aff *aff, |
1576 | __isl_take isl_val *m) |
1577 | { |
1578 | isl_aff *res; |
1579 | |
1580 | if (!aff || !m) |
1581 | goto error; |
1582 | |
1583 | if (!isl_val_is_int(m)) |
1584 | isl_die(isl_val_get_ctx(m), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(m), isl_error_invalid, "expecting integer modulo" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1585); goto error; } while (0) |
1585 | "expecting integer modulo", goto error)do { isl_handle_error(isl_val_get_ctx(m), isl_error_invalid, "expecting integer modulo" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1585); goto error; } while (0); |
1586 | |
1587 | res = isl_aff_copy(aff); |
1588 | aff = isl_aff_scale_down_val(aff, isl_val_copy(m)); |
1589 | aff = isl_aff_floor(aff); |
1590 | aff = isl_aff_scale_val(aff, m); |
1591 | res = isl_aff_sub(res, aff); |
1592 | |
1593 | return res; |
1594 | error: |
1595 | isl_aff_free(aff); |
1596 | isl_val_free(m); |
1597 | return NULL((void*)0); |
1598 | } |
1599 | |
1600 | /* Compute |
1601 | * |
1602 | * pwaff mod m = pwaff - m * floor(pwaff/m) |
1603 | */ |
1604 | __isl_give isl_pw_aff *isl_pw_aff_mod(__isl_take isl_pw_aff *pwaff, isl_int m) |
1605 | { |
1606 | isl_pw_aff *res; |
1607 | |
1608 | res = isl_pw_aff_copy(pwaff); |
1609 | pwaff = isl_pw_aff_scale_down(pwaff, m); |
1610 | pwaff = isl_pw_aff_floor(pwaff); |
1611 | pwaff = isl_pw_aff_scale(pwaff, m); |
1612 | res = isl_pw_aff_sub(res, pwaff); |
1613 | |
1614 | return res; |
1615 | } |
1616 | |
1617 | /* Compute |
1618 | * |
1619 | * pa mod m = pa - m * floor(pa/m) |
1620 | * |
1621 | * with m an integer value. |
1622 | */ |
1623 | __isl_give isl_pw_aff *isl_pw_aff_mod_val(__isl_take isl_pw_aff *pa, |
1624 | __isl_take isl_val *m) |
1625 | { |
1626 | if (!pa || !m) |
1627 | goto error; |
1628 | if (!isl_val_is_int(m)) |
1629 | isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid , "expecting integer modulo", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1630); goto error; } while (0) |
1630 | "expecting integer modulo", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid , "expecting integer modulo", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1630); goto error; } while (0); |
1631 | pa = isl_pw_aff_mod(pa, m->n); |
1632 | isl_val_free(m); |
1633 | return pa; |
1634 | error: |
1635 | isl_pw_aff_free(pa); |
1636 | isl_val_free(m); |
1637 | return NULL((void*)0); |
1638 | } |
1639 | |
1640 | /* Given f, return ceil(f). |
1641 | * If f is an integer expression, then just return f. |
1642 | * Otherwise, let f be the expression |
1643 | * |
1644 | * e/m |
1645 | * |
1646 | * then return |
1647 | * |
1648 | * floor((e + m - 1)/m) |
1649 | * |
1650 | * As a special case, ceil(NaN) = NaN. |
1651 | */ |
1652 | __isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff) |
1653 | { |
1654 | if (!aff) |
1655 | return NULL((void*)0); |
1656 | |
1657 | if (isl_aff_is_nan(aff)) |
1658 | return aff; |
1659 | if (isl_int_is_one(aff->v->el[0])(isl_sioimath_cmp_si(*(aff->v->el[0]), 1) == 0)) |
1660 | return aff; |
1661 | |
1662 | aff = isl_aff_cow(aff); |
1663 | if (!aff) |
1664 | return NULL((void*)0); |
1665 | aff->v = isl_vec_cow(aff->v); |
1666 | if (!aff->v) |
1667 | return isl_aff_free(aff); |
1668 | |
1669 | isl_int_add(aff->v->el[1], aff->v->el[1], aff->v->el[0])isl_sioimath_add((aff->v->el[1]), *(aff->v->el[1] ), *(aff->v->el[0])); |
1670 | isl_int_sub_ui(aff->v->el[1], aff->v->el[1], 1)isl_sioimath_sub_ui((aff->v->el[1]), *(aff->v->el [1]), 1); |
1671 | aff = isl_aff_floor(aff); |
1672 | |
1673 | return aff; |
1674 | } |
1675 | |
1676 | /* Apply the expansion computed by isl_merge_divs. |
1677 | * The expansion itself is given by "exp" while the resulting |
1678 | * list of divs is given by "div". |
1679 | */ |
1680 | __isl_give isl_aff *isl_aff_expand_divs(__isl_take isl_aff *aff, |
1681 | __isl_take isl_mat *div, int *exp) |
1682 | { |
1683 | int old_n_div; |
1684 | int new_n_div; |
1685 | int offset; |
1686 | |
1687 | aff = isl_aff_cow(aff); |
1688 | if (!aff || !div) |
1689 | goto error; |
1690 | |
1691 | old_n_div = isl_local_space_dim(aff->ls, isl_dim_div); |
1692 | new_n_div = isl_mat_rows(div); |
1693 | offset = 1 + isl_local_space_offset(aff->ls, isl_dim_div); |
1694 | |
1695 | aff->v = isl_vec_expand(aff->v, offset, old_n_div, exp, new_n_div); |
1696 | aff->ls = isl_local_space_replace_divs(aff->ls, div); |
1697 | if (!aff->v || !aff->ls) |
1698 | return isl_aff_free(aff); |
1699 | return aff; |
1700 | error: |
1701 | isl_aff_free(aff); |
1702 | isl_mat_free(div); |
1703 | return NULL((void*)0); |
1704 | } |
1705 | |
1706 | /* Add two affine expressions that live in the same local space. |
1707 | */ |
1708 | static __isl_give isl_aff *add_expanded(__isl_take isl_aff *aff1, |
1709 | __isl_take isl_aff *aff2) |
1710 | { |
1711 | isl_int gcd, f; |
1712 | |
1713 | aff1 = isl_aff_cow(aff1); |
1714 | if (!aff1 || !aff2) |
1715 | goto error; |
1716 | |
1717 | aff1->v = isl_vec_cow(aff1->v); |
1718 | if (!aff1->v) |
1719 | goto error; |
1720 | |
1721 | isl_int_init(gcd)isl_sioimath_init((gcd)); |
1722 | isl_int_init(f)isl_sioimath_init((f)); |
1723 | isl_int_gcd(gcd, aff1->v->el[0], aff2->v->el[0])isl_sioimath_gcd((gcd), *(aff1->v->el[0]), *(aff2->v ->el[0])); |
1724 | isl_int_divexact(f, aff2->v->el[0], gcd)isl_sioimath_tdiv_q((f), *(aff2->v->el[0]), *(gcd)); |
1725 | isl_seq_scale(aff1->v->el + 1, aff1->v->el + 1, f, aff1->v->size - 1); |
1726 | isl_int_divexact(f, aff1->v->el[0], gcd)isl_sioimath_tdiv_q((f), *(aff1->v->el[0]), *(gcd)); |
1727 | isl_seq_addmul(aff1->v->el + 1, f, aff2->v->el + 1, aff1->v->size - 1); |
1728 | isl_int_divexact(f, aff2->v->el[0], gcd)isl_sioimath_tdiv_q((f), *(aff2->v->el[0]), *(gcd)); |
1729 | isl_int_mul(aff1->v->el[0], aff1->v->el[0], f)isl_sioimath_mul((aff1->v->el[0]), *(aff1->v->el[ 0]), *(f)); |
1730 | isl_int_clear(f)isl_sioimath_clear((f)); |
1731 | isl_int_clear(gcd)isl_sioimath_clear((gcd)); |
1732 | |
1733 | isl_aff_free(aff2); |
1734 | return aff1; |
1735 | error: |
1736 | isl_aff_free(aff1); |
1737 | isl_aff_free(aff2); |
1738 | return NULL((void*)0); |
1739 | } |
1740 | |
1741 | /* Return the sum of "aff1" and "aff2". |
1742 | * |
1743 | * If either of the two is NaN, then the result is NaN. |
1744 | */ |
1745 | __isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1, |
1746 | __isl_take isl_aff *aff2) |
1747 | { |
1748 | isl_ctx *ctx; |
1749 | int *exp1 = NULL((void*)0); |
1750 | int *exp2 = NULL((void*)0); |
1751 | isl_mat *div; |
1752 | int n_div1, n_div2; |
1753 | |
1754 | if (!aff1 || !aff2) |
1755 | goto error; |
1756 | |
1757 | ctx = isl_aff_get_ctx(aff1); |
1758 | if (!isl_space_is_equal(aff1->ls->dim, aff2->ls->dim)) |
1759 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1760); goto error; } while (0) |
1760 | "spaces don't match", goto error)do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1760); goto error; } while (0); |
1761 | |
1762 | if (isl_aff_is_nan(aff1)) { |
1763 | isl_aff_free(aff2); |
1764 | return aff1; |
1765 | } |
1766 | if (isl_aff_is_nan(aff2)) { |
1767 | isl_aff_free(aff1); |
1768 | return aff2; |
1769 | } |
1770 | |
1771 | n_div1 = isl_aff_dim(aff1, isl_dim_div); |
1772 | n_div2 = isl_aff_dim(aff2, isl_dim_div); |
1773 | if (n_div1 == 0 && n_div2 == 0) |
1774 | return add_expanded(aff1, aff2); |
1775 | |
1776 | exp1 = isl_alloc_array(ctx, int, n_div1)((int *)isl_malloc_or_die(ctx, (n_div1)*sizeof(int))); |
1777 | exp2 = isl_alloc_array(ctx, int, n_div2)((int *)isl_malloc_or_die(ctx, (n_div2)*sizeof(int))); |
1778 | if ((n_div1 && !exp1) || (n_div2 && !exp2)) |
1779 | goto error; |
1780 | |
1781 | div = isl_merge_divs(aff1->ls->div, aff2->ls->div, exp1, exp2); |
1782 | aff1 = isl_aff_expand_divs(aff1, isl_mat_copy(div), exp1); |
1783 | aff2 = isl_aff_expand_divs(aff2, div, exp2); |
1784 | free(exp1); |
1785 | free(exp2); |
1786 | |
1787 | return add_expanded(aff1, aff2); |
1788 | error: |
1789 | free(exp1); |
1790 | free(exp2); |
1791 | isl_aff_free(aff1); |
1792 | isl_aff_free(aff2); |
1793 | return NULL((void*)0); |
1794 | } |
1795 | |
1796 | __isl_give isl_aff *isl_aff_sub(__isl_take isl_aff *aff1, |
1797 | __isl_take isl_aff *aff2) |
1798 | { |
1799 | return isl_aff_add(aff1, isl_aff_neg(aff2)); |
1800 | } |
1801 | |
1802 | /* Return the result of scaling "aff" by a factor of "f". |
1803 | * |
1804 | * As a special case, f * NaN = NaN. |
1805 | */ |
1806 | __isl_give isl_aff *isl_aff_scale(__isl_take isl_aff *aff, isl_int f) |
1807 | { |
1808 | isl_int gcd; |
1809 | |
1810 | if (!aff) |
1811 | return NULL((void*)0); |
1812 | if (isl_aff_is_nan(aff)) |
1813 | return aff; |
1814 | |
1815 | if (isl_int_is_one(f)(isl_sioimath_cmp_si(*(f), 1) == 0)) |
1816 | return aff; |
1817 | |
1818 | aff = isl_aff_cow(aff); |
1819 | if (!aff) |
1820 | return NULL((void*)0); |
1821 | aff->v = isl_vec_cow(aff->v); |
1822 | if (!aff->v) |
1823 | return isl_aff_free(aff); |
1824 | |
1825 | if (isl_int_is_pos(f)(isl_sioimath_sgn(*(f)) > 0) && isl_int_is_divisible_by(aff->v->el[0], f)isl_sioimath_is_divisible_by(*(aff->v->el[0]), *(f))) { |
1826 | isl_int_divexact(aff->v->el[0], aff->v->el[0], f)isl_sioimath_tdiv_q((aff->v->el[0]), *(aff->v->el [0]), *(f)); |
1827 | return aff; |
1828 | } |
1829 | |
1830 | isl_int_init(gcd)isl_sioimath_init((gcd)); |
1831 | isl_int_gcd(gcd, aff->v->el[0], f)isl_sioimath_gcd((gcd), *(aff->v->el[0]), *(f)); |
1832 | isl_int_divexact(aff->v->el[0], aff->v->el[0], gcd)isl_sioimath_tdiv_q((aff->v->el[0]), *(aff->v->el [0]), *(gcd)); |
1833 | isl_int_divexact(gcd, f, gcd)isl_sioimath_tdiv_q((gcd), *(f), *(gcd)); |
1834 | isl_seq_scale(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1); |
1835 | isl_int_clear(gcd)isl_sioimath_clear((gcd)); |
1836 | |
1837 | return aff; |
1838 | } |
1839 | |
1840 | /* Multiple "aff" by "v". |
1841 | */ |
1842 | __isl_give isl_aff *isl_aff_scale_val(__isl_take isl_aff *aff, |
1843 | __isl_take isl_val *v) |
1844 | { |
1845 | if (!aff || !v) |
1846 | goto error; |
1847 | |
1848 | if (isl_val_is_one(v)) { |
1849 | isl_val_free(v); |
1850 | return aff; |
1851 | } |
1852 | |
1853 | if (!isl_val_is_rat(v)) |
1854 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "expecting rational factor", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1855); goto error; } while (0) |
1855 | "expecting rational factor", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "expecting rational factor", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1855); goto error; } while (0); |
1856 | |
1857 | aff = isl_aff_scale(aff, v->n); |
1858 | aff = isl_aff_scale_down(aff, v->d); |
1859 | |
1860 | isl_val_free(v); |
1861 | return aff; |
1862 | error: |
1863 | isl_aff_free(aff); |
1864 | isl_val_free(v); |
1865 | return NULL((void*)0); |
1866 | } |
1867 | |
1868 | /* Return the result of scaling "aff" down by a factor of "f". |
1869 | * |
1870 | * As a special case, NaN/f = NaN. |
1871 | */ |
1872 | __isl_give isl_aff *isl_aff_scale_down(__isl_take isl_aff *aff, isl_int f) |
1873 | { |
1874 | isl_int gcd; |
1875 | |
1876 | if (!aff) |
1877 | return NULL((void*)0); |
1878 | if (isl_aff_is_nan(aff)) |
1879 | return aff; |
1880 | |
1881 | if (isl_int_is_one(f)(isl_sioimath_cmp_si(*(f), 1) == 0)) |
1882 | return aff; |
1883 | |
1884 | aff = isl_aff_cow(aff); |
1885 | if (!aff) |
1886 | return NULL((void*)0); |
1887 | |
1888 | if (isl_int_is_zero(f)(isl_sioimath_sgn(*(f)) == 0)) |
1889 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "cannot scale down by zero", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1890); return isl_aff_free(aff); } while (0) |
1890 | "cannot scale down by zero", return isl_aff_free(aff))do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "cannot scale down by zero", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1890); return isl_aff_free(aff); } while (0); |
1891 | |
1892 | aff->v = isl_vec_cow(aff->v); |
1893 | if (!aff->v) |
1894 | return isl_aff_free(aff); |
1895 | |
1896 | isl_int_init(gcd)isl_sioimath_init((gcd)); |
1897 | isl_seq_gcd(aff->v->el + 1, aff->v->size - 1, &gcd); |
1898 | isl_int_gcd(gcd, gcd, f)isl_sioimath_gcd((gcd), *(gcd), *(f)); |
1899 | isl_seq_scale_down(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1); |
1900 | isl_int_divexact(gcd, f, gcd)isl_sioimath_tdiv_q((gcd), *(f), *(gcd)); |
1901 | isl_int_mul(aff->v->el[0], aff->v->el[0], gcd)isl_sioimath_mul((aff->v->el[0]), *(aff->v->el[0] ), *(gcd)); |
1902 | isl_int_clear(gcd)isl_sioimath_clear((gcd)); |
1903 | |
1904 | return aff; |
1905 | } |
1906 | |
1907 | /* Divide "aff" by "v". |
1908 | */ |
1909 | __isl_give isl_aff *isl_aff_scale_down_val(__isl_take isl_aff *aff, |
1910 | __isl_take isl_val *v) |
1911 | { |
1912 | if (!aff || !v) |
1913 | goto error; |
1914 | |
1915 | if (isl_val_is_one(v)) { |
1916 | isl_val_free(v); |
1917 | return aff; |
1918 | } |
1919 | |
1920 | if (!isl_val_is_rat(v)) |
1921 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "expecting rational factor", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1922); goto error; } while (0) |
1922 | "expecting rational factor", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "expecting rational factor", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1922); goto error; } while (0); |
1923 | if (!isl_val_is_pos(v)) |
1924 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "factor needs to be positive", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1925); goto error; } while (0) |
1925 | "factor needs to be positive", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "factor needs to be positive", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1925); goto error; } while (0); |
1926 | |
1927 | aff = isl_aff_scale(aff, v->d); |
1928 | aff = isl_aff_scale_down(aff, v->n); |
1929 | |
1930 | isl_val_free(v); |
1931 | return aff; |
1932 | error: |
1933 | isl_aff_free(aff); |
1934 | isl_val_free(v); |
1935 | return NULL((void*)0); |
1936 | } |
1937 | |
1938 | __isl_give isl_aff *isl_aff_scale_down_ui(__isl_take isl_aff *aff, unsigned f) |
1939 | { |
1940 | isl_int v; |
1941 | |
1942 | if (f == 1) |
1943 | return aff; |
1944 | |
1945 | isl_int_init(v)isl_sioimath_init((v)); |
1946 | isl_int_set_ui(v, f)isl_sioimath_set_ui((v), f); |
1947 | aff = isl_aff_scale_down(aff, v); |
1948 | isl_int_clear(v)isl_sioimath_clear((v)); |
1949 | |
1950 | return aff; |
1951 | } |
1952 | |
1953 | __isl_give isl_aff *isl_aff_set_dim_name(__isl_take isl_aff *aff, |
1954 | enum isl_dim_type type, unsigned pos, const char *s) |
1955 | { |
1956 | aff = isl_aff_cow(aff); |
1957 | if (!aff) |
1958 | return NULL((void*)0); |
1959 | if (type == isl_dim_out) |
1960 | isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot set name of output/set dimension" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1962); return isl_aff_free(aff); } while (0) |
1961 | "cannot set name of output/set dimension",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot set name of output/set dimension" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1962); return isl_aff_free(aff); } while (0) |
1962 | return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot set name of output/set dimension" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1962); return isl_aff_free(aff); } while (0); |
1963 | if (type == isl_dim_in) |
1964 | type = isl_dim_set; |
1965 | aff->ls = isl_local_space_set_dim_name(aff->ls, type, pos, s); |
1966 | if (!aff->ls) |
1967 | return isl_aff_free(aff); |
1968 | |
1969 | return aff; |
1970 | } |
1971 | |
1972 | __isl_give isl_aff *isl_aff_set_dim_id(__isl_take isl_aff *aff, |
1973 | enum isl_dim_type type, unsigned pos, __isl_take isl_id *id) |
1974 | { |
1975 | aff = isl_aff_cow(aff); |
1976 | if (!aff) |
1977 | goto error; |
1978 | if (type == isl_dim_out) |
1979 | isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot set name of output/set dimension" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1981); goto error; } while (0) |
1980 | "cannot set name of output/set dimension",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot set name of output/set dimension" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1981); goto error; } while (0) |
1981 | goto error)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot set name of output/set dimension" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 1981); goto error; } while (0); |
1982 | if (type == isl_dim_in) |
1983 | type = isl_dim_set; |
1984 | aff->ls = isl_local_space_set_dim_id(aff->ls, type, pos, id); |
1985 | if (!aff->ls) |
1986 | return isl_aff_free(aff); |
1987 | |
1988 | return aff; |
1989 | error: |
1990 | isl_id_free(id); |
1991 | isl_aff_free(aff); |
1992 | return NULL((void*)0); |
1993 | } |
1994 | |
1995 | /* Replace the identifier of the input tuple of "aff" by "id". |
1996 | * type is currently required to be equal to isl_dim_in |
1997 | */ |
1998 | __isl_give isl_aff *isl_aff_set_tuple_id(__isl_take isl_aff *aff, |
1999 | enum isl_dim_type type, __isl_take isl_id *id) |
2000 | { |
2001 | aff = isl_aff_cow(aff); |
2002 | if (!aff) |
2003 | goto error; |
2004 | if (type != isl_dim_in) |
2005 | isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot only set id of input tuple" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2006); goto error; } while (0) |
2006 | "cannot only set id of input tuple", goto error)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot only set id of input tuple" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2006); goto error; } while (0); |
2007 | aff->ls = isl_local_space_set_tuple_id(aff->ls, isl_dim_set, id); |
2008 | if (!aff->ls) |
2009 | return isl_aff_free(aff); |
2010 | |
2011 | return aff; |
2012 | error: |
2013 | isl_id_free(id); |
2014 | isl_aff_free(aff); |
2015 | return NULL((void*)0); |
2016 | } |
2017 | |
2018 | /* Exploit the equalities in "eq" to simplify the affine expression |
2019 | * and the expressions of the integer divisions in the local space. |
2020 | * The integer divisions in this local space are assumed to appear |
2021 | * as regular dimensions in "eq". |
2022 | */ |
2023 | static __isl_give isl_aff *isl_aff_substitute_equalities_lifted( |
2024 | __isl_take isl_aff *aff, __isl_take isl_basic_setisl_basic_map *eq) |
2025 | { |
2026 | int i, j; |
2027 | unsigned total; |
2028 | unsigned n_div; |
2029 | |
2030 | if (!eq) |
2031 | goto error; |
2032 | if (eq->n_eq == 0) { |
2033 | isl_basic_set_free(eq); |
2034 | return aff; |
2035 | } |
2036 | |
2037 | aff = isl_aff_cow(aff); |
2038 | if (!aff) |
2039 | goto error; |
2040 | |
2041 | aff->ls = isl_local_space_substitute_equalities(aff->ls, |
2042 | isl_basic_set_copy(eq)); |
2043 | aff->v = isl_vec_cow(aff->v); |
2044 | if (!aff->ls || !aff->v) |
2045 | goto error; |
2046 | |
2047 | total = 1 + isl_space_dim(eq->dim, isl_dim_all); |
2048 | n_div = eq->n_div; |
2049 | for (i = 0; i < eq->n_eq; ++i) { |
2050 | j = isl_seq_last_non_zero(eq->eq[i], total + n_div); |
2051 | if (j < 0 || j == 0 || j >= total) |
2052 | continue; |
2053 | |
2054 | isl_seq_elim(aff->v->el + 1, eq->eq[i], j, total, |
2055 | &aff->v->el[0]); |
2056 | } |
2057 | |
2058 | isl_basic_set_free(eq); |
2059 | aff = isl_aff_normalize(aff); |
2060 | return aff; |
2061 | error: |
2062 | isl_basic_set_free(eq); |
2063 | isl_aff_free(aff); |
2064 | return NULL((void*)0); |
2065 | } |
2066 | |
2067 | /* Exploit the equalities in "eq" to simplify the affine expression |
2068 | * and the expressions of the integer divisions in the local space. |
2069 | */ |
2070 | __isl_give isl_aff *isl_aff_substitute_equalities(__isl_take isl_aff *aff, |
2071 | __isl_take isl_basic_setisl_basic_map *eq) |
2072 | { |
2073 | int n_div; |
2074 | |
2075 | if (!aff || !eq) |
2076 | goto error; |
2077 | n_div = isl_local_space_dim(aff->ls, isl_dim_div); |
2078 | if (n_div > 0) |
2079 | eq = isl_basic_set_add_dims(eq, isl_dim_set, n_div); |
2080 | return isl_aff_substitute_equalities_lifted(aff, eq); |
2081 | error: |
2082 | isl_basic_set_free(eq); |
2083 | isl_aff_free(aff); |
2084 | return NULL((void*)0); |
2085 | } |
2086 | |
2087 | /* Look for equalities among the variables shared by context and aff |
2088 | * and the integer divisions of aff, if any. |
2089 | * The equalities are then used to eliminate coefficients and/or integer |
2090 | * divisions from aff. |
2091 | */ |
2092 | __isl_give isl_aff *isl_aff_gist(__isl_take isl_aff *aff, |
2093 | __isl_take isl_setisl_map *context) |
2094 | { |
2095 | isl_basic_setisl_basic_map *hull; |
2096 | int n_div; |
2097 | |
2098 | if (!aff) |
2099 | goto error; |
2100 | n_div = isl_local_space_dim(aff->ls, isl_dim_div); |
2101 | if (n_div > 0) { |
2102 | isl_basic_setisl_basic_map *bset; |
2103 | isl_local_space *ls; |
2104 | context = isl_set_add_dims(context, isl_dim_set, n_div); |
2105 | ls = isl_aff_get_domain_local_space(aff); |
2106 | bset = isl_basic_set_from_local_space(ls); |
2107 | bset = isl_basic_set_lift(bset); |
2108 | bset = isl_basic_set_flatten(bset); |
2109 | context = isl_set_intersect(context, |
2110 | isl_set_from_basic_set(bset)); |
2111 | } |
2112 | |
2113 | hull = isl_set_affine_hull(context); |
2114 | return isl_aff_substitute_equalities_lifted(aff, hull); |
2115 | error: |
2116 | isl_aff_free(aff); |
2117 | isl_set_free(context); |
2118 | return NULL((void*)0); |
2119 | } |
2120 | |
2121 | __isl_give isl_aff *isl_aff_gist_params(__isl_take isl_aff *aff, |
2122 | __isl_take isl_setisl_map *context) |
2123 | { |
2124 | isl_setisl_map *dom_context = isl_set_universe(isl_aff_get_domain_space(aff)); |
2125 | dom_context = isl_set_intersect_params(dom_context, context); |
2126 | return isl_aff_gist(aff, dom_context); |
2127 | } |
2128 | |
2129 | /* Return a basic set containing those elements in the space |
2130 | * of aff where it is positive. "rational" should not be set. |
2131 | * |
2132 | * If "aff" is NaN, then it is not positive. |
2133 | */ |
2134 | static __isl_give isl_basic_setisl_basic_map *aff_pos_basic_set(__isl_take isl_aff *aff, |
2135 | int rational) |
2136 | { |
2137 | isl_constraint *ineq; |
2138 | isl_basic_setisl_basic_map *bset; |
2139 | isl_val *c; |
2140 | |
2141 | if (!aff) |
2142 | return NULL((void*)0); |
2143 | if (isl_aff_is_nan(aff)) { |
2144 | isl_space *space = isl_aff_get_domain_space(aff); |
2145 | isl_aff_free(aff); |
2146 | return isl_basic_set_empty(space); |
2147 | } |
2148 | if (rational) |
2149 | isl_die(isl_aff_get_ctx(aff), isl_error_unsupported,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_unsupported , "rational sets not supported", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2150); goto error; } while (0) |
2150 | "rational sets not supported", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_unsupported , "rational sets not supported", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2150); goto error; } while (0); |
2151 | |
2152 | ineq = isl_inequality_from_aff(aff); |
2153 | c = isl_constraint_get_constant_val(ineq); |
2154 | c = isl_val_sub_ui(c, 1); |
2155 | ineq = isl_constraint_set_constant_val(ineq, c); |
2156 | |
2157 | bset = isl_basic_set_from_constraint(ineq); |
2158 | bset = isl_basic_set_simplify(bset); |
2159 | return bset; |
2160 | error: |
2161 | isl_aff_free(aff); |
2162 | return NULL((void*)0); |
2163 | } |
2164 | |
2165 | /* Return a basic set containing those elements in the space |
2166 | * of aff where it is non-negative. |
2167 | * If "rational" is set, then return a rational basic set. |
2168 | * |
2169 | * If "aff" is NaN, then it is not non-negative (it's not negative either). |
2170 | */ |
2171 | static __isl_give isl_basic_setisl_basic_map *aff_nonneg_basic_set( |
2172 | __isl_take isl_aff *aff, int rational) |
2173 | { |
2174 | isl_constraint *ineq; |
2175 | isl_basic_setisl_basic_map *bset; |
2176 | |
2177 | if (!aff) |
2178 | return NULL((void*)0); |
2179 | if (isl_aff_is_nan(aff)) { |
2180 | isl_space *space = isl_aff_get_domain_space(aff); |
2181 | isl_aff_free(aff); |
2182 | return isl_basic_set_empty(space); |
2183 | } |
2184 | |
2185 | ineq = isl_inequality_from_aff(aff); |
2186 | |
2187 | bset = isl_basic_set_from_constraint(ineq); |
2188 | if (rational) |
2189 | bset = isl_basic_set_set_rational(bset); |
2190 | bset = isl_basic_set_simplify(bset); |
2191 | return bset; |
2192 | } |
2193 | |
2194 | /* Return a basic set containing those elements in the space |
2195 | * of aff where it is non-negative. |
2196 | */ |
2197 | __isl_give isl_basic_setisl_basic_map *isl_aff_nonneg_basic_set(__isl_take isl_aff *aff) |
2198 | { |
2199 | return aff_nonneg_basic_set(aff, 0); |
2200 | } |
2201 | |
2202 | /* Return a basic set containing those elements in the domain space |
2203 | * of "aff" where it is positive. |
2204 | */ |
2205 | __isl_give isl_basic_setisl_basic_map *isl_aff_pos_basic_set(__isl_take isl_aff *aff) |
2206 | { |
2207 | aff = isl_aff_add_constant_num_si(aff, -1); |
2208 | return isl_aff_nonneg_basic_set(aff); |
2209 | } |
2210 | |
2211 | /* Return a basic set containing those elements in the domain space |
2212 | * of aff where it is negative. |
2213 | */ |
2214 | __isl_give isl_basic_setisl_basic_map *isl_aff_neg_basic_set(__isl_take isl_aff *aff) |
2215 | { |
2216 | aff = isl_aff_neg(aff); |
2217 | return isl_aff_pos_basic_set(aff); |
2218 | } |
2219 | |
2220 | /* Return a basic set containing those elements in the space |
2221 | * of aff where it is zero. |
2222 | * If "rational" is set, then return a rational basic set. |
2223 | * |
2224 | * If "aff" is NaN, then it is not zero. |
2225 | */ |
2226 | static __isl_give isl_basic_setisl_basic_map *aff_zero_basic_set(__isl_take isl_aff *aff, |
2227 | int rational) |
2228 | { |
2229 | isl_constraint *ineq; |
2230 | isl_basic_setisl_basic_map *bset; |
2231 | |
2232 | if (!aff) |
2233 | return NULL((void*)0); |
2234 | if (isl_aff_is_nan(aff)) { |
2235 | isl_space *space = isl_aff_get_domain_space(aff); |
2236 | isl_aff_free(aff); |
2237 | return isl_basic_set_empty(space); |
2238 | } |
2239 | |
2240 | ineq = isl_equality_from_aff(aff); |
2241 | |
2242 | bset = isl_basic_set_from_constraint(ineq); |
2243 | if (rational) |
2244 | bset = isl_basic_set_set_rational(bset); |
2245 | bset = isl_basic_set_simplify(bset); |
2246 | return bset; |
2247 | } |
2248 | |
2249 | /* Return a basic set containing those elements in the space |
2250 | * of aff where it is zero. |
2251 | */ |
2252 | __isl_give isl_basic_setisl_basic_map *isl_aff_zero_basic_set(__isl_take isl_aff *aff) |
2253 | { |
2254 | return aff_zero_basic_set(aff, 0); |
2255 | } |
2256 | |
2257 | /* Return a basic set containing those elements in the shared space |
2258 | * of aff1 and aff2 where aff1 is greater than or equal to aff2. |
2259 | */ |
2260 | __isl_give isl_basic_setisl_basic_map *isl_aff_ge_basic_set(__isl_take isl_aff *aff1, |
2261 | __isl_take isl_aff *aff2) |
2262 | { |
2263 | aff1 = isl_aff_sub(aff1, aff2); |
2264 | |
2265 | return isl_aff_nonneg_basic_set(aff1); |
2266 | } |
2267 | |
2268 | /* Return a basic set containing those elements in the shared domain space |
2269 | * of "aff1" and "aff2" where "aff1" is greater than "aff2". |
2270 | */ |
2271 | __isl_give isl_basic_setisl_basic_map *isl_aff_gt_basic_set(__isl_take isl_aff *aff1, |
2272 | __isl_take isl_aff *aff2) |
2273 | { |
2274 | aff1 = isl_aff_sub(aff1, aff2); |
2275 | |
2276 | return isl_aff_pos_basic_set(aff1); |
2277 | } |
2278 | |
2279 | /* Return a set containing those elements in the shared space |
2280 | * of aff1 and aff2 where aff1 is greater than or equal to aff2. |
2281 | */ |
2282 | __isl_give isl_setisl_map *isl_aff_ge_set(__isl_take isl_aff *aff1, |
2283 | __isl_take isl_aff *aff2) |
2284 | { |
2285 | return isl_set_from_basic_set(isl_aff_ge_basic_set(aff1, aff2)); |
2286 | } |
2287 | |
2288 | /* Return a set containing those elements in the shared domain space |
2289 | * of aff1 and aff2 where aff1 is greater than aff2. |
2290 | * |
2291 | * If either of the two inputs is NaN, then the result is empty, |
2292 | * as comparisons with NaN always return false. |
2293 | */ |
2294 | __isl_give isl_setisl_map *isl_aff_gt_set(__isl_take isl_aff *aff1, |
2295 | __isl_take isl_aff *aff2) |
2296 | { |
2297 | return isl_set_from_basic_set(isl_aff_gt_basic_set(aff1, aff2)); |
2298 | } |
2299 | |
2300 | /* Return a basic set containing those elements in the shared space |
2301 | * of aff1 and aff2 where aff1 is smaller than or equal to aff2. |
2302 | */ |
2303 | __isl_give isl_basic_setisl_basic_map *isl_aff_le_basic_set(__isl_take isl_aff *aff1, |
2304 | __isl_take isl_aff *aff2) |
2305 | { |
2306 | return isl_aff_ge_basic_set(aff2, aff1); |
2307 | } |
2308 | |
2309 | /* Return a basic set containing those elements in the shared domain space |
2310 | * of "aff1" and "aff2" where "aff1" is smaller than "aff2". |
2311 | */ |
2312 | __isl_give isl_basic_setisl_basic_map *isl_aff_lt_basic_set(__isl_take isl_aff *aff1, |
2313 | __isl_take isl_aff *aff2) |
2314 | { |
2315 | return isl_aff_gt_basic_set(aff2, aff1); |
2316 | } |
2317 | |
2318 | /* Return a set containing those elements in the shared space |
2319 | * of aff1 and aff2 where aff1 is smaller than or equal to aff2. |
2320 | */ |
2321 | __isl_give isl_setisl_map *isl_aff_le_set(__isl_take isl_aff *aff1, |
2322 | __isl_take isl_aff *aff2) |
2323 | { |
2324 | return isl_aff_ge_set(aff2, aff1); |
2325 | } |
2326 | |
2327 | /* Return a set containing those elements in the shared domain space |
2328 | * of "aff1" and "aff2" where "aff1" is smaller than "aff2". |
2329 | */ |
2330 | __isl_give isl_setisl_map *isl_aff_lt_set(__isl_take isl_aff *aff1, |
2331 | __isl_take isl_aff *aff2) |
2332 | { |
2333 | return isl_set_from_basic_set(isl_aff_lt_basic_set(aff1, aff2)); |
2334 | } |
2335 | |
2336 | /* Return a basic set containing those elements in the shared space |
2337 | * of aff1 and aff2 where aff1 and aff2 are equal. |
2338 | */ |
2339 | __isl_give isl_basic_setisl_basic_map *isl_aff_eq_basic_set(__isl_take isl_aff *aff1, |
2340 | __isl_take isl_aff *aff2) |
2341 | { |
2342 | aff1 = isl_aff_sub(aff1, aff2); |
2343 | |
2344 | return isl_aff_zero_basic_set(aff1); |
2345 | } |
2346 | |
2347 | /* Return a set containing those elements in the shared space |
2348 | * of aff1 and aff2 where aff1 and aff2 are equal. |
2349 | */ |
2350 | __isl_give isl_setisl_map *isl_aff_eq_set(__isl_take isl_aff *aff1, |
2351 | __isl_take isl_aff *aff2) |
2352 | { |
2353 | return isl_set_from_basic_set(isl_aff_eq_basic_set(aff1, aff2)); |
2354 | } |
2355 | |
2356 | /* Return a set containing those elements in the shared domain space |
2357 | * of aff1 and aff2 where aff1 and aff2 are not equal. |
2358 | * |
2359 | * If either of the two inputs is NaN, then the result is empty, |
2360 | * as comparisons with NaN always return false. |
2361 | */ |
2362 | __isl_give isl_setisl_map *isl_aff_ne_set(__isl_take isl_aff *aff1, |
2363 | __isl_take isl_aff *aff2) |
2364 | { |
2365 | isl_setisl_map *set_lt, *set_gt; |
2366 | |
2367 | set_lt = isl_aff_lt_set(isl_aff_copy(aff1), |
2368 | isl_aff_copy(aff2)); |
2369 | set_gt = isl_aff_gt_set(aff1, aff2); |
2370 | return isl_set_union_disjoint(set_lt, set_gt); |
2371 | } |
2372 | |
2373 | __isl_give isl_aff *isl_aff_add_on_domain(__isl_keep isl_setisl_map *dom, |
2374 | __isl_take isl_aff *aff1, __isl_take isl_aff *aff2) |
2375 | { |
2376 | aff1 = isl_aff_add(aff1, aff2); |
2377 | aff1 = isl_aff_gist(aff1, isl_set_copy(dom)); |
2378 | return aff1; |
2379 | } |
2380 | |
2381 | int isl_aff_is_empty(__isl_keep isl_aff *aff) |
2382 | { |
2383 | if (!aff) |
2384 | return -1; |
2385 | |
2386 | return 0; |
2387 | } |
2388 | |
2389 | /* Check whether the given affine expression has non-zero coefficient |
2390 | * for any dimension in the given range or if any of these dimensions |
2391 | * appear with non-zero coefficients in any of the integer divisions |
2392 | * involved in the affine expression. |
2393 | */ |
2394 | isl_bool isl_aff_involves_dims(__isl_keep isl_aff *aff, |
2395 | enum isl_dim_type type, unsigned first, unsigned n) |
2396 | { |
2397 | int i; |
2398 | isl_ctx *ctx; |
2399 | int *active = NULL((void*)0); |
2400 | isl_bool involves = isl_bool_false; |
2401 | |
2402 | if (!aff) |
2403 | return isl_bool_error; |
2404 | if (n == 0) |
2405 | return isl_bool_false; |
2406 | |
2407 | ctx = isl_aff_get_ctx(aff); |
2408 | if (first + n > isl_aff_dim(aff, type)) |
2409 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "range out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2410); return isl_bool_error; } while (0) |
2410 | "range out of bounds", return isl_bool_error)do { isl_handle_error(ctx, isl_error_invalid, "range out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2410); return isl_bool_error; } while (0); |
2411 | |
2412 | active = isl_local_space_get_active(aff->ls, aff->v->el + 2); |
2413 | if (!active) |
2414 | goto error; |
2415 | |
2416 | first += isl_local_space_offset(aff->ls, type) - 1; |
2417 | for (i = 0; i < n; ++i) |
2418 | if (active[first + i]) { |
2419 | involves = isl_bool_true; |
2420 | break; |
2421 | } |
2422 | |
2423 | free(active); |
2424 | |
2425 | return involves; |
2426 | error: |
2427 | free(active); |
2428 | return isl_bool_error; |
2429 | } |
2430 | |
2431 | __isl_give isl_aff *isl_aff_drop_dims(__isl_take isl_aff *aff, |
2432 | enum isl_dim_type type, unsigned first, unsigned n) |
2433 | { |
2434 | isl_ctx *ctx; |
2435 | |
2436 | if (!aff) |
2437 | return NULL((void*)0); |
2438 | if (type == isl_dim_out) |
2439 | isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot drop output/set dimension" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2441); return isl_aff_free(aff); } while (0) |
2440 | "cannot drop output/set dimension",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot drop output/set dimension" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2441); return isl_aff_free(aff); } while (0) |
2441 | return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot drop output/set dimension" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2441); return isl_aff_free(aff); } while (0); |
2442 | if (type == isl_dim_in) |
2443 | type = isl_dim_set; |
2444 | if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type)) |
2445 | return aff; |
2446 | |
2447 | ctx = isl_aff_get_ctx(aff); |
2448 | if (first + n > isl_local_space_dim(aff->ls, type)) |
2449 | isl_die(ctx, isl_error_invalid, "range out of bounds",do { isl_handle_error(ctx, isl_error_invalid, "range out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2450); return isl_aff_free(aff); } while (0) |
2450 | return isl_aff_free(aff))do { isl_handle_error(ctx, isl_error_invalid, "range out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2450); return isl_aff_free(aff); } while (0); |
2451 | |
2452 | aff = isl_aff_cow(aff); |
2453 | if (!aff) |
2454 | return NULL((void*)0); |
2455 | |
2456 | aff->ls = isl_local_space_drop_dims(aff->ls, type, first, n); |
2457 | if (!aff->ls) |
2458 | return isl_aff_free(aff); |
2459 | |
2460 | first += 1 + isl_local_space_offset(aff->ls, type); |
2461 | aff->v = isl_vec_drop_els(aff->v, first, n); |
2462 | if (!aff->v) |
2463 | return isl_aff_free(aff); |
2464 | |
2465 | return aff; |
2466 | } |
2467 | |
2468 | /* Drop the "n" domain dimensions starting at "first" from "aff", |
2469 | * after checking that they do not appear in the affine expression. |
2470 | */ |
2471 | static __isl_give isl_aff *drop_domain(__isl_take isl_aff *aff, unsigned first, |
2472 | unsigned n) |
2473 | { |
2474 | isl_bool involves; |
2475 | |
2476 | involves = isl_aff_involves_dims(aff, isl_dim_in, first, n); |
2477 | if (involves < 0) |
2478 | return isl_aff_free(aff); |
2479 | if (involves) |
2480 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "affine expression involves some of the domain dimensions", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2482); return isl_aff_free(aff); } while (0) |
2481 | "affine expression involves some of the domain dimensions",do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "affine expression involves some of the domain dimensions", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2482); return isl_aff_free(aff); } while (0) |
2482 | return isl_aff_free(aff))do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "affine expression involves some of the domain dimensions", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2482); return isl_aff_free(aff); } while (0); |
2483 | return isl_aff_drop_dims(aff, isl_dim_in, first, n); |
2484 | } |
2485 | |
2486 | /* Project the domain of the affine expression onto its parameter space. |
2487 | * The affine expression may not involve any of the domain dimensions. |
2488 | */ |
2489 | __isl_give isl_aff *isl_aff_project_domain_on_params(__isl_take isl_aff *aff) |
2490 | { |
2491 | isl_space *space; |
2492 | unsigned n; |
2493 | |
2494 | n = isl_aff_dim(aff, isl_dim_in); |
2495 | aff = drop_domain(aff, 0, n); |
2496 | space = isl_aff_get_domain_space(aff); |
2497 | space = isl_space_params(space); |
2498 | aff = isl_aff_reset_domain_space(aff, space); |
2499 | return aff; |
2500 | } |
2501 | |
2502 | /* Check that the domain of "aff" is a product. |
2503 | */ |
2504 | static isl_stat check_domain_product(__isl_keep isl_aff *aff) |
2505 | { |
2506 | isl_bool is_product; |
2507 | |
2508 | is_product = isl_space_is_product(isl_aff_peek_domain_space(aff)); |
2509 | if (is_product < 0) |
2510 | return isl_stat_error; |
2511 | if (!is_product) |
2512 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "domain is not a product", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2513); return isl_stat_error; } while (0) |
2513 | "domain is not a product", return isl_stat_error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "domain is not a product", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2513); return isl_stat_error; } while (0); |
2514 | return isl_stat_ok; |
2515 | } |
2516 | |
2517 | /* Given an affine function with a domain of the form [A -> B] that |
2518 | * does not depend on B, return the same function on domain A. |
2519 | */ |
2520 | __isl_give isl_aff *isl_aff_domain_factor_domain(__isl_take isl_aff *aff) |
2521 | { |
2522 | isl_space *space; |
2523 | int n, n_in; |
2524 | |
2525 | if (check_domain_product(aff) < 0) |
2526 | return isl_aff_free(aff); |
2527 | space = isl_aff_get_domain_space(aff); |
2528 | n = isl_space_dim(space, isl_dim_set); |
2529 | space = isl_space_factor_domain(space); |
2530 | n_in = isl_space_dim(space, isl_dim_set); |
2531 | aff = drop_domain(aff, n_in, n - n_in); |
2532 | aff = isl_aff_reset_domain_space(aff, space); |
2533 | return aff; |
2534 | } |
2535 | |
2536 | /* Convert an affine expression defined over a parameter domain |
2537 | * into one that is defined over a zero-dimensional set. |
2538 | */ |
2539 | __isl_give isl_aff *isl_aff_from_range(__isl_take isl_aff *aff) |
2540 | { |
2541 | isl_local_space *ls; |
2542 | |
2543 | ls = isl_aff_take_domain_local_space(aff); |
2544 | ls = isl_local_space_set_from_params(ls); |
2545 | aff = isl_aff_restore_domain_local_space(aff, ls); |
2546 | |
2547 | return aff; |
2548 | } |
2549 | |
2550 | __isl_give isl_aff *isl_aff_insert_dims(__isl_take isl_aff *aff, |
2551 | enum isl_dim_type type, unsigned first, unsigned n) |
2552 | { |
2553 | isl_ctx *ctx; |
2554 | |
2555 | if (!aff) |
2556 | return NULL((void*)0); |
2557 | if (type == isl_dim_out) |
2558 | isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot insert output/set dimensions" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2560); return isl_aff_free(aff); } while (0) |
2559 | "cannot insert output/set dimensions",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot insert output/set dimensions" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2560); return isl_aff_free(aff); } while (0) |
2560 | return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot insert output/set dimensions" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2560); return isl_aff_free(aff); } while (0); |
2561 | if (type == isl_dim_in) |
2562 | type = isl_dim_set; |
2563 | if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type)) |
2564 | return aff; |
2565 | |
2566 | ctx = isl_aff_get_ctx(aff); |
2567 | if (first > isl_local_space_dim(aff->ls, type)) |
2568 | isl_die(ctx, isl_error_invalid, "position out of bounds",do { isl_handle_error(ctx, isl_error_invalid, "position out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2569); return isl_aff_free(aff); } while (0) |
2569 | return isl_aff_free(aff))do { isl_handle_error(ctx, isl_error_invalid, "position out of bounds" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2569); return isl_aff_free(aff); } while (0); |
2570 | |
2571 | aff = isl_aff_cow(aff); |
2572 | if (!aff) |
2573 | return NULL((void*)0); |
2574 | |
2575 | aff->ls = isl_local_space_insert_dims(aff->ls, type, first, n); |
2576 | if (!aff->ls) |
2577 | return isl_aff_free(aff); |
2578 | |
2579 | first += 1 + isl_local_space_offset(aff->ls, type); |
2580 | aff->v = isl_vec_insert_zero_els(aff->v, first, n); |
2581 | if (!aff->v) |
2582 | return isl_aff_free(aff); |
2583 | |
2584 | return aff; |
2585 | } |
2586 | |
2587 | __isl_give isl_aff *isl_aff_add_dims(__isl_take isl_aff *aff, |
2588 | enum isl_dim_type type, unsigned n) |
2589 | { |
2590 | unsigned pos; |
2591 | |
2592 | pos = isl_aff_dim(aff, type); |
2593 | |
2594 | return isl_aff_insert_dims(aff, type, pos, n); |
2595 | } |
2596 | |
2597 | __isl_give isl_pw_aff *isl_pw_aff_add_dims(__isl_take isl_pw_aff *pwaff, |
2598 | enum isl_dim_type type, unsigned n) |
2599 | { |
2600 | unsigned pos; |
2601 | |
2602 | pos = isl_pw_aff_dim(pwaff, type); |
2603 | |
2604 | return isl_pw_aff_insert_dims(pwaff, type, pos, n); |
2605 | } |
2606 | |
2607 | /* Move the "n" dimensions of "src_type" starting at "src_pos" of "aff" |
2608 | * to dimensions of "dst_type" at "dst_pos". |
2609 | * |
2610 | * We only support moving input dimensions to parameters and vice versa. |
2611 | */ |
2612 | __isl_give isl_aff *isl_aff_move_dims(__isl_take isl_aff *aff, |
2613 | enum isl_dim_type dst_type, unsigned dst_pos, |
2614 | enum isl_dim_type src_type, unsigned src_pos, unsigned n) |
2615 | { |
2616 | unsigned g_dst_pos; |
2617 | unsigned g_src_pos; |
2618 | |
2619 | if (!aff) |
2620 | return NULL((void*)0); |
2621 | if (n == 0 && |
2622 | !isl_local_space_is_named_or_nested(aff->ls, src_type) && |
2623 | !isl_local_space_is_named_or_nested(aff->ls, dst_type)) |
2624 | return aff; |
2625 | |
2626 | if (dst_type == isl_dim_out || src_type == isl_dim_out) |
2627 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "cannot move output/set dimension", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2629); return isl_aff_free(aff); } while (0) |
2628 | "cannot move output/set dimension",do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "cannot move output/set dimension", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2629); return isl_aff_free(aff); } while (0) |
2629 | return isl_aff_free(aff))do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "cannot move output/set dimension", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2629); return isl_aff_free(aff); } while (0); |
2630 | if (dst_type == isl_dim_div || src_type == isl_dim_div) |
2631 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "cannot move divs", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2632); return isl_aff_free(aff); } while (0) |
2632 | "cannot move divs", return isl_aff_free(aff))do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "cannot move divs", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2632); return isl_aff_free(aff); } while (0); |
2633 | if (dst_type == isl_dim_in) |
2634 | dst_type = isl_dim_set; |
2635 | if (src_type == isl_dim_in) |
2636 | src_type = isl_dim_set; |
2637 | |
2638 | if (src_pos + n > isl_local_space_dim(aff->ls, src_type)) |
2639 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "range out of bounds", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2640); return isl_aff_free(aff); } while (0) |
2640 | "range out of bounds", return isl_aff_free(aff))do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "range out of bounds", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2640); return isl_aff_free(aff); } while (0); |
2641 | if (dst_type == src_type) |
2642 | isl_die(isl_aff_get_ctx(aff), isl_error_unsupported,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_unsupported , "moving dims within the same type not supported", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2644); return isl_aff_free(aff); } while (0) |
2643 | "moving dims within the same type not supported",do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_unsupported , "moving dims within the same type not supported", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2644); return isl_aff_free(aff); } while (0) |
2644 | return isl_aff_free(aff))do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_unsupported , "moving dims within the same type not supported", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 2644); return isl_aff_free(aff); } while (0); |
2645 | |
2646 | aff = isl_aff_cow(aff); |
2647 | if (!aff) |
2648 | return NULL((void*)0); |
2649 | |
2650 | g_src_pos = 1 + isl_local_space_offset(aff->ls, src_type) + src_pos; |
2651 | g_dst_pos = 1 + isl_local_space_offset(aff->ls, dst_type) + dst_pos; |
2652 | if (dst_type > src_type) |
2653 | g_dst_pos -= n; |
2654 | |
2655 | aff->v = isl_vec_move_els(aff->v, g_dst_pos, g_src_pos, n); |
2656 | aff->ls = isl_local_space_move_dims(aff->ls, dst_type, dst_pos, |
2657 | src_type, src_pos, n); |
2658 | if (!aff->v || !aff->ls) |
2659 | return isl_aff_free(aff); |
2660 | |
2661 | aff = sort_divs(aff); |
2662 | |
2663 | return aff; |
2664 | } |
2665 | |
2666 | __isl_give isl_pw_aff *isl_pw_aff_from_aff(__isl_take isl_aff *aff) |
2667 | { |
2668 | isl_setisl_map *dom = isl_set_universe(isl_aff_get_domain_space(aff)); |
2669 | return isl_pw_aff_alloc(dom, aff); |
2670 | } |
2671 | |
2672 | #define isl_aff_involves_nanisl_aff_is_nan isl_aff_is_nan |
2673 | |
2674 | #undef PWisl_pw_multi_aff |
2675 | #define PWisl_pw_multi_aff isl_pw_aff |
2676 | #undef ELisl_union_pw_aff |
2677 | #define ELisl_union_pw_aff isl_aff |
2678 | #undef EL_IS_ZEROis_empty |
2679 | #define EL_IS_ZEROis_empty is_empty |
2680 | #undef ZEROempty |
2681 | #define ZEROempty empty |
2682 | #undef IS_ZEROis_empty |
2683 | #define IS_ZEROis_empty is_empty |
2684 | #undef FIELDmaff |
2685 | #define FIELDmaff aff |
2686 | #undef DEFAULT_IS_ZERO0 |
2687 | #define DEFAULT_IS_ZERO0 0 |
2688 | |
2689 | #define NO_OPT |
2690 | #define NO_LIFT |
2691 | #define NO_MORPH |
2692 | |
2693 | #include <isl_pw_templ.c> |
2694 | #include <isl_pw_eval.c> |
2695 | #include <isl_pw_hash.c> |
2696 | #include <isl_pw_union_opt.c> |
2697 | |
2698 | #undef BASEunion_pw_aff |
2699 | #define BASEunion_pw_aff pw_aff |
2700 | |
2701 | #include <isl_union_single.c> |
2702 | #include <isl_union_neg.c> |
2703 | |
2704 | static __isl_give isl_setisl_map *align_params_pw_pw_set_and( |
2705 | __isl_take isl_pw_aff *pwaff1, __isl_take isl_pw_aff *pwaff2, |
2706 | __isl_give isl_setisl_map *(*fn)(__isl_take isl_pw_aff *pwaff1, |
2707 | __isl_take isl_pw_aff *pwaff2)) |
2708 | { |
2709 | isl_bool equal_params; |
2710 | |
2711 | if (!pwaff1 || !pwaff2) |
2712 | goto error; |
2713 | equal_params = isl_space_has_equal_params(pwaff1->dim, pwaff2->dim); |
2714 | if (equal_params < 0) |
2715 | goto error; |
2716 | if (equal_params) |
2717 | return fn(pwaff1, pwaff2); |
2718 | if (isl_pw_aff_check_named_params(pwaff1) < 0 || |
2719 | isl_pw_aff_check_named_params(pwaff2) < 0) |
2720 | goto error; |
2721 | pwaff1 = isl_pw_aff_align_params(pwaff1, isl_pw_aff_get_space(pwaff2)); |
2722 | pwaff2 = isl_pw_aff_align_params(pwaff2, isl_pw_aff_get_space(pwaff1)); |
2723 | return fn(pwaff1, pwaff2); |
2724 | error: |
2725 | isl_pw_aff_free(pwaff1); |
2726 | isl_pw_aff_free(pwaff2); |
2727 | return NULL((void*)0); |
2728 | } |
2729 | |
2730 | /* Align the parameters of the to isl_pw_aff arguments and |
2731 | * then apply a function "fn" on them that returns an isl_map. |
2732 | */ |
2733 | static __isl_give isl_map *align_params_pw_pw_map_and( |
2734 | __isl_take isl_pw_aff *pa1, __isl_take isl_pw_aff *pa2, |
2735 | __isl_give isl_map *(*fn)(__isl_take isl_pw_aff *pa1, |
2736 | __isl_take isl_pw_aff *pa2)) |
2737 | { |
2738 | isl_bool equal_params; |
2739 | |
2740 | if (!pa1 || !pa2) |
2741 | goto error; |
2742 | equal_params = isl_space_has_equal_params(pa1->dim, pa2->dim); |
2743 | if (equal_params < 0) |
2744 | goto error; |
2745 | if (equal_params) |
2746 | return fn(pa1, pa2); |
2747 | if (isl_pw_aff_check_named_params(pa1) < 0 || |
2748 | isl_pw_aff_check_named_params(pa2) < 0) |
2749 | goto error; |
2750 | pa1 = isl_pw_aff_align_params(pa1, isl_pw_aff_get_space(pa2)); |
2751 | pa2 = isl_pw_aff_align_params(pa2, isl_pw_aff_get_space(pa1)); |
2752 | return fn(pa1, pa2); |
2753 | error: |
2754 | isl_pw_aff_free(pa1); |
2755 | isl_pw_aff_free(pa2); |
2756 | return NULL((void*)0); |
2757 | } |
2758 | |
2759 | /* Compute a piecewise quasi-affine expression with a domain that |
2760 | * is the union of those of pwaff1 and pwaff2 and such that on each |
2761 | * cell, the quasi-affine expression is the maximum of those of pwaff1 |
2762 | * and pwaff2. If only one of pwaff1 or pwaff2 is defined on a given |
2763 | * cell, then the associated expression is the defined one. |
2764 | */ |
2765 | static __isl_give isl_pw_aff *pw_aff_union_max(__isl_take isl_pw_aff *pwaff1, |
2766 | __isl_take isl_pw_aff *pwaff2) |
2767 | { |
2768 | return isl_pw_aff_union_opt_cmp(pwaff1, pwaff2, &isl_aff_ge_set); |
2769 | } |
2770 | |
2771 | __isl_give isl_pw_aff *isl_pw_aff_union_max(__isl_take isl_pw_aff *pwaff1, |
2772 | __isl_take isl_pw_aff *pwaff2) |
2773 | { |
2774 | return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, |
2775 | &pw_aff_union_max); |
2776 | } |
2777 | |
2778 | /* Compute a piecewise quasi-affine expression with a domain that |
2779 | * is the union of those of pwaff1 and pwaff2 and such that on each |
2780 | * cell, the quasi-affine expression is the minimum of those of pwaff1 |
2781 | * and pwaff2. If only one of pwaff1 or pwaff2 is defined on a given |
2782 | * cell, then the associated expression is the defined one. |
2783 | */ |
2784 | static __isl_give isl_pw_aff *pw_aff_union_min(__isl_take isl_pw_aff *pwaff1, |
2785 | __isl_take isl_pw_aff *pwaff2) |
2786 | { |
2787 | return isl_pw_aff_union_opt_cmp(pwaff1, pwaff2, &isl_aff_le_set); |
2788 | } |
2789 | |
2790 | __isl_give isl_pw_aff *isl_pw_aff_union_min(__isl_take isl_pw_aff *pwaff1, |
2791 | __isl_take isl_pw_aff *pwaff2) |
2792 | { |
2793 | return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, |
2794 | &pw_aff_union_min); |
2795 | } |
2796 | |
2797 | __isl_give isl_pw_aff *isl_pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1, |
2798 | __isl_take isl_pw_aff *pwaff2, int max) |
2799 | { |
2800 | if (max) |
2801 | return isl_pw_aff_union_max(pwaff1, pwaff2); |
2802 | else |
2803 | return isl_pw_aff_union_min(pwaff1, pwaff2); |
2804 | } |
2805 | |
2806 | /* Return a set containing those elements in the domain |
2807 | * of "pwaff" where it satisfies "fn" (if complement is 0) or |
2808 | * does not satisfy "fn" (if complement is 1). |
2809 | * |
2810 | * The pieces with a NaN never belong to the result since |
2811 | * NaN does not satisfy any property. |
2812 | */ |
2813 | static __isl_give isl_setisl_map *pw_aff_locus(__isl_take isl_pw_aff *pwaff, |
2814 | __isl_give isl_basic_setisl_basic_map *(*fn)(__isl_take isl_aff *aff, int rational), |
2815 | int complement) |
2816 | { |
2817 | int i; |
2818 | isl_setisl_map *set; |
2819 | |
2820 | if (!pwaff) |
2821 | return NULL((void*)0); |
2822 | |
2823 | set = isl_set_empty(isl_pw_aff_get_domain_space(pwaff)); |
2824 | |
2825 | for (i = 0; i < pwaff->n; ++i) { |
2826 | isl_basic_setisl_basic_map *bset; |
2827 | isl_setisl_map *set_i, *locus; |
2828 | isl_bool rational; |
2829 | |
2830 | if (isl_aff_is_nan(pwaff->p[i].aff)) |
2831 | continue; |
2832 | |
2833 | rational = isl_set_has_rational(pwaff->p[i].set); |
2834 | bset = fn(isl_aff_copy(pwaff->p[i].aff), rational); |
2835 | locus = isl_set_from_basic_set(bset); |
2836 | set_i = isl_set_copy(pwaff->p[i].set); |
2837 | if (complement) |
2838 | set_i = isl_set_subtract(set_i, locus); |
2839 | else |
2840 | set_i = isl_set_intersect(set_i, locus); |
2841 | set = isl_set_union_disjoint(set, set_i); |
2842 | } |
2843 | |
2844 | isl_pw_aff_free(pwaff); |
2845 | |
2846 | return set; |
2847 | } |
2848 | |
2849 | /* Return a set containing those elements in the domain |
2850 | * of "pa" where it is positive. |
2851 | */ |
2852 | __isl_give isl_setisl_map *isl_pw_aff_pos_set(__isl_take isl_pw_aff *pa) |
2853 | { |
2854 | return pw_aff_locus(pa, &aff_pos_basic_set, 0); |
2855 | } |
2856 | |
2857 | /* Return a set containing those elements in the domain |
2858 | * of pwaff where it is non-negative. |
2859 | */ |
2860 | __isl_give isl_setisl_map *isl_pw_aff_nonneg_set(__isl_take isl_pw_aff *pwaff) |
2861 | { |
2862 | return pw_aff_locus(pwaff, &aff_nonneg_basic_set, 0); |
2863 | } |
2864 | |
2865 | /* Return a set containing those elements in the domain |
2866 | * of pwaff where it is zero. |
2867 | */ |
2868 | __isl_give isl_setisl_map *isl_pw_aff_zero_set(__isl_take isl_pw_aff *pwaff) |
2869 | { |
2870 | return pw_aff_locus(pwaff, &aff_zero_basic_set, 0); |
2871 | } |
2872 | |
2873 | /* Return a set containing those elements in the domain |
2874 | * of pwaff where it is not zero. |
2875 | */ |
2876 | __isl_give isl_setisl_map *isl_pw_aff_non_zero_set(__isl_take isl_pw_aff *pwaff) |
2877 | { |
2878 | return pw_aff_locus(pwaff, &aff_zero_basic_set, 1); |
2879 | } |
2880 | |
2881 | /* Return a set containing those elements in the shared domain |
2882 | * of pwaff1 and pwaff2 where pwaff1 is greater than (or equal) to pwaff2. |
2883 | * |
2884 | * We compute the difference on the shared domain and then construct |
2885 | * the set of values where this difference is non-negative. |
2886 | * If strict is set, we first subtract 1 from the difference. |
2887 | * If equal is set, we only return the elements where pwaff1 and pwaff2 |
2888 | * are equal. |
2889 | */ |
2890 | static __isl_give isl_setisl_map *pw_aff_gte_set(__isl_take isl_pw_aff *pwaff1, |
2891 | __isl_take isl_pw_aff *pwaff2, int strict, int equal) |
2892 | { |
2893 | isl_setisl_map *set1, *set2; |
2894 | |
2895 | set1 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)); |
2896 | set2 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff2)); |
2897 | set1 = isl_set_intersect(set1, set2); |
2898 | pwaff1 = isl_pw_aff_intersect_domain(pwaff1, isl_set_copy(set1)); |
2899 | pwaff2 = isl_pw_aff_intersect_domain(pwaff2, isl_set_copy(set1)); |
2900 | pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_neg(pwaff2)); |
2901 | |
2902 | if (strict) { |
2903 | isl_space *dim = isl_set_get_space(set1); |
2904 | isl_aff *aff; |
2905 | aff = isl_aff_zero_on_domain(isl_local_space_from_space(dim)); |
2906 | aff = isl_aff_add_constant_si(aff, -1); |
2907 | pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_alloc(set1, aff)); |
2908 | } else |
2909 | isl_set_free(set1); |
2910 | |
2911 | if (equal) |
2912 | return isl_pw_aff_zero_set(pwaff1); |
2913 | return isl_pw_aff_nonneg_set(pwaff1); |
2914 | } |
2915 | |
2916 | /* Return a set containing those elements in the shared domain |
2917 | * of pwaff1 and pwaff2 where pwaff1 is equal to pwaff2. |
2918 | */ |
2919 | static __isl_give isl_setisl_map *pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1, |
2920 | __isl_take isl_pw_aff *pwaff2) |
2921 | { |
2922 | return pw_aff_gte_set(pwaff1, pwaff2, 0, 1); |
2923 | } |
2924 | |
2925 | __isl_give isl_setisl_map *isl_pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1, |
2926 | __isl_take isl_pw_aff *pwaff2) |
2927 | { |
2928 | return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_eq_set); |
2929 | } |
2930 | |
2931 | /* Return a set containing those elements in the shared domain |
2932 | * of pwaff1 and pwaff2 where pwaff1 is greater than or equal to pwaff2. |
2933 | */ |
2934 | static __isl_give isl_setisl_map *pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1, |
2935 | __isl_take isl_pw_aff *pwaff2) |
2936 | { |
2937 | return pw_aff_gte_set(pwaff1, pwaff2, 0, 0); |
2938 | } |
2939 | |
2940 | __isl_give isl_setisl_map *isl_pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1, |
2941 | __isl_take isl_pw_aff *pwaff2) |
2942 | { |
2943 | return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_ge_set); |
2944 | } |
2945 | |
2946 | /* Return a set containing those elements in the shared domain |
2947 | * of pwaff1 and pwaff2 where pwaff1 is strictly greater than pwaff2. |
2948 | */ |
2949 | static __isl_give isl_setisl_map *pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1, |
2950 | __isl_take isl_pw_aff *pwaff2) |
2951 | { |
2952 | return pw_aff_gte_set(pwaff1, pwaff2, 1, 0); |
2953 | } |
2954 | |
2955 | __isl_give isl_setisl_map *isl_pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1, |
2956 | __isl_take isl_pw_aff *pwaff2) |
2957 | { |
2958 | return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_gt_set); |
2959 | } |
2960 | |
2961 | __isl_give isl_setisl_map *isl_pw_aff_le_set(__isl_take isl_pw_aff *pwaff1, |
2962 | __isl_take isl_pw_aff *pwaff2) |
2963 | { |
2964 | return isl_pw_aff_ge_set(pwaff2, pwaff1); |
2965 | } |
2966 | |
2967 | __isl_give isl_setisl_map *isl_pw_aff_lt_set(__isl_take isl_pw_aff *pwaff1, |
2968 | __isl_take isl_pw_aff *pwaff2) |
2969 | { |
2970 | return isl_pw_aff_gt_set(pwaff2, pwaff1); |
2971 | } |
2972 | |
2973 | /* Return a map containing pairs of elements in the domains of "pa1" and "pa2" |
2974 | * where the function values are ordered in the same way as "order", |
2975 | * which returns a set in the shared domain of its two arguments. |
2976 | * The parameters of "pa1" and "pa2" are assumed to have been aligned. |
2977 | * |
2978 | * Let "pa1" and "pa2" be defined on domains A and B respectively. |
2979 | * We first pull back the two functions such that they are defined on |
2980 | * the domain [A -> B]. Then we apply "order", resulting in a set |
2981 | * in the space [A -> B]. Finally, we unwrap this set to obtain |
2982 | * a map in the space A -> B. |
2983 | */ |
2984 | static __isl_give isl_map *isl_pw_aff_order_map_aligned( |
2985 | __isl_take isl_pw_aff *pa1, __isl_take isl_pw_aff *pa2, |
2986 | __isl_give isl_setisl_map *(*order)(__isl_take isl_pw_aff *pa1, |
2987 | __isl_take isl_pw_aff *pa2)) |
2988 | { |
2989 | isl_space *space1, *space2; |
2990 | isl_multi_aff *ma; |
2991 | isl_setisl_map *set; |
2992 | |
2993 | space1 = isl_space_domain(isl_pw_aff_get_space(pa1)); |
2994 | space2 = isl_space_domain(isl_pw_aff_get_space(pa2)); |
2995 | space1 = isl_space_map_from_domain_and_range(space1, space2); |
2996 | ma = isl_multi_aff_domain_map(isl_space_copy(space1)); |
2997 | pa1 = isl_pw_aff_pullback_multi_aff(pa1, ma); |
2998 | ma = isl_multi_aff_range_map(space1); |
2999 | pa2 = isl_pw_aff_pullback_multi_aff(pa2, ma); |
3000 | set = order(pa1, pa2); |
3001 | |
3002 | return isl_set_unwrap(set); |
3003 | } |
3004 | |
3005 | /* Return a map containing pairs of elements in the domains of "pa1" and "pa2" |
3006 | * where the function values are equal. |
3007 | * The parameters of "pa1" and "pa2" are assumed to have been aligned. |
3008 | */ |
3009 | static __isl_give isl_map *isl_pw_aff_eq_map_aligned(__isl_take isl_pw_aff *pa1, |
3010 | __isl_take isl_pw_aff *pa2) |
3011 | { |
3012 | return isl_pw_aff_order_map_aligned(pa1, pa2, &isl_pw_aff_eq_set); |
3013 | } |
3014 | |
3015 | /* Return a map containing pairs of elements in the domains of "pa1" and "pa2" |
3016 | * where the function values are equal. |
3017 | */ |
3018 | __isl_give isl_map *isl_pw_aff_eq_map(__isl_take isl_pw_aff *pa1, |
3019 | __isl_take isl_pw_aff *pa2) |
3020 | { |
3021 | return align_params_pw_pw_map_and(pa1, pa2, &isl_pw_aff_eq_map_aligned); |
3022 | } |
3023 | |
3024 | /* Return a map containing pairs of elements in the domains of "pa1" and "pa2" |
3025 | * where the function value of "pa1" is less than the function value of "pa2". |
3026 | * The parameters of "pa1" and "pa2" are assumed to have been aligned. |
3027 | */ |
3028 | static __isl_give isl_map *isl_pw_aff_lt_map_aligned(__isl_take isl_pw_aff *pa1, |
3029 | __isl_take isl_pw_aff *pa2) |
3030 | { |
3031 | return isl_pw_aff_order_map_aligned(pa1, pa2, &isl_pw_aff_lt_set); |
3032 | } |
3033 | |
3034 | /* Return a map containing pairs of elements in the domains of "pa1" and "pa2" |
3035 | * where the function value of "pa1" is less than the function value of "pa2". |
3036 | */ |
3037 | __isl_give isl_map *isl_pw_aff_lt_map(__isl_take isl_pw_aff *pa1, |
3038 | __isl_take isl_pw_aff *pa2) |
3039 | { |
3040 | return align_params_pw_pw_map_and(pa1, pa2, &isl_pw_aff_lt_map_aligned); |
3041 | } |
3042 | |
3043 | /* Return a map containing pairs of elements in the domains of "pa1" and "pa2" |
3044 | * where the function value of "pa1" is greater than the function value |
3045 | * of "pa2". |
3046 | * The parameters of "pa1" and "pa2" are assumed to have been aligned. |
3047 | */ |
3048 | static __isl_give isl_map *isl_pw_aff_gt_map_aligned(__isl_take isl_pw_aff *pa1, |
3049 | __isl_take isl_pw_aff *pa2) |
3050 | { |
3051 | return isl_pw_aff_order_map_aligned(pa1, pa2, &isl_pw_aff_gt_set); |
3052 | } |
3053 | |
3054 | /* Return a map containing pairs of elements in the domains of "pa1" and "pa2" |
3055 | * where the function value of "pa1" is greater than the function value |
3056 | * of "pa2". |
3057 | */ |
3058 | __isl_give isl_map *isl_pw_aff_gt_map(__isl_take isl_pw_aff *pa1, |
3059 | __isl_take isl_pw_aff *pa2) |
3060 | { |
3061 | return align_params_pw_pw_map_and(pa1, pa2, &isl_pw_aff_gt_map_aligned); |
3062 | } |
3063 | |
3064 | /* Return a set containing those elements in the shared domain |
3065 | * of the elements of list1 and list2 where each element in list1 |
3066 | * has the relation specified by "fn" with each element in list2. |
3067 | */ |
3068 | static __isl_give isl_setisl_map *pw_aff_list_set(__isl_take isl_pw_aff_list *list1, |
3069 | __isl_take isl_pw_aff_list *list2, |
3070 | __isl_give isl_setisl_map *(*fn)(__isl_take isl_pw_aff *pwaff1, |
3071 | __isl_take isl_pw_aff *pwaff2)) |
3072 | { |
3073 | int i, j; |
3074 | isl_ctx *ctx; |
3075 | isl_setisl_map *set; |
3076 | |
3077 | if (!list1 || !list2) |
3078 | goto error; |
3079 | |
3080 | ctx = isl_pw_aff_list_get_ctx(list1); |
3081 | if (list1->n < 1 || list2->n < 1) |
3082 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "list should contain at least one element" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3083); goto error; } while (0) |
3083 | "list should contain at least one element", goto error)do { isl_handle_error(ctx, isl_error_invalid, "list should contain at least one element" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3083); goto error; } while (0); |
3084 | |
3085 | set = isl_set_universe(isl_pw_aff_get_domain_space(list1->p[0])); |
3086 | for (i = 0; i < list1->n; ++i) |
3087 | for (j = 0; j < list2->n; ++j) { |
3088 | isl_setisl_map *set_ij; |
3089 | |
3090 | set_ij = fn(isl_pw_aff_copy(list1->p[i]), |
3091 | isl_pw_aff_copy(list2->p[j])); |
3092 | set = isl_set_intersect(set, set_ij); |
3093 | } |
3094 | |
3095 | isl_pw_aff_list_free(list1); |
3096 | isl_pw_aff_list_free(list2); |
3097 | return set; |
3098 | error: |
3099 | isl_pw_aff_list_free(list1); |
3100 | isl_pw_aff_list_free(list2); |
3101 | return NULL((void*)0); |
3102 | } |
3103 | |
3104 | /* Return a set containing those elements in the shared domain |
3105 | * of the elements of list1 and list2 where each element in list1 |
3106 | * is equal to each element in list2. |
3107 | */ |
3108 | __isl_give isl_setisl_map *isl_pw_aff_list_eq_set(__isl_take isl_pw_aff_list *list1, |
3109 | __isl_take isl_pw_aff_list *list2) |
3110 | { |
3111 | return pw_aff_list_set(list1, list2, &isl_pw_aff_eq_set); |
3112 | } |
3113 | |
3114 | __isl_give isl_setisl_map *isl_pw_aff_list_ne_set(__isl_take isl_pw_aff_list *list1, |
3115 | __isl_take isl_pw_aff_list *list2) |
3116 | { |
3117 | return pw_aff_list_set(list1, list2, &isl_pw_aff_ne_set); |
3118 | } |
3119 | |
3120 | /* Return a set containing those elements in the shared domain |
3121 | * of the elements of list1 and list2 where each element in list1 |
3122 | * is less than or equal to each element in list2. |
3123 | */ |
3124 | __isl_give isl_setisl_map *isl_pw_aff_list_le_set(__isl_take isl_pw_aff_list *list1, |
3125 | __isl_take isl_pw_aff_list *list2) |
3126 | { |
3127 | return pw_aff_list_set(list1, list2, &isl_pw_aff_le_set); |
3128 | } |
3129 | |
3130 | __isl_give isl_setisl_map *isl_pw_aff_list_lt_set(__isl_take isl_pw_aff_list *list1, |
3131 | __isl_take isl_pw_aff_list *list2) |
3132 | { |
3133 | return pw_aff_list_set(list1, list2, &isl_pw_aff_lt_set); |
3134 | } |
3135 | |
3136 | __isl_give isl_setisl_map *isl_pw_aff_list_ge_set(__isl_take isl_pw_aff_list *list1, |
3137 | __isl_take isl_pw_aff_list *list2) |
3138 | { |
3139 | return pw_aff_list_set(list1, list2, &isl_pw_aff_ge_set); |
3140 | } |
3141 | |
3142 | __isl_give isl_setisl_map *isl_pw_aff_list_gt_set(__isl_take isl_pw_aff_list *list1, |
3143 | __isl_take isl_pw_aff_list *list2) |
3144 | { |
3145 | return pw_aff_list_set(list1, list2, &isl_pw_aff_gt_set); |
3146 | } |
3147 | |
3148 | |
3149 | /* Return a set containing those elements in the shared domain |
3150 | * of pwaff1 and pwaff2 where pwaff1 is not equal to pwaff2. |
3151 | */ |
3152 | static __isl_give isl_setisl_map *pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1, |
3153 | __isl_take isl_pw_aff *pwaff2) |
3154 | { |
3155 | isl_setisl_map *set_lt, *set_gt; |
3156 | |
3157 | set_lt = isl_pw_aff_lt_set(isl_pw_aff_copy(pwaff1), |
3158 | isl_pw_aff_copy(pwaff2)); |
3159 | set_gt = isl_pw_aff_gt_set(pwaff1, pwaff2); |
3160 | return isl_set_union_disjoint(set_lt, set_gt); |
3161 | } |
3162 | |
3163 | __isl_give isl_setisl_map *isl_pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1, |
3164 | __isl_take isl_pw_aff *pwaff2) |
3165 | { |
3166 | return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_ne_set); |
3167 | } |
3168 | |
3169 | __isl_give isl_pw_aff *isl_pw_aff_scale_down(__isl_take isl_pw_aff *pwaff, |
3170 | isl_int v) |
3171 | { |
3172 | int i; |
3173 | |
3174 | if (isl_int_is_one(v)(isl_sioimath_cmp_si(*(v), 1) == 0)) |
3175 | return pwaff; |
3176 | if (!isl_int_is_pos(v)(isl_sioimath_sgn(*(v)) > 0)) |
3177 | isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pwaff), isl_error_invalid , "factor needs to be positive", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3179); return isl_pw_aff_free(pwaff); } while (0) |
3178 | "factor needs to be positive",do { isl_handle_error(isl_pw_aff_get_ctx(pwaff), isl_error_invalid , "factor needs to be positive", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3179); return isl_pw_aff_free(pwaff); } while (0) |
3179 | return isl_pw_aff_free(pwaff))do { isl_handle_error(isl_pw_aff_get_ctx(pwaff), isl_error_invalid , "factor needs to be positive", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3179); return isl_pw_aff_free(pwaff); } while (0); |
3180 | pwaff = isl_pw_aff_cow(pwaff); |
3181 | if (!pwaff) |
3182 | return NULL((void*)0); |
3183 | if (pwaff->n == 0) |
3184 | return pwaff; |
3185 | |
3186 | for (i = 0; i < pwaff->n; ++i) { |
3187 | pwaff->p[i].aff = isl_aff_scale_down(pwaff->p[i].aff, v); |
3188 | if (!pwaff->p[i].aff) |
3189 | return isl_pw_aff_free(pwaff); |
3190 | } |
3191 | |
3192 | return pwaff; |
3193 | } |
3194 | |
3195 | __isl_give isl_pw_aff *isl_pw_aff_floor(__isl_take isl_pw_aff *pwaff) |
3196 | { |
3197 | int i; |
3198 | |
3199 | pwaff = isl_pw_aff_cow(pwaff); |
3200 | if (!pwaff) |
3201 | return NULL((void*)0); |
3202 | if (pwaff->n == 0) |
3203 | return pwaff; |
3204 | |
3205 | for (i = 0; i < pwaff->n; ++i) { |
3206 | pwaff->p[i].aff = isl_aff_floor(pwaff->p[i].aff); |
3207 | if (!pwaff->p[i].aff) |
3208 | return isl_pw_aff_free(pwaff); |
3209 | } |
3210 | |
3211 | return pwaff; |
3212 | } |
3213 | |
3214 | __isl_give isl_pw_aff *isl_pw_aff_ceil(__isl_take isl_pw_aff *pwaff) |
3215 | { |
3216 | int i; |
3217 | |
3218 | pwaff = isl_pw_aff_cow(pwaff); |
3219 | if (!pwaff) |
3220 | return NULL((void*)0); |
3221 | if (pwaff->n == 0) |
3222 | return pwaff; |
3223 | |
3224 | for (i = 0; i < pwaff->n; ++i) { |
3225 | pwaff->p[i].aff = isl_aff_ceil(pwaff->p[i].aff); |
3226 | if (!pwaff->p[i].aff) |
3227 | return isl_pw_aff_free(pwaff); |
3228 | } |
3229 | |
3230 | return pwaff; |
3231 | } |
3232 | |
3233 | /* Assuming that "cond1" and "cond2" are disjoint, |
3234 | * return an affine expression that is equal to pwaff1 on cond1 |
3235 | * and to pwaff2 on cond2. |
3236 | */ |
3237 | static __isl_give isl_pw_aff *isl_pw_aff_select( |
3238 | __isl_take isl_setisl_map *cond1, __isl_take isl_pw_aff *pwaff1, |
3239 | __isl_take isl_setisl_map *cond2, __isl_take isl_pw_aff *pwaff2) |
3240 | { |
3241 | pwaff1 = isl_pw_aff_intersect_domain(pwaff1, cond1); |
3242 | pwaff2 = isl_pw_aff_intersect_domain(pwaff2, cond2); |
3243 | |
3244 | return isl_pw_aff_add_disjoint(pwaff1, pwaff2); |
3245 | } |
3246 | |
3247 | /* Return an affine expression that is equal to pwaff_true for elements |
3248 | * where "cond" is non-zero and to pwaff_false for elements where "cond" |
3249 | * is zero. |
3250 | * That is, return cond ? pwaff_true : pwaff_false; |
3251 | * |
3252 | * If "cond" involves and NaN, then we conservatively return a NaN |
3253 | * on its entire domain. In principle, we could consider the pieces |
3254 | * where it is NaN separately from those where it is not. |
3255 | * |
3256 | * If "pwaff_true" and "pwaff_false" are obviously equal to each other, |
3257 | * then only use the domain of "cond" to restrict the domain. |
3258 | */ |
3259 | __isl_give isl_pw_aff *isl_pw_aff_cond(__isl_take isl_pw_aff *cond, |
3260 | __isl_take isl_pw_aff *pwaff_true, __isl_take isl_pw_aff *pwaff_false) |
3261 | { |
3262 | isl_setisl_map *cond_true, *cond_false; |
3263 | isl_bool equal; |
3264 | |
3265 | if (!cond) |
3266 | goto error; |
3267 | if (isl_pw_aff_involves_nan(cond)) { |
3268 | isl_space *space = isl_pw_aff_get_domain_space(cond); |
3269 | isl_local_space *ls = isl_local_space_from_space(space); |
3270 | isl_pw_aff_free(cond); |
3271 | isl_pw_aff_free(pwaff_true); |
3272 | isl_pw_aff_free(pwaff_false); |
3273 | return isl_pw_aff_nan_on_domain(ls); |
3274 | } |
3275 | |
3276 | pwaff_true = isl_pw_aff_align_params(pwaff_true, |
3277 | isl_pw_aff_get_space(pwaff_false)); |
3278 | pwaff_false = isl_pw_aff_align_params(pwaff_false, |
3279 | isl_pw_aff_get_space(pwaff_true)); |
3280 | equal = isl_pw_aff_plain_is_equal(pwaff_true, pwaff_false); |
3281 | if (equal < 0) |
3282 | goto error; |
3283 | if (equal) { |
3284 | isl_setisl_map *dom; |
3285 | |
3286 | dom = isl_set_coalesce(isl_pw_aff_domain(cond)); |
3287 | isl_pw_aff_free(pwaff_false); |
3288 | return isl_pw_aff_intersect_domain(pwaff_true, dom); |
3289 | } |
3290 | |
3291 | cond_true = isl_pw_aff_non_zero_set(isl_pw_aff_copy(cond)); |
3292 | cond_false = isl_pw_aff_zero_set(cond); |
3293 | return isl_pw_aff_select(cond_true, pwaff_true, |
3294 | cond_false, pwaff_false); |
3295 | error: |
3296 | isl_pw_aff_free(cond); |
3297 | isl_pw_aff_free(pwaff_true); |
3298 | isl_pw_aff_free(pwaff_false); |
3299 | return NULL((void*)0); |
3300 | } |
3301 | |
3302 | isl_bool isl_aff_is_cst(__isl_keep isl_aff *aff) |
3303 | { |
3304 | if (!aff) |
3305 | return isl_bool_error; |
3306 | |
3307 | return isl_seq_first_non_zero(aff->v->el + 2, aff->v->size - 2) == -1; |
3308 | } |
3309 | |
3310 | /* Check whether pwaff is a piecewise constant. |
3311 | */ |
3312 | isl_bool isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff) |
3313 | { |
3314 | int i; |
3315 | |
3316 | if (!pwaff) |
3317 | return isl_bool_error; |
3318 | |
3319 | for (i = 0; i < pwaff->n; ++i) { |
3320 | isl_bool is_cst = isl_aff_is_cst(pwaff->p[i].aff); |
3321 | if (is_cst < 0 || !is_cst) |
3322 | return is_cst; |
3323 | } |
3324 | |
3325 | return isl_bool_true; |
3326 | } |
3327 | |
3328 | /* Are all elements of "mpa" piecewise constants? |
3329 | */ |
3330 | isl_bool isl_multi_pw_aff_is_cst(__isl_keep isl_multi_pw_aff *mpa) |
3331 | { |
3332 | int i; |
3333 | |
3334 | if (!mpa) |
3335 | return isl_bool_error; |
3336 | |
3337 | for (i = 0; i < mpa->n; ++i) { |
3338 | isl_bool is_cst = isl_pw_aff_is_cst(mpa->u.p[i]); |
3339 | if (is_cst < 0 || !is_cst) |
3340 | return is_cst; |
3341 | } |
3342 | |
3343 | return isl_bool_true; |
3344 | } |
3345 | |
3346 | /* Return the product of "aff1" and "aff2". |
3347 | * |
3348 | * If either of the two is NaN, then the result is NaN. |
3349 | * |
3350 | * Otherwise, at least one of "aff1" or "aff2" needs to be a constant. |
3351 | */ |
3352 | __isl_give isl_aff *isl_aff_mul(__isl_take isl_aff *aff1, |
3353 | __isl_take isl_aff *aff2) |
3354 | { |
3355 | if (!aff1 || !aff2) |
3356 | goto error; |
3357 | |
3358 | if (isl_aff_is_nan(aff1)) { |
3359 | isl_aff_free(aff2); |
3360 | return aff1; |
3361 | } |
3362 | if (isl_aff_is_nan(aff2)) { |
3363 | isl_aff_free(aff1); |
3364 | return aff2; |
3365 | } |
3366 | |
3367 | if (!isl_aff_is_cst(aff2) && isl_aff_is_cst(aff1)) |
3368 | return isl_aff_mul(aff2, aff1); |
3369 | |
3370 | if (!isl_aff_is_cst(aff2)) |
3371 | isl_die(isl_aff_get_ctx(aff1), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff1), isl_error_invalid , "at least one affine expression should be constant", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3373); goto error; } while (0) |
3372 | "at least one affine expression should be constant",do { isl_handle_error(isl_aff_get_ctx(aff1), isl_error_invalid , "at least one affine expression should be constant", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3373); goto error; } while (0) |
3373 | goto error)do { isl_handle_error(isl_aff_get_ctx(aff1), isl_error_invalid , "at least one affine expression should be constant", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3373); goto error; } while (0); |
3374 | |
3375 | aff1 = isl_aff_cow(aff1); |
3376 | if (!aff1 || !aff2) |
3377 | goto error; |
3378 | |
3379 | aff1 = isl_aff_scale(aff1, aff2->v->el[1]); |
3380 | aff1 = isl_aff_scale_down(aff1, aff2->v->el[0]); |
3381 | |
3382 | isl_aff_free(aff2); |
3383 | return aff1; |
3384 | error: |
3385 | isl_aff_free(aff1); |
3386 | isl_aff_free(aff2); |
3387 | return NULL((void*)0); |
3388 | } |
3389 | |
3390 | /* Divide "aff1" by "aff2", assuming "aff2" is a constant. |
3391 | * |
3392 | * If either of the two is NaN, then the result is NaN. |
3393 | */ |
3394 | __isl_give isl_aff *isl_aff_div(__isl_take isl_aff *aff1, |
3395 | __isl_take isl_aff *aff2) |
3396 | { |
3397 | int is_cst; |
3398 | int neg; |
3399 | |
3400 | if (!aff1 || !aff2) |
3401 | goto error; |
3402 | |
3403 | if (isl_aff_is_nan(aff1)) { |
3404 | isl_aff_free(aff2); |
3405 | return aff1; |
3406 | } |
3407 | if (isl_aff_is_nan(aff2)) { |
3408 | isl_aff_free(aff1); |
3409 | return aff2; |
3410 | } |
3411 | |
3412 | is_cst = isl_aff_is_cst(aff2); |
3413 | if (is_cst < 0) |
3414 | goto error; |
3415 | if (!is_cst) |
3416 | isl_die(isl_aff_get_ctx(aff2), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff2), isl_error_invalid , "second argument should be a constant", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3417); goto error; } while (0) |
3417 | "second argument should be a constant", goto error)do { isl_handle_error(isl_aff_get_ctx(aff2), isl_error_invalid , "second argument should be a constant", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3417); goto error; } while (0); |
3418 | |
3419 | if (!aff2) |
3420 | goto error; |
3421 | |
3422 | neg = isl_int_is_neg(aff2->v->el[1])(isl_sioimath_sgn(*(aff2->v->el[1])) < 0); |
3423 | if (neg) { |
3424 | isl_int_neg(aff2->v->el[0], aff2->v->el[0])isl_sioimath_neg((aff2->v->el[0]), *(aff2->v->el[ 0])); |
3425 | isl_int_neg(aff2->v->el[1], aff2->v->el[1])isl_sioimath_neg((aff2->v->el[1]), *(aff2->v->el[ 1])); |
3426 | } |
3427 | |
3428 | aff1 = isl_aff_scale(aff1, aff2->v->el[0]); |
3429 | aff1 = isl_aff_scale_down(aff1, aff2->v->el[1]); |
3430 | |
3431 | if (neg) { |
3432 | isl_int_neg(aff2->v->el[0], aff2->v->el[0])isl_sioimath_neg((aff2->v->el[0]), *(aff2->v->el[ 0])); |
3433 | isl_int_neg(aff2->v->el[1], aff2->v->el[1])isl_sioimath_neg((aff2->v->el[1]), *(aff2->v->el[ 1])); |
3434 | } |
3435 | |
3436 | isl_aff_free(aff2); |
3437 | return aff1; |
3438 | error: |
3439 | isl_aff_free(aff1); |
3440 | isl_aff_free(aff2); |
3441 | return NULL((void*)0); |
3442 | } |
3443 | |
3444 | static __isl_give isl_pw_aff *pw_aff_add(__isl_take isl_pw_aff *pwaff1, |
3445 | __isl_take isl_pw_aff *pwaff2) |
3446 | { |
3447 | return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_add); |
3448 | } |
3449 | |
3450 | __isl_give isl_pw_aff *isl_pw_aff_add(__isl_take isl_pw_aff *pwaff1, |
3451 | __isl_take isl_pw_aff *pwaff2) |
3452 | { |
3453 | return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_add); |
3454 | } |
3455 | |
3456 | __isl_give isl_pw_aff *isl_pw_aff_union_add(__isl_take isl_pw_aff *pwaff1, |
3457 | __isl_take isl_pw_aff *pwaff2) |
3458 | { |
3459 | return isl_pw_aff_union_add_(pwaff1, pwaff2); |
3460 | } |
3461 | |
3462 | static __isl_give isl_pw_aff *pw_aff_mul(__isl_take isl_pw_aff *pwaff1, |
3463 | __isl_take isl_pw_aff *pwaff2) |
3464 | { |
3465 | return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_mul); |
3466 | } |
3467 | |
3468 | __isl_give isl_pw_aff *isl_pw_aff_mul(__isl_take isl_pw_aff *pwaff1, |
3469 | __isl_take isl_pw_aff *pwaff2) |
3470 | { |
3471 | return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_mul); |
3472 | } |
3473 | |
3474 | static __isl_give isl_pw_aff *pw_aff_div(__isl_take isl_pw_aff *pa1, |
3475 | __isl_take isl_pw_aff *pa2) |
3476 | { |
3477 | return isl_pw_aff_on_shared_domain(pa1, pa2, &isl_aff_div); |
3478 | } |
3479 | |
3480 | /* Divide "pa1" by "pa2", assuming "pa2" is a piecewise constant. |
3481 | */ |
3482 | __isl_give isl_pw_aff *isl_pw_aff_div(__isl_take isl_pw_aff *pa1, |
3483 | __isl_take isl_pw_aff *pa2) |
3484 | { |
3485 | int is_cst; |
3486 | |
3487 | is_cst = isl_pw_aff_is_cst(pa2); |
3488 | if (is_cst < 0) |
3489 | goto error; |
3490 | if (!is_cst) |
3491 | isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid , "second argument should be a piecewise constant", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3493); goto error; } while (0) |
3492 | "second argument should be a piecewise constant",do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid , "second argument should be a piecewise constant", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3493); goto error; } while (0) |
3493 | goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid , "second argument should be a piecewise constant", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3493); goto error; } while (0); |
3494 | return isl_pw_aff_align_params_pw_pw_and(pa1, pa2, &pw_aff_div); |
3495 | error: |
3496 | isl_pw_aff_free(pa1); |
3497 | isl_pw_aff_free(pa2); |
3498 | return NULL((void*)0); |
3499 | } |
3500 | |
3501 | /* Compute the quotient of the integer division of "pa1" by "pa2" |
3502 | * with rounding towards zero. |
3503 | * "pa2" is assumed to be a piecewise constant. |
3504 | * |
3505 | * In particular, return |
3506 | * |
3507 | * pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2) |
3508 | * |
3509 | */ |
3510 | __isl_give isl_pw_aff *isl_pw_aff_tdiv_q(__isl_take isl_pw_aff *pa1, |
3511 | __isl_take isl_pw_aff *pa2) |
3512 | { |
3513 | int is_cst; |
3514 | isl_setisl_map *cond; |
3515 | isl_pw_aff *f, *c; |
3516 | |
3517 | is_cst = isl_pw_aff_is_cst(pa2); |
3518 | if (is_cst < 0) |
3519 | goto error; |
3520 | if (!is_cst) |
3521 | isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid , "second argument should be a piecewise constant", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3523); goto error; } while (0) |
3522 | "second argument should be a piecewise constant",do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid , "second argument should be a piecewise constant", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3523); goto error; } while (0) |
3523 | goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid , "second argument should be a piecewise constant", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3523); goto error; } while (0); |
3524 | |
3525 | pa1 = isl_pw_aff_div(pa1, pa2); |
3526 | |
3527 | cond = isl_pw_aff_nonneg_set(isl_pw_aff_copy(pa1)); |
3528 | f = isl_pw_aff_floor(isl_pw_aff_copy(pa1)); |
3529 | c = isl_pw_aff_ceil(pa1); |
3530 | return isl_pw_aff_cond(isl_set_indicator_function(cond), f, c); |
3531 | error: |
3532 | isl_pw_aff_free(pa1); |
3533 | isl_pw_aff_free(pa2); |
3534 | return NULL((void*)0); |
3535 | } |
3536 | |
3537 | /* Compute the remainder of the integer division of "pa1" by "pa2" |
3538 | * with rounding towards zero. |
3539 | * "pa2" is assumed to be a piecewise constant. |
3540 | * |
3541 | * In particular, return |
3542 | * |
3543 | * pa1 - pa2 * (pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2)) |
3544 | * |
3545 | */ |
3546 | __isl_give isl_pw_aff *isl_pw_aff_tdiv_r(__isl_take isl_pw_aff *pa1, |
3547 | __isl_take isl_pw_aff *pa2) |
3548 | { |
3549 | int is_cst; |
3550 | isl_pw_aff *res; |
3551 | |
3552 | is_cst = isl_pw_aff_is_cst(pa2); |
3553 | if (is_cst < 0) |
3554 | goto error; |
3555 | if (!is_cst) |
3556 | isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid , "second argument should be a piecewise constant", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3558); goto error; } while (0) |
3557 | "second argument should be a piecewise constant",do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid , "second argument should be a piecewise constant", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3558); goto error; } while (0) |
3558 | goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid , "second argument should be a piecewise constant", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3558); goto error; } while (0); |
3559 | res = isl_pw_aff_tdiv_q(isl_pw_aff_copy(pa1), isl_pw_aff_copy(pa2)); |
3560 | res = isl_pw_aff_mul(pa2, res); |
3561 | res = isl_pw_aff_sub(pa1, res); |
3562 | return res; |
3563 | error: |
3564 | isl_pw_aff_free(pa1); |
3565 | isl_pw_aff_free(pa2); |
3566 | return NULL((void*)0); |
3567 | } |
3568 | |
3569 | /* Does either of "pa1" or "pa2" involve any NaN2? |
3570 | */ |
3571 | static isl_bool either_involves_nan(__isl_keep isl_pw_aff *pa1, |
3572 | __isl_keep isl_pw_aff *pa2) |
3573 | { |
3574 | isl_bool has_nan; |
3575 | |
3576 | has_nan = isl_pw_aff_involves_nan(pa1); |
3577 | if (has_nan < 0 || has_nan) |
3578 | return has_nan; |
3579 | return isl_pw_aff_involves_nan(pa2); |
3580 | } |
3581 | |
3582 | /* Replace "pa1" and "pa2" (at least one of which involves a NaN) |
3583 | * by a NaN on their shared domain. |
3584 | * |
3585 | * In principle, the result could be refined to only being NaN |
3586 | * on the parts of this domain where at least one of "pa1" or "pa2" is NaN. |
3587 | */ |
3588 | static __isl_give isl_pw_aff *replace_by_nan(__isl_take isl_pw_aff *pa1, |
3589 | __isl_take isl_pw_aff *pa2) |
3590 | { |
3591 | isl_local_space *ls; |
3592 | isl_setisl_map *dom; |
3593 | isl_pw_aff *pa; |
3594 | |
3595 | dom = isl_set_intersect(isl_pw_aff_domain(pa1), isl_pw_aff_domain(pa2)); |
3596 | ls = isl_local_space_from_space(isl_set_get_space(dom)); |
3597 | pa = isl_pw_aff_nan_on_domain(ls); |
3598 | pa = isl_pw_aff_intersect_domain(pa, dom); |
3599 | |
3600 | return pa; |
3601 | } |
3602 | |
3603 | static __isl_give isl_pw_aff *pw_aff_min(__isl_take isl_pw_aff *pwaff1, |
3604 | __isl_take isl_pw_aff *pwaff2) |
3605 | { |
3606 | isl_setisl_map *le; |
3607 | isl_setisl_map *dom; |
3608 | |
3609 | dom = isl_set_intersect(isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)), |
3610 | isl_pw_aff_domain(isl_pw_aff_copy(pwaff2))); |
3611 | le = isl_pw_aff_le_set(isl_pw_aff_copy(pwaff1), |
3612 | isl_pw_aff_copy(pwaff2)); |
3613 | dom = isl_set_subtract(dom, isl_set_copy(le)); |
3614 | return isl_pw_aff_select(le, pwaff1, dom, pwaff2); |
3615 | } |
3616 | |
3617 | static __isl_give isl_pw_aff *pw_aff_max(__isl_take isl_pw_aff *pwaff1, |
3618 | __isl_take isl_pw_aff *pwaff2) |
3619 | { |
3620 | isl_setisl_map *ge; |
3621 | isl_setisl_map *dom; |
3622 | |
3623 | dom = isl_set_intersect(isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)), |
3624 | isl_pw_aff_domain(isl_pw_aff_copy(pwaff2))); |
3625 | ge = isl_pw_aff_ge_set(isl_pw_aff_copy(pwaff1), |
3626 | isl_pw_aff_copy(pwaff2)); |
3627 | dom = isl_set_subtract(dom, isl_set_copy(ge)); |
3628 | return isl_pw_aff_select(ge, pwaff1, dom, pwaff2); |
3629 | } |
3630 | |
3631 | /* Return an expression for the minimum (if "max" is not set) or |
3632 | * the maximum (if "max" is set) of "pa1" and "pa2". |
3633 | * If either expression involves any NaN, then return a NaN |
3634 | * on the shared domain as result. |
3635 | */ |
3636 | static __isl_give isl_pw_aff *pw_aff_min_max(__isl_take isl_pw_aff *pa1, |
3637 | __isl_take isl_pw_aff *pa2, int max) |
3638 | { |
3639 | isl_bool has_nan; |
3640 | |
3641 | has_nan = either_involves_nan(pa1, pa2); |
3642 | if (has_nan < 0) |
3643 | pa1 = isl_pw_aff_free(pa1); |
3644 | else if (has_nan) |
3645 | return replace_by_nan(pa1, pa2); |
3646 | |
3647 | if (max) |
3648 | return isl_pw_aff_align_params_pw_pw_and(pa1, pa2, &pw_aff_max); |
3649 | else |
3650 | return isl_pw_aff_align_params_pw_pw_and(pa1, pa2, &pw_aff_min); |
3651 | } |
3652 | |
3653 | /* Return an expression for the minimum of "pwaff1" and "pwaff2". |
3654 | */ |
3655 | __isl_give isl_pw_aff *isl_pw_aff_min(__isl_take isl_pw_aff *pwaff1, |
3656 | __isl_take isl_pw_aff *pwaff2) |
3657 | { |
3658 | return pw_aff_min_max(pwaff1, pwaff2, 0); |
3659 | } |
3660 | |
3661 | /* Return an expression for the maximum of "pwaff1" and "pwaff2". |
3662 | */ |
3663 | __isl_give isl_pw_aff *isl_pw_aff_max(__isl_take isl_pw_aff *pwaff1, |
3664 | __isl_take isl_pw_aff *pwaff2) |
3665 | { |
3666 | return pw_aff_min_max(pwaff1, pwaff2, 1); |
3667 | } |
3668 | |
3669 | static __isl_give isl_pw_aff *pw_aff_list_reduce( |
3670 | __isl_take isl_pw_aff_list *list, |
3671 | __isl_give isl_pw_aff *(*fn)(__isl_take isl_pw_aff *pwaff1, |
3672 | __isl_take isl_pw_aff *pwaff2)) |
3673 | { |
3674 | int i; |
3675 | isl_ctx *ctx; |
3676 | isl_pw_aff *res; |
3677 | |
3678 | if (!list) |
3679 | return NULL((void*)0); |
3680 | |
3681 | ctx = isl_pw_aff_list_get_ctx(list); |
3682 | if (list->n < 1) |
3683 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "list should contain at least one element" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3684); goto error; } while (0) |
3684 | "list should contain at least one element", goto error)do { isl_handle_error(ctx, isl_error_invalid, "list should contain at least one element" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3684); goto error; } while (0); |
3685 | |
3686 | res = isl_pw_aff_copy(list->p[0]); |
3687 | for (i = 1; i < list->n; ++i) |
3688 | res = fn(res, isl_pw_aff_copy(list->p[i])); |
3689 | |
3690 | isl_pw_aff_list_free(list); |
3691 | return res; |
3692 | error: |
3693 | isl_pw_aff_list_free(list); |
3694 | return NULL((void*)0); |
3695 | } |
3696 | |
3697 | /* Return an isl_pw_aff that maps each element in the intersection of the |
3698 | * domains of the elements of list to the minimal corresponding affine |
3699 | * expression. |
3700 | */ |
3701 | __isl_give isl_pw_aff *isl_pw_aff_list_min(__isl_take isl_pw_aff_list *list) |
3702 | { |
3703 | return pw_aff_list_reduce(list, &isl_pw_aff_min); |
3704 | } |
3705 | |
3706 | /* Return an isl_pw_aff that maps each element in the intersection of the |
3707 | * domains of the elements of list to the maximal corresponding affine |
3708 | * expression. |
3709 | */ |
3710 | __isl_give isl_pw_aff *isl_pw_aff_list_max(__isl_take isl_pw_aff_list *list) |
3711 | { |
3712 | return pw_aff_list_reduce(list, &isl_pw_aff_max); |
3713 | } |
3714 | |
3715 | /* Mark the domains of "pwaff" as rational. |
3716 | */ |
3717 | __isl_give isl_pw_aff *isl_pw_aff_set_rational(__isl_take isl_pw_aff *pwaff) |
3718 | { |
3719 | int i; |
3720 | |
3721 | pwaff = isl_pw_aff_cow(pwaff); |
3722 | if (!pwaff) |
3723 | return NULL((void*)0); |
3724 | if (pwaff->n == 0) |
3725 | return pwaff; |
3726 | |
3727 | for (i = 0; i < pwaff->n; ++i) { |
3728 | pwaff->p[i].set = isl_set_set_rational(pwaff->p[i].set); |
3729 | if (!pwaff->p[i].set) |
3730 | return isl_pw_aff_free(pwaff); |
3731 | } |
3732 | |
3733 | return pwaff; |
3734 | } |
3735 | |
3736 | /* Mark the domains of the elements of "list" as rational. |
3737 | */ |
3738 | __isl_give isl_pw_aff_list *isl_pw_aff_list_set_rational( |
3739 | __isl_take isl_pw_aff_list *list) |
3740 | { |
3741 | int i, n; |
3742 | |
3743 | if (!list) |
3744 | return NULL((void*)0); |
3745 | if (list->n == 0) |
3746 | return list; |
3747 | |
3748 | n = list->n; |
3749 | for (i = 0; i < n; ++i) { |
3750 | isl_pw_aff *pa; |
3751 | |
3752 | pa = isl_pw_aff_list_get_pw_aff(list, i); |
3753 | pa = isl_pw_aff_set_rational(pa); |
3754 | list = isl_pw_aff_list_set_pw_aff(list, i, pa); |
3755 | } |
3756 | |
3757 | return list; |
3758 | } |
3759 | |
3760 | /* Do the parameters of "aff" match those of "space"? |
3761 | */ |
3762 | isl_bool isl_aff_matching_params(__isl_keep isl_aff *aff, |
3763 | __isl_keep isl_space *space) |
3764 | { |
3765 | isl_space *aff_space; |
3766 | isl_bool match; |
3767 | |
3768 | if (!aff || !space) |
3769 | return isl_bool_error; |
3770 | |
3771 | aff_space = isl_aff_get_domain_space(aff); |
3772 | |
3773 | match = isl_space_has_equal_params(space, aff_space); |
3774 | |
3775 | isl_space_free(aff_space); |
3776 | return match; |
3777 | } |
3778 | |
3779 | /* Check that the domain space of "aff" matches "space". |
3780 | */ |
3781 | isl_stat isl_aff_check_match_domain_space(__isl_keep isl_aff *aff, |
3782 | __isl_keep isl_space *space) |
3783 | { |
3784 | isl_space *aff_space; |
3785 | isl_bool match; |
3786 | |
3787 | if (!aff || !space) |
3788 | return isl_stat_error; |
3789 | |
3790 | aff_space = isl_aff_get_domain_space(aff); |
3791 | |
3792 | match = isl_space_has_equal_params(space, aff_space); |
3793 | if (match < 0) |
3794 | goto error; |
3795 | if (!match) |
3796 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "parameters don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3797); goto error; } while (0) |
3797 | "parameters don't match", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "parameters don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3797); goto error; } while (0); |
3798 | match = isl_space_tuple_is_equal(space, isl_dim_in, |
3799 | aff_space, isl_dim_set); |
3800 | if (match < 0) |
3801 | goto error; |
3802 | if (!match) |
3803 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "domains don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3804); goto error; } while (0) |
3804 | "domains don't match", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "domains don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3804); goto error; } while (0); |
3805 | isl_space_free(aff_space); |
3806 | return isl_stat_ok; |
3807 | error: |
3808 | isl_space_free(aff_space); |
3809 | return isl_stat_error; |
3810 | } |
3811 | |
3812 | #undef BASEunion_pw_aff |
3813 | #define BASEunion_pw_aff aff |
3814 | #undef DOMBASEunion_set |
3815 | #define DOMBASEunion_set set |
3816 | #define NO_DOMAIN |
3817 | |
3818 | #include <isl_multi_no_explicit_domain.c> |
3819 | #include <isl_multi_templ.c> |
3820 | #include <isl_multi_apply_set.c> |
3821 | #include <isl_multi_cmp.c> |
3822 | #include <isl_multi_dims.c> |
3823 | #include <isl_multi_floor.c> |
3824 | #include <isl_multi_gist.c> |
3825 | |
3826 | #undef NO_DOMAIN |
3827 | |
3828 | /* Construct an isl_multi_aff living in "space" that corresponds |
3829 | * to the affine transformation matrix "mat". |
3830 | */ |
3831 | __isl_give isl_multi_aff *isl_multi_aff_from_aff_mat( |
3832 | __isl_take isl_space *space, __isl_take isl_mat *mat) |
3833 | { |
3834 | isl_ctx *ctx; |
3835 | isl_local_space *ls = NULL((void*)0); |
3836 | isl_multi_aff *ma = NULL((void*)0); |
3837 | int n_row, n_col, n_out, total; |
3838 | int i; |
3839 | |
3840 | if (!space || !mat) |
3841 | goto error; |
3842 | |
3843 | ctx = isl_mat_get_ctx(mat); |
3844 | |
3845 | n_row = isl_mat_rows(mat); |
3846 | n_col = isl_mat_cols(mat); |
3847 | if (n_row < 1) |
3848 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "insufficient number of rows" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3849); goto error; } while (0) |
3849 | "insufficient number of rows", goto error)do { isl_handle_error(ctx, isl_error_invalid, "insufficient number of rows" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3849); goto error; } while (0); |
3850 | if (n_col < 1) |
3851 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "insufficient number of columns" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3852); goto error; } while (0) |
3852 | "insufficient number of columns", goto error)do { isl_handle_error(ctx, isl_error_invalid, "insufficient number of columns" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3852); goto error; } while (0); |
3853 | n_out = isl_space_dim(space, isl_dim_out); |
3854 | total = isl_space_dim(space, isl_dim_all); |
3855 | if (1 + n_out != n_row || 2 + total != n_row + n_col) |
3856 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "dimension mismatch" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3857); goto error; } while (0) |
3857 | "dimension mismatch", goto error)do { isl_handle_error(ctx, isl_error_invalid, "dimension mismatch" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3857); goto error; } while (0); |
3858 | |
3859 | ma = isl_multi_aff_zero(isl_space_copy(space)); |
3860 | ls = isl_local_space_from_space(isl_space_domain(space)); |
3861 | |
3862 | for (i = 0; i < n_row - 1; ++i) { |
3863 | isl_vec *v; |
3864 | isl_aff *aff; |
3865 | |
3866 | v = isl_vec_alloc(ctx, 1 + n_col); |
3867 | if (!v) |
3868 | goto error; |
3869 | isl_int_set(v->el[0], mat->row[0][0])isl_sioimath_set((v->el[0]), *(mat->row[0][0])); |
3870 | isl_seq_cpy(v->el + 1, mat->row[1 + i], n_col); |
3871 | v = isl_vec_normalize(v); |
3872 | aff = isl_aff_alloc_vec(isl_local_space_copy(ls), v); |
3873 | ma = isl_multi_aff_set_aff(ma, i, aff); |
3874 | } |
3875 | |
3876 | isl_local_space_free(ls); |
3877 | isl_mat_free(mat); |
3878 | return ma; |
3879 | error: |
3880 | isl_local_space_free(ls); |
3881 | isl_mat_free(mat); |
3882 | isl_multi_aff_free(ma); |
3883 | return NULL((void*)0); |
3884 | } |
3885 | |
3886 | /* Remove any internal structure of the domain of "ma". |
3887 | * If there is any such internal structure in the input, |
3888 | * then the name of the corresponding space is also removed. |
3889 | */ |
3890 | __isl_give isl_multi_aff *isl_multi_aff_flatten_domain( |
3891 | __isl_take isl_multi_aff *ma) |
3892 | { |
3893 | isl_space *space; |
3894 | |
3895 | if (!ma) |
3896 | return NULL((void*)0); |
3897 | |
3898 | if (!ma->space->nested[0]) |
3899 | return ma; |
3900 | |
3901 | space = isl_multi_aff_get_space(ma); |
3902 | space = isl_space_flatten_domain(space); |
3903 | ma = isl_multi_aff_reset_space(ma, space); |
3904 | |
3905 | return ma; |
3906 | } |
3907 | |
3908 | /* Given a map space, return an isl_multi_aff that maps a wrapped copy |
3909 | * of the space to its domain. |
3910 | */ |
3911 | __isl_give isl_multi_aff *isl_multi_aff_domain_map(__isl_take isl_space *space) |
3912 | { |
3913 | int i, n_in; |
3914 | isl_local_space *ls; |
3915 | isl_multi_aff *ma; |
3916 | |
3917 | if (!space) |
3918 | return NULL((void*)0); |
3919 | if (!isl_space_is_map(space)) |
3920 | isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "not a map space", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3921); goto error; } while (0) |
3921 | "not a map space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "not a map space", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3921); goto error; } while (0); |
3922 | |
3923 | n_in = isl_space_dim(space, isl_dim_in); |
3924 | space = isl_space_domain_map(space); |
3925 | |
3926 | ma = isl_multi_aff_alloc(isl_space_copy(space)); |
3927 | if (n_in == 0) { |
3928 | isl_space_free(space); |
3929 | return ma; |
3930 | } |
3931 | |
3932 | space = isl_space_domain(space); |
3933 | ls = isl_local_space_from_space(space); |
3934 | for (i = 0; i < n_in; ++i) { |
3935 | isl_aff *aff; |
3936 | |
3937 | aff = isl_aff_var_on_domain(isl_local_space_copy(ls), |
3938 | isl_dim_set, i); |
3939 | ma = isl_multi_aff_set_aff(ma, i, aff); |
3940 | } |
3941 | isl_local_space_free(ls); |
3942 | return ma; |
3943 | error: |
3944 | isl_space_free(space); |
3945 | return NULL((void*)0); |
3946 | } |
3947 | |
3948 | /* Given a map space, return an isl_multi_aff that maps a wrapped copy |
3949 | * of the space to its range. |
3950 | */ |
3951 | __isl_give isl_multi_aff *isl_multi_aff_range_map(__isl_take isl_space *space) |
3952 | { |
3953 | int i, n_in, n_out; |
3954 | isl_local_space *ls; |
3955 | isl_multi_aff *ma; |
3956 | |
3957 | if (!space) |
3958 | return NULL((void*)0); |
3959 | if (!isl_space_is_map(space)) |
3960 | isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "not a map space", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3961); goto error; } while (0) |
3961 | "not a map space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "not a map space", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 3961); goto error; } while (0); |
3962 | |
3963 | n_in = isl_space_dim(space, isl_dim_in); |
3964 | n_out = isl_space_dim(space, isl_dim_out); |
3965 | space = isl_space_range_map(space); |
3966 | |
3967 | ma = isl_multi_aff_alloc(isl_space_copy(space)); |
3968 | if (n_out == 0) { |
3969 | isl_space_free(space); |
3970 | return ma; |
3971 | } |
3972 | |
3973 | space = isl_space_domain(space); |
3974 | ls = isl_local_space_from_space(space); |
3975 | for (i = 0; i < n_out; ++i) { |
3976 | isl_aff *aff; |
3977 | |
3978 | aff = isl_aff_var_on_domain(isl_local_space_copy(ls), |
3979 | isl_dim_set, n_in + i); |
3980 | ma = isl_multi_aff_set_aff(ma, i, aff); |
3981 | } |
3982 | isl_local_space_free(ls); |
3983 | return ma; |
3984 | error: |
3985 | isl_space_free(space); |
3986 | return NULL((void*)0); |
3987 | } |
3988 | |
3989 | /* Given a map space, return an isl_pw_multi_aff that maps a wrapped copy |
3990 | * of the space to its range. |
3991 | */ |
3992 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map( |
3993 | __isl_take isl_space *space) |
3994 | { |
3995 | return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_range_map(space)); |
3996 | } |
3997 | |
3998 | /* Given the space of a set and a range of set dimensions, |
3999 | * construct an isl_multi_aff that projects out those dimensions. |
4000 | */ |
4001 | __isl_give isl_multi_aff *isl_multi_aff_project_out_map( |
4002 | __isl_take isl_space *space, enum isl_dim_type type, |
4003 | unsigned first, unsigned n) |
4004 | { |
4005 | int i, dim; |
4006 | isl_local_space *ls; |
4007 | isl_multi_aff *ma; |
4008 | |
4009 | if (!space) |
4010 | return NULL((void*)0); |
4011 | if (!isl_space_is_set(space)) |
4012 | isl_die(isl_space_get_ctx(space), isl_error_unsupported,do { isl_handle_error(isl_space_get_ctx(space), isl_error_unsupported , "expecting set space", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 4013); goto error; } while (0) |
4013 | "expecting set space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_unsupported , "expecting set space", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 4013); goto error; } while (0); |
4014 | if (type != isl_dim_set) |
4015 | isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "only set dimensions can be projected out", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 4016); goto error; } while (0) |
4016 | "only set dimensions can be projected out", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "only set dimensions can be projected out", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 4016); goto error; } while (0); |
4017 | |
4018 | dim = isl_space_dim(space, isl_dim_set); |
4019 | if (first + n > dim) |
4020 | isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "range out of bounds", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 4021); goto error; } while (0) |
4021 | "range out of bounds", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "range out of bounds", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 4021); goto error; } while (0); |
4022 | |
4023 | space = isl_space_from_domain(space); |
4024 | space = isl_space_add_dims(space, isl_dim_out, dim - n); |
4025 | |
4026 | if (dim == n) |
4027 | return isl_multi_aff_alloc(space); |
4028 | |
4029 | ma = isl_multi_aff_alloc(isl_space_copy(space)); |
4030 | space = isl_space_domain(space); |
4031 | ls = isl_local_space_from_space(space); |
4032 | |
4033 | for (i = 0; i < first; ++i) { |
4034 | isl_aff *aff; |
4035 | |
4036 | aff = isl_aff_var_on_domain(isl_local_space_copy(ls), |
4037 | isl_dim_set, i); |
4038 | ma = isl_multi_aff_set_aff(ma, i, aff); |
4039 | } |
4040 | |
4041 | for (i = 0; i < dim - (first + n); ++i) { |
4042 | isl_aff *aff; |
4043 | |
4044 | aff = isl_aff_var_on_domain(isl_local_space_copy(ls), |
4045 | isl_dim_set, first + n + i); |
4046 | ma = isl_multi_aff_set_aff(ma, first + i, aff); |
4047 | } |
4048 | |
4049 | isl_local_space_free(ls); |
4050 | return ma; |
4051 | error: |
4052 | isl_space_free(space); |
4053 | return NULL((void*)0); |
4054 | } |
4055 | |
4056 | /* Given the space of a set and a range of set dimensions, |
4057 | * construct an isl_pw_multi_aff that projects out those dimensions. |
4058 | */ |
4059 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_out_map( |
4060 | __isl_take isl_space *space, enum isl_dim_type type, |
4061 | unsigned first, unsigned n) |
4062 | { |
4063 | isl_multi_aff *ma; |
4064 | |
4065 | ma = isl_multi_aff_project_out_map(space, type, first, n); |
4066 | return isl_pw_multi_aff_from_multi_aff(ma); |
4067 | } |
4068 | |
4069 | /* Create an isl_pw_multi_aff with the given isl_multi_aff on a universe |
4070 | * domain. |
4071 | */ |
4072 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_aff( |
4073 | __isl_take isl_multi_aff *ma) |
4074 | { |
4075 | isl_setisl_map *dom = isl_set_universe(isl_multi_aff_get_domain_space(ma)); |
4076 | return isl_pw_multi_aff_alloc(dom, ma); |
4077 | } |
4078 | |
4079 | /* Create a piecewise multi-affine expression in the given space that maps each |
4080 | * input dimension to the corresponding output dimension. |
4081 | */ |
4082 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity( |
4083 | __isl_take isl_space *space) |
4084 | { |
4085 | return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_identity(space)); |
4086 | } |
4087 | |
4088 | /* Exploit the equalities in "eq" to simplify the affine expressions. |
4089 | */ |
4090 | static __isl_give isl_multi_aff *isl_multi_aff_substitute_equalities( |
4091 | __isl_take isl_multi_aff *maff, __isl_take isl_basic_setisl_basic_map *eq) |
4092 | { |
4093 | int i; |
4094 | |
4095 | maff = isl_multi_aff_cow(maff); |
4096 | if (!maff || !eq) |
4097 | goto error; |
4098 | |
4099 | for (i = 0; i < maff->n; ++i) { |
4100 | maff->u.p[i] = isl_aff_substitute_equalities(maff->u.p[i], |
4101 | isl_basic_set_copy(eq)); |
4102 | if (!maff->u.p[i]) |
4103 | goto error; |
4104 | } |
4105 | |
4106 | isl_basic_set_free(eq); |
4107 | return maff; |
4108 | error: |
4109 | isl_basic_set_free(eq); |
4110 | isl_multi_aff_free(maff); |
4111 | return NULL((void*)0); |
4112 | } |
4113 | |
4114 | __isl_give isl_multi_aff *isl_multi_aff_scale(__isl_take isl_multi_aff *maff, |
4115 | isl_int f) |
4116 | { |
4117 | int i; |
4118 | |
4119 | maff = isl_multi_aff_cow(maff); |
4120 | if (!maff) |
4121 | return NULL((void*)0); |
4122 | |
4123 | for (i = 0; i < maff->n; ++i) { |
4124 | maff->u.p[i] = isl_aff_scale(maff->u.p[i], f); |
4125 | if (!maff->u.p[i]) |
4126 | return isl_multi_aff_free(maff); |
4127 | } |
4128 | |
4129 | return maff; |
4130 | } |
4131 | |
4132 | __isl_give isl_multi_aff *isl_multi_aff_add_on_domain(__isl_keep isl_setisl_map *dom, |
4133 | __isl_take isl_multi_aff *maff1, __isl_take isl_multi_aff *maff2) |
4134 | { |
4135 | maff1 = isl_multi_aff_add(maff1, maff2); |
4136 | maff1 = isl_multi_aff_gist(maff1, isl_set_copy(dom)); |
4137 | return maff1; |
4138 | } |
4139 | |
4140 | int isl_multi_aff_is_empty(__isl_keep isl_multi_aff *maff) |
4141 | { |
4142 | if (!maff) |
4143 | return -1; |
4144 | |
4145 | return 0; |
4146 | } |
4147 | |
4148 | /* Return the set of domain elements where "ma1" is lexicographically |
4149 | * smaller than or equal to "ma2". |
4150 | */ |
4151 | __isl_give isl_setisl_map *isl_multi_aff_lex_le_set(__isl_take isl_multi_aff *ma1, |
4152 | __isl_take isl_multi_aff *ma2) |
4153 | { |
4154 | return isl_multi_aff_lex_ge_set(ma2, ma1); |
4155 | } |
4156 | |
4157 | /* Return the set of domain elements where "ma1" is lexicographically |
4158 | * smaller than "ma2". |
4159 | */ |
4160 | __isl_give isl_setisl_map *isl_multi_aff_lex_lt_set(__isl_take isl_multi_aff *ma1, |
4161 | __isl_take isl_multi_aff *ma2) |
4162 | { |
4163 | return isl_multi_aff_lex_gt_set(ma2, ma1); |
4164 | } |
4165 | |
4166 | /* Return the set of domain elements where "ma1" and "ma2" |
4167 | * satisfy "order". |
4168 | */ |
4169 | static __isl_give isl_setisl_map *isl_multi_aff_order_set( |
4170 | __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2, |
4171 | __isl_give isl_map *order(__isl_take isl_space *set_space)) |
4172 | { |
4173 | isl_space *space; |
4174 | isl_map *map1, *map2; |
4175 | isl_map *map, *ge; |
4176 | |
4177 | map1 = isl_map_from_multi_aff_internal(ma1); |
4178 | map2 = isl_map_from_multi_aff_internal(ma2); |
4179 | map = isl_map_range_product(map1, map2); |
4180 | space = isl_space_range(isl_map_get_space(map)); |
4181 | space = isl_space_domain(isl_space_unwrap(space)); |
4182 | ge = order(space); |
4183 | map = isl_map_intersect_range(map, isl_map_wrap(ge)); |
4184 | |
4185 | return isl_map_domain(map); |
4186 | } |
4187 | |
4188 | /* Return the set of domain elements where "ma1" is lexicographically |
4189 | * greater than or equal to "ma2". |
4190 | */ |
4191 | __isl_give isl_setisl_map *isl_multi_aff_lex_ge_set(__isl_take isl_multi_aff *ma1, |
4192 | __isl_take isl_multi_aff *ma2) |
4193 | { |
4194 | return isl_multi_aff_order_set(ma1, ma2, &isl_map_lex_ge); |
4195 | } |
4196 | |
4197 | /* Return the set of domain elements where "ma1" is lexicographically |
4198 | * greater than "ma2". |
4199 | */ |
4200 | __isl_give isl_setisl_map *isl_multi_aff_lex_gt_set(__isl_take isl_multi_aff *ma1, |
4201 | __isl_take isl_multi_aff *ma2) |
4202 | { |
4203 | return isl_multi_aff_order_set(ma1, ma2, &isl_map_lex_gt); |
4204 | } |
4205 | |
4206 | #undef PWisl_pw_multi_aff |
4207 | #define PWisl_pw_multi_aff isl_pw_multi_aff |
4208 | #undef ELisl_union_pw_aff |
4209 | #define ELisl_union_pw_aff isl_multi_aff |
4210 | #undef EL_IS_ZEROis_empty |
4211 | #define EL_IS_ZEROis_empty is_empty |
4212 | #undef ZEROempty |
4213 | #define ZEROempty empty |
4214 | #undef IS_ZEROis_empty |
4215 | #define IS_ZEROis_empty is_empty |
4216 | #undef FIELDmaff |
4217 | #define FIELDmaff maff |
4218 | #undef DEFAULT_IS_ZERO0 |
4219 | #define DEFAULT_IS_ZERO0 0 |
4220 | |
4221 | #define NO_SUB |
4222 | #define NO_OPT |
4223 | #define NO_INSERT_DIMS |
4224 | #define NO_LIFT |
4225 | #define NO_MORPH |
4226 | |
4227 | #include <isl_pw_templ.c> |
4228 | #include <isl_pw_union_opt.c> |
4229 | |
4230 | #undef NO_SUB |
4231 | |
4232 | #undef BASEunion_pw_aff |
4233 | #define BASEunion_pw_aff pw_multi_aff |
4234 | |
4235 | #include <isl_union_multi.c> |
4236 | #include <isl_union_neg.c> |
4237 | |
4238 | static __isl_give isl_pw_multi_aff *pw_multi_aff_union_lexmax( |
4239 | __isl_take isl_pw_multi_aff *pma1, |
4240 | __isl_take isl_pw_multi_aff *pma2) |
4241 | { |
4242 | return isl_pw_multi_aff_union_opt_cmp(pma1, pma2, |
4243 | &isl_multi_aff_lex_ge_set); |
4244 | } |
4245 | |
4246 | /* Given two piecewise multi affine expressions, return a piecewise |
4247 | * multi-affine expression defined on the union of the definition domains |
4248 | * of the inputs that is equal to the lexicographic maximum of the two |
4249 | * inputs on each cell. If only one of the two inputs is defined on |
4250 | * a given cell, then it is considered to be the maximum. |
4251 | */ |
4252 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmax( |
4253 | __isl_take isl_pw_multi_aff *pma1, |
4254 | __isl_take isl_pw_multi_aff *pma2) |
4255 | { |
4256 | return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2, |
4257 | &pw_multi_aff_union_lexmax); |
4258 | } |
4259 | |
4260 | static __isl_give isl_pw_multi_aff *pw_multi_aff_union_lexmin( |
4261 | __isl_take isl_pw_multi_aff *pma1, |
4262 | __isl_take isl_pw_multi_aff *pma2) |
4263 | { |
4264 | return isl_pw_multi_aff_union_opt_cmp(pma1, pma2, |
4265 | &isl_multi_aff_lex_le_set); |
4266 | } |
4267 | |
4268 | /* Given two piecewise multi affine expressions, return a piecewise |
4269 | * multi-affine expression defined on the union of the definition domains |
4270 | * of the inputs that is equal to the lexicographic minimum of the two |
4271 | * inputs on each cell. If only one of the two inputs is defined on |
4272 | * a given cell, then it is considered to be the minimum. |
4273 | */ |
4274 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmin( |
4275 | __isl_take isl_pw_multi_aff *pma1, |
4276 | __isl_take isl_pw_multi_aff *pma2) |
4277 | { |
4278 | return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2, |
4279 | &pw_multi_aff_union_lexmin); |
4280 | } |
4281 | |
4282 | static __isl_give isl_pw_multi_aff *pw_multi_aff_add( |
4283 | __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2) |
4284 | { |
4285 | return isl_pw_multi_aff_on_shared_domain(pma1, pma2, |
4286 | &isl_multi_aff_add); |
4287 | } |
4288 | |
4289 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_add( |
4290 | __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2) |
4291 | { |
4292 | return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2, |
4293 | &pw_multi_aff_add); |
4294 | } |
4295 | |
4296 | static __isl_give isl_pw_multi_aff *pw_multi_aff_sub( |
4297 | __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2) |
4298 | { |
4299 | return isl_pw_multi_aff_on_shared_domain(pma1, pma2, |
4300 | &isl_multi_aff_sub); |
4301 | } |
4302 | |
4303 | /* Subtract "pma2" from "pma1" and return the result. |
4304 | */ |
4305 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_sub( |
4306 | __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2) |
4307 | { |
4308 | return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2, |
4309 | &pw_multi_aff_sub); |
4310 | } |
4311 | |
4312 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_add( |
4313 | __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2) |
4314 | { |
4315 | return isl_pw_multi_aff_union_add_(pma1, pma2); |
4316 | } |
4317 | |
4318 | /* Compute the sum of "upa1" and "upa2" on the union of their domains, |
4319 | * with the actual sum on the shared domain and |
4320 | * the defined expression on the symmetric difference of the domains. |
4321 | */ |
4322 | __isl_give isl_union_pw_aff *isl_union_pw_aff_union_add( |
4323 | __isl_take isl_union_pw_aff *upa1, __isl_take isl_union_pw_aff *upa2) |
4324 | { |
4325 | return isl_union_pw_aff_union_add_(upa1, upa2); |
4326 | } |
4327 | |
4328 | /* Compute the sum of "upma1" and "upma2" on the union of their domains, |
4329 | * with the actual sum on the shared domain and |
4330 | * the defined expression on the symmetric difference of the domains. |
4331 | */ |
4332 | __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_union_add( |
4333 | __isl_take isl_union_pw_multi_aff *upma1, |
4334 | __isl_take isl_union_pw_multi_aff *upma2) |
4335 | { |
4336 | return isl_union_pw_multi_aff_union_add_(upma1, upma2); |
4337 | } |
4338 | |
4339 | /* Given two piecewise multi-affine expressions A -> B and C -> D, |
4340 | * construct a piecewise multi-affine expression [A -> C] -> [B -> D]. |
4341 | */ |
4342 | static __isl_give isl_pw_multi_aff *pw_multi_aff_product( |
4343 | __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2) |
4344 | { |
4345 | int i, j, n; |
4346 | isl_space *space; |
4347 | isl_pw_multi_aff *res; |
4348 | |
4349 | if (!pma1 || !pma2) |
4350 | goto error; |
4351 | |
4352 | n = pma1->n * pma2->n; |
4353 | space = isl_space_product(isl_space_copy(pma1->dim), |
4354 | isl_space_copy(pma2->dim)); |
4355 | res = isl_pw_multi_aff_alloc_size(space, n); |
4356 | |
4357 | for (i = 0; i < pma1->n; ++i) { |
4358 | for (j = 0; j < pma2->n; ++j) { |
4359 | isl_setisl_map *domain; |
4360 | isl_multi_aff *ma; |
4361 | |
4362 | domain = isl_set_product(isl_set_copy(pma1->p[i].set), |
4363 | isl_set_copy(pma2->p[j].set)); |
4364 | ma = isl_multi_aff_product( |
4365 | isl_multi_aff_copy(pma1->p[i].maff), |
4366 | isl_multi_aff_copy(pma2->p[j].maff)); |
4367 | res = isl_pw_multi_aff_add_piece(res, domain, ma); |
4368 | } |
4369 | } |
4370 | |
4371 | isl_pw_multi_aff_free(pma1); |
4372 | isl_pw_multi_aff_free(pma2); |
4373 | return res; |
4374 | error: |
4375 | isl_pw_multi_aff_free(pma1); |
4376 | isl_pw_multi_aff_free(pma2); |
4377 | return NULL((void*)0); |
4378 | } |
4379 | |
4380 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_product( |
4381 | __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2) |
4382 | { |
4383 | return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2, |
4384 | &pw_multi_aff_product); |
4385 | } |
4386 | |
4387 | /* Subtract the initial "n" elements in "ma" with coefficients in "c" and |
4388 | * denominator "denom". |
4389 | * "denom" is allowed to be negative, in which case the actual denominator |
4390 | * is -denom and the expressions are added instead. |
4391 | */ |
4392 | static __isl_give isl_aff *subtract_initial(__isl_take isl_aff *aff, |
4393 | __isl_keep isl_multi_aff *ma, int n, isl_int *c, isl_int denom) |
4394 | { |
4395 | int i, first; |
4396 | int sign; |
4397 | isl_int d; |
4398 | |
4399 | first = isl_seq_first_non_zero(c, n); |
4400 | if (first == -1) |
4401 | return aff; |
4402 | |
4403 | sign = isl_int_sgn(denom)isl_sioimath_sgn(*(denom)); |
4404 | isl_int_init(d)isl_sioimath_init((d)); |
4405 | isl_int_abs(d, denom)isl_sioimath_abs((d), *(denom)); |
4406 | for (i = first; i < n; ++i) { |
4407 | isl_aff *aff_i; |
4408 | |
4409 | if (isl_int_is_zero(c[i])(isl_sioimath_sgn(*(c[i])) == 0)) |
4410 | continue; |
4411 | aff_i = isl_multi_aff_get_aff(ma, i); |
4412 | aff_i = isl_aff_scale(aff_i, c[i]); |
4413 | aff_i = isl_aff_scale_down(aff_i, d); |
4414 | if (sign >= 0) |
4415 | aff = isl_aff_sub(aff, aff_i); |
4416 | else |
4417 | aff = isl_aff_add(aff, aff_i); |
4418 | } |
4419 | isl_int_clear(d)isl_sioimath_clear((d)); |
4420 | |
4421 | return aff; |
4422 | } |
4423 | |
4424 | /* Extract an affine expression that expresses the output dimension "pos" |
4425 | * of "bmap" in terms of the parameters and input dimensions from |
4426 | * equality "eq". |
4427 | * Note that this expression may involve integer divisions defined |
4428 | * in terms of parameters and input dimensions. |
4429 | * The equality may also involve references to earlier (but not later) |
4430 | * output dimensions. These are replaced by the corresponding elements |
4431 | * in "ma". |
4432 | * |
4433 | * If the equality is of the form |
4434 | * |
4435 | * f(i) + h(j) + a x + g(i) = 0, |
4436 | * |
4437 | * with f(i) a linear combinations of the parameters and input dimensions, |
4438 | * g(i) a linear combination of integer divisions defined in terms of the same |
4439 | * and h(j) a linear combinations of earlier output dimensions, |
4440 | * then the affine expression is |
4441 | * |
4442 | * (-f(i) - g(i))/a - h(j)/a |
4443 | * |
4444 | * If the equality is of the form |
4445 | * |
4446 | * f(i) + h(j) - a x + g(i) = 0, |
4447 | * |
4448 | * then the affine expression is |
4449 | * |
4450 | * (f(i) + g(i))/a - h(j)/(-a) |
4451 | * |
4452 | * |
4453 | * If "div" refers to an integer division (i.e., it is smaller than |
4454 | * the number of integer divisions), then the equality constraint |
4455 | * does involve an integer division (the one at position "div") that |
4456 | * is defined in terms of output dimensions. However, this integer |
4457 | * division can be eliminated by exploiting a pair of constraints |
4458 | * x >= l and x <= l + n, with n smaller than the coefficient of "div" |
4459 | * in the equality constraint. "ineq" refers to inequality x >= l, i.e., |
4460 | * -l + x >= 0. |
4461 | * In particular, let |
4462 | * |
4463 | * x = e(i) + m floor(...) |
4464 | * |
4465 | * with e(i) the expression derived above and floor(...) the integer |
4466 | * division involving output dimensions. |
4467 | * From |
4468 | * |
4469 | * l <= x <= l + n, |
4470 | * |
4471 | * we have |
4472 | * |
4473 | * 0 <= x - l <= n |
4474 | * |
4475 | * This means |
4476 | * |
4477 | * e(i) + m floor(...) - l = (e(i) + m floor(...) - l) mod m |
4478 | * = (e(i) - l) mod m |
4479 | * |
4480 | * Therefore, |
4481 | * |
4482 | * x - l = (e(i) - l) mod m |
4483 | * |
4484 | * or |
4485 | * |
4486 | * x = ((e(i) - l) mod m) + l |
4487 | * |
4488 | * The variable "shift" below contains the expression -l, which may |
4489 | * also involve a linear combination of earlier output dimensions. |
4490 | */ |
4491 | static __isl_give isl_aff *extract_aff_from_equality( |
4492 | __isl_keep isl_basic_map *bmap, int pos, int eq, int div, int ineq, |
4493 | __isl_keep isl_multi_aff *ma) |
4494 | { |
4495 | unsigned o_out; |
4496 | unsigned n_div, n_out; |
4497 | isl_ctx *ctx; |
4498 | isl_local_space *ls; |
4499 | isl_aff *aff, *shift; |
4500 | isl_val *mod; |
4501 | |
4502 | ctx = isl_basic_map_get_ctx(bmap); |
4503 | ls = isl_basic_map_get_local_space(bmap); |
4504 | ls = isl_local_space_domain(ls); |
4505 | aff = isl_aff_alloc(isl_local_space_copy(ls)); |
4506 | if (!aff) |
4507 | goto error; |
4508 | o_out = isl_basic_map_offset(bmap, isl_dim_out); |
4509 | n_out = isl_basic_map_dim(bmap, isl_dim_out); |
4510 | n_div = isl_basic_map_dim(bmap, isl_dim_div); |
4511 | if (isl_int_is_neg(bmap->eq[eq][o_out + pos])(isl_sioimath_sgn(*(bmap->eq[eq][o_out + pos])) < 0)) { |
4512 | isl_seq_cpy(aff->v->el + 1, bmap->eq[eq], o_out); |
4513 | isl_seq_cpy(aff->v->el + 1 + o_out, |
4514 | bmap->eq[eq] + o_out + n_out, n_div); |
4515 | } else { |
4516 | isl_seq_neg(aff->v->el + 1, bmap->eq[eq], o_out); |
4517 | isl_seq_neg(aff->v->el + 1 + o_out, |
4518 | bmap->eq[eq] + o_out + n_out, n_div); |
4519 | } |
4520 | if (div < n_div) |
4521 | isl_int_set_si(aff->v->el[1 + o_out + div], 0)isl_sioimath_set_si((aff->v->el[1 + o_out + div]), 0); |
4522 | isl_int_abs(aff->v->el[0], bmap->eq[eq][o_out + pos])isl_sioimath_abs((aff->v->el[0]), *(bmap->eq[eq][o_out + pos])); |
4523 | aff = subtract_initial(aff, ma, pos, bmap->eq[eq] + o_out, |
4524 | bmap->eq[eq][o_out + pos]); |
4525 | if (div < n_div) { |
4526 | shift = isl_aff_alloc(isl_local_space_copy(ls)); |
4527 | if (!shift) |
4528 | goto error; |
4529 | isl_seq_cpy(shift->v->el + 1, bmap->ineq[ineq], o_out); |
4530 | isl_seq_cpy(shift->v->el + 1 + o_out, |
4531 | bmap->ineq[ineq] + o_out + n_out, n_div); |
4532 | isl_int_set_si(shift->v->el[0], 1)isl_sioimath_set_si((shift->v->el[0]), 1); |
4533 | shift = subtract_initial(shift, ma, pos, |
4534 | bmap->ineq[ineq] + o_out, ctx->negone); |
4535 | aff = isl_aff_add(aff, isl_aff_copy(shift)); |
4536 | mod = isl_val_int_from_isl_int(ctx, |
4537 | bmap->eq[eq][o_out + n_out + div]); |
4538 | mod = isl_val_abs(mod); |
4539 | aff = isl_aff_mod_val(aff, mod); |
4540 | aff = isl_aff_sub(aff, shift); |
4541 | } |
4542 | |
4543 | isl_local_space_free(ls); |
4544 | return aff; |
4545 | error: |
4546 | isl_local_space_free(ls); |
4547 | isl_aff_free(aff); |
4548 | return NULL((void*)0); |
4549 | } |
4550 | |
4551 | /* Given a basic map with output dimensions defined |
4552 | * in terms of the parameters input dimensions and earlier |
4553 | * output dimensions using an equality (and possibly a pair on inequalities), |
4554 | * extract an isl_aff that expresses output dimension "pos" in terms |
4555 | * of the parameters and input dimensions. |
4556 | * Note that this expression may involve integer divisions defined |
4557 | * in terms of parameters and input dimensions. |
4558 | * "ma" contains the expressions corresponding to earlier output dimensions. |
4559 | * |
4560 | * This function shares some similarities with |
4561 | * isl_basic_map_has_defining_equality and isl_constraint_get_bound. |
4562 | */ |
4563 | static __isl_give isl_aff *extract_isl_aff_from_basic_map( |
4564 | __isl_keep isl_basic_map *bmap, int pos, __isl_keep isl_multi_aff *ma) |
4565 | { |
4566 | int eq, div, ineq; |
4567 | isl_aff *aff; |
4568 | |
4569 | if (!bmap) |
4570 | return NULL((void*)0); |
4571 | eq = isl_basic_map_output_defining_equality(bmap, pos, &div, &ineq); |
4572 | if (eq >= bmap->n_eq) |
4573 | isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid , "unable to find suitable equality", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 4574); return ((void*)0); } while (0) |
4574 | "unable to find suitable equality", return NULL)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid , "unable to find suitable equality", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 4574); return ((void*)0); } while (0); |
4575 | aff = extract_aff_from_equality(bmap, pos, eq, div, ineq, ma); |
4576 | |
4577 | aff = isl_aff_remove_unused_divs(aff); |
4578 | return aff; |
4579 | } |
4580 | |
4581 | /* Given a basic map where each output dimension is defined |
4582 | * in terms of the parameters and input dimensions using an equality, |
4583 | * extract an isl_multi_aff that expresses the output dimensions in terms |
4584 | * of the parameters and input dimensions. |
4585 | */ |
4586 | static __isl_give isl_multi_aff *extract_isl_multi_aff_from_basic_map( |
4587 | __isl_take isl_basic_map *bmap) |
4588 | { |
4589 | int i; |
4590 | unsigned n_out; |
4591 | isl_multi_aff *ma; |
4592 | |
4593 | if (!bmap) |
4594 | return NULL((void*)0); |
4595 | |
4596 | ma = isl_multi_aff_alloc(isl_basic_map_get_space(bmap)); |
4597 | n_out = isl_basic_map_dim(bmap, isl_dim_out); |
4598 | |
4599 | for (i = 0; i < n_out; ++i) { |
4600 | isl_aff *aff; |
4601 | |
4602 | aff = extract_isl_aff_from_basic_map(bmap, i, ma); |
4603 | ma = isl_multi_aff_set_aff(ma, i, aff); |
4604 | } |
4605 | |
4606 | isl_basic_map_free(bmap); |
4607 | |
4608 | return ma; |
4609 | } |
4610 | |
4611 | /* Given a basic set where each set dimension is defined |
4612 | * in terms of the parameters using an equality, |
4613 | * extract an isl_multi_aff that expresses the set dimensions in terms |
4614 | * of the parameters. |
4615 | */ |
4616 | __isl_give isl_multi_aff *isl_multi_aff_from_basic_set_equalities( |
4617 | __isl_take isl_basic_setisl_basic_map *bset) |
4618 | { |
4619 | return extract_isl_multi_aff_from_basic_map(bset); |
4620 | } |
4621 | |
4622 | /* Create an isl_pw_multi_aff that is equivalent to |
4623 | * isl_map_intersect_domain(isl_map_from_basic_map(bmap), domain). |
4624 | * The given basic map is such that each output dimension is defined |
4625 | * in terms of the parameters and input dimensions using an equality. |
4626 | * |
4627 | * Since some applications expect the result of isl_pw_multi_aff_from_map |
4628 | * to only contain integer affine expressions, we compute the floor |
4629 | * of the expression before returning. |
4630 | * |
4631 | * Remove all constraints involving local variables without |
4632 | * an explicit representation (resulting in the removal of those |
4633 | * local variables) prior to the actual extraction to ensure |
4634 | * that the local spaces in which the resulting affine expressions |
4635 | * are created do not contain any unknown local variables. |
4636 | * Removing such constraints is safe because constraints involving |
4637 | * unknown local variables are not used to determine whether |
4638 | * a basic map is obviously single-valued. |
4639 | */ |
4640 | static __isl_give isl_pw_multi_aff *plain_pw_multi_aff_from_map( |
4641 | __isl_take isl_setisl_map *domain, __isl_take isl_basic_map *bmap) |
4642 | { |
4643 | isl_multi_aff *ma; |
4644 | |
4645 | bmap = isl_basic_map_drop_constraint_involving_unknown_divs(bmap); |
4646 | ma = extract_isl_multi_aff_from_basic_map(bmap); |
4647 | ma = isl_multi_aff_floor(ma); |
4648 | return isl_pw_multi_aff_alloc(domain, ma); |
4649 | } |
4650 | |
4651 | /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map. |
4652 | * This obviously only works if the input "map" is single-valued. |
4653 | * If so, we compute the lexicographic minimum of the image in the form |
4654 | * of an isl_pw_multi_aff. Since the image is unique, it is equal |
4655 | * to its lexicographic minimum. |
4656 | * If the input is not single-valued, we produce an error. |
4657 | */ |
4658 | static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_base( |
4659 | __isl_take isl_map *map) |
4660 | { |
4661 | int i; |
4662 | int sv; |
4663 | isl_pw_multi_aff *pma; |
4664 | |
4665 | sv = isl_map_is_single_valued(map); |
4666 | if (sv < 0) |
4667 | goto error; |
4668 | if (!sv) |
4669 | isl_die(isl_map_get_ctx(map), isl_error_invalid,do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid , "map is not single-valued", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 4670); goto error; } while (0) |
4670 | "map is not single-valued", goto error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid , "map is not single-valued", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 4670); goto error; } while (0); |
4671 | map = isl_map_make_disjoint(map); |
4672 | if (!map) |
4673 | return NULL((void*)0); |
4674 | |
4675 | pma = isl_pw_multi_aff_empty(isl_map_get_space(map)); |
4676 | |
4677 | for (i = 0; i < map->n; ++i) { |
4678 | isl_pw_multi_aff *pma_i; |
4679 | isl_basic_map *bmap; |
4680 | bmap = isl_basic_map_copy(map->p[i]); |
4681 | pma_i = isl_basic_map_lexmin_pw_multi_aff(bmap); |
4682 | pma = isl_pw_multi_aff_add_disjoint(pma, pma_i); |
4683 | } |
4684 | |
4685 | isl_map_free(map); |
4686 | return pma; |
4687 | error: |
4688 | isl_map_free(map); |
4689 | return NULL((void*)0); |
4690 | } |
4691 | |
4692 | /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map, |
4693 | * taking into account that the output dimension at position "d" |
4694 | * can be represented as |
4695 | * |
4696 | * x = floor((e(...) + c1) / m) |
4697 | * |
4698 | * given that constraint "i" is of the form |
4699 | * |
4700 | * e(...) + c1 - m x >= 0 |
4701 | * |
4702 | * |
4703 | * Let "map" be of the form |
4704 | * |
4705 | * A -> B |
4706 | * |
4707 | * We construct a mapping |
4708 | * |
4709 | * A -> [A -> x = floor(...)] |
4710 | * |
4711 | * apply that to the map, obtaining |
4712 | * |
4713 | * [A -> x = floor(...)] -> B |
4714 | * |
4715 | * and equate dimension "d" to x. |
4716 | * We then compute a isl_pw_multi_aff representation of the resulting map |
4717 | * and plug in the mapping above. |
4718 | */ |
4719 | static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_div( |
4720 | __isl_take isl_map *map, __isl_take isl_basic_map *hull, int d, int i) |
4721 | { |
4722 | isl_ctx *ctx; |
4723 | isl_space *space; |
4724 | isl_local_space *ls; |
4725 | isl_multi_aff *ma; |
4726 | isl_aff *aff; |
4727 | isl_vec *v; |
4728 | isl_map *insert; |
4729 | int offset; |
4730 | int n; |
4731 | int n_in; |
4732 | isl_pw_multi_aff *pma; |
4733 | isl_bool is_set; |
4734 | |
4735 | is_set = isl_map_is_set(map); |
4736 | if (is_set < 0) |
4737 | goto error; |
4738 | |
4739 | offset = isl_basic_map_offset(hull, isl_dim_out); |
4740 | ctx = isl_map_get_ctx(map); |
4741 | space = isl_space_domain(isl_map_get_space(map)); |
4742 | n_in = isl_space_dim(space, isl_dim_set); |
4743 | n = isl_space_dim(space, isl_dim_all); |
4744 | |
4745 | v = isl_vec_alloc(ctx, 1 + 1 + n); |
4746 | if (v) { |
4747 | isl_int_neg(v->el[0], hull->ineq[i][offset + d])isl_sioimath_neg((v->el[0]), *(hull->ineq[i][offset + d ])); |
4748 | isl_seq_cpy(v->el + 1, hull->ineq[i], 1 + n); |
4749 | } |
4750 | isl_basic_map_free(hull); |
4751 | |
4752 | ls = isl_local_space_from_space(isl_space_copy(space)); |
4753 | aff = isl_aff_alloc_vec(ls, v); |
4754 | aff = isl_aff_floor(aff); |
4755 | if (is_set) { |
4756 | isl_space_free(space); |
4757 | ma = isl_multi_aff_from_aff(aff); |
4758 | } else { |
4759 | ma = isl_multi_aff_identity(isl_space_map_from_set(space)); |
4760 | ma = isl_multi_aff_range_product(ma, |
4761 | isl_multi_aff_from_aff(aff)); |
4762 | } |
4763 | |
4764 | insert = isl_map_from_multi_aff_internal(isl_multi_aff_copy(ma)); |
4765 | map = isl_map_apply_domain(map, insert); |
4766 | map = isl_map_equate(map, isl_dim_in, n_in, isl_dim_out, d); |
4767 | pma = isl_pw_multi_aff_from_map(map); |
4768 | pma = isl_pw_multi_aff_pullback_multi_aff(pma, ma); |
4769 | |
4770 | return pma; |
4771 | error: |
4772 | isl_map_free(map); |
4773 | isl_basic_map_free(hull); |
4774 | return NULL((void*)0); |
4775 | } |
4776 | |
4777 | /* Is constraint "c" of the form |
4778 | * |
4779 | * e(...) + c1 - m x >= 0 |
4780 | * |
4781 | * or |
4782 | * |
4783 | * -e(...) + c2 + m x >= 0 |
4784 | * |
4785 | * where m > 1 and e only depends on parameters and input dimemnsions? |
4786 | * |
4787 | * "offset" is the offset of the output dimensions |
4788 | * "pos" is the position of output dimension x. |
4789 | */ |
4790 | static int is_potential_div_constraint(isl_int *c, int offset, int d, int total) |
4791 | { |
4792 | if (isl_int_is_zero(c[offset + d])(isl_sioimath_sgn(*(c[offset + d])) == 0)) |
4793 | return 0; |
4794 | if (isl_int_is_one(c[offset + d])(isl_sioimath_cmp_si(*(c[offset + d]), 1) == 0)) |
4795 | return 0; |
4796 | if (isl_int_is_negone(c[offset + d])(isl_sioimath_cmp_si(*(c[offset + d]), -1) == 0)) |
4797 | return 0; |
4798 | if (isl_seq_first_non_zero(c + offset, d) != -1) |
4799 | return 0; |
4800 | if (isl_seq_first_non_zero(c + offset + d + 1, |
4801 | total - (offset + d + 1)) != -1) |
4802 | return 0; |
4803 | return 1; |
4804 | } |
4805 | |
4806 | /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map. |
4807 | * |
4808 | * As a special case, we first check if there is any pair of constraints, |
4809 | * shared by all the basic maps in "map" that force a given dimension |
4810 | * to be equal to the floor of some affine combination of the input dimensions. |
4811 | * |
4812 | * In particular, if we can find two constraints |
4813 | * |
4814 | * e(...) + c1 - m x >= 0 i.e., m x <= e(...) + c1 |
4815 | * |
4816 | * and |
4817 | * |
4818 | * -e(...) + c2 + m x >= 0 i.e., m x >= e(...) - c2 |
4819 | * |
4820 | * where m > 1 and e only depends on parameters and input dimemnsions, |
4821 | * and such that |
4822 | * |
4823 | * c1 + c2 < m i.e., -c2 >= c1 - (m - 1) |
4824 | * |
4825 | * then we know that we can take |
4826 | * |
4827 | * x = floor((e(...) + c1) / m) |
4828 | * |
4829 | * without having to perform any computation. |
4830 | * |
4831 | * Note that we know that |
4832 | * |
4833 | * c1 + c2 >= 1 |
4834 | * |
4835 | * If c1 + c2 were 0, then we would have detected an equality during |
4836 | * simplification. If c1 + c2 were negative, then we would have detected |
4837 | * a contradiction. |
4838 | */ |
4839 | static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_check_div( |
4840 | __isl_take isl_map *map) |
4841 | { |
4842 | int d, dim; |
4843 | int i, j, n; |
4844 | int offset, total; |
4845 | isl_int sum; |
4846 | isl_basic_map *hull; |
4847 | |
4848 | hull = isl_map_unshifted_simple_hull(isl_map_copy(map)); |
4849 | if (!hull) |
4850 | goto error; |
4851 | |
4852 | isl_int_init(sum)isl_sioimath_init((sum)); |
4853 | dim = isl_map_dim(map, isl_dim_out); |
4854 | offset = isl_basic_map_offset(hull, isl_dim_out); |
4855 | total = 1 + isl_basic_map_total_dim(hull); |
4856 | n = hull->n_ineq; |
4857 | for (d = 0; d < dim; ++d) { |
4858 | for (i = 0; i < n; ++i) { |
4859 | if (!is_potential_div_constraint(hull->ineq[i], |
4860 | offset, d, total)) |
4861 | continue; |
4862 | for (j = i + 1; j < n; ++j) { |
4863 | if (!isl_seq_is_neg(hull->ineq[i] + 1, |
4864 | hull->ineq[j] + 1, total - 1)) |
4865 | continue; |
4866 | isl_int_add(sum, hull->ineq[i][0],isl_sioimath_add((sum), *(hull->ineq[i][0]), *(hull->ineq [j][0])) |
4867 | hull->ineq[j][0])isl_sioimath_add((sum), *(hull->ineq[i][0]), *(hull->ineq [j][0])); |
4868 | if (isl_int_abs_lt(sum,(isl_sioimath_abs_cmp(*(sum), *(hull->ineq[i][offset + d]) ) < 0) |
4869 | hull->ineq[i][offset + d])(isl_sioimath_abs_cmp(*(sum), *(hull->ineq[i][offset + d]) ) < 0)) |
4870 | break; |
4871 | |
4872 | } |
4873 | if (j >= n) |
4874 | continue; |
4875 | isl_int_clear(sum)isl_sioimath_clear((sum)); |
4876 | if (isl_int_is_pos(hull->ineq[j][offset + d])(isl_sioimath_sgn(*(hull->ineq[j][offset + d])) > 0)) |
4877 | j = i; |
4878 | return pw_multi_aff_from_map_div(map, hull, d, j); |
4879 | } |
4880 | } |
4881 | isl_int_clear(sum)isl_sioimath_clear((sum)); |
4882 | isl_basic_map_free(hull); |
4883 | return pw_multi_aff_from_map_base(map); |
4884 | error: |
4885 | isl_map_free(map); |
4886 | isl_basic_map_free(hull); |
4887 | return NULL((void*)0); |
4888 | } |
4889 | |
4890 | /* Given an affine expression |
4891 | * |
4892 | * [A -> B] -> f(A,B) |
4893 | * |
4894 | * construct an isl_multi_aff |
4895 | * |
4896 | * [A -> B] -> B' |
4897 | * |
4898 | * such that dimension "d" in B' is set to "aff" and the remaining |
4899 | * dimensions are set equal to the corresponding dimensions in B. |
4900 | * "n_in" is the dimension of the space A. |
4901 | * "n_out" is the dimension of the space B. |
4902 | * |
4903 | * If "is_set" is set, then the affine expression is of the form |
4904 | * |
4905 | * [B] -> f(B) |
4906 | * |
4907 | * and we construct an isl_multi_aff |
4908 | * |
4909 | * B -> B' |
4910 | */ |
4911 | static __isl_give isl_multi_aff *range_map(__isl_take isl_aff *aff, int d, |
4912 | unsigned n_in, unsigned n_out, int is_set) |
4913 | { |
4914 | int i; |
4915 | isl_multi_aff *ma; |
4916 | isl_space *space, *space2; |
4917 | isl_local_space *ls; |
4918 | |
4919 | space = isl_aff_get_domain_space(aff); |
4920 | ls = isl_local_space_from_space(isl_space_copy(space)); |
4921 | space2 = isl_space_copy(space); |
4922 | if (!is_set) |
4923 | space2 = isl_space_range(isl_space_unwrap(space2)); |
4924 | space = isl_space_map_from_domain_and_range(space, space2); |
4925 | ma = isl_multi_aff_alloc(space); |
4926 | ma = isl_multi_aff_set_aff(ma, d, aff); |
4927 | |
4928 | for (i = 0; i < n_out; ++i) { |
4929 | if (i == d) |
4930 | continue; |
4931 | aff = isl_aff_var_on_domain(isl_local_space_copy(ls), |
4932 | isl_dim_set, n_in + i); |
4933 | ma = isl_multi_aff_set_aff(ma, i, aff); |
4934 | } |
4935 | |
4936 | isl_local_space_free(ls); |
4937 | |
4938 | return ma; |
4939 | } |
4940 | |
4941 | /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map, |
4942 | * taking into account that the dimension at position "d" can be written as |
4943 | * |
4944 | * x = m a + f(..) (1) |
4945 | * |
4946 | * where m is equal to "gcd". |
4947 | * "i" is the index of the equality in "hull" that defines f(..). |
4948 | * In particular, the equality is of the form |
4949 | * |
4950 | * f(..) - x + m g(existentials) = 0 |
4951 | * |
4952 | * or |
4953 | * |
4954 | * -f(..) + x + m g(existentials) = 0 |
4955 | * |
4956 | * We basically plug (1) into "map", resulting in a map with "a" |
4957 | * in the range instead of "x". The corresponding isl_pw_multi_aff |
4958 | * defining "a" is then plugged back into (1) to obtain a definition for "x". |
4959 | * |
4960 | * Specifically, given the input map |
4961 | * |
4962 | * A -> B |
4963 | * |
4964 | * We first wrap it into a set |
4965 | * |
4966 | * [A -> B] |
4967 | * |
4968 | * and define (1) on top of the corresponding space, resulting in "aff". |
4969 | * We use this to create an isl_multi_aff that maps the output position "d" |
4970 | * from "a" to "x", leaving all other (intput and output) dimensions unchanged. |
4971 | * We plug this into the wrapped map, unwrap the result and compute the |
4972 | * corresponding isl_pw_multi_aff. |
4973 | * The result is an expression |
4974 | * |
4975 | * A -> T(A) |
4976 | * |
4977 | * We adjust that to |
4978 | * |
4979 | * A -> [A -> T(A)] |
4980 | * |
4981 | * so that we can plug that into "aff", after extending the latter to |
4982 | * a mapping |
4983 | * |
4984 | * [A -> B] -> B' |
4985 | * |
4986 | * |
4987 | * If "map" is actually a set, then there is no "A" space, meaning |
4988 | * that we do not need to perform any wrapping, and that the result |
4989 | * of the recursive call is of the form |
4990 | * |
4991 | * [T] |
4992 | * |
4993 | * which is plugged into a mapping of the form |
4994 | * |
4995 | * B -> B' |
4996 | */ |
4997 | static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_stride( |
4998 | __isl_take isl_map *map, __isl_take isl_basic_map *hull, int d, int i, |
4999 | isl_int gcd) |
5000 | { |
5001 | isl_setisl_map *set; |
5002 | isl_space *space; |
5003 | isl_local_space *ls; |
5004 | isl_aff *aff; |
5005 | isl_multi_aff *ma; |
5006 | isl_pw_multi_aff *pma, *id; |
5007 | unsigned n_in; |
5008 | unsigned o_out; |
5009 | unsigned n_out; |
5010 | isl_bool is_set; |
5011 | |
5012 | is_set = isl_map_is_set(map); |
5013 | if (is_set < 0) |
5014 | goto error; |
5015 | |
5016 | n_in = isl_basic_map_dim(hull, isl_dim_in); |
5017 | n_out = isl_basic_map_dim(hull, isl_dim_out); |
5018 | o_out = isl_basic_map_offset(hull, isl_dim_out); |
5019 | |
5020 | if (is_set) |
5021 | set = map; |
5022 | else |
5023 | set = isl_map_wrap(map); |
5024 | space = isl_space_map_from_set(isl_set_get_space(set)); |
5025 | ma = isl_multi_aff_identity(space); |
5026 | ls = isl_local_space_from_space(isl_set_get_space(set)); |
5027 | aff = isl_aff_alloc(ls); |
5028 | if (aff) { |
5029 | isl_int_set_si(aff->v->el[0], 1)isl_sioimath_set_si((aff->v->el[0]), 1); |
5030 | if (isl_int_is_one(hull->eq[i][o_out + d])(isl_sioimath_cmp_si(*(hull->eq[i][o_out + d]), 1) == 0)) |
5031 | isl_seq_neg(aff->v->el + 1, hull->eq[i], |
5032 | aff->v->size - 1); |
5033 | else |
5034 | isl_seq_cpy(aff->v->el + 1, hull->eq[i], |
5035 | aff->v->size - 1); |
5036 | isl_int_set(aff->v->el[1 + o_out + d], gcd)isl_sioimath_set((aff->v->el[1 + o_out + d]), *(gcd)); |
5037 | } |
5038 | ma = isl_multi_aff_set_aff(ma, n_in + d, isl_aff_copy(aff)); |
5039 | set = isl_set_preimage_multi_aff(set, ma); |
5040 | |
5041 | ma = range_map(aff, d, n_in, n_out, is_set); |
5042 | |
5043 | if (is_set) |
5044 | map = set; |
5045 | else |
5046 | map = isl_set_unwrap(set); |
5047 | pma = isl_pw_multi_aff_from_map(map); |
5048 | |
5049 | if (!is_set) { |
5050 | space = isl_pw_multi_aff_get_domain_space(pma); |
5051 | space = isl_space_map_from_set(space); |
5052 | id = isl_pw_multi_aff_identity(space); |
5053 | pma = isl_pw_multi_aff_range_product(id, pma); |
5054 | } |
5055 | id = isl_pw_multi_aff_from_multi_aff(ma); |
5056 | pma = isl_pw_multi_aff_pullback_pw_multi_aff(id, pma); |
5057 | |
5058 | isl_basic_map_free(hull); |
5059 | return pma; |
5060 | error: |
5061 | isl_map_free(map); |
5062 | isl_basic_map_free(hull); |
5063 | return NULL((void*)0); |
5064 | } |
5065 | |
5066 | /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map. |
5067 | * "hull" contains the equalities valid for "map". |
5068 | * |
5069 | * Check if any of the output dimensions is "strided". |
5070 | * That is, we check if it can be written as |
5071 | * |
5072 | * x = m a + f(..) |
5073 | * |
5074 | * with m greater than 1, a some combination of existentially quantified |
5075 | * variables and f an expression in the parameters and input dimensions. |
5076 | * If so, we remove the stride in pw_multi_aff_from_map_stride. |
5077 | * |
5078 | * Otherwise, we continue with pw_multi_aff_from_map_check_div for a further |
5079 | * special case. |
5080 | */ |
5081 | static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_check_strides( |
5082 | __isl_take isl_map *map, __isl_take isl_basic_map *hull) |
5083 | { |
5084 | int i, j; |
5085 | unsigned n_out; |
5086 | unsigned o_out; |
5087 | unsigned n_div; |
5088 | unsigned o_div; |
5089 | isl_int gcd; |
5090 | |
5091 | n_div = isl_basic_map_dim(hull, isl_dim_div); |
5092 | o_div = isl_basic_map_offset(hull, isl_dim_div); |
5093 | |
5094 | if (n_div == 0) { |
5095 | isl_basic_map_free(hull); |
5096 | return pw_multi_aff_from_map_check_div(map); |
5097 | } |
5098 | |
5099 | isl_int_init(gcd)isl_sioimath_init((gcd)); |
5100 | |
5101 | n_out = isl_basic_map_dim(hull, isl_dim_out); |
5102 | o_out = isl_basic_map_offset(hull, isl_dim_out); |
5103 | |
5104 | for (i = 0; i < n_out; ++i) { |
5105 | for (j = 0; j < hull->n_eq; ++j) { |
5106 | isl_int *eq = hull->eq[j]; |
5107 | isl_pw_multi_aff *res; |
5108 | |
5109 | if (!isl_int_is_one(eq[o_out + i])(isl_sioimath_cmp_si(*(eq[o_out + i]), 1) == 0) && |
5110 | !isl_int_is_negone(eq[o_out + i])(isl_sioimath_cmp_si(*(eq[o_out + i]), -1) == 0)) |
5111 | continue; |
5112 | if (isl_seq_first_non_zero(eq + o_out, i) != -1) |
5113 | continue; |
5114 | if (isl_seq_first_non_zero(eq + o_out + i + 1, |
5115 | n_out - (i + 1)) != -1) |
5116 | continue; |
5117 | isl_seq_gcd(eq + o_div, n_div, &gcd); |
5118 | if (isl_int_is_zero(gcd)(isl_sioimath_sgn(*(gcd)) == 0)) |
5119 | continue; |
5120 | if (isl_int_is_one(gcd)(isl_sioimath_cmp_si(*(gcd), 1) == 0)) |
5121 | continue; |
5122 | |
5123 | res = pw_multi_aff_from_map_stride(map, hull, |
5124 | i, j, gcd); |
5125 | isl_int_clear(gcd)isl_sioimath_clear((gcd)); |
5126 | return res; |
5127 | } |
5128 | } |
5129 | |
5130 | isl_int_clear(gcd)isl_sioimath_clear((gcd)); |
5131 | isl_basic_map_free(hull); |
5132 | return pw_multi_aff_from_map_check_div(map); |
5133 | } |
5134 | |
5135 | /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map. |
5136 | * |
5137 | * As a special case, we first check if all output dimensions are uniquely |
5138 | * defined in terms of the parameters and input dimensions over the entire |
5139 | * domain. If so, we extract the desired isl_pw_multi_aff directly |
5140 | * from the affine hull of "map" and its domain. |
5141 | * |
5142 | * Otherwise, continue with pw_multi_aff_from_map_check_strides for more |
5143 | * special cases. |
5144 | */ |
5145 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map) |
5146 | { |
5147 | isl_bool sv; |
5148 | isl_basic_map *hull; |
5149 | |
5150 | if (!map) |
5151 | return NULL((void*)0); |
5152 | |
5153 | if (isl_map_n_basic_map(map) == 1) { |
5154 | hull = isl_map_unshifted_simple_hull(isl_map_copy(map)); |
5155 | hull = isl_basic_map_plain_affine_hull(hull); |
5156 | sv = isl_basic_map_plain_is_single_valued(hull); |
5157 | if (sv >= 0 && sv) |
5158 | return plain_pw_multi_aff_from_map(isl_map_domain(map), |
5159 | hull); |
5160 | isl_basic_map_free(hull); |
5161 | } |
5162 | map = isl_map_detect_equalities(map); |
5163 | hull = isl_map_unshifted_simple_hull(isl_map_copy(map)); |
5164 | sv = isl_basic_map_plain_is_single_valued(hull); |
5165 | if (sv >= 0 && sv) |
5166 | return plain_pw_multi_aff_from_map(isl_map_domain(map), hull); |
5167 | if (sv >= 0) |
5168 | return pw_multi_aff_from_map_check_strides(map, hull); |
5169 | isl_basic_map_free(hull); |
5170 | isl_map_free(map); |
5171 | return NULL((void*)0); |
5172 | } |
5173 | |
5174 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(__isl_take isl_setisl_map *set) |
5175 | { |
5176 | return isl_pw_multi_aff_from_map(set); |
5177 | } |
5178 | |
5179 | /* Convert "map" into an isl_pw_multi_aff (if possible) and |
5180 | * add it to *user. |
5181 | */ |
5182 | static isl_stat pw_multi_aff_from_map(__isl_take isl_map *map, void *user) |
5183 | { |
5184 | isl_union_pw_multi_aff **upma = user; |
5185 | isl_pw_multi_aff *pma; |
5186 | |
5187 | pma = isl_pw_multi_aff_from_map(map); |
5188 | *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma); |
5189 | |
5190 | return *upma ? isl_stat_ok : isl_stat_error; |
5191 | } |
5192 | |
5193 | /* Create an isl_union_pw_multi_aff with the given isl_aff on a universe |
5194 | * domain. |
5195 | */ |
5196 | __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_aff( |
5197 | __isl_take isl_aff *aff) |
5198 | { |
5199 | isl_multi_aff *ma; |
5200 | isl_pw_multi_aff *pma; |
5201 | |
5202 | ma = isl_multi_aff_from_aff(aff); |
5203 | pma = isl_pw_multi_aff_from_multi_aff(ma); |
5204 | return isl_union_pw_multi_aff_from_pw_multi_aff(pma); |
5205 | } |
5206 | |
5207 | /* Try and create an isl_union_pw_multi_aff that is equivalent |
5208 | * to the given isl_union_map. |
5209 | * The isl_union_map is required to be single-valued in each space. |
5210 | * Otherwise, an error is produced. |
5211 | */ |
5212 | __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_map( |
5213 | __isl_take isl_union_map *umap) |
5214 | { |
5215 | isl_space *space; |
5216 | isl_union_pw_multi_aff *upma; |
5217 | |
5218 | space = isl_union_map_get_space(umap); |
5219 | upma = isl_union_pw_multi_aff_empty(space); |
5220 | if (isl_union_map_foreach_map(umap, &pw_multi_aff_from_map, &upma) < 0) |
5221 | upma = isl_union_pw_multi_aff_free(upma); |
5222 | isl_union_map_free(umap); |
5223 | |
5224 | return upma; |
5225 | } |
5226 | |
5227 | /* Try and create an isl_union_pw_multi_aff that is equivalent |
5228 | * to the given isl_union_set. |
5229 | * The isl_union_set is required to be a singleton in each space. |
5230 | * Otherwise, an error is produced. |
5231 | */ |
5232 | __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_set( |
5233 | __isl_take isl_union_setisl_union_map *uset) |
5234 | { |
5235 | return isl_union_pw_multi_aff_from_union_map(uset); |
5236 | } |
5237 | |
5238 | /* Return the piecewise affine expression "set ? 1 : 0". |
5239 | */ |
5240 | __isl_give isl_pw_aff *isl_set_indicator_function(__isl_take isl_setisl_map *set) |
5241 | { |
5242 | isl_pw_aff *pa; |
5243 | isl_space *space = isl_set_get_space(set); |
5244 | isl_local_space *ls = isl_local_space_from_space(space); |
5245 | isl_aff *zero = isl_aff_zero_on_domain(isl_local_space_copy(ls)); |
5246 | isl_aff *one = isl_aff_zero_on_domain(ls); |
5247 | |
5248 | one = isl_aff_add_constant_si(one, 1); |
5249 | pa = isl_pw_aff_alloc(isl_set_copy(set), one); |
5250 | set = isl_set_complement(set); |
5251 | pa = isl_pw_aff_add_disjoint(pa, isl_pw_aff_alloc(set, zero)); |
5252 | |
5253 | return pa; |
5254 | } |
5255 | |
5256 | /* Plug in "subs" for dimension "type", "pos" of "aff". |
5257 | * |
5258 | * Let i be the dimension to replace and let "subs" be of the form |
5259 | * |
5260 | * f/d |
5261 | * |
5262 | * and "aff" of the form |
5263 | * |
5264 | * (a i + g)/m |
5265 | * |
5266 | * The result is |
5267 | * |
5268 | * (a f + d g')/(m d) |
5269 | * |
5270 | * where g' is the result of plugging in "subs" in each of the integer |
5271 | * divisions in g. |
5272 | */ |
5273 | __isl_give isl_aff *isl_aff_substitute(__isl_take isl_aff *aff, |
5274 | enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs) |
5275 | { |
5276 | isl_ctx *ctx; |
5277 | isl_int v; |
5278 | |
5279 | aff = isl_aff_cow(aff); |
5280 | if (!aff || !subs) |
5281 | return isl_aff_free(aff); |
5282 | |
5283 | ctx = isl_aff_get_ctx(aff); |
5284 | if (!isl_space_is_equal(aff->ls->dim, subs->ls->dim)) |
5285 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 5286); return isl_aff_free(aff); } while (0) |
5286 | "spaces don't match", return isl_aff_free(aff))do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 5286); return isl_aff_free(aff); } while (0); |
5287 | if (isl_local_space_dim(subs->ls, isl_dim_div) != 0) |
5288 | isl_die(ctx, isl_error_unsupported,do { isl_handle_error(ctx, isl_error_unsupported, "cannot handle divs yet" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 5289); return isl_aff_free(aff); } while (0) |
5289 | "cannot handle divs yet", return isl_aff_free(aff))do { isl_handle_error(ctx, isl_error_unsupported, "cannot handle divs yet" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 5289); return isl_aff_free(aff); } while (0); |
5290 | |
5291 | aff->ls = isl_local_space_substitute(aff->ls, type, pos, subs); |
5292 | if (!aff->ls) |
5293 | return isl_aff_free(aff); |
5294 | |
5295 | aff->v = isl_vec_cow(aff->v); |
5296 | if (!aff->v) |
5297 | return isl_aff_free(aff); |
5298 | |
5299 | pos += isl_local_space_offset(aff->ls, type); |
5300 | |
5301 | isl_int_init(v)isl_sioimath_init((v)); |
5302 | isl_seq_substitute(aff->v->el, pos, subs->v->el, |
5303 | aff->v->size, subs->v->size, v); |
5304 | isl_int_clear(v)isl_sioimath_clear((v)); |
5305 | |
5306 | return aff; |
5307 | } |
5308 | |
5309 | /* Plug in "subs" for dimension "type", "pos" in each of the affine |
5310 | * expressions in "maff". |
5311 | */ |
5312 | __isl_give isl_multi_aff *isl_multi_aff_substitute( |
5313 | __isl_take isl_multi_aff *maff, enum isl_dim_type type, unsigned pos, |
5314 | __isl_keep isl_aff *subs) |
5315 | { |
5316 | int i; |
5317 | |
5318 | maff = isl_multi_aff_cow(maff); |
5319 | if (!maff || !subs) |
5320 | return isl_multi_aff_free(maff); |
5321 | |
5322 | if (type == isl_dim_in) |
5323 | type = isl_dim_set; |
5324 | |
5325 | for (i = 0; i < maff->n; ++i) { |
5326 | maff->u.p[i] = isl_aff_substitute(maff->u.p[i], |
5327 | type, pos, subs); |
5328 | if (!maff->u.p[i]) |
5329 | return isl_multi_aff_free(maff); |
5330 | } |
5331 | |
5332 | return maff; |
5333 | } |
5334 | |
5335 | /* Plug in "subs" for dimension "type", "pos" of "pma". |
5336 | * |
5337 | * pma is of the form |
5338 | * |
5339 | * A_i(v) -> M_i(v) |
5340 | * |
5341 | * while subs is of the form |
5342 | * |
5343 | * v' = B_j(v) -> S_j |
5344 | * |
5345 | * Each pair i,j such that C_ij = A_i \cap B_i is non-empty |
5346 | * has a contribution in the result, in particular |
5347 | * |
5348 | * C_ij(S_j) -> M_i(S_j) |
5349 | * |
5350 | * Note that plugging in S_j in C_ij may also result in an empty set |
5351 | * and this contribution should simply be discarded. |
5352 | */ |
5353 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute( |
5354 | __isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, unsigned pos, |
5355 | __isl_keep isl_pw_aff *subs) |
5356 | { |
5357 | int i, j, n; |
5358 | isl_pw_multi_aff *res; |
5359 | |
5360 | if (!pma || !subs) |
5361 | return isl_pw_multi_aff_free(pma); |
5362 | |
5363 | n = pma->n * subs->n; |
5364 | res = isl_pw_multi_aff_alloc_size(isl_space_copy(pma->dim), n); |
5365 | |
5366 | for (i = 0; i < pma->n; ++i) { |
5367 | for (j = 0; j < subs->n; ++j) { |
5368 | isl_setisl_map *common; |
5369 | isl_multi_aff *res_ij; |
5370 | int empty; |
5371 | |
5372 | common = isl_set_intersect( |
5373 | isl_set_copy(pma->p[i].set), |
5374 | isl_set_copy(subs->p[j].set)); |
5375 | common = isl_set_substitute(common, |
5376 | type, pos, subs->p[j].aff); |
5377 | empty = isl_set_plain_is_empty(common); |
5378 | if (empty < 0 || empty) { |
5379 | isl_set_free(common); |
5380 | if (empty < 0) |
5381 | goto error; |
5382 | continue; |
5383 | } |
5384 | |
5385 | res_ij = isl_multi_aff_substitute( |
5386 | isl_multi_aff_copy(pma->p[i].maff), |
5387 | type, pos, subs->p[j].aff); |
5388 | |
5389 | res = isl_pw_multi_aff_add_piece(res, common, res_ij); |
5390 | } |
5391 | } |
5392 | |
5393 | isl_pw_multi_aff_free(pma); |
5394 | return res; |
5395 | error: |
5396 | isl_pw_multi_aff_free(pma); |
5397 | isl_pw_multi_aff_free(res); |
5398 | return NULL((void*)0); |
5399 | } |
5400 | |
5401 | /* Compute the preimage of a range of dimensions in the affine expression "src" |
5402 | * under "ma" and put the result in "dst". The number of dimensions in "src" |
5403 | * that precede the range is given by "n_before". The number of dimensions |
5404 | * in the range is given by the number of output dimensions of "ma". |
5405 | * The number of dimensions that follow the range is given by "n_after". |
5406 | * If "has_denom" is set (to one), |
5407 | * then "src" and "dst" have an extra initial denominator. |
5408 | * "n_div_ma" is the number of existentials in "ma" |
5409 | * "n_div_bset" is the number of existentials in "src" |
5410 | * The resulting "dst" (which is assumed to have been allocated by |
5411 | * the caller) contains coefficients for both sets of existentials, |
5412 | * first those in "ma" and then those in "src". |
5413 | * f, c1, c2 and g are temporary objects that have been initialized |
5414 | * by the caller. |
5415 | * |
5416 | * Let src represent the expression |
5417 | * |
5418 | * (a(p) + f_u u + b v + f_w w + c(divs))/d |
5419 | * |
5420 | * and let ma represent the expressions |
5421 | * |
5422 | * v_i = (r_i(p) + s_i(y) + t_i(divs'))/m_i |
5423 | * |
5424 | * We start out with the following expression for dst: |
5425 | * |
5426 | * (a(p) + f_u u + 0 y + f_w w + 0 divs' + c(divs) + f \sum_i b_i v_i)/d |
5427 | * |
5428 | * with the multiplication factor f initially equal to 1 |
5429 | * and f \sum_i b_i v_i kept separately. |
5430 | * For each x_i that we substitute, we multiply the numerator |
5431 | * (and denominator) of dst by c_1 = m_i and add the numerator |
5432 | * of the x_i expression multiplied by c_2 = f b_i, |
5433 | * after removing the common factors of c_1 and c_2. |
5434 | * The multiplication factor f also needs to be multiplied by c_1 |
5435 | * for the next x_j, j > i. |
5436 | */ |
5437 | void isl_seq_preimage(isl_int *dst, isl_int *src, |
5438 | __isl_keep isl_multi_aff *ma, int n_before, int n_after, |
5439 | int n_div_ma, int n_div_bmap, |
5440 | isl_int f, isl_int c1, isl_int c2, isl_int g, int has_denom) |
5441 | { |
5442 | int i; |
5443 | int n_param, n_in, n_out; |
5444 | int o_dst, o_src; |
5445 | |
5446 | n_param = isl_multi_aff_dim(ma, isl_dim_param); |
5447 | n_in = isl_multi_aff_dim(ma, isl_dim_in); |
5448 | n_out = isl_multi_aff_dim(ma, isl_dim_out); |
5449 | |
5450 | isl_seq_cpy(dst, src, has_denom + 1 + n_param + n_before); |
5451 | o_dst = o_src = has_denom + 1 + n_param + n_before; |
5452 | isl_seq_clr(dst + o_dst, n_in); |
5453 | o_dst += n_in; |
5454 | o_src += n_out; |
5455 | isl_seq_cpy(dst + o_dst, src + o_src, n_after); |
5456 | o_dst += n_after; |
5457 | o_src += n_after; |
5458 | isl_seq_clr(dst + o_dst, n_div_ma); |
5459 | o_dst += n_div_ma; |
5460 | isl_seq_cpy(dst + o_dst, src + o_src, n_div_bmap); |
5461 | |
5462 | isl_int_set_si(f, 1)isl_sioimath_set_si((f), 1); |
5463 | |
5464 | for (i = 0; i < n_out; ++i) { |
5465 | int offset = has_denom + 1 + n_param + n_before + i; |
5466 | |
5467 | if (isl_int_is_zero(src[offset])(isl_sioimath_sgn(*(src[offset])) == 0)) |
5468 | continue; |
5469 | isl_int_set(c1, ma->u.p[i]->v->el[0])isl_sioimath_set((c1), *(ma->u.p[i]->v->el[0])); |
5470 | isl_int_mul(c2, f, src[offset])isl_sioimath_mul((c2), *(f), *(src[offset])); |
5471 | isl_int_gcd(g, c1, c2)isl_sioimath_gcd((g), *(c1), *(c2)); |
5472 | isl_int_divexact(c1, c1, g)isl_sioimath_tdiv_q((c1), *(c1), *(g)); |
5473 | isl_int_divexact(c2, c2, g)isl_sioimath_tdiv_q((c2), *(c2), *(g)); |
5474 | |
5475 | isl_int_mul(f, f, c1)isl_sioimath_mul((f), *(f), *(c1)); |
5476 | o_dst = has_denom; |
5477 | o_src = 1; |
5478 | isl_seq_combine(dst + o_dst, c1, dst + o_dst, |
5479 | c2, ma->u.p[i]->v->el + o_src, 1 + n_param); |
5480 | o_dst += 1 + n_param; |
5481 | o_src += 1 + n_param; |
5482 | isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_before); |
5483 | o_dst += n_before; |
5484 | isl_seq_combine(dst + o_dst, c1, dst + o_dst, |
5485 | c2, ma->u.p[i]->v->el + o_src, n_in); |
5486 | o_dst += n_in; |
5487 | o_src += n_in; |
5488 | isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_after); |
5489 | o_dst += n_after; |
5490 | isl_seq_combine(dst + o_dst, c1, dst + o_dst, |
5491 | c2, ma->u.p[i]->v->el + o_src, n_div_ma); |
5492 | o_dst += n_div_ma; |
5493 | o_src += n_div_ma; |
Value stored to 'o_src' is never read | |
5494 | isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_div_bmap); |
5495 | if (has_denom) |
5496 | isl_int_mul(dst[0], dst[0], c1)isl_sioimath_mul((dst[0]), *(dst[0]), *(c1)); |
5497 | } |
5498 | } |
5499 | |
5500 | /* Compute the pullback of "aff" by the function represented by "ma". |
5501 | * In other words, plug in "ma" in "aff". The result is an affine expression |
5502 | * defined over the domain space of "ma". |
5503 | * |
5504 | * If "aff" is represented by |
5505 | * |
5506 | * (a(p) + b x + c(divs))/d |
5507 | * |
5508 | * and ma is represented by |
5509 | * |
5510 | * x = D(p) + F(y) + G(divs') |
5511 | * |
5512 | * then the result is |
5513 | * |
5514 | * (a(p) + b D(p) + b F(y) + b G(divs') + c(divs))/d |
5515 | * |
5516 | * The divs in the local space of the input are similarly adjusted |
5517 | * through a call to isl_local_space_preimage_multi_aff. |
5518 | */ |
5519 | __isl_give isl_aff *isl_aff_pullback_multi_aff(__isl_take isl_aff *aff, |
5520 | __isl_take isl_multi_aff *ma) |
5521 | { |
5522 | isl_aff *res = NULL((void*)0); |
5523 | isl_local_space *ls; |
5524 | int n_div_aff, n_div_ma; |
5525 | isl_int f, c1, c2, g; |
5526 | |
5527 | ma = isl_multi_aff_align_divs(ma); |
5528 | if (!aff || !ma) |
5529 | goto error; |
5530 | |
5531 | n_div_aff = isl_aff_dim(aff, isl_dim_div); |
5532 | n_div_ma = ma->n ? isl_aff_dim(ma->u.p[0], isl_dim_div) : 0; |
5533 | |
5534 | ls = isl_aff_get_domain_local_space(aff); |
5535 | ls = isl_local_space_preimage_multi_aff(ls, isl_multi_aff_copy(ma)); |
5536 | res = isl_aff_alloc(ls); |
5537 | if (!res) |
5538 | goto error; |
5539 | |
5540 | isl_int_init(f)isl_sioimath_init((f)); |
5541 | isl_int_init(c1)isl_sioimath_init((c1)); |
5542 | isl_int_init(c2)isl_sioimath_init((c2)); |
5543 | isl_int_init(g)isl_sioimath_init((g)); |
5544 | |
5545 | isl_seq_preimage(res->v->el, aff->v->el, ma, 0, 0, n_div_ma, n_div_aff, |
5546 | f, c1, c2, g, 1); |
5547 | |
5548 | isl_int_clear(f)isl_sioimath_clear((f)); |
5549 | isl_int_clear(c1)isl_sioimath_clear((c1)); |
5550 | isl_int_clear(c2)isl_sioimath_clear((c2)); |
5551 | isl_int_clear(g)isl_sioimath_clear((g)); |
5552 | |
5553 | isl_aff_free(aff); |
5554 | isl_multi_aff_free(ma); |
5555 | res = isl_aff_normalize(res); |
5556 | return res; |
5557 | error: |
5558 | isl_aff_free(aff); |
5559 | isl_multi_aff_free(ma); |
5560 | isl_aff_free(res); |
5561 | return NULL((void*)0); |
5562 | } |
5563 | |
5564 | /* Compute the pullback of "aff1" by the function represented by "aff2". |
5565 | * In other words, plug in "aff2" in "aff1". The result is an affine expression |
5566 | * defined over the domain space of "aff1". |
5567 | * |
5568 | * The domain of "aff1" should match the range of "aff2", which means |
5569 | * that it should be single-dimensional. |
5570 | */ |
5571 | __isl_give isl_aff *isl_aff_pullback_aff(__isl_take isl_aff *aff1, |
5572 | __isl_take isl_aff *aff2) |
5573 | { |
5574 | isl_multi_aff *ma; |
5575 | |
5576 | ma = isl_multi_aff_from_aff(aff2); |
5577 | return isl_aff_pullback_multi_aff(aff1, ma); |
5578 | } |
5579 | |
5580 | /* Compute the pullback of "ma1" by the function represented by "ma2". |
5581 | * In other words, plug in "ma2" in "ma1". |
5582 | * |
5583 | * The parameters of "ma1" and "ma2" are assumed to have been aligned. |
5584 | */ |
5585 | static __isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff_aligned( |
5586 | __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2) |
5587 | { |
5588 | int i; |
5589 | isl_space *space = NULL((void*)0); |
5590 | |
5591 | ma2 = isl_multi_aff_align_divs(ma2); |
5592 | ma1 = isl_multi_aff_cow(ma1); |
5593 | if (!ma1 || !ma2) |
5594 | goto error; |
5595 | |
5596 | space = isl_space_join(isl_multi_aff_get_space(ma2), |
5597 | isl_multi_aff_get_space(ma1)); |
5598 | |
5599 | for (i = 0; i < ma1->n; ++i) { |
5600 | ma1->u.p[i] = isl_aff_pullback_multi_aff(ma1->u.p[i], |
5601 | isl_multi_aff_copy(ma2)); |
5602 | if (!ma1->u.p[i]) |
5603 | goto error; |
5604 | } |
5605 | |
5606 | ma1 = isl_multi_aff_reset_space(ma1, space); |
5607 | isl_multi_aff_free(ma2); |
5608 | return ma1; |
5609 | error: |
5610 | isl_space_free(space); |
5611 | isl_multi_aff_free(ma2); |
5612 | isl_multi_aff_free(ma1); |
5613 | return NULL((void*)0); |
5614 | } |
5615 | |
5616 | /* Compute the pullback of "ma1" by the function represented by "ma2". |
5617 | * In other words, plug in "ma2" in "ma1". |
5618 | */ |
5619 | __isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff( |
5620 | __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2) |
5621 | { |
5622 | return isl_multi_aff_align_params_multi_multi_and(ma1, ma2, |
5623 | &isl_multi_aff_pullback_multi_aff_aligned); |
5624 | } |
5625 | |
5626 | /* Extend the local space of "dst" to include the divs |
5627 | * in the local space of "src". |
5628 | * |
5629 | * If "src" does not have any divs or if the local spaces of "dst" and |
5630 | * "src" are the same, then no extension is required. |
5631 | */ |
5632 | __isl_give isl_aff *isl_aff_align_divs(__isl_take isl_aff *dst, |
5633 | __isl_keep isl_aff *src) |
5634 | { |
5635 | isl_ctx *ctx; |
5636 | int src_n_div, dst_n_div; |
5637 | int *exp1 = NULL((void*)0); |
5638 | int *exp2 = NULL((void*)0); |
5639 | isl_bool equal; |
5640 | isl_mat *div; |
5641 | |
5642 | if (!src || !dst) |
5643 | return isl_aff_free(dst); |
5644 | |
5645 | ctx = isl_aff_get_ctx(src); |
5646 | equal = isl_local_space_has_equal_space(src->ls, dst->ls); |
5647 | if (equal < 0) |
5648 | return isl_aff_free(dst); |
5649 | if (!equal) |
5650 | isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 5651); goto error; } while (0) |
5651 | "spaces don't match", goto error)do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 5651); goto error; } while (0); |
5652 | |
5653 | src_n_div = isl_local_space_dim(src->ls, isl_dim_div); |
5654 | if (src_n_div == 0) |
5655 | return dst; |
5656 | equal = isl_local_space_is_equal(src->ls, dst->ls); |
5657 | if (equal < 0) |
5658 | return isl_aff_free(dst); |
5659 | if (equal) |
5660 | return dst; |
5661 | |
5662 | dst_n_div = isl_local_space_dim(dst->ls, isl_dim_div); |
5663 | exp1 = isl_alloc_array(ctx, int, src_n_div)((int *)isl_malloc_or_die(ctx, (src_n_div)*sizeof(int))); |
5664 | exp2 = isl_alloc_array(ctx, int, dst_n_div)((int *)isl_malloc_or_die(ctx, (dst_n_div)*sizeof(int))); |
5665 | if (!exp1 || (dst_n_div && !exp2)) |
5666 | goto error; |
5667 | |
5668 | div = isl_merge_divs(src->ls->div, dst->ls->div, exp1, exp2); |
5669 | dst = isl_aff_expand_divs(dst, div, exp2); |
5670 | free(exp1); |
5671 | free(exp2); |
5672 | |
5673 | return dst; |
5674 | error: |
5675 | free(exp1); |
5676 | free(exp2); |
5677 | return isl_aff_free(dst); |
5678 | } |
5679 | |
5680 | /* Adjust the local spaces of the affine expressions in "maff" |
5681 | * such that they all have the save divs. |
5682 | */ |
5683 | __isl_give isl_multi_aff *isl_multi_aff_align_divs( |
5684 | __isl_take isl_multi_aff *maff) |
5685 | { |
5686 | int i; |
5687 | |
5688 | if (!maff) |
5689 | return NULL((void*)0); |
5690 | if (maff->n == 0) |
5691 | return maff; |
5692 | maff = isl_multi_aff_cow(maff); |
5693 | if (!maff) |
5694 | return NULL((void*)0); |
5695 | |
5696 | for (i = 1; i < maff->n; ++i) |
5697 | maff->u.p[0] = isl_aff_align_divs(maff->u.p[0], maff->u.p[i]); |
5698 | for (i = 1; i < maff->n; ++i) { |
5699 | maff->u.p[i] = isl_aff_align_divs(maff->u.p[i], maff->u.p[0]); |
5700 | if (!maff->u.p[i]) |
5701 | return isl_multi_aff_free(maff); |
5702 | } |
5703 | |
5704 | return maff; |
5705 | } |
5706 | |
5707 | __isl_give isl_aff *isl_aff_lift(__isl_take isl_aff *aff) |
5708 | { |
5709 | aff = isl_aff_cow(aff); |
5710 | if (!aff) |
5711 | return NULL((void*)0); |
5712 | |
5713 | aff->ls = isl_local_space_lift(aff->ls); |
5714 | if (!aff->ls) |
5715 | return isl_aff_free(aff); |
5716 | |
5717 | return aff; |
5718 | } |
5719 | |
5720 | /* Lift "maff" to a space with extra dimensions such that the result |
5721 | * has no more existentially quantified variables. |
5722 | * If "ls" is not NULL, then *ls is assigned the local space that lies |
5723 | * at the basis of the lifting applied to "maff". |
5724 | */ |
5725 | __isl_give isl_multi_aff *isl_multi_aff_lift(__isl_take isl_multi_aff *maff, |
5726 | __isl_give isl_local_space **ls) |
5727 | { |
5728 | int i; |
5729 | isl_space *space; |
5730 | unsigned n_div; |
5731 | |
5732 | if (ls) |
5733 | *ls = NULL((void*)0); |
5734 | |
5735 | if (!maff) |
5736 | return NULL((void*)0); |
5737 | |
5738 | if (maff->n == 0) { |
5739 | if (ls) { |
5740 | isl_space *space = isl_multi_aff_get_domain_space(maff); |
5741 | *ls = isl_local_space_from_space(space); |
5742 | if (!*ls) |
5743 | return isl_multi_aff_free(maff); |
5744 | } |
5745 | return maff; |
5746 | } |
5747 | |
5748 | maff = isl_multi_aff_cow(maff); |
5749 | maff = isl_multi_aff_align_divs(maff); |
5750 | if (!maff) |
5751 | return NULL((void*)0); |
5752 | |
5753 | n_div = isl_aff_dim(maff->u.p[0], isl_dim_div); |
5754 | space = isl_multi_aff_get_space(maff); |
5755 | space = isl_space_lift(isl_space_domain(space), n_div); |
5756 | space = isl_space_extend_domain_with_range(space, |
5757 | isl_multi_aff_get_space(maff)); |
5758 | if (!space) |
5759 | return isl_multi_aff_free(maff); |
5760 | isl_space_free(maff->space); |
5761 | maff->space = space; |
5762 | |
5763 | if (ls) { |
5764 | *ls = isl_aff_get_domain_local_space(maff->u.p[0]); |
5765 | if (!*ls) |
5766 | return isl_multi_aff_free(maff); |
5767 | } |
5768 | |
5769 | for (i = 0; i < maff->n; ++i) { |
5770 | maff->u.p[i] = isl_aff_lift(maff->u.p[i]); |
5771 | if (!maff->u.p[i]) |
5772 | goto error; |
5773 | } |
5774 | |
5775 | return maff; |
5776 | error: |
5777 | if (ls) |
5778 | isl_local_space_free(*ls); |
5779 | return isl_multi_aff_free(maff); |
5780 | } |
5781 | |
5782 | |
5783 | /* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma". |
5784 | */ |
5785 | __isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff( |
5786 | __isl_keep isl_pw_multi_aff *pma, int pos) |
5787 | { |
5788 | int i; |
5789 | int n_out; |
5790 | isl_space *space; |
5791 | isl_pw_aff *pa; |
5792 | |
5793 | if (!pma) |
5794 | return NULL((void*)0); |
5795 | |
5796 | n_out = isl_pw_multi_aff_dim(pma, isl_dim_out); |
5797 | if (pos < 0 || pos >= n_out) |
5798 | isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid , "index out of bounds", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 5799); return ((void*)0); } while (0) |
5799 | "index out of bounds", return NULL)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid , "index out of bounds", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 5799); return ((void*)0); } while (0); |
5800 | |
5801 | space = isl_pw_multi_aff_get_space(pma); |
5802 | space = isl_space_drop_dims(space, isl_dim_out, |
5803 | pos + 1, n_out - pos - 1); |
5804 | space = isl_space_drop_dims(space, isl_dim_out, 0, pos); |
5805 | |
5806 | pa = isl_pw_aff_alloc_size(space, pma->n); |
5807 | for (i = 0; i < pma->n; ++i) { |
5808 | isl_aff *aff; |
5809 | aff = isl_multi_aff_get_aff(pma->p[i].maff, pos); |
5810 | pa = isl_pw_aff_add_piece(pa, isl_set_copy(pma->p[i].set), aff); |
5811 | } |
5812 | |
5813 | return pa; |
5814 | } |
5815 | |
5816 | /* Return an isl_pw_multi_aff with the given "set" as domain and |
5817 | * an unnamed zero-dimensional range. |
5818 | */ |
5819 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_domain( |
5820 | __isl_take isl_setisl_map *set) |
5821 | { |
5822 | isl_multi_aff *ma; |
5823 | isl_space *space; |
5824 | |
5825 | space = isl_set_get_space(set); |
5826 | space = isl_space_from_domain(space); |
5827 | ma = isl_multi_aff_zero(space); |
5828 | return isl_pw_multi_aff_alloc(set, ma); |
5829 | } |
5830 | |
5831 | /* Add an isl_pw_multi_aff with the given "set" as domain and |
5832 | * an unnamed zero-dimensional range to *user. |
5833 | */ |
5834 | static isl_stat add_pw_multi_aff_from_domain(__isl_take isl_setisl_map *set, |
5835 | void *user) |
5836 | { |
5837 | isl_union_pw_multi_aff **upma = user; |
5838 | isl_pw_multi_aff *pma; |
5839 | |
5840 | pma = isl_pw_multi_aff_from_domain(set); |
5841 | *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma); |
5842 | |
5843 | return isl_stat_ok; |
5844 | } |
5845 | |
5846 | /* Return an isl_union_pw_multi_aff with the given "uset" as domain and |
5847 | * an unnamed zero-dimensional range. |
5848 | */ |
5849 | __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_domain( |
5850 | __isl_take isl_union_setisl_union_map *uset) |
5851 | { |
5852 | isl_space *space; |
5853 | isl_union_pw_multi_aff *upma; |
5854 | |
5855 | if (!uset) |
5856 | return NULL((void*)0); |
5857 | |
5858 | space = isl_union_set_get_space(uset); |
5859 | upma = isl_union_pw_multi_aff_empty(space); |
5860 | |
5861 | if (isl_union_set_foreach_set(uset, |
5862 | &add_pw_multi_aff_from_domain, &upma) < 0) |
5863 | goto error; |
5864 | |
5865 | isl_union_set_free(uset); |
5866 | return upma; |
5867 | error: |
5868 | isl_union_set_free(uset); |
5869 | isl_union_pw_multi_aff_free(upma); |
5870 | return NULL((void*)0); |
5871 | } |
5872 | |
5873 | /* Local data for bin_entry and the callback "fn". |
5874 | */ |
5875 | struct isl_union_pw_multi_aff_bin_data { |
5876 | isl_union_pw_multi_aff *upma2; |
5877 | isl_union_pw_multi_aff *res; |
5878 | isl_pw_multi_aff *pma; |
5879 | isl_stat (*fn)(__isl_take isl_pw_multi_aff *pma, void *user); |
5880 | }; |
5881 | |
5882 | /* Given an isl_pw_multi_aff from upma1, store it in data->pma |
5883 | * and call data->fn for each isl_pw_multi_aff in data->upma2. |
5884 | */ |
5885 | static isl_stat bin_entry(__isl_take isl_pw_multi_aff *pma, void *user) |
5886 | { |
5887 | struct isl_union_pw_multi_aff_bin_data *data = user; |
5888 | isl_stat r; |
5889 | |
5890 | data->pma = pma; |
5891 | r = isl_union_pw_multi_aff_foreach_pw_multi_aff(data->upma2, |
5892 | data->fn, data); |
5893 | isl_pw_multi_aff_free(pma); |
5894 | |
5895 | return r; |
5896 | } |
5897 | |
5898 | /* Call "fn" on each pair of isl_pw_multi_affs in "upma1" and "upma2". |
5899 | * The isl_pw_multi_aff from upma1 is stored in data->pma (where data is |
5900 | * passed as user field) and the isl_pw_multi_aff from upma2 is available |
5901 | * as *entry. The callback should adjust data->res if desired. |
5902 | */ |
5903 | static __isl_give isl_union_pw_multi_aff *bin_op( |
5904 | __isl_take isl_union_pw_multi_aff *upma1, |
5905 | __isl_take isl_union_pw_multi_aff *upma2, |
5906 | isl_stat (*fn)(__isl_take isl_pw_multi_aff *pma, void *user)) |
5907 | { |
5908 | isl_space *space; |
5909 | struct isl_union_pw_multi_aff_bin_data data = { NULL((void*)0), NULL((void*)0), NULL((void*)0), fn }; |
5910 | |
5911 | space = isl_union_pw_multi_aff_get_space(upma2); |
5912 | upma1 = isl_union_pw_multi_aff_align_params(upma1, space); |
5913 | space = isl_union_pw_multi_aff_get_space(upma1); |
5914 | upma2 = isl_union_pw_multi_aff_align_params(upma2, space); |
5915 | |
5916 | if (!upma1 || !upma2) |
5917 | goto error; |
5918 | |
5919 | data.upma2 = upma2; |
5920 | data.res = isl_union_pw_multi_aff_alloc_same_size(upma1); |
5921 | if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma1, |
5922 | &bin_entry, &data) < 0) |
5923 | goto error; |
5924 | |
5925 | isl_union_pw_multi_aff_free(upma1); |
5926 | isl_union_pw_multi_aff_free(upma2); |
5927 | return data.res; |
5928 | error: |
5929 | isl_union_pw_multi_aff_free(upma1); |
5930 | isl_union_pw_multi_aff_free(upma2); |
5931 | isl_union_pw_multi_aff_free(data.res); |
5932 | return NULL((void*)0); |
5933 | } |
5934 | |
5935 | /* Given two aligned isl_pw_multi_affs A -> B and C -> D, |
5936 | * construct an isl_pw_multi_aff (A * C) -> [B -> D]. |
5937 | */ |
5938 | static __isl_give isl_pw_multi_aff *pw_multi_aff_range_product( |
5939 | __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2) |
5940 | { |
5941 | isl_space *space; |
5942 | |
5943 | space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1), |
5944 | isl_pw_multi_aff_get_space(pma2)); |
5945 | return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space, |
5946 | &isl_multi_aff_range_product); |
5947 | } |
5948 | |
5949 | /* Given two isl_pw_multi_affs A -> B and C -> D, |
5950 | * construct an isl_pw_multi_aff (A * C) -> [B -> D]. |
5951 | */ |
5952 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_product( |
5953 | __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2) |
5954 | { |
5955 | return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2, |
5956 | &pw_multi_aff_range_product); |
5957 | } |
5958 | |
5959 | /* Given two aligned isl_pw_multi_affs A -> B and C -> D, |
5960 | * construct an isl_pw_multi_aff (A * C) -> (B, D). |
5961 | */ |
5962 | static __isl_give isl_pw_multi_aff *pw_multi_aff_flat_range_product( |
5963 | __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2) |
5964 | { |
5965 | isl_space *space; |
5966 | |
5967 | space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1), |
5968 | isl_pw_multi_aff_get_space(pma2)); |
5969 | space = isl_space_flatten_range(space); |
5970 | return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space, |
5971 | &isl_multi_aff_flat_range_product); |
5972 | } |
5973 | |
5974 | /* Given two isl_pw_multi_affs A -> B and C -> D, |
5975 | * construct an isl_pw_multi_aff (A * C) -> (B, D). |
5976 | */ |
5977 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_flat_range_product( |
5978 | __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2) |
5979 | { |
5980 | return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2, |
5981 | &pw_multi_aff_flat_range_product); |
5982 | } |
5983 | |
5984 | /* If data->pma and "pma2" have the same domain space, then compute |
5985 | * their flat range product and the result to data->res. |
5986 | */ |
5987 | static isl_stat flat_range_product_entry(__isl_take isl_pw_multi_aff *pma2, |
5988 | void *user) |
5989 | { |
5990 | struct isl_union_pw_multi_aff_bin_data *data = user; |
5991 | |
5992 | if (!isl_space_tuple_is_equal(data->pma->dim, isl_dim_in, |
5993 | pma2->dim, isl_dim_in)) { |
5994 | isl_pw_multi_aff_free(pma2); |
5995 | return isl_stat_ok; |
5996 | } |
5997 | |
5998 | pma2 = isl_pw_multi_aff_flat_range_product( |
5999 | isl_pw_multi_aff_copy(data->pma), pma2); |
6000 | |
6001 | data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2); |
6002 | |
6003 | return isl_stat_ok; |
6004 | } |
6005 | |
6006 | /* Given two isl_union_pw_multi_affs A -> B and C -> D, |
6007 | * construct an isl_union_pw_multi_aff (A * C) -> (B, D). |
6008 | */ |
6009 | __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_flat_range_product( |
6010 | __isl_take isl_union_pw_multi_aff *upma1, |
6011 | __isl_take isl_union_pw_multi_aff *upma2) |
6012 | { |
6013 | return bin_op(upma1, upma2, &flat_range_product_entry); |
6014 | } |
6015 | |
6016 | /* Replace the affine expressions at position "pos" in "pma" by "pa". |
6017 | * The parameters are assumed to have been aligned. |
6018 | * |
6019 | * The implementation essentially performs an isl_pw_*_on_shared_domain, |
6020 | * except that it works on two different isl_pw_* types. |
6021 | */ |
6022 | static __isl_give isl_pw_multi_aff *pw_multi_aff_set_pw_aff( |
6023 | __isl_take isl_pw_multi_aff *pma, unsigned pos, |
6024 | __isl_take isl_pw_aff *pa) |
6025 | { |
6026 | int i, j, n; |
6027 | isl_pw_multi_aff *res = NULL((void*)0); |
6028 | |
6029 | if (!pma || !pa) |
6030 | goto error; |
6031 | |
6032 | if (!isl_space_tuple_is_equal(pma->dim, isl_dim_in, |
6033 | pa->dim, isl_dim_in)) |
6034 | isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid , "domains don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 6035); goto error; } while (0) |
6035 | "domains don't match", goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid , "domains don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 6035); goto error; } while (0); |
6036 | if (pos >= isl_pw_multi_aff_dim(pma, isl_dim_out)) |
6037 | isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid , "index out of bounds", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 6038); goto error; } while (0) |
6038 | "index out of bounds", goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid , "index out of bounds", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 6038); goto error; } while (0); |
6039 | |
6040 | n = pma->n * pa->n; |
6041 | res = isl_pw_multi_aff_alloc_size(isl_pw_multi_aff_get_space(pma), n); |
6042 | |
6043 | for (i = 0; i < pma->n; ++i) { |
6044 | for (j = 0; j < pa->n; ++j) { |
6045 | isl_setisl_map *common; |
6046 | isl_multi_aff *res_ij; |
6047 | int empty; |
6048 | |
6049 | common = isl_set_intersect(isl_set_copy(pma->p[i].set), |
6050 | isl_set_copy(pa->p[j].set)); |
6051 | empty = isl_set_plain_is_empty(common); |
6052 | if (empty < 0 || empty) { |
6053 | isl_set_free(common); |
6054 | if (empty < 0) |
6055 | goto error; |
6056 | continue; |
6057 | } |
6058 | |
6059 | res_ij = isl_multi_aff_set_aff( |
6060 | isl_multi_aff_copy(pma->p[i].maff), pos, |
6061 | isl_aff_copy(pa->p[j].aff)); |
6062 | res_ij = isl_multi_aff_gist(res_ij, |
6063 | isl_set_copy(common)); |
6064 | |
6065 | res = isl_pw_multi_aff_add_piece(res, common, res_ij); |
6066 | } |
6067 | } |
6068 | |
6069 | isl_pw_multi_aff_free(pma); |
6070 | isl_pw_aff_free(pa); |
6071 | return res; |
6072 | error: |
6073 | isl_pw_multi_aff_free(pma); |
6074 | isl_pw_aff_free(pa); |
6075 | return isl_pw_multi_aff_free(res); |
6076 | } |
6077 | |
6078 | /* Replace the affine expressions at position "pos" in "pma" by "pa". |
6079 | */ |
6080 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_pw_aff( |
6081 | __isl_take isl_pw_multi_aff *pma, unsigned pos, |
6082 | __isl_take isl_pw_aff *pa) |
6083 | { |
6084 | isl_bool equal_params; |
6085 | |
6086 | if (!pma || !pa) |
6087 | goto error; |
6088 | equal_params = isl_space_has_equal_params(pma->dim, pa->dim); |
6089 | if (equal_params < 0) |
6090 | goto error; |
6091 | if (equal_params) |
6092 | return pw_multi_aff_set_pw_aff(pma, pos, pa); |
6093 | if (isl_pw_multi_aff_check_named_params(pma) < 0 || |
6094 | isl_pw_aff_check_named_params(pa) < 0) |
6095 | goto error; |
6096 | pma = isl_pw_multi_aff_align_params(pma, isl_pw_aff_get_space(pa)); |
6097 | pa = isl_pw_aff_align_params(pa, isl_pw_multi_aff_get_space(pma)); |
6098 | return pw_multi_aff_set_pw_aff(pma, pos, pa); |
6099 | error: |
6100 | isl_pw_multi_aff_free(pma); |
6101 | isl_pw_aff_free(pa); |
6102 | return NULL((void*)0); |
6103 | } |
6104 | |
6105 | /* Do the parameters of "pa" match those of "space"? |
6106 | */ |
6107 | isl_bool isl_pw_aff_matching_params(__isl_keep isl_pw_aff *pa, |
6108 | __isl_keep isl_space *space) |
6109 | { |
6110 | isl_space *pa_space; |
6111 | isl_bool match; |
6112 | |
6113 | if (!pa || !space) |
6114 | return isl_bool_error; |
6115 | |
6116 | pa_space = isl_pw_aff_get_space(pa); |
6117 | |
6118 | match = isl_space_has_equal_params(space, pa_space); |
6119 | |
6120 | isl_space_free(pa_space); |
6121 | return match; |
6122 | } |
6123 | |
6124 | /* Check that the domain space of "pa" matches "space". |
6125 | */ |
6126 | isl_stat isl_pw_aff_check_match_domain_space(__isl_keep isl_pw_aff *pa, |
6127 | __isl_keep isl_space *space) |
6128 | { |
6129 | isl_space *pa_space; |
6130 | isl_bool match; |
6131 | |
6132 | if (!pa || !space) |
6133 | return isl_stat_error; |
6134 | |
6135 | pa_space = isl_pw_aff_get_space(pa); |
6136 | |
6137 | match = isl_space_has_equal_params(space, pa_space); |
6138 | if (match < 0) |
6139 | goto error; |
6140 | if (!match) |
6141 | isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid , "parameters don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 6142); goto error; } while (0) |
6142 | "parameters don't match", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid , "parameters don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 6142); goto error; } while (0); |
6143 | match = isl_space_tuple_is_equal(space, isl_dim_in, |
6144 | pa_space, isl_dim_in); |
6145 | if (match < 0) |
6146 | goto error; |
6147 | if (!match) |
6148 | isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid , "domains don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 6149); goto error; } while (0) |
6149 | "domains don't match", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid , "domains don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 6149); goto error; } while (0); |
6150 | isl_space_free(pa_space); |
6151 | return isl_stat_ok; |
6152 | error: |
6153 | isl_space_free(pa_space); |
6154 | return isl_stat_error; |
6155 | } |
6156 | |
6157 | #undef BASEunion_pw_aff |
6158 | #define BASEunion_pw_aff pw_aff |
6159 | #undef DOMBASEunion_set |
6160 | #define DOMBASEunion_set set |
6161 | |
6162 | #include <isl_multi_explicit_domain.c> |
6163 | #include <isl_multi_pw_aff_explicit_domain.c> |
6164 | #include <isl_multi_templ.c> |
6165 | #include <isl_multi_apply_set.c> |
6166 | #include <isl_multi_coalesce.c> |
6167 | #include <isl_multi_dims.c> |
6168 | #include <isl_multi_gist.c> |
6169 | #include <isl_multi_hash.c> |
6170 | #include <isl_multi_align_set.c> |
6171 | #include <isl_multi_intersect.c> |
6172 | |
6173 | /* Does "mpa" have a non-trivial explicit domain? |
6174 | * |
6175 | * The explicit domain, if present, is trivial if it represents |
6176 | * an (obviously) universe set. |
6177 | */ |
6178 | isl_bool isl_multi_pw_aff_has_non_trivial_domain( |
6179 | __isl_keep isl_multi_pw_aff *mpa) |
6180 | { |
6181 | if (!mpa) |
6182 | return isl_bool_error; |
6183 | if (!isl_multi_pw_aff_has_explicit_domain(mpa)) |
6184 | return isl_bool_false; |
6185 | return isl_bool_not(isl_set_plain_is_universe(mpa->u.dom)); |
6186 | } |
6187 | |
6188 | /* Scale the elements of "pma" by the corresponding elements of "mv". |
6189 | */ |
6190 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_multi_val( |
6191 | __isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv) |
6192 | { |
6193 | int i; |
6194 | isl_bool equal_params; |
6195 | |
6196 | pma = isl_pw_multi_aff_cow(pma); |
6197 | if (!pma || !mv) |
6198 | goto error; |
6199 | if (!isl_space_tuple_is_equal(pma->dim, isl_dim_out, |
6200 | mv->space, isl_dim_set)) |
6201 | isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid , "spaces don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 6202); goto error; } while (0) |
6202 | "spaces don't match", goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid , "spaces don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 6202); goto error; } while (0); |
6203 | equal_params = isl_space_has_equal_params(pma->dim, mv->space); |
6204 | if (equal_params < 0) |
6205 | goto error; |
6206 | if (!equal_params) { |
6207 | pma = isl_pw_multi_aff_align_params(pma, |
6208 | isl_multi_val_get_space(mv)); |
6209 | mv = isl_multi_val_align_params(mv, |
6210 | isl_pw_multi_aff_get_space(pma)); |
6211 | if (!pma || !mv) |
6212 | goto error; |
6213 | } |
6214 | |
6215 | for (i = 0; i < pma->n; ++i) { |
6216 | pma->p[i].maff = isl_multi_aff_scale_multi_val(pma->p[i].maff, |
6217 | isl_multi_val_copy(mv)); |
6218 | if (!pma->p[i].maff) |
6219 | goto error; |
6220 | } |
6221 | |
6222 | isl_multi_val_free(mv); |
6223 | return pma; |
6224 | error: |
6225 | isl_multi_val_free(mv); |
6226 | isl_pw_multi_aff_free(pma); |
6227 | return NULL((void*)0); |
6228 | } |
6229 | |
6230 | /* This function is called for each entry of an isl_union_pw_multi_aff. |
6231 | * If the space of the entry matches that of data->mv, |
6232 | * then apply isl_pw_multi_aff_scale_multi_val and return the result. |
6233 | * Otherwise, return an empty isl_pw_multi_aff. |
6234 | */ |
6235 | static __isl_give isl_pw_multi_aff *union_pw_multi_aff_scale_multi_val_entry( |
6236 | __isl_take isl_pw_multi_aff *pma, void *user) |
6237 | { |
6238 | isl_multi_val *mv = user; |
6239 | |
6240 | if (!pma) |
6241 | return NULL((void*)0); |
6242 | if (!isl_space_tuple_is_equal(pma->dim, isl_dim_out, |
6243 | mv->space, isl_dim_set)) { |
6244 | isl_space *space = isl_pw_multi_aff_get_space(pma); |
6245 | isl_pw_multi_aff_free(pma); |
6246 | return isl_pw_multi_aff_empty(space); |
6247 | } |
6248 | |
6249 | return isl_pw_multi_aff_scale_multi_val(pma, isl_multi_val_copy(mv)); |
6250 | } |
6251 | |
6252 | /* Scale the elements of "upma" by the corresponding elements of "mv", |
6253 | * for those entries that match the space of "mv". |
6254 | */ |
6255 | __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_scale_multi_val( |
6256 | __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_multi_val *mv) |
6257 | { |
6258 | upma = isl_union_pw_multi_aff_align_params(upma, |
6259 | isl_multi_val_get_space(mv)); |
6260 | mv = isl_multi_val_align_params(mv, |
6261 | isl_union_pw_multi_aff_get_space(upma)); |
6262 | if (!upma || !mv) |
6263 | goto error; |
6264 | |
6265 | return isl_union_pw_multi_aff_transform(upma, |
6266 | &union_pw_multi_aff_scale_multi_val_entry, mv); |
6267 | |
6268 | isl_multi_val_free(mv); |
6269 | return upma; |
6270 | error: |
6271 | isl_multi_val_free(mv); |
6272 | isl_union_pw_multi_aff_free(upma); |
6273 | return NULL((void*)0); |
6274 | } |
6275 | |
6276 | /* Construct and return a piecewise multi affine expression |
6277 | * in the given space with value zero in each of the output dimensions and |
6278 | * a universe domain. |
6279 | */ |
6280 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_zero(__isl_take isl_space *space) |
6281 | { |
6282 | return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_zero(space)); |
6283 | } |
6284 | |
6285 | /* Construct and return a piecewise multi affine expression |
6286 | * that is equal to the given piecewise affine expression. |
6287 | */ |
6288 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_pw_aff( |
6289 | __isl_take isl_pw_aff *pa) |
6290 | { |
6291 | int i; |
6292 | isl_space *space; |
6293 | isl_pw_multi_aff *pma; |
6294 | |
6295 | if (!pa) |
6296 | return NULL((void*)0); |
6297 | |
6298 | space = isl_pw_aff_get_space(pa); |
6299 | pma = isl_pw_multi_aff_alloc_size(space, pa->n); |
6300 | |
6301 | for (i = 0; i < pa->n; ++i) { |
6302 | isl_setisl_map *set; |
6303 | isl_multi_aff *ma; |
6304 | |
6305 | set = isl_set_copy(pa->p[i].set); |
6306 | ma = isl_multi_aff_from_aff(isl_aff_copy(pa->p[i].aff)); |
6307 | pma = isl_pw_multi_aff_add_piece(pma, set, ma); |
6308 | } |
6309 | |
6310 | isl_pw_aff_free(pa); |
6311 | return pma; |
6312 | } |
6313 | |
6314 | /* Construct and return a piecewise multi affine expression |
6315 | * that is equal to the given multi piecewise affine expression |
6316 | * on the shared domain of the piecewise affine expressions, |
6317 | * in the special case of a 0D multi piecewise affine expression. |
6318 | * |
6319 | * Create a piecewise multi affine expression with the explicit domain of |
6320 | * the 0D multi piecewise affine expression as domain. |
6321 | */ |
6322 | static __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff_0D( |
6323 | __isl_take isl_multi_pw_aff *mpa) |
6324 | { |
6325 | isl_space *space; |
6326 | isl_setisl_map *dom; |
6327 | isl_multi_aff *ma; |
6328 | |
6329 | space = isl_multi_pw_aff_get_space(mpa); |
6330 | dom = isl_multi_pw_aff_get_explicit_domain(mpa); |
6331 | isl_multi_pw_aff_free(mpa); |
6332 | |
6333 | ma = isl_multi_aff_zero(space); |
6334 | return isl_pw_multi_aff_alloc(dom, ma); |
6335 | } |
6336 | |
6337 | /* Construct and return a piecewise multi affine expression |
6338 | * that is equal to the given multi piecewise affine expression |
6339 | * on the shared domain of the piecewise affine expressions. |
6340 | */ |
6341 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff( |
6342 | __isl_take isl_multi_pw_aff *mpa) |
6343 | { |
6344 | int i; |
6345 | isl_space *space; |
6346 | isl_pw_aff *pa; |
6347 | isl_pw_multi_aff *pma; |
6348 | |
6349 | if (!mpa) |
6350 | return NULL((void*)0); |
6351 | |
6352 | if (mpa->n == 0) |
6353 | return isl_pw_multi_aff_from_multi_pw_aff_0D(mpa); |
6354 | |
6355 | space = isl_multi_pw_aff_get_space(mpa); |
6356 | pa = isl_multi_pw_aff_get_pw_aff(mpa, 0); |
6357 | pma = isl_pw_multi_aff_from_pw_aff(pa); |
6358 | |
6359 | for (i = 1; i < mpa->n; ++i) { |
6360 | isl_pw_multi_aff *pma_i; |
6361 | |
6362 | pa = isl_multi_pw_aff_get_pw_aff(mpa, i); |
6363 | pma_i = isl_pw_multi_aff_from_pw_aff(pa); |
6364 | pma = isl_pw_multi_aff_range_product(pma, pma_i); |
6365 | } |
6366 | |
6367 | pma = isl_pw_multi_aff_reset_space(pma, space); |
6368 | |
6369 | isl_multi_pw_aff_free(mpa); |
6370 | return pma; |
6371 | } |
6372 | |
6373 | /* Construct and return a multi piecewise affine expression |
6374 | * that is equal to the given multi affine expression. |
6375 | */ |
6376 | __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_multi_aff( |
6377 | __isl_take isl_multi_aff *ma) |
6378 | { |
6379 | int i, n; |
6380 | isl_multi_pw_aff *mpa; |
6381 | |
6382 | if (!ma) |
6383 | return NULL((void*)0); |
6384 | |
6385 | n = isl_multi_aff_dim(ma, isl_dim_out); |
6386 | mpa = isl_multi_pw_aff_alloc(isl_multi_aff_get_space(ma)); |
6387 | |
6388 | for (i = 0; i < n; ++i) { |
6389 | isl_pw_aff *pa; |
6390 | |
6391 | pa = isl_pw_aff_from_aff(isl_multi_aff_get_aff(ma, i)); |
6392 | mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa); |
6393 | } |
6394 | |
6395 | isl_multi_aff_free(ma); |
6396 | return mpa; |
6397 | } |
6398 | |
6399 | /* Construct and return a multi piecewise affine expression |
6400 | * that is equal to the given piecewise multi affine expression. |
6401 | * |
6402 | * If the resulting multi piecewise affine expression has |
6403 | * an explicit domain, then assign it the domain of the input. |
6404 | * In other cases, the domain is stored in the individual elements. |
6405 | */ |
6406 | __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_multi_aff( |
6407 | __isl_take isl_pw_multi_aff *pma) |
6408 | { |
6409 | int i, n; |
6410 | isl_space *space; |
6411 | isl_multi_pw_aff *mpa; |
6412 | |
6413 | if (!pma) |
6414 | return NULL((void*)0); |
6415 | |
6416 | n = isl_pw_multi_aff_dim(pma, isl_dim_out); |
6417 | space = isl_pw_multi_aff_get_space(pma); |
6418 | mpa = isl_multi_pw_aff_alloc(space); |
6419 | |
6420 | for (i = 0; i < n; ++i) { |
6421 | isl_pw_aff *pa; |
6422 | |
6423 | pa = isl_pw_multi_aff_get_pw_aff(pma, i); |
6424 | mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa); |
6425 | } |
6426 | if (isl_multi_pw_aff_has_explicit_domain(mpa)) { |
6427 | isl_setisl_map *dom; |
6428 | |
6429 | dom = isl_pw_multi_aff_domain(isl_pw_multi_aff_copy(pma)); |
6430 | mpa = isl_multi_pw_aff_intersect_domain(mpa, dom); |
6431 | } |
6432 | |
6433 | isl_pw_multi_aff_free(pma); |
6434 | return mpa; |
6435 | } |
6436 | |
6437 | /* Do "pa1" and "pa2" represent the same function? |
6438 | * |
6439 | * We first check if they are obviously equal. |
6440 | * If not, we convert them to maps and check if those are equal. |
6441 | * |
6442 | * If "pa1" or "pa2" contain any NaNs, then they are considered |
6443 | * not to be the same. A NaN is not equal to anything, not even |
6444 | * to another NaN. |
6445 | */ |
6446 | isl_bool isl_pw_aff_is_equal(__isl_keep isl_pw_aff *pa1, |
6447 | __isl_keep isl_pw_aff *pa2) |
6448 | { |
6449 | isl_bool equal; |
6450 | isl_bool has_nan; |
6451 | isl_map *map1, *map2; |
6452 | |
6453 | if (!pa1 || !pa2) |
6454 | return isl_bool_error; |
6455 | |
6456 | equal = isl_pw_aff_plain_is_equal(pa1, pa2); |
6457 | if (equal < 0 || equal) |
6458 | return equal; |
6459 | has_nan = either_involves_nan(pa1, pa2); |
6460 | if (has_nan < 0) |
6461 | return isl_bool_error; |
6462 | if (has_nan) |
6463 | return isl_bool_false; |
6464 | |
6465 | map1 = isl_map_from_pw_aff_internal(isl_pw_aff_copy(pa1)); |
6466 | map2 = isl_map_from_pw_aff_internal(isl_pw_aff_copy(pa2)); |
6467 | equal = isl_map_is_equal(map1, map2); |
6468 | isl_map_free(map1); |
6469 | isl_map_free(map2); |
6470 | |
6471 | return equal; |
6472 | } |
6473 | |
6474 | /* Do "mpa1" and "mpa2" represent the same function? |
6475 | * |
6476 | * Note that we cannot convert the entire isl_multi_pw_aff |
6477 | * to a map because the domains of the piecewise affine expressions |
6478 | * may not be the same. |
6479 | */ |
6480 | isl_bool isl_multi_pw_aff_is_equal(__isl_keep isl_multi_pw_aff *mpa1, |
6481 | __isl_keep isl_multi_pw_aff *mpa2) |
6482 | { |
6483 | int i; |
6484 | isl_bool equal, equal_params; |
6485 | |
6486 | if (!mpa1 || !mpa2) |
6487 | return isl_bool_error; |
6488 | |
6489 | equal_params = isl_space_has_equal_params(mpa1->space, mpa2->space); |
6490 | if (equal_params < 0) |
6491 | return isl_bool_error; |
6492 | if (!equal_params) { |
6493 | if (!isl_space_has_named_params(mpa1->space)) |
6494 | return isl_bool_false; |
6495 | if (!isl_space_has_named_params(mpa2->space)) |
6496 | return isl_bool_false; |
6497 | mpa1 = isl_multi_pw_aff_copy(mpa1); |
6498 | mpa2 = isl_multi_pw_aff_copy(mpa2); |
6499 | mpa1 = isl_multi_pw_aff_align_params(mpa1, |
6500 | isl_multi_pw_aff_get_space(mpa2)); |
6501 | mpa2 = isl_multi_pw_aff_align_params(mpa2, |
6502 | isl_multi_pw_aff_get_space(mpa1)); |
6503 | equal = isl_multi_pw_aff_is_equal(mpa1, mpa2); |
6504 | isl_multi_pw_aff_free(mpa1); |
6505 | isl_multi_pw_aff_free(mpa2); |
6506 | return equal; |
6507 | } |
6508 | |
6509 | equal = isl_space_is_equal(mpa1->space, mpa2->space); |
6510 | if (equal < 0 || !equal) |
6511 | return equal; |
6512 | |
6513 | for (i = 0; i < mpa1->n; ++i) { |
6514 | equal = isl_pw_aff_is_equal(mpa1->u.p[i], mpa2->u.p[i]); |
6515 | if (equal < 0 || !equal) |
6516 | return equal; |
6517 | } |
6518 | |
6519 | return isl_bool_true; |
6520 | } |
6521 | |
6522 | /* Do "pma1" and "pma2" represent the same function? |
6523 | * |
6524 | * First check if they are obviously equal. |
6525 | * If not, then convert them to maps and check if those are equal. |
6526 | * |
6527 | * If "pa1" or "pa2" contain any NaNs, then they are considered |
6528 | * not to be the same. A NaN is not equal to anything, not even |
6529 | * to another NaN. |
6530 | */ |
6531 | isl_bool isl_pw_multi_aff_is_equal(__isl_keep isl_pw_multi_aff *pma1, |
6532 | __isl_keep isl_pw_multi_aff *pma2) |
6533 | { |
6534 | isl_bool equal; |
6535 | isl_bool has_nan; |
6536 | isl_map *map1, *map2; |
6537 | |
6538 | if (!pma1 || !pma2) |
6539 | return isl_bool_error; |
6540 | |
6541 | equal = isl_pw_multi_aff_plain_is_equal(pma1, pma2); |
6542 | if (equal < 0 || equal) |
6543 | return equal; |
6544 | has_nan = isl_pw_multi_aff_involves_nan(pma1); |
6545 | if (has_nan >= 0 && !has_nan) |
6546 | has_nan = isl_pw_multi_aff_involves_nan(pma2); |
6547 | if (has_nan < 0 || has_nan) |
6548 | return isl_bool_not(has_nan); |
6549 | |
6550 | map1 = isl_map_from_pw_multi_aff(isl_pw_multi_aff_copy(pma1)); |
6551 | map2 = isl_map_from_pw_multi_aff(isl_pw_multi_aff_copy(pma2)); |
6552 | equal = isl_map_is_equal(map1, map2); |
6553 | isl_map_free(map1); |
6554 | isl_map_free(map2); |
6555 | |
6556 | return equal; |
6557 | } |
6558 | |
6559 | /* Compute the pullback of "mpa" by the function represented by "ma". |
6560 | * In other words, plug in "ma" in "mpa". |
6561 | * |
6562 | * The parameters of "mpa" and "ma" are assumed to have been aligned. |
6563 | * |
6564 | * If "mpa" has an explicit domain, then it is this domain |
6565 | * that needs to undergo a pullback, i.e., a preimage. |
6566 | */ |
6567 | static __isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_aff_aligned( |
6568 | __isl_take isl_multi_pw_aff *mpa, __isl_take isl_multi_aff *ma) |
6569 | { |
6570 | int i; |
6571 | isl_space *space = NULL((void*)0); |
6572 | |
6573 | mpa = isl_multi_pw_aff_cow(mpa); |
6574 | if (!mpa || !ma) |
6575 | goto error; |
6576 | |
6577 | space = isl_space_join(isl_multi_aff_get_space(ma), |
6578 | isl_multi_pw_aff_get_space(mpa)); |
6579 | if (!space) |
6580 | goto error; |
6581 | |
6582 | for (i = 0; i < mpa->n; ++i) { |
6583 | mpa->u.p[i] = isl_pw_aff_pullback_multi_aff(mpa->u.p[i], |
6584 | isl_multi_aff_copy(ma)); |
6585 | if (!mpa->u.p[i]) |
6586 | goto error; |
6587 | } |
6588 | if (isl_multi_pw_aff_has_explicit_domain(mpa)) { |
6589 | mpa->u.dom = isl_set_preimage_multi_aff(mpa->u.dom, |
6590 | isl_multi_aff_copy(ma)); |
6591 | if (!mpa->u.dom) |
6592 | goto error; |
6593 | } |
6594 | |
6595 | isl_multi_aff_free(ma); |
6596 | isl_space_free(mpa->space); |
6597 | mpa->space = space; |
6598 | return mpa; |
6599 | error: |
6600 | isl_space_free(space); |
6601 | isl_multi_pw_aff_free(mpa); |
6602 | isl_multi_aff_free(ma); |
6603 | return NULL((void*)0); |
6604 | } |
6605 | |
6606 | /* Compute the pullback of "mpa" by the function represented by "ma". |
6607 | * In other words, plug in "ma" in "mpa". |
6608 | */ |
6609 | __isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_aff( |
6610 | __isl_take isl_multi_pw_aff *mpa, __isl_take isl_multi_aff *ma) |
6611 | { |
6612 | isl_bool equal_params; |
6613 | |
6614 | if (!mpa || !ma) |
6615 | goto error; |
6616 | equal_params = isl_space_has_equal_params(mpa->space, ma->space); |
6617 | if (equal_params < 0) |
6618 | goto error; |
6619 | if (equal_params) |
6620 | return isl_multi_pw_aff_pullback_multi_aff_aligned(mpa, ma); |
6621 | mpa = isl_multi_pw_aff_align_params(mpa, isl_multi_aff_get_space(ma)); |
6622 | ma = isl_multi_aff_align_params(ma, isl_multi_pw_aff_get_space(mpa)); |
6623 | return isl_multi_pw_aff_pullback_multi_aff_aligned(mpa, ma); |
6624 | error: |
6625 | isl_multi_pw_aff_free(mpa); |
6626 | isl_multi_aff_free(ma); |
6627 | return NULL((void*)0); |
6628 | } |
6629 | |
6630 | /* Compute the pullback of "mpa" by the function represented by "pma". |
6631 | * In other words, plug in "pma" in "mpa". |
6632 | * |
6633 | * The parameters of "mpa" and "mpa" are assumed to have been aligned. |
6634 | * |
6635 | * If "mpa" has an explicit domain, then it is this domain |
6636 | * that needs to undergo a pullback, i.e., a preimage. |
6637 | */ |
6638 | static __isl_give isl_multi_pw_aff * |
6639 | isl_multi_pw_aff_pullback_pw_multi_aff_aligned( |
6640 | __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_multi_aff *pma) |
6641 | { |
6642 | int i; |
6643 | isl_space *space = NULL((void*)0); |
6644 | |
6645 | mpa = isl_multi_pw_aff_cow(mpa); |
6646 | if (!mpa || !pma) |
6647 | goto error; |
6648 | |
6649 | space = isl_space_join(isl_pw_multi_aff_get_space(pma), |
6650 | isl_multi_pw_aff_get_space(mpa)); |
6651 | |
6652 | for (i = 0; i < mpa->n; ++i) { |
6653 | mpa->u.p[i] = isl_pw_aff_pullback_pw_multi_aff_aligned( |
6654 | mpa->u.p[i], isl_pw_multi_aff_copy(pma)); |
6655 | if (!mpa->u.p[i]) |
6656 | goto error; |
6657 | } |
6658 | if (isl_multi_pw_aff_has_explicit_domain(mpa)) { |
6659 | mpa->u.dom = isl_set_preimage_pw_multi_aff(mpa->u.dom, |
6660 | isl_pw_multi_aff_copy(pma)); |
6661 | if (!mpa->u.dom) |
6662 | goto error; |
6663 | } |
6664 | |
6665 | isl_pw_multi_aff_free(pma); |
6666 | isl_space_free(mpa->space); |
6667 | mpa->space = space; |
6668 | return mpa; |
6669 | error: |
6670 | isl_space_free(space); |
6671 | isl_multi_pw_aff_free(mpa); |
6672 | isl_pw_multi_aff_free(pma); |
6673 | return NULL((void*)0); |
6674 | } |
6675 | |
6676 | /* Compute the pullback of "mpa" by the function represented by "pma". |
6677 | * In other words, plug in "pma" in "mpa". |
6678 | */ |
6679 | __isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_pw_multi_aff( |
6680 | __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_multi_aff *pma) |
6681 | { |
6682 | isl_bool equal_params; |
6683 | |
6684 | if (!mpa || !pma) |
6685 | goto error; |
6686 | equal_params = isl_space_has_equal_params(mpa->space, pma->dim); |
6687 | if (equal_params < 0) |
6688 | goto error; |
6689 | if (equal_params) |
6690 | return isl_multi_pw_aff_pullback_pw_multi_aff_aligned(mpa, pma); |
6691 | mpa = isl_multi_pw_aff_align_params(mpa, |
6692 | isl_pw_multi_aff_get_space(pma)); |
6693 | pma = isl_pw_multi_aff_align_params(pma, |
6694 | isl_multi_pw_aff_get_space(mpa)); |
6695 | return isl_multi_pw_aff_pullback_pw_multi_aff_aligned(mpa, pma); |
6696 | error: |
6697 | isl_multi_pw_aff_free(mpa); |
6698 | isl_pw_multi_aff_free(pma); |
6699 | return NULL((void*)0); |
6700 | } |
6701 | |
6702 | /* Apply "aff" to "mpa". The range of "mpa" needs to be compatible |
6703 | * with the domain of "aff". The domain of the result is the same |
6704 | * as that of "mpa". |
6705 | * "mpa" and "aff" are assumed to have been aligned. |
6706 | * |
6707 | * We first extract the parametric constant from "aff", defined |
6708 | * over the correct domain. |
6709 | * Then we add the appropriate combinations of the members of "mpa". |
6710 | * Finally, we add the integer divisions through recursive calls. |
6711 | */ |
6712 | static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff_aligned( |
6713 | __isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff) |
6714 | { |
6715 | int i, n_in, n_div; |
6716 | isl_space *space; |
6717 | isl_val *v; |
6718 | isl_pw_aff *pa; |
6719 | isl_aff *tmp; |
6720 | |
6721 | n_in = isl_aff_dim(aff, isl_dim_in); |
6722 | n_div = isl_aff_dim(aff, isl_dim_div); |
6723 | |
6724 | space = isl_space_domain(isl_multi_pw_aff_get_space(mpa)); |
6725 | tmp = isl_aff_copy(aff); |
6726 | tmp = isl_aff_drop_dims(tmp, isl_dim_div, 0, n_div); |
6727 | tmp = isl_aff_drop_dims(tmp, isl_dim_in, 0, n_in); |
6728 | tmp = isl_aff_add_dims(tmp, isl_dim_in, |
6729 | isl_space_dim(space, isl_dim_set)); |
6730 | tmp = isl_aff_reset_domain_space(tmp, space); |
6731 | pa = isl_pw_aff_from_aff(tmp); |
6732 | |
6733 | for (i = 0; i < n_in; ++i) { |
6734 | isl_pw_aff *pa_i; |
6735 | |
6736 | if (!isl_aff_involves_dims(aff, isl_dim_in, i, 1)) |
6737 | continue; |
6738 | v = isl_aff_get_coefficient_val(aff, isl_dim_in, i); |
6739 | pa_i = isl_multi_pw_aff_get_pw_aff(mpa, i); |
6740 | pa_i = isl_pw_aff_scale_val(pa_i, v); |
6741 | pa = isl_pw_aff_add(pa, pa_i); |
6742 | } |
6743 | |
6744 | for (i = 0; i < n_div; ++i) { |
6745 | isl_aff *div; |
6746 | isl_pw_aff *pa_i; |
6747 | |
6748 | if (!isl_aff_involves_dims(aff, isl_dim_div, i, 1)) |
6749 | continue; |
6750 | div = isl_aff_get_div(aff, i); |
6751 | pa_i = isl_multi_pw_aff_apply_aff_aligned( |
6752 | isl_multi_pw_aff_copy(mpa), div); |
6753 | pa_i = isl_pw_aff_floor(pa_i); |
6754 | v = isl_aff_get_coefficient_val(aff, isl_dim_div, i); |
6755 | pa_i = isl_pw_aff_scale_val(pa_i, v); |
6756 | pa = isl_pw_aff_add(pa, pa_i); |
6757 | } |
6758 | |
6759 | isl_multi_pw_aff_free(mpa); |
6760 | isl_aff_free(aff); |
6761 | |
6762 | return pa; |
6763 | } |
6764 | |
6765 | /* Apply "aff" to "mpa". The range of "mpa" needs to be compatible |
6766 | * with the domain of "aff". The domain of the result is the same |
6767 | * as that of "mpa". |
6768 | */ |
6769 | __isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff( |
6770 | __isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff) |
6771 | { |
6772 | isl_bool equal_params; |
6773 | |
6774 | if (!aff || !mpa) |
6775 | goto error; |
6776 | equal_params = isl_space_has_equal_params(aff->ls->dim, mpa->space); |
6777 | if (equal_params < 0) |
6778 | goto error; |
6779 | if (equal_params) |
6780 | return isl_multi_pw_aff_apply_aff_aligned(mpa, aff); |
6781 | |
6782 | aff = isl_aff_align_params(aff, isl_multi_pw_aff_get_space(mpa)); |
6783 | mpa = isl_multi_pw_aff_align_params(mpa, isl_aff_get_space(aff)); |
6784 | |
6785 | return isl_multi_pw_aff_apply_aff_aligned(mpa, aff); |
6786 | error: |
6787 | isl_aff_free(aff); |
6788 | isl_multi_pw_aff_free(mpa); |
6789 | return NULL((void*)0); |
6790 | } |
6791 | |
6792 | /* Apply "pa" to "mpa". The range of "mpa" needs to be compatible |
6793 | * with the domain of "pa". The domain of the result is the same |
6794 | * as that of "mpa". |
6795 | * "mpa" and "pa" are assumed to have been aligned. |
6796 | * |
6797 | * We consider each piece in turn. Note that the domains of the |
6798 | * pieces are assumed to be disjoint and they remain disjoint |
6799 | * after taking the preimage (over the same function). |
6800 | */ |
6801 | static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_pw_aff_aligned( |
6802 | __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *pa) |
6803 | { |
6804 | isl_space *space; |
6805 | isl_pw_aff *res; |
6806 | int i; |
6807 | |
6808 | if (!mpa || !pa) |
6809 | goto error; |
6810 | |
6811 | space = isl_space_join(isl_multi_pw_aff_get_space(mpa), |
6812 | isl_pw_aff_get_space(pa)); |
6813 | res = isl_pw_aff_empty(space); |
6814 | |
6815 | for (i = 0; i < pa->n; ++i) { |
6816 | isl_pw_aff *pa_i; |
6817 | isl_setisl_map *domain; |
6818 | |
6819 | pa_i = isl_multi_pw_aff_apply_aff_aligned( |
6820 | isl_multi_pw_aff_copy(mpa), |
6821 | isl_aff_copy(pa->p[i].aff)); |
6822 | domain = isl_set_copy(pa->p[i].set); |
6823 | domain = isl_set_preimage_multi_pw_aff(domain, |
6824 | isl_multi_pw_aff_copy(mpa)); |
6825 | pa_i = isl_pw_aff_intersect_domain(pa_i, domain); |
6826 | res = isl_pw_aff_add_disjoint(res, pa_i); |
6827 | } |
6828 | |
6829 | isl_pw_aff_free(pa); |
6830 | isl_multi_pw_aff_free(mpa); |
6831 | return res; |
6832 | error: |
6833 | isl_pw_aff_free(pa); |
6834 | isl_multi_pw_aff_free(mpa); |
6835 | return NULL((void*)0); |
6836 | } |
6837 | |
6838 | /* Apply "pa" to "mpa". The range of "mpa" needs to be compatible |
6839 | * with the domain of "pa". The domain of the result is the same |
6840 | * as that of "mpa". |
6841 | */ |
6842 | __isl_give isl_pw_aff *isl_multi_pw_aff_apply_pw_aff( |
6843 | __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *pa) |
6844 | { |
6845 | isl_bool equal_params; |
6846 | |
6847 | if (!pa || !mpa) |
6848 | goto error; |
6849 | equal_params = isl_space_has_equal_params(pa->dim, mpa->space); |
6850 | if (equal_params < 0) |
6851 | goto error; |
6852 | if (equal_params) |
6853 | return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa); |
6854 | |
6855 | pa = isl_pw_aff_align_params(pa, isl_multi_pw_aff_get_space(mpa)); |
6856 | mpa = isl_multi_pw_aff_align_params(mpa, isl_pw_aff_get_space(pa)); |
6857 | |
6858 | return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa); |
6859 | error: |
6860 | isl_pw_aff_free(pa); |
6861 | isl_multi_pw_aff_free(mpa); |
6862 | return NULL((void*)0); |
6863 | } |
6864 | |
6865 | /* Compute the pullback of "pa" by the function represented by "mpa". |
6866 | * In other words, plug in "mpa" in "pa". |
6867 | * "pa" and "mpa" are assumed to have been aligned. |
6868 | * |
6869 | * The pullback is computed by applying "pa" to "mpa". |
6870 | */ |
6871 | static __isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff_aligned( |
6872 | __isl_take isl_pw_aff *pa, __isl_take isl_multi_pw_aff *mpa) |
6873 | { |
6874 | return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa); |
6875 | } |
6876 | |
6877 | /* Compute the pullback of "pa" by the function represented by "mpa". |
6878 | * In other words, plug in "mpa" in "pa". |
6879 | * |
6880 | * The pullback is computed by applying "pa" to "mpa". |
6881 | */ |
6882 | __isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff( |
6883 | __isl_take isl_pw_aff *pa, __isl_take isl_multi_pw_aff *mpa) |
6884 | { |
6885 | return isl_multi_pw_aff_apply_pw_aff(mpa, pa); |
6886 | } |
6887 | |
6888 | /* Compute the pullback of "mpa1" by the function represented by "mpa2". |
6889 | * In other words, plug in "mpa2" in "mpa1". |
6890 | * |
6891 | * The parameters of "mpa1" and "mpa2" are assumed to have been aligned. |
6892 | * |
6893 | * We pullback each member of "mpa1" in turn. |
6894 | * |
6895 | * If "mpa1" has an explicit domain, then it is this domain |
6896 | * that needs to undergo a pullback instead, i.e., a preimage. |
6897 | */ |
6898 | static __isl_give isl_multi_pw_aff * |
6899 | isl_multi_pw_aff_pullback_multi_pw_aff_aligned( |
6900 | __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2) |
6901 | { |
6902 | int i; |
6903 | isl_space *space = NULL((void*)0); |
6904 | |
6905 | mpa1 = isl_multi_pw_aff_cow(mpa1); |
6906 | if (!mpa1 || !mpa2) |
6907 | goto error; |
6908 | |
6909 | space = isl_space_join(isl_multi_pw_aff_get_space(mpa2), |
6910 | isl_multi_pw_aff_get_space(mpa1)); |
6911 | |
6912 | for (i = 0; i < mpa1->n; ++i) { |
6913 | mpa1->u.p[i] = isl_pw_aff_pullback_multi_pw_aff_aligned( |
6914 | mpa1->u.p[i], isl_multi_pw_aff_copy(mpa2)); |
6915 | if (!mpa1->u.p[i]) |
6916 | goto error; |
6917 | } |
6918 | |
6919 | if (isl_multi_pw_aff_has_explicit_domain(mpa1)) { |
6920 | mpa1->u.dom = isl_set_preimage_multi_pw_aff(mpa1->u.dom, |
6921 | isl_multi_pw_aff_copy(mpa2)); |
6922 | if (!mpa1->u.dom) |
6923 | goto error; |
6924 | } |
6925 | mpa1 = isl_multi_pw_aff_reset_space(mpa1, space); |
6926 | |
6927 | isl_multi_pw_aff_free(mpa2); |
6928 | return mpa1; |
6929 | error: |
6930 | isl_space_free(space); |
6931 | isl_multi_pw_aff_free(mpa1); |
6932 | isl_multi_pw_aff_free(mpa2); |
6933 | return NULL((void*)0); |
6934 | } |
6935 | |
6936 | /* Compute the pullback of "mpa1" by the function represented by "mpa2". |
6937 | * In other words, plug in "mpa2" in "mpa1". |
6938 | */ |
6939 | __isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_pw_aff( |
6940 | __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2) |
6941 | { |
6942 | return isl_multi_pw_aff_align_params_multi_multi_and(mpa1, mpa2, |
6943 | &isl_multi_pw_aff_pullback_multi_pw_aff_aligned); |
6944 | } |
6945 | |
6946 | /* Align the parameters of "mpa1" and "mpa2", check that the ranges |
6947 | * of "mpa1" and "mpa2" live in the same space, construct map space |
6948 | * between the domain spaces of "mpa1" and "mpa2" and call "order" |
6949 | * with this map space as extract argument. |
6950 | */ |
6951 | static __isl_give isl_map *isl_multi_pw_aff_order_map( |
6952 | __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2, |
6953 | __isl_give isl_map *(*order)(__isl_keep isl_multi_pw_aff *mpa1, |
6954 | __isl_keep isl_multi_pw_aff *mpa2, __isl_take isl_space *space)) |
6955 | { |
6956 | int match; |
6957 | isl_space *space1, *space2; |
6958 | isl_map *res; |
6959 | |
6960 | mpa1 = isl_multi_pw_aff_align_params(mpa1, |
6961 | isl_multi_pw_aff_get_space(mpa2)); |
6962 | mpa2 = isl_multi_pw_aff_align_params(mpa2, |
6963 | isl_multi_pw_aff_get_space(mpa1)); |
6964 | if (!mpa1 || !mpa2) |
6965 | goto error; |
6966 | match = isl_space_tuple_is_equal(mpa1->space, isl_dim_out, |
6967 | mpa2->space, isl_dim_out); |
6968 | if (match < 0) |
6969 | goto error; |
6970 | if (!match) |
6971 | isl_die(isl_multi_pw_aff_get_ctx(mpa1), isl_error_invalid,do { isl_handle_error(isl_multi_pw_aff_get_ctx(mpa1), isl_error_invalid , "range spaces don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 6972); goto error; } while (0) |
6972 | "range spaces don't match", goto error)do { isl_handle_error(isl_multi_pw_aff_get_ctx(mpa1), isl_error_invalid , "range spaces don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 6972); goto error; } while (0); |
6973 | space1 = isl_space_domain(isl_multi_pw_aff_get_space(mpa1)); |
6974 | space2 = isl_space_domain(isl_multi_pw_aff_get_space(mpa2)); |
6975 | space1 = isl_space_map_from_domain_and_range(space1, space2); |
6976 | |
6977 | res = order(mpa1, mpa2, space1); |
6978 | isl_multi_pw_aff_free(mpa1); |
6979 | isl_multi_pw_aff_free(mpa2); |
6980 | return res; |
6981 | error: |
6982 | isl_multi_pw_aff_free(mpa1); |
6983 | isl_multi_pw_aff_free(mpa2); |
6984 | return NULL((void*)0); |
6985 | } |
6986 | |
6987 | /* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" |
6988 | * where the function values are equal. "space" is the space of the result. |
6989 | * The parameters of "mpa1" and "mpa2" are assumed to have been aligned. |
6990 | * |
6991 | * "mpa1" and "mpa2" are equal when each of the pairs of elements |
6992 | * in the sequences are equal. |
6993 | */ |
6994 | static __isl_give isl_map *isl_multi_pw_aff_eq_map_on_space( |
6995 | __isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2, |
6996 | __isl_take isl_space *space) |
6997 | { |
6998 | int i, n; |
6999 | isl_map *res; |
7000 | |
7001 | res = isl_map_universe(space); |
7002 | |
7003 | n = isl_multi_pw_aff_dim(mpa1, isl_dim_out); |
7004 | for (i = 0; i < n; ++i) { |
7005 | isl_pw_aff *pa1, *pa2; |
7006 | isl_map *map; |
7007 | |
7008 | pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i); |
7009 | pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i); |
7010 | map = isl_pw_aff_eq_map(pa1, pa2); |
7011 | res = isl_map_intersect(res, map); |
7012 | } |
7013 | |
7014 | return res; |
7015 | } |
7016 | |
7017 | /* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" |
7018 | * where the function values are equal. |
7019 | */ |
7020 | __isl_give isl_map *isl_multi_pw_aff_eq_map(__isl_take isl_multi_pw_aff *mpa1, |
7021 | __isl_take isl_multi_pw_aff *mpa2) |
7022 | { |
7023 | return isl_multi_pw_aff_order_map(mpa1, mpa2, |
7024 | &isl_multi_pw_aff_eq_map_on_space); |
7025 | } |
7026 | |
7027 | /* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" |
7028 | * where the function values of "mpa1" is lexicographically satisfies "base" |
7029 | * compared to that of "mpa2". "space" is the space of the result. |
7030 | * The parameters of "mpa1" and "mpa2" are assumed to have been aligned. |
7031 | * |
7032 | * "mpa1" lexicographically satisfies "base" compared to "mpa2" |
7033 | * if its i-th element satisfies "base" when compared to |
7034 | * the i-th element of "mpa2" while all previous elements are |
7035 | * pairwise equal. |
7036 | */ |
7037 | static __isl_give isl_map *isl_multi_pw_aff_lex_map_on_space( |
7038 | __isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2, |
7039 | __isl_give isl_map *(*base)(__isl_take isl_pw_aff *pa1, |
7040 | __isl_take isl_pw_aff *pa2), |
7041 | __isl_take isl_space *space) |
7042 | { |
7043 | int i, n; |
7044 | isl_map *res, *rest; |
7045 | |
7046 | res = isl_map_empty(isl_space_copy(space)); |
7047 | rest = isl_map_universe(space); |
7048 | |
7049 | n = isl_multi_pw_aff_dim(mpa1, isl_dim_out); |
7050 | for (i = 0; i < n; ++i) { |
7051 | isl_pw_aff *pa1, *pa2; |
7052 | isl_map *map; |
7053 | |
7054 | pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i); |
7055 | pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i); |
7056 | map = base(pa1, pa2); |
7057 | map = isl_map_intersect(map, isl_map_copy(rest)); |
7058 | res = isl_map_union(res, map); |
7059 | |
7060 | if (i == n - 1) |
7061 | continue; |
7062 | |
7063 | pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i); |
7064 | pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i); |
7065 | map = isl_pw_aff_eq_map(pa1, pa2); |
7066 | rest = isl_map_intersect(rest, map); |
7067 | } |
7068 | |
7069 | isl_map_free(rest); |
7070 | return res; |
7071 | } |
7072 | |
7073 | /* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" |
7074 | * where the function value of "mpa1" is lexicographically less than that |
7075 | * of "mpa2". "space" is the space of the result. |
7076 | * The parameters of "mpa1" and "mpa2" are assumed to have been aligned. |
7077 | * |
7078 | * "mpa1" is less than "mpa2" if its i-th element is smaller |
7079 | * than the i-th element of "mpa2" while all previous elements are |
7080 | * pairwise equal. |
7081 | */ |
7082 | __isl_give isl_map *isl_multi_pw_aff_lex_lt_map_on_space( |
7083 | __isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2, |
7084 | __isl_take isl_space *space) |
7085 | { |
7086 | return isl_multi_pw_aff_lex_map_on_space(mpa1, mpa2, |
7087 | &isl_pw_aff_lt_map, space); |
7088 | } |
7089 | |
7090 | /* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" |
7091 | * where the function value of "mpa1" is lexicographically less than that |
7092 | * of "mpa2". |
7093 | */ |
7094 | __isl_give isl_map *isl_multi_pw_aff_lex_lt_map( |
7095 | __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2) |
7096 | { |
7097 | return isl_multi_pw_aff_order_map(mpa1, mpa2, |
7098 | &isl_multi_pw_aff_lex_lt_map_on_space); |
7099 | } |
7100 | |
7101 | /* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" |
7102 | * where the function value of "mpa1" is lexicographically greater than that |
7103 | * of "mpa2". "space" is the space of the result. |
7104 | * The parameters of "mpa1" and "mpa2" are assumed to have been aligned. |
7105 | * |
7106 | * "mpa1" is greater than "mpa2" if its i-th element is greater |
7107 | * than the i-th element of "mpa2" while all previous elements are |
7108 | * pairwise equal. |
7109 | */ |
7110 | __isl_give isl_map *isl_multi_pw_aff_lex_gt_map_on_space( |
7111 | __isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2, |
7112 | __isl_take isl_space *space) |
7113 | { |
7114 | return isl_multi_pw_aff_lex_map_on_space(mpa1, mpa2, |
7115 | &isl_pw_aff_gt_map, space); |
7116 | } |
7117 | |
7118 | /* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2" |
7119 | * where the function value of "mpa1" is lexicographically greater than that |
7120 | * of "mpa2". |
7121 | */ |
7122 | __isl_give isl_map *isl_multi_pw_aff_lex_gt_map( |
7123 | __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2) |
7124 | { |
7125 | return isl_multi_pw_aff_order_map(mpa1, mpa2, |
7126 | &isl_multi_pw_aff_lex_gt_map_on_space); |
7127 | } |
7128 | |
7129 | /* Compare two isl_affs. |
7130 | * |
7131 | * Return -1 if "aff1" is "smaller" than "aff2", 1 if "aff1" is "greater" |
7132 | * than "aff2" and 0 if they are equal. |
7133 | * |
7134 | * The order is fairly arbitrary. We do consider expressions that only involve |
7135 | * earlier dimensions as "smaller". |
7136 | */ |
7137 | int isl_aff_plain_cmp(__isl_keep isl_aff *aff1, __isl_keep isl_aff *aff2) |
7138 | { |
7139 | int cmp; |
7140 | int last1, last2; |
7141 | |
7142 | if (aff1 == aff2) |
7143 | return 0; |
7144 | |
7145 | if (!aff1) |
7146 | return -1; |
7147 | if (!aff2) |
7148 | return 1; |
7149 | |
7150 | cmp = isl_local_space_cmp(aff1->ls, aff2->ls); |
7151 | if (cmp != 0) |
7152 | return cmp; |
7153 | |
7154 | last1 = isl_seq_last_non_zero(aff1->v->el + 1, aff1->v->size - 1); |
7155 | last2 = isl_seq_last_non_zero(aff2->v->el + 1, aff1->v->size - 1); |
7156 | if (last1 != last2) |
7157 | return last1 - last2; |
7158 | |
7159 | return isl_seq_cmp(aff1->v->el, aff2->v->el, aff1->v->size); |
7160 | } |
7161 | |
7162 | /* Compare two isl_pw_affs. |
7163 | * |
7164 | * Return -1 if "pa1" is "smaller" than "pa2", 1 if "pa1" is "greater" |
7165 | * than "pa2" and 0 if they are equal. |
7166 | * |
7167 | * The order is fairly arbitrary. We do consider expressions that only involve |
7168 | * earlier dimensions as "smaller". |
7169 | */ |
7170 | int isl_pw_aff_plain_cmp(__isl_keep isl_pw_aff *pa1, |
7171 | __isl_keep isl_pw_aff *pa2) |
7172 | { |
7173 | int i; |
7174 | int cmp; |
7175 | |
7176 | if (pa1 == pa2) |
7177 | return 0; |
7178 | |
7179 | if (!pa1) |
7180 | return -1; |
7181 | if (!pa2) |
7182 | return 1; |
7183 | |
7184 | cmp = isl_space_cmp(pa1->dim, pa2->dim); |
7185 | if (cmp != 0) |
7186 | return cmp; |
7187 | |
7188 | if (pa1->n != pa2->n) |
7189 | return pa1->n - pa2->n; |
7190 | |
7191 | for (i = 0; i < pa1->n; ++i) { |
7192 | cmp = isl_set_plain_cmp(pa1->p[i].set, pa2->p[i].set); |
7193 | if (cmp != 0) |
7194 | return cmp; |
7195 | cmp = isl_aff_plain_cmp(pa1->p[i].aff, pa2->p[i].aff); |
7196 | if (cmp != 0) |
7197 | return cmp; |
7198 | } |
7199 | |
7200 | return 0; |
7201 | } |
7202 | |
7203 | /* Return a piecewise affine expression that is equal to "v" on "domain". |
7204 | */ |
7205 | __isl_give isl_pw_aff *isl_pw_aff_val_on_domain(__isl_take isl_setisl_map *domain, |
7206 | __isl_take isl_val *v) |
7207 | { |
7208 | isl_space *space; |
7209 | isl_local_space *ls; |
7210 | isl_aff *aff; |
7211 | |
7212 | space = isl_set_get_space(domain); |
7213 | ls = isl_local_space_from_space(space); |
7214 | aff = isl_aff_val_on_domain(ls, v); |
7215 | |
7216 | return isl_pw_aff_alloc(domain, aff); |
7217 | } |
7218 | |
7219 | /* Return a multi affine expression that is equal to "mv" on domain |
7220 | * space "space". |
7221 | */ |
7222 | __isl_give isl_multi_aff *isl_multi_aff_multi_val_on_space( |
7223 | __isl_take isl_space *space, __isl_take isl_multi_val *mv) |
7224 | { |
7225 | int i, n; |
7226 | isl_space *space2; |
7227 | isl_local_space *ls; |
7228 | isl_multi_aff *ma; |
7229 | |
7230 | if (!space || !mv) |
7231 | goto error; |
7232 | |
7233 | n = isl_multi_val_dim(mv, isl_dim_set); |
7234 | space2 = isl_multi_val_get_space(mv); |
7235 | space2 = isl_space_align_params(space2, isl_space_copy(space)); |
7236 | space = isl_space_align_params(space, isl_space_copy(space2)); |
7237 | space = isl_space_map_from_domain_and_range(space, space2); |
7238 | ma = isl_multi_aff_alloc(isl_space_copy(space)); |
7239 | ls = isl_local_space_from_space(isl_space_domain(space)); |
7240 | for (i = 0; i < n; ++i) { |
7241 | isl_val *v; |
7242 | isl_aff *aff; |
7243 | |
7244 | v = isl_multi_val_get_val(mv, i); |
7245 | aff = isl_aff_val_on_domain(isl_local_space_copy(ls), v); |
7246 | ma = isl_multi_aff_set_aff(ma, i, aff); |
7247 | } |
7248 | isl_local_space_free(ls); |
7249 | |
7250 | isl_multi_val_free(mv); |
7251 | return ma; |
7252 | error: |
7253 | isl_space_free(space); |
7254 | isl_multi_val_free(mv); |
7255 | return NULL((void*)0); |
7256 | } |
7257 | |
7258 | /* Return a piecewise multi-affine expression |
7259 | * that is equal to "mv" on "domain". |
7260 | */ |
7261 | __isl_give isl_pw_multi_aff *isl_pw_multi_aff_multi_val_on_domain( |
7262 | __isl_take isl_setisl_map *domain, __isl_take isl_multi_val *mv) |
7263 | { |
7264 | isl_space *space; |
7265 | isl_multi_aff *ma; |
7266 | |
7267 | space = isl_set_get_space(domain); |
7268 | ma = isl_multi_aff_multi_val_on_space(space, mv); |
7269 | |
7270 | return isl_pw_multi_aff_alloc(domain, ma); |
7271 | } |
7272 | |
7273 | /* Internal data structure for isl_union_pw_multi_aff_multi_val_on_domain. |
7274 | * mv is the value that should be attained on each domain set |
7275 | * res collects the results |
7276 | */ |
7277 | struct isl_union_pw_multi_aff_multi_val_on_domain_data { |
7278 | isl_multi_val *mv; |
7279 | isl_union_pw_multi_aff *res; |
7280 | }; |
7281 | |
7282 | /* Create an isl_pw_multi_aff equal to data->mv on "domain" |
7283 | * and add it to data->res. |
7284 | */ |
7285 | static isl_stat pw_multi_aff_multi_val_on_domain(__isl_take isl_setisl_map *domain, |
7286 | void *user) |
7287 | { |
7288 | struct isl_union_pw_multi_aff_multi_val_on_domain_data *data = user; |
7289 | isl_pw_multi_aff *pma; |
7290 | isl_multi_val *mv; |
7291 | |
7292 | mv = isl_multi_val_copy(data->mv); |
7293 | pma = isl_pw_multi_aff_multi_val_on_domain(domain, mv); |
7294 | data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma); |
7295 | |
7296 | return data->res ? isl_stat_ok : isl_stat_error; |
7297 | } |
7298 | |
7299 | /* Return a union piecewise multi-affine expression |
7300 | * that is equal to "mv" on "domain". |
7301 | */ |
7302 | __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_multi_val_on_domain( |
7303 | __isl_take isl_union_setisl_union_map *domain, __isl_take isl_multi_val *mv) |
7304 | { |
7305 | struct isl_union_pw_multi_aff_multi_val_on_domain_data data; |
7306 | isl_space *space; |
7307 | |
7308 | space = isl_union_set_get_space(domain); |
7309 | data.res = isl_union_pw_multi_aff_empty(space); |
7310 | data.mv = mv; |
7311 | if (isl_union_set_foreach_set(domain, |
7312 | &pw_multi_aff_multi_val_on_domain, &data) < 0) |
7313 | data.res = isl_union_pw_multi_aff_free(data.res); |
7314 | isl_union_set_free(domain); |
7315 | isl_multi_val_free(mv); |
7316 | return data.res; |
7317 | } |
7318 | |
7319 | /* Compute the pullback of data->pma by the function represented by "pma2", |
7320 | * provided the spaces match, and add the results to data->res. |
7321 | */ |
7322 | static isl_stat pullback_entry(__isl_take isl_pw_multi_aff *pma2, void *user) |
7323 | { |
7324 | struct isl_union_pw_multi_aff_bin_data *data = user; |
7325 | |
7326 | if (!isl_space_tuple_is_equal(data->pma->dim, isl_dim_in, |
7327 | pma2->dim, isl_dim_out)) { |
7328 | isl_pw_multi_aff_free(pma2); |
7329 | return isl_stat_ok; |
7330 | } |
7331 | |
7332 | pma2 = isl_pw_multi_aff_pullback_pw_multi_aff( |
7333 | isl_pw_multi_aff_copy(data->pma), pma2); |
7334 | |
7335 | data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2); |
7336 | if (!data->res) |
7337 | return isl_stat_error; |
7338 | |
7339 | return isl_stat_ok; |
7340 | } |
7341 | |
7342 | /* Compute the pullback of "upma1" by the function represented by "upma2". |
7343 | */ |
7344 | __isl_give isl_union_pw_multi_aff * |
7345 | isl_union_pw_multi_aff_pullback_union_pw_multi_aff( |
7346 | __isl_take isl_union_pw_multi_aff *upma1, |
7347 | __isl_take isl_union_pw_multi_aff *upma2) |
7348 | { |
7349 | return bin_op(upma1, upma2, &pullback_entry); |
7350 | } |
7351 | |
7352 | /* Check that the domain space of "upa" matches "space". |
7353 | * |
7354 | * This function is called from isl_multi_union_pw_aff_set_union_pw_aff and |
7355 | * can in principle never fail since the space "space" is that |
7356 | * of the isl_multi_union_pw_aff and is a set space such that |
7357 | * there is no domain space to match. |
7358 | * |
7359 | * We check the parameters and double-check that "space" is |
7360 | * indeed that of a set. |
7361 | */ |
7362 | static isl_stat isl_union_pw_aff_check_match_domain_space( |
7363 | __isl_keep isl_union_pw_aff *upa, __isl_keep isl_space *space) |
7364 | { |
7365 | isl_space *upa_space; |
7366 | isl_bool match; |
7367 | |
7368 | if (!upa || !space) |
7369 | return isl_stat_error; |
7370 | |
7371 | match = isl_space_is_set(space); |
7372 | if (match < 0) |
7373 | return isl_stat_error; |
7374 | if (!match) |
7375 | isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "expecting set space", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 7376); return isl_stat_error; } while (0) |
7376 | "expecting set space", return isl_stat_error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "expecting set space", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 7376); return isl_stat_error; } while (0); |
7377 | |
7378 | upa_space = isl_union_pw_aff_get_space(upa); |
7379 | match = isl_space_has_equal_params(space, upa_space); |
7380 | if (match < 0) |
7381 | goto error; |
7382 | if (!match) |
7383 | isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "parameters don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 7384); goto error; } while (0) |
7384 | "parameters don't match", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "parameters don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 7384); goto error; } while (0); |
7385 | |
7386 | isl_space_free(upa_space); |
7387 | return isl_stat_ok; |
7388 | error: |
7389 | isl_space_free(upa_space); |
7390 | return isl_stat_error; |
7391 | } |
7392 | |
7393 | /* Do the parameters of "upa" match those of "space"? |
7394 | */ |
7395 | static isl_bool isl_union_pw_aff_matching_params( |
7396 | __isl_keep isl_union_pw_aff *upa, __isl_keep isl_space *space) |
7397 | { |
7398 | isl_space *upa_space; |
7399 | isl_bool match; |
7400 | |
7401 | if (!upa || !space) |
7402 | return isl_bool_error; |
7403 | |
7404 | upa_space = isl_union_pw_aff_get_space(upa); |
7405 | |
7406 | match = isl_space_has_equal_params(space, upa_space); |
7407 | |
7408 | isl_space_free(upa_space); |
7409 | return match; |
7410 | } |
7411 | |
7412 | /* Internal data structure for isl_union_pw_aff_reset_domain_space. |
7413 | * space represents the new parameters. |
7414 | * res collects the results. |
7415 | */ |
7416 | struct isl_union_pw_aff_reset_params_data { |
7417 | isl_space *space; |
7418 | isl_union_pw_aff *res; |
7419 | }; |
7420 | |
7421 | /* Replace the parameters of "pa" by data->space and |
7422 | * add the result to data->res. |
7423 | */ |
7424 | static isl_stat reset_params(__isl_take isl_pw_aff *pa, void *user) |
7425 | { |
7426 | struct isl_union_pw_aff_reset_params_data *data = user; |
7427 | isl_space *space; |
7428 | |
7429 | space = isl_pw_aff_get_space(pa); |
7430 | space = isl_space_replace_params(space, data->space); |
7431 | pa = isl_pw_aff_reset_space(pa, space); |
7432 | data->res = isl_union_pw_aff_add_pw_aff(data->res, pa); |
7433 | |
7434 | return data->res ? isl_stat_ok : isl_stat_error; |
7435 | } |
7436 | |
7437 | /* Replace the domain space of "upa" by "space". |
7438 | * Since a union expression does not have a (single) domain space, |
7439 | * "space" is necessarily a parameter space. |
7440 | * |
7441 | * Since the order and the names of the parameters determine |
7442 | * the hash value, we need to create a new hash table. |
7443 | */ |
7444 | static __isl_give isl_union_pw_aff *isl_union_pw_aff_reset_domain_space( |
7445 | __isl_take isl_union_pw_aff *upa, __isl_take isl_space *space) |
7446 | { |
7447 | struct isl_union_pw_aff_reset_params_data data = { space }; |
7448 | isl_bool match; |
7449 | |
7450 | match = isl_union_pw_aff_matching_params(upa, space); |
7451 | if (match < 0) |
7452 | upa = isl_union_pw_aff_free(upa); |
7453 | else if (match) { |
7454 | isl_space_free(space); |
7455 | return upa; |
7456 | } |
7457 | |
7458 | data.res = isl_union_pw_aff_empty(isl_space_copy(space)); |
7459 | if (isl_union_pw_aff_foreach_pw_aff(upa, &reset_params, &data) < 0) |
7460 | data.res = isl_union_pw_aff_free(data.res); |
7461 | |
7462 | isl_union_pw_aff_free(upa); |
7463 | isl_space_free(space); |
7464 | return data.res; |
7465 | } |
7466 | |
7467 | /* Return the floor of "pa". |
7468 | */ |
7469 | static __isl_give isl_pw_aff *floor_entry(__isl_take isl_pw_aff *pa, void *user) |
7470 | { |
7471 | return isl_pw_aff_floor(pa); |
7472 | } |
7473 | |
7474 | /* Given f, return floor(f). |
7475 | */ |
7476 | __isl_give isl_union_pw_aff *isl_union_pw_aff_floor( |
7477 | __isl_take isl_union_pw_aff *upa) |
7478 | { |
7479 | return isl_union_pw_aff_transform_inplace(upa, &floor_entry, NULL((void*)0)); |
7480 | } |
7481 | |
7482 | /* Compute |
7483 | * |
7484 | * upa mod m = upa - m * floor(upa/m) |
7485 | * |
7486 | * with m an integer value. |
7487 | */ |
7488 | __isl_give isl_union_pw_aff *isl_union_pw_aff_mod_val( |
7489 | __isl_take isl_union_pw_aff *upa, __isl_take isl_val *m) |
7490 | { |
7491 | isl_union_pw_aff *res; |
7492 | |
7493 | if (!upa || !m) |
7494 | goto error; |
7495 | |
7496 | if (!isl_val_is_int(m)) |
7497 | isl_die(isl_val_get_ctx(m), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(m), isl_error_invalid, "expecting integer modulo" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 7498); goto error; } while (0) |
7498 | "expecting integer modulo", goto error)do { isl_handle_error(isl_val_get_ctx(m), isl_error_invalid, "expecting integer modulo" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 7498); goto error; } while (0); |
7499 | if (!isl_val_is_pos(m)) |
7500 | isl_die(isl_val_get_ctx(m), isl_error_invalid,do { isl_handle_error(isl_val_get_ctx(m), isl_error_invalid, "expecting positive modulo" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 7501); goto error; } while (0) |
7501 | "expecting positive modulo", goto error)do { isl_handle_error(isl_val_get_ctx(m), isl_error_invalid, "expecting positive modulo" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 7501); goto error; } while (0); |
7502 | |
7503 | res = isl_union_pw_aff_copy(upa); |
7504 | upa = isl_union_pw_aff_scale_down_val(upa, isl_val_copy(m)); |
7505 | upa = isl_union_pw_aff_floor(upa); |
7506 | upa = isl_union_pw_aff_scale_val(upa, m); |
7507 | res = isl_union_pw_aff_sub(res, upa); |
7508 | |
7509 | return res; |
7510 | error: |
7511 | isl_val_free(m); |
7512 | isl_union_pw_aff_free(upa); |
7513 | return NULL((void*)0); |
7514 | } |
7515 | |
7516 | /* Internal data structure for isl_union_pw_multi_aff_get_union_pw_aff. |
7517 | * pos is the output position that needs to be extracted. |
7518 | * res collects the results. |
7519 | */ |
7520 | struct isl_union_pw_multi_aff_get_union_pw_aff_data { |
7521 | int pos; |
7522 | isl_union_pw_aff *res; |
7523 | }; |
7524 | |
7525 | /* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma" |
7526 | * (assuming it has such a dimension) and add it to data->res. |
7527 | */ |
7528 | static isl_stat get_union_pw_aff(__isl_take isl_pw_multi_aff *pma, void *user) |
7529 | { |
7530 | struct isl_union_pw_multi_aff_get_union_pw_aff_data *data = user; |
7531 | int n_out; |
7532 | isl_pw_aff *pa; |
7533 | |
7534 | if (!pma) |
7535 | return isl_stat_error; |
7536 | |
7537 | n_out = isl_pw_multi_aff_dim(pma, isl_dim_out); |
7538 | if (data->pos >= n_out) { |
7539 | isl_pw_multi_aff_free(pma); |
7540 | return isl_stat_ok; |
7541 | } |
7542 | |
7543 | pa = isl_pw_multi_aff_get_pw_aff(pma, data->pos); |
7544 | isl_pw_multi_aff_free(pma); |
7545 | |
7546 | data->res = isl_union_pw_aff_add_pw_aff(data->res, pa); |
7547 | |
7548 | return data->res ? isl_stat_ok : isl_stat_error; |
7549 | } |
7550 | |
7551 | /* Extract an isl_union_pw_aff corresponding to |
7552 | * output dimension "pos" of "upma". |
7553 | */ |
7554 | __isl_give isl_union_pw_aff *isl_union_pw_multi_aff_get_union_pw_aff( |
7555 | __isl_keep isl_union_pw_multi_aff *upma, int pos) |
7556 | { |
7557 | struct isl_union_pw_multi_aff_get_union_pw_aff_data data; |
7558 | isl_space *space; |
7559 | |
7560 | if (!upma) |
7561 | return NULL((void*)0); |
7562 | |
7563 | if (pos < 0) |
7564 | isl_die(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid,do { isl_handle_error(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid , "cannot extract at negative position", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 7565); return ((void*)0); } while (0) |
7565 | "cannot extract at negative position", return NULL)do { isl_handle_error(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid , "cannot extract at negative position", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 7565); return ((void*)0); } while (0); |
7566 | |
7567 | space = isl_union_pw_multi_aff_get_space(upma); |
7568 | data.res = isl_union_pw_aff_empty(space); |
7569 | data.pos = pos; |
7570 | if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, |
7571 | &get_union_pw_aff, &data) < 0) |
7572 | data.res = isl_union_pw_aff_free(data.res); |
7573 | |
7574 | return data.res; |
7575 | } |
7576 | |
7577 | /* Return a union piecewise affine expression |
7578 | * that is equal to "aff" on "domain". |
7579 | */ |
7580 | __isl_give isl_union_pw_aff *isl_union_pw_aff_aff_on_domain( |
7581 | __isl_take isl_union_setisl_union_map *domain, __isl_take isl_aff *aff) |
7582 | { |
7583 | isl_pw_aff *pa; |
7584 | |
7585 | pa = isl_pw_aff_from_aff(aff); |
7586 | return isl_union_pw_aff_pw_aff_on_domain(domain, pa); |
7587 | } |
7588 | |
7589 | /* Return a union piecewise affine expression |
7590 | * that is equal to the parameter identified by "id" on "domain". |
7591 | * |
7592 | * Make sure the parameter appears in the space passed to |
7593 | * isl_aff_param_on_domain_space_id. |
7594 | */ |
7595 | __isl_give isl_union_pw_aff *isl_union_pw_aff_param_on_domain_id( |
7596 | __isl_take isl_union_setisl_union_map *domain, __isl_take isl_id *id) |
7597 | { |
7598 | isl_space *space; |
7599 | isl_aff *aff; |
7600 | |
7601 | space = isl_union_set_get_space(domain); |
7602 | space = isl_space_add_param_id(space, isl_id_copy(id)); |
7603 | aff = isl_aff_param_on_domain_space_id(space, id); |
7604 | return isl_union_pw_aff_aff_on_domain(domain, aff); |
7605 | } |
7606 | |
7607 | /* Internal data structure for isl_union_pw_aff_pw_aff_on_domain. |
7608 | * "pa" is the piecewise symbolic value that the resulting isl_union_pw_aff |
7609 | * needs to attain. |
7610 | * "res" collects the results. |
7611 | */ |
7612 | struct isl_union_pw_aff_pw_aff_on_domain_data { |
7613 | isl_pw_aff *pa; |
7614 | isl_union_pw_aff *res; |
7615 | }; |
7616 | |
7617 | /* Construct a piecewise affine expression that is equal to data->pa |
7618 | * on "domain" and add the result to data->res. |
7619 | */ |
7620 | static isl_stat pw_aff_on_domain(__isl_take isl_setisl_map *domain, void *user) |
7621 | { |
7622 | struct isl_union_pw_aff_pw_aff_on_domain_data *data = user; |
7623 | isl_pw_aff *pa; |
7624 | int dim; |
7625 | |
7626 | pa = isl_pw_aff_copy(data->pa); |
7627 | dim = isl_set_dim(domain, isl_dim_set); |
7628 | pa = isl_pw_aff_from_range(pa); |
7629 | pa = isl_pw_aff_add_dims(pa, isl_dim_in, dim); |
7630 | pa = isl_pw_aff_reset_domain_space(pa, isl_set_get_space(domain)); |
7631 | pa = isl_pw_aff_intersect_domain(pa, domain); |
7632 | data->res = isl_union_pw_aff_add_pw_aff(data->res, pa); |
7633 | |
7634 | return data->res ? isl_stat_ok : isl_stat_error; |
7635 | } |
7636 | |
7637 | /* Return a union piecewise affine expression |
7638 | * that is equal to "pa" on "domain", assuming "domain" and "pa" |
7639 | * have been aligned. |
7640 | * |
7641 | * Construct an isl_pw_aff on each of the sets in "domain" and |
7642 | * collect the results. |
7643 | */ |
7644 | static __isl_give isl_union_pw_aff *isl_union_pw_aff_pw_aff_on_domain_aligned( |
7645 | __isl_take isl_union_setisl_union_map *domain, __isl_take isl_pw_aff *pa) |
7646 | { |
7647 | struct isl_union_pw_aff_pw_aff_on_domain_data data; |
7648 | isl_space *space; |
7649 | |
7650 | space = isl_union_set_get_space(domain); |
7651 | data.res = isl_union_pw_aff_empty(space); |
7652 | data.pa = pa; |
7653 | if (isl_union_set_foreach_set(domain, &pw_aff_on_domain, &data) < 0) |
7654 | data.res = isl_union_pw_aff_free(data.res); |
7655 | isl_union_set_free(domain); |
7656 | isl_pw_aff_free(pa); |
7657 | return data.res; |
7658 | } |
7659 | |
7660 | /* Return a union piecewise affine expression |
7661 | * that is equal to "pa" on "domain". |
7662 | * |
7663 | * Check that "pa" is a parametric expression, |
7664 | * align the parameters if needed and call |
7665 | * isl_union_pw_aff_pw_aff_on_domain_aligned. |
7666 | */ |
7667 | __isl_give isl_union_pw_aff *isl_union_pw_aff_pw_aff_on_domain( |
7668 | __isl_take isl_union_setisl_union_map *domain, __isl_take isl_pw_aff *pa) |
7669 | { |
7670 | isl_bool is_set; |
7671 | isl_bool equal_params; |
7672 | isl_space *domain_space, *pa_space; |
7673 | |
7674 | pa_space = isl_pw_aff_peek_space(pa); |
7675 | is_set = isl_space_is_set(pa_space); |
7676 | if (is_set < 0) |
7677 | goto error; |
7678 | if (!is_set) |
7679 | isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid , "expecting parametric expression", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 7680); goto error; } while (0) |
7680 | "expecting parametric expression", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid , "expecting parametric expression", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 7680); goto error; } while (0); |
7681 | |
7682 | domain_space = isl_union_set_get_space(domain); |
7683 | pa_space = isl_pw_aff_get_space(pa); |
7684 | equal_params = isl_space_has_equal_params(domain_space, pa_space); |
7685 | if (equal_params >= 0 && !equal_params) { |
7686 | isl_space *space; |
7687 | |
7688 | space = isl_space_align_params(domain_space, pa_space); |
7689 | pa = isl_pw_aff_align_params(pa, isl_space_copy(space)); |
7690 | domain = isl_union_set_align_params(domain, space); |
7691 | } else { |
7692 | isl_space_free(domain_space); |
7693 | isl_space_free(pa_space); |
7694 | } |
7695 | |
7696 | if (equal_params < 0) |
7697 | goto error; |
7698 | return isl_union_pw_aff_pw_aff_on_domain_aligned(domain, pa); |
7699 | error: |
7700 | isl_union_set_free(domain); |
7701 | isl_pw_aff_free(pa); |
7702 | return NULL((void*)0); |
7703 | } |
7704 | |
7705 | /* Internal data structure for isl_union_pw_aff_val_on_domain. |
7706 | * "v" is the value that the resulting isl_union_pw_aff needs to attain. |
7707 | * "res" collects the results. |
7708 | */ |
7709 | struct isl_union_pw_aff_val_on_domain_data { |
7710 | isl_val *v; |
7711 | isl_union_pw_aff *res; |
7712 | }; |
7713 | |
7714 | /* Construct a piecewise affine expression that is equal to data->v |
7715 | * on "domain" and add the result to data->res. |
7716 | */ |
7717 | static isl_stat pw_aff_val_on_domain(__isl_take isl_setisl_map *domain, void *user) |
7718 | { |
7719 | struct isl_union_pw_aff_val_on_domain_data *data = user; |
7720 | isl_pw_aff *pa; |
7721 | isl_val *v; |
7722 | |
7723 | v = isl_val_copy(data->v); |
7724 | pa = isl_pw_aff_val_on_domain(domain, v); |
7725 | data->res = isl_union_pw_aff_add_pw_aff(data->res, pa); |
7726 | |
7727 | return data->res ? isl_stat_ok : isl_stat_error; |
7728 | } |
7729 | |
7730 | /* Return a union piecewise affine expression |
7731 | * that is equal to "v" on "domain". |
7732 | * |
7733 | * Construct an isl_pw_aff on each of the sets in "domain" and |
7734 | * collect the results. |
7735 | */ |
7736 | __isl_give isl_union_pw_aff *isl_union_pw_aff_val_on_domain( |
7737 | __isl_take isl_union_setisl_union_map *domain, __isl_take isl_val *v) |
7738 | { |
7739 | struct isl_union_pw_aff_val_on_domain_data data; |
7740 | isl_space *space; |
7741 | |
7742 | space = isl_union_set_get_space(domain); |
7743 | data.res = isl_union_pw_aff_empty(space); |
7744 | data.v = v; |
7745 | if (isl_union_set_foreach_set(domain, &pw_aff_val_on_domain, &data) < 0) |
7746 | data.res = isl_union_pw_aff_free(data.res); |
7747 | isl_union_set_free(domain); |
7748 | isl_val_free(v); |
7749 | return data.res; |
7750 | } |
7751 | |
7752 | /* Construct a piecewise multi affine expression |
7753 | * that is equal to "pa" and add it to upma. |
7754 | */ |
7755 | static isl_stat pw_multi_aff_from_pw_aff_entry(__isl_take isl_pw_aff *pa, |
7756 | void *user) |
7757 | { |
7758 | isl_union_pw_multi_aff **upma = user; |
7759 | isl_pw_multi_aff *pma; |
7760 | |
7761 | pma = isl_pw_multi_aff_from_pw_aff(pa); |
7762 | *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma); |
7763 | |
7764 | return *upma ? isl_stat_ok : isl_stat_error; |
7765 | } |
7766 | |
7767 | /* Construct and return a union piecewise multi affine expression |
7768 | * that is equal to the given union piecewise affine expression. |
7769 | */ |
7770 | __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_pw_aff( |
7771 | __isl_take isl_union_pw_aff *upa) |
7772 | { |
7773 | isl_space *space; |
7774 | isl_union_pw_multi_aff *upma; |
7775 | |
7776 | if (!upa) |
7777 | return NULL((void*)0); |
7778 | |
7779 | space = isl_union_pw_aff_get_space(upa); |
7780 | upma = isl_union_pw_multi_aff_empty(space); |
7781 | |
7782 | if (isl_union_pw_aff_foreach_pw_aff(upa, |
7783 | &pw_multi_aff_from_pw_aff_entry, &upma) < 0) |
7784 | upma = isl_union_pw_multi_aff_free(upma); |
7785 | |
7786 | isl_union_pw_aff_free(upa); |
7787 | return upma; |
7788 | } |
7789 | |
7790 | /* Compute the set of elements in the domain of "pa" where it is zero and |
7791 | * add this set to "uset". |
7792 | */ |
7793 | static isl_stat zero_union_set(__isl_take isl_pw_aff *pa, void *user) |
7794 | { |
7795 | isl_union_setisl_union_map **uset = (isl_union_setisl_union_map **)user; |
7796 | |
7797 | *uset = isl_union_set_add_set(*uset, isl_pw_aff_zero_set(pa)); |
7798 | |
7799 | return *uset ? isl_stat_ok : isl_stat_error; |
7800 | } |
7801 | |
7802 | /* Return a union set containing those elements in the domain |
7803 | * of "upa" where it is zero. |
7804 | */ |
7805 | __isl_give isl_union_setisl_union_map *isl_union_pw_aff_zero_union_set( |
7806 | __isl_take isl_union_pw_aff *upa) |
7807 | { |
7808 | isl_union_setisl_union_map *zero; |
7809 | |
7810 | zero = isl_union_set_empty(isl_union_pw_aff_get_space(upa)); |
7811 | if (isl_union_pw_aff_foreach_pw_aff(upa, &zero_union_set, &zero) < 0) |
7812 | zero = isl_union_set_free(zero); |
7813 | |
7814 | isl_union_pw_aff_free(upa); |
7815 | return zero; |
7816 | } |
7817 | |
7818 | /* Internal data structure for isl_union_pw_aff_pullback_union_pw_multi_aff. |
7819 | * upma is the function that is plugged in. |
7820 | * pa is the current part of the function in which upma is plugged in. |
7821 | * res collects the results. |
7822 | */ |
7823 | struct isl_union_pw_aff_pullback_upma_data { |
7824 | isl_union_pw_multi_aff *upma; |
7825 | isl_pw_aff *pa; |
7826 | isl_union_pw_aff *res; |
7827 | }; |
7828 | |
7829 | /* Check if "pma" can be plugged into data->pa. |
7830 | * If so, perform the pullback and add the result to data->res. |
7831 | */ |
7832 | static isl_stat pa_pb_pma(__isl_take isl_pw_multi_aff *pma, void *user) |
7833 | { |
7834 | struct isl_union_pw_aff_pullback_upma_data *data = user; |
7835 | isl_pw_aff *pa; |
7836 | |
7837 | if (!isl_space_tuple_is_equal(data->pa->dim, isl_dim_in, |
7838 | pma->dim, isl_dim_out)) { |
7839 | isl_pw_multi_aff_free(pma); |
7840 | return isl_stat_ok; |
7841 | } |
7842 | |
7843 | pa = isl_pw_aff_copy(data->pa); |
7844 | pa = isl_pw_aff_pullback_pw_multi_aff(pa, pma); |
7845 | |
7846 | data->res = isl_union_pw_aff_add_pw_aff(data->res, pa); |
7847 | |
7848 | return data->res ? isl_stat_ok : isl_stat_error; |
7849 | } |
7850 | |
7851 | /* Check if any of the elements of data->upma can be plugged into pa, |
7852 | * add if so add the result to data->res. |
7853 | */ |
7854 | static isl_stat upa_pb_upma(__isl_take isl_pw_aff *pa, void *user) |
7855 | { |
7856 | struct isl_union_pw_aff_pullback_upma_data *data = user; |
7857 | isl_stat r; |
7858 | |
7859 | data->pa = pa; |
7860 | r = isl_union_pw_multi_aff_foreach_pw_multi_aff(data->upma, |
7861 | &pa_pb_pma, data); |
7862 | isl_pw_aff_free(pa); |
7863 | |
7864 | return r; |
7865 | } |
7866 | |
7867 | /* Compute the pullback of "upa" by the function represented by "upma". |
7868 | * In other words, plug in "upma" in "upa". The result contains |
7869 | * expressions defined over the domain space of "upma". |
7870 | * |
7871 | * Run over all pairs of elements in "upa" and "upma", perform |
7872 | * the pullback when appropriate and collect the results. |
7873 | * If the hash value were based on the domain space rather than |
7874 | * the function space, then we could run through all elements |
7875 | * of "upma" and directly pick out the corresponding element of "upa". |
7876 | */ |
7877 | __isl_give isl_union_pw_aff *isl_union_pw_aff_pullback_union_pw_multi_aff( |
7878 | __isl_take isl_union_pw_aff *upa, |
7879 | __isl_take isl_union_pw_multi_aff *upma) |
7880 | { |
7881 | struct isl_union_pw_aff_pullback_upma_data data = { NULL((void*)0), NULL((void*)0) }; |
7882 | isl_space *space; |
7883 | |
7884 | space = isl_union_pw_multi_aff_get_space(upma); |
7885 | upa = isl_union_pw_aff_align_params(upa, space); |
7886 | space = isl_union_pw_aff_get_space(upa); |
7887 | upma = isl_union_pw_multi_aff_align_params(upma, space); |
7888 | |
7889 | if (!upa || !upma) |
7890 | goto error; |
7891 | |
7892 | data.upma = upma; |
7893 | data.res = isl_union_pw_aff_alloc_same_size(upa); |
7894 | if (isl_union_pw_aff_foreach_pw_aff(upa, &upa_pb_upma, &data) < 0) |
7895 | data.res = isl_union_pw_aff_free(data.res); |
7896 | |
7897 | isl_union_pw_aff_free(upa); |
7898 | isl_union_pw_multi_aff_free(upma); |
7899 | return data.res; |
7900 | error: |
7901 | isl_union_pw_aff_free(upa); |
7902 | isl_union_pw_multi_aff_free(upma); |
7903 | return NULL((void*)0); |
7904 | } |
7905 | |
7906 | #undef BASEunion_pw_aff |
7907 | #define BASEunion_pw_aff union_pw_aff |
7908 | #undef DOMBASEunion_set |
7909 | #define DOMBASEunion_set union_set |
7910 | |
7911 | #define NO_MOVE_DIMS |
7912 | #define NO_DOMAIN |
7913 | #define NO_PRODUCT |
7914 | #define NO_SPLICE |
7915 | #define NO_ZERO |
7916 | #define NO_IDENTITY |
7917 | |
7918 | #include <isl_multi_explicit_domain.c> |
7919 | #include <isl_multi_union_pw_aff_explicit_domain.c> |
7920 | #include <isl_multi_templ.c> |
7921 | #include <isl_multi_apply_set.c> |
7922 | #include <isl_multi_apply_union_set.c> |
7923 | #include <isl_multi_coalesce.c> |
7924 | #include <isl_multi_floor.c> |
7925 | #include <isl_multi_gist.c> |
7926 | #include <isl_multi_align_set.c> |
7927 | #include <isl_multi_align_union_set.c> |
7928 | #include <isl_multi_intersect.c> |
7929 | |
7930 | /* Does "mupa" have a non-trivial explicit domain? |
7931 | * |
7932 | * The explicit domain, if present, is trivial if it represents |
7933 | * an (obviously) universe parameter set. |
7934 | */ |
7935 | isl_bool isl_multi_union_pw_aff_has_non_trivial_domain( |
7936 | __isl_keep isl_multi_union_pw_aff *mupa) |
7937 | { |
7938 | isl_bool is_params, trivial; |
7939 | isl_setisl_map *set; |
7940 | |
7941 | if (!mupa) |
7942 | return isl_bool_error; |
7943 | if (!isl_multi_union_pw_aff_has_explicit_domain(mupa)) |
7944 | return isl_bool_false; |
7945 | is_params = isl_union_set_is_params(mupa->u.dom); |
7946 | if (is_params < 0 || !is_params) |
7947 | return isl_bool_not(is_params); |
7948 | set = isl_set_from_union_set(isl_union_set_copy(mupa->u.dom)); |
7949 | trivial = isl_set_plain_is_universe(set); |
7950 | isl_set_free(set); |
7951 | return isl_bool_not(trivial); |
7952 | } |
7953 | |
7954 | /* Construct a multiple union piecewise affine expression |
7955 | * in the given space with value zero in each of the output dimensions. |
7956 | * |
7957 | * Since there is no canonical zero value for |
7958 | * a union piecewise affine expression, we can only construct |
7959 | * a zero-dimensional "zero" value. |
7960 | */ |
7961 | __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_zero( |
7962 | __isl_take isl_space *space) |
7963 | { |
7964 | isl_bool params; |
7965 | |
7966 | if (!space) |
7967 | return NULL((void*)0); |
7968 | |
7969 | params = isl_space_is_params(space); |
7970 | if (params < 0) |
7971 | goto error; |
7972 | if (params) |
7973 | isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "expecting proper set space", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 7974); goto error; } while (0) |
7974 | "expecting proper set space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "expecting proper set space", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 7974); goto error; } while (0); |
7975 | if (!isl_space_is_set(space)) |
7976 | isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "expecting set space", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 7977); goto error; } while (0) |
7977 | "expecting set space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "expecting set space", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 7977); goto error; } while (0); |
7978 | if (isl_space_dim(space , isl_dim_out) != 0) |
7979 | isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "expecting 0D space", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 7980); goto error; } while (0) |
7980 | "expecting 0D space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid , "expecting 0D space", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 7980); goto error; } while (0); |
7981 | |
7982 | return isl_multi_union_pw_aff_alloc(space); |
7983 | error: |
7984 | isl_space_free(space); |
7985 | return NULL((void*)0); |
7986 | } |
7987 | |
7988 | /* Compute the sum of "mupa1" and "mupa2" on the union of their domains, |
7989 | * with the actual sum on the shared domain and |
7990 | * the defined expression on the symmetric difference of the domains. |
7991 | * |
7992 | * We simply iterate over the elements in both arguments and |
7993 | * call isl_union_pw_aff_union_add on each of them, if there is |
7994 | * at least one element. |
7995 | * |
7996 | * Otherwise, the two expressions have an explicit domain and |
7997 | * the union of these explicit domains is computed. |
7998 | * This assumes that the explicit domains are either both in terms |
7999 | * of specific domains elements or both in terms of parameters. |
8000 | * However, if one of the expressions does not have any constraints |
8001 | * on its explicit domain, then this is allowed as well and the result |
8002 | * is the expression with no constraints on its explicit domain. |
8003 | */ |
8004 | static __isl_give isl_multi_union_pw_aff * |
8005 | isl_multi_union_pw_aff_union_add_aligned( |
8006 | __isl_take isl_multi_union_pw_aff *mupa1, |
8007 | __isl_take isl_multi_union_pw_aff *mupa2) |
8008 | { |
8009 | isl_bool has_domain, is_params1, is_params2; |
8010 | |
8011 | if (isl_multi_union_pw_aff_check_equal_space(mupa1, mupa2) < 0) |
8012 | goto error; |
8013 | if (mupa1->n > 0) |
8014 | return isl_multi_union_pw_aff_bin_op(mupa1, mupa2, |
8015 | &isl_union_pw_aff_union_add); |
8016 | if (isl_multi_union_pw_aff_check_has_explicit_domain(mupa1) < 0 || |
8017 | isl_multi_union_pw_aff_check_has_explicit_domain(mupa2) < 0) |
8018 | goto error; |
8019 | |
8020 | has_domain = isl_multi_union_pw_aff_has_non_trivial_domain(mupa1); |
8021 | if (has_domain < 0) |
8022 | goto error; |
8023 | if (!has_domain) { |
8024 | isl_multi_union_pw_aff_free(mupa2); |
8025 | return mupa1; |
8026 | } |
8027 | has_domain = isl_multi_union_pw_aff_has_non_trivial_domain(mupa2); |
8028 | if (has_domain < 0) |
8029 | goto error; |
8030 | if (!has_domain) { |
8031 | isl_multi_union_pw_aff_free(mupa1); |
8032 | return mupa2; |
8033 | } |
8034 | |
8035 | is_params1 = isl_union_set_is_params(mupa1->u.dom); |
8036 | is_params2 = isl_union_set_is_params(mupa2->u.dom); |
8037 | if (is_params1 < 0 || is_params2 < 0) |
8038 | goto error; |
8039 | if (is_params1 != is_params2) |
8040 | isl_die(isl_multi_union_pw_aff_get_ctx(mupa1),do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa1), isl_error_invalid , "cannot compute union of concrete domain and " "parameter constraints" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8043); goto error; } while (0) |
8041 | isl_error_invalid,do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa1), isl_error_invalid , "cannot compute union of concrete domain and " "parameter constraints" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8043); goto error; } while (0) |
8042 | "cannot compute union of concrete domain and "do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa1), isl_error_invalid , "cannot compute union of concrete domain and " "parameter constraints" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8043); goto error; } while (0) |
8043 | "parameter constraints", goto error)do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa1), isl_error_invalid , "cannot compute union of concrete domain and " "parameter constraints" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8043); goto error; } while (0); |
8044 | mupa1 = isl_multi_union_pw_aff_cow(mupa1); |
8045 | if (!mupa1) |
8046 | goto error; |
8047 | mupa1->u.dom = isl_union_set_union(mupa1->u.dom, |
8048 | isl_union_set_copy(mupa2->u.dom)); |
8049 | if (!mupa1->u.dom) |
8050 | goto error; |
8051 | isl_multi_union_pw_aff_free(mupa2); |
8052 | return mupa1; |
8053 | error: |
8054 | isl_multi_union_pw_aff_free(mupa1); |
8055 | isl_multi_union_pw_aff_free(mupa2); |
8056 | return NULL((void*)0); |
8057 | } |
8058 | |
8059 | /* Compute the sum of "mupa1" and "mupa2" on the union of their domains, |
8060 | * with the actual sum on the shared domain and |
8061 | * the defined expression on the symmetric difference of the domains. |
8062 | */ |
8063 | __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_union_add( |
8064 | __isl_take isl_multi_union_pw_aff *mupa1, |
8065 | __isl_take isl_multi_union_pw_aff *mupa2) |
8066 | { |
8067 | return isl_multi_union_pw_aff_align_params_multi_multi_and(mupa1, mupa2, |
8068 | &isl_multi_union_pw_aff_union_add_aligned); |
8069 | } |
8070 | |
8071 | /* Construct and return a multi union piecewise affine expression |
8072 | * that is equal to the given multi affine expression. |
8073 | */ |
8074 | __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_aff( |
8075 | __isl_take isl_multi_aff *ma) |
8076 | { |
8077 | isl_multi_pw_aff *mpa; |
8078 | |
8079 | mpa = isl_multi_pw_aff_from_multi_aff(ma); |
8080 | return isl_multi_union_pw_aff_from_multi_pw_aff(mpa); |
8081 | } |
8082 | |
8083 | /* Construct and return a multi union piecewise affine expression |
8084 | * that is equal to the given multi piecewise affine expression. |
8085 | */ |
8086 | __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_pw_aff( |
8087 | __isl_take isl_multi_pw_aff *mpa) |
8088 | { |
8089 | int i, n; |
8090 | isl_space *space; |
8091 | isl_multi_union_pw_aff *mupa; |
8092 | |
8093 | if (!mpa) |
8094 | return NULL((void*)0); |
8095 | |
8096 | space = isl_multi_pw_aff_get_space(mpa); |
8097 | space = isl_space_range(space); |
8098 | mupa = isl_multi_union_pw_aff_alloc(space); |
8099 | |
8100 | n = isl_multi_pw_aff_dim(mpa, isl_dim_out); |
8101 | for (i = 0; i < n; ++i) { |
8102 | isl_pw_aff *pa; |
8103 | isl_union_pw_aff *upa; |
8104 | |
8105 | pa = isl_multi_pw_aff_get_pw_aff(mpa, i); |
8106 | upa = isl_union_pw_aff_from_pw_aff(pa); |
8107 | mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa); |
8108 | } |
8109 | |
8110 | isl_multi_pw_aff_free(mpa); |
8111 | |
8112 | return mupa; |
8113 | } |
8114 | |
8115 | /* Extract the range space of "pma" and assign it to *space. |
8116 | * If *space has already been set (through a previous call to this function), |
8117 | * then check that the range space is the same. |
8118 | */ |
8119 | static isl_stat extract_space(__isl_take isl_pw_multi_aff *pma, void *user) |
8120 | { |
8121 | isl_space **space = user; |
8122 | isl_space *pma_space; |
8123 | isl_bool equal; |
8124 | |
8125 | pma_space = isl_space_range(isl_pw_multi_aff_get_space(pma)); |
8126 | isl_pw_multi_aff_free(pma); |
8127 | |
8128 | if (!pma_space) |
8129 | return isl_stat_error; |
8130 | if (!*space) { |
8131 | *space = pma_space; |
8132 | return isl_stat_ok; |
8133 | } |
8134 | |
8135 | equal = isl_space_is_equal(pma_space, *space); |
8136 | isl_space_free(pma_space); |
8137 | |
8138 | if (equal < 0) |
8139 | return isl_stat_error; |
8140 | if (!equal) |
8141 | isl_die(isl_space_get_ctx(*space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(*space), isl_error_invalid , "range spaces not the same", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8142); return isl_stat_error; } while (0) |
8142 | "range spaces not the same", return isl_stat_error)do { isl_handle_error(isl_space_get_ctx(*space), isl_error_invalid , "range spaces not the same", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8142); return isl_stat_error; } while (0); |
8143 | return isl_stat_ok; |
8144 | } |
8145 | |
8146 | /* Construct and return a multi union piecewise affine expression |
8147 | * that is equal to the given union piecewise multi affine expression. |
8148 | * |
8149 | * In order to be able to perform the conversion, the input |
8150 | * needs to be non-empty and may only involve a single range space. |
8151 | * |
8152 | * If the resulting multi union piecewise affine expression has |
8153 | * an explicit domain, then assign it the domain of the input. |
8154 | * In other cases, the domain is stored in the individual elements. |
8155 | */ |
8156 | __isl_give isl_multi_union_pw_aff * |
8157 | isl_multi_union_pw_aff_from_union_pw_multi_aff( |
8158 | __isl_take isl_union_pw_multi_aff *upma) |
8159 | { |
8160 | isl_space *space = NULL((void*)0); |
8161 | isl_multi_union_pw_aff *mupa; |
8162 | int i, n; |
8163 | |
8164 | if (!upma) |
8165 | return NULL((void*)0); |
8166 | if (isl_union_pw_multi_aff_n_pw_multi_aff(upma) == 0) |
8167 | isl_die(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid,do { isl_handle_error(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid , "cannot extract range space from empty input", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8169); goto error; } while (0) |
8168 | "cannot extract range space from empty input",do { isl_handle_error(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid , "cannot extract range space from empty input", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8169); goto error; } while (0) |
8169 | goto error)do { isl_handle_error(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid , "cannot extract range space from empty input", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8169); goto error; } while (0); |
8170 | if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, &extract_space, |
8171 | &space) < 0) |
8172 | goto error; |
8173 | |
8174 | if (!space) |
8175 | goto error; |
8176 | |
8177 | n = isl_space_dim(space, isl_dim_set); |
8178 | mupa = isl_multi_union_pw_aff_alloc(space); |
8179 | |
8180 | for (i = 0; i < n; ++i) { |
8181 | isl_union_pw_aff *upa; |
8182 | |
8183 | upa = isl_union_pw_multi_aff_get_union_pw_aff(upma, i); |
8184 | mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa); |
8185 | } |
8186 | if (isl_multi_union_pw_aff_has_explicit_domain(mupa)) { |
8187 | isl_union_setisl_union_map *dom; |
8188 | isl_union_pw_multi_aff *copy; |
8189 | |
8190 | copy = isl_union_pw_multi_aff_copy(upma); |
8191 | dom = isl_union_pw_multi_aff_domain(copy); |
8192 | mupa = isl_multi_union_pw_aff_intersect_domain(mupa, dom); |
8193 | } |
8194 | |
8195 | isl_union_pw_multi_aff_free(upma); |
8196 | return mupa; |
8197 | error: |
8198 | isl_space_free(space); |
8199 | isl_union_pw_multi_aff_free(upma); |
8200 | return NULL((void*)0); |
8201 | } |
8202 | |
8203 | /* Try and create an isl_multi_union_pw_aff that is equivalent |
8204 | * to the given isl_union_map. |
8205 | * The isl_union_map is required to be single-valued in each space. |
8206 | * Moreover, it cannot be empty and all range spaces need to be the same. |
8207 | * Otherwise, an error is produced. |
8208 | */ |
8209 | __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_map( |
8210 | __isl_take isl_union_map *umap) |
8211 | { |
8212 | isl_union_pw_multi_aff *upma; |
8213 | |
8214 | upma = isl_union_pw_multi_aff_from_union_map(umap); |
8215 | return isl_multi_union_pw_aff_from_union_pw_multi_aff(upma); |
8216 | } |
8217 | |
8218 | /* Return a multiple union piecewise affine expression |
8219 | * that is equal to "mv" on "domain", assuming "domain" and "mv" |
8220 | * have been aligned. |
8221 | * |
8222 | * If the resulting multi union piecewise affine expression has |
8223 | * an explicit domain, then assign it the input domain. |
8224 | * In other cases, the domain is stored in the individual elements. |
8225 | */ |
8226 | static __isl_give isl_multi_union_pw_aff * |
8227 | isl_multi_union_pw_aff_multi_val_on_domain_aligned( |
8228 | __isl_take isl_union_setisl_union_map *domain, __isl_take isl_multi_val *mv) |
8229 | { |
8230 | int i, n; |
8231 | isl_space *space; |
8232 | isl_multi_union_pw_aff *mupa; |
8233 | |
8234 | if (!domain || !mv) |
8235 | goto error; |
8236 | |
8237 | n = isl_multi_val_dim(mv, isl_dim_set); |
8238 | space = isl_multi_val_get_space(mv); |
8239 | mupa = isl_multi_union_pw_aff_alloc(space); |
8240 | for (i = 0; i < n; ++i) { |
8241 | isl_val *v; |
8242 | isl_union_pw_aff *upa; |
8243 | |
8244 | v = isl_multi_val_get_val(mv, i); |
8245 | upa = isl_union_pw_aff_val_on_domain(isl_union_set_copy(domain), |
8246 | v); |
8247 | mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa); |
8248 | } |
8249 | if (isl_multi_union_pw_aff_has_explicit_domain(mupa)) |
8250 | mupa = isl_multi_union_pw_aff_intersect_domain(mupa, |
8251 | isl_union_set_copy(domain)); |
8252 | |
8253 | isl_union_set_free(domain); |
8254 | isl_multi_val_free(mv); |
8255 | return mupa; |
8256 | error: |
8257 | isl_union_set_free(domain); |
8258 | isl_multi_val_free(mv); |
8259 | return NULL((void*)0); |
8260 | } |
8261 | |
8262 | /* Return a multiple union piecewise affine expression |
8263 | * that is equal to "mv" on "domain". |
8264 | */ |
8265 | __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_val_on_domain( |
8266 | __isl_take isl_union_setisl_union_map *domain, __isl_take isl_multi_val *mv) |
8267 | { |
8268 | isl_bool equal_params; |
8269 | |
8270 | if (!domain || !mv) |
8271 | goto error; |
8272 | equal_params = isl_space_has_equal_params(domain->dim, mv->space); |
8273 | if (equal_params < 0) |
8274 | goto error; |
8275 | if (equal_params) |
8276 | return isl_multi_union_pw_aff_multi_val_on_domain_aligned( |
8277 | domain, mv); |
8278 | domain = isl_union_set_align_params(domain, |
8279 | isl_multi_val_get_space(mv)); |
8280 | mv = isl_multi_val_align_params(mv, isl_union_set_get_space(domain)); |
8281 | return isl_multi_union_pw_aff_multi_val_on_domain_aligned(domain, mv); |
8282 | error: |
8283 | isl_union_set_free(domain); |
8284 | isl_multi_val_free(mv); |
8285 | return NULL((void*)0); |
8286 | } |
8287 | |
8288 | /* Return a multiple union piecewise affine expression |
8289 | * that is equal to "ma" on "domain". |
8290 | */ |
8291 | __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_aff_on_domain( |
8292 | __isl_take isl_union_setisl_union_map *domain, __isl_take isl_multi_aff *ma) |
8293 | { |
8294 | isl_pw_multi_aff *pma; |
8295 | |
8296 | pma = isl_pw_multi_aff_from_multi_aff(ma); |
8297 | return isl_multi_union_pw_aff_pw_multi_aff_on_domain(domain, pma); |
8298 | } |
8299 | |
8300 | /* Return a multiple union piecewise affine expression |
8301 | * that is equal to "pma" on "domain", assuming "domain" and "pma" |
8302 | * have been aligned. |
8303 | * |
8304 | * If the resulting multi union piecewise affine expression has |
8305 | * an explicit domain, then assign it the input domain. |
8306 | * In other cases, the domain is stored in the individual elements. |
8307 | */ |
8308 | static __isl_give isl_multi_union_pw_aff * |
8309 | isl_multi_union_pw_aff_pw_multi_aff_on_domain_aligned( |
8310 | __isl_take isl_union_setisl_union_map *domain, __isl_take isl_pw_multi_aff *pma) |
8311 | { |
8312 | int i, n; |
8313 | isl_space *space; |
8314 | isl_multi_union_pw_aff *mupa; |
8315 | |
8316 | if (!domain || !pma) |
8317 | goto error; |
8318 | |
8319 | n = isl_pw_multi_aff_dim(pma, isl_dim_set); |
8320 | space = isl_pw_multi_aff_get_space(pma); |
8321 | mupa = isl_multi_union_pw_aff_alloc(space); |
8322 | for (i = 0; i < n; ++i) { |
8323 | isl_pw_aff *pa; |
8324 | isl_union_pw_aff *upa; |
8325 | |
8326 | pa = isl_pw_multi_aff_get_pw_aff(pma, i); |
8327 | upa = isl_union_pw_aff_pw_aff_on_domain( |
8328 | isl_union_set_copy(domain), pa); |
8329 | mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa); |
8330 | } |
8331 | if (isl_multi_union_pw_aff_has_explicit_domain(mupa)) |
8332 | mupa = isl_multi_union_pw_aff_intersect_domain(mupa, |
8333 | isl_union_set_copy(domain)); |
8334 | |
8335 | isl_union_set_free(domain); |
8336 | isl_pw_multi_aff_free(pma); |
8337 | return mupa; |
8338 | error: |
8339 | isl_union_set_free(domain); |
8340 | isl_pw_multi_aff_free(pma); |
8341 | return NULL((void*)0); |
8342 | } |
8343 | |
8344 | /* Return a multiple union piecewise affine expression |
8345 | * that is equal to "pma" on "domain". |
8346 | */ |
8347 | __isl_give isl_multi_union_pw_aff * |
8348 | isl_multi_union_pw_aff_pw_multi_aff_on_domain(__isl_take isl_union_setisl_union_map *domain, |
8349 | __isl_take isl_pw_multi_aff *pma) |
8350 | { |
8351 | isl_bool equal_params; |
8352 | isl_space *space; |
8353 | |
8354 | space = isl_pw_multi_aff_peek_space(pma); |
8355 | equal_params = isl_union_set_space_has_equal_params(domain, space); |
8356 | if (equal_params < 0) |
8357 | goto error; |
8358 | if (equal_params) |
8359 | return isl_multi_union_pw_aff_pw_multi_aff_on_domain_aligned( |
8360 | domain, pma); |
8361 | domain = isl_union_set_align_params(domain, |
8362 | isl_pw_multi_aff_get_space(pma)); |
8363 | pma = isl_pw_multi_aff_align_params(pma, |
8364 | isl_union_set_get_space(domain)); |
8365 | return isl_multi_union_pw_aff_pw_multi_aff_on_domain_aligned(domain, |
8366 | pma); |
8367 | error: |
8368 | isl_union_set_free(domain); |
8369 | isl_pw_multi_aff_free(pma); |
8370 | return NULL((void*)0); |
8371 | } |
8372 | |
8373 | /* Return a union set containing those elements in the domains |
8374 | * of the elements of "mupa" where they are all zero. |
8375 | * |
8376 | * If there are no elements, then simply return the entire domain. |
8377 | */ |
8378 | __isl_give isl_union_setisl_union_map *isl_multi_union_pw_aff_zero_union_set( |
8379 | __isl_take isl_multi_union_pw_aff *mupa) |
8380 | { |
8381 | int i, n; |
8382 | isl_union_pw_aff *upa; |
8383 | isl_union_setisl_union_map *zero; |
8384 | |
8385 | if (!mupa) |
8386 | return NULL((void*)0); |
8387 | |
8388 | n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); |
8389 | if (n == 0) |
8390 | return isl_multi_union_pw_aff_domain(mupa); |
8391 | |
8392 | upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0); |
8393 | zero = isl_union_pw_aff_zero_union_set(upa); |
8394 | |
8395 | for (i = 1; i < n; ++i) { |
8396 | isl_union_setisl_union_map *zero_i; |
8397 | |
8398 | upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); |
8399 | zero_i = isl_union_pw_aff_zero_union_set(upa); |
8400 | |
8401 | zero = isl_union_set_intersect(zero, zero_i); |
8402 | } |
8403 | |
8404 | isl_multi_union_pw_aff_free(mupa); |
8405 | return zero; |
8406 | } |
8407 | |
8408 | /* Construct a union map mapping the shared domain |
8409 | * of the union piecewise affine expressions to the range of "mupa" |
8410 | * in the special case of a 0D multi union piecewise affine expression. |
8411 | * |
8412 | * Construct a map between the explicit domain of "mupa" and |
8413 | * the range space. |
8414 | * Note that this assumes that the domain consists of explicit elements. |
8415 | */ |
8416 | static __isl_give isl_union_map *isl_union_map_from_multi_union_pw_aff_0D( |
8417 | __isl_take isl_multi_union_pw_aff *mupa) |
8418 | { |
8419 | isl_bool is_params; |
8420 | isl_space *space; |
8421 | isl_union_setisl_union_map *dom, *ran; |
8422 | |
8423 | space = isl_multi_union_pw_aff_get_space(mupa); |
8424 | dom = isl_multi_union_pw_aff_domain(mupa); |
8425 | ran = isl_union_set_from_set(isl_set_universe(space)); |
8426 | |
8427 | is_params = isl_union_set_is_params(dom); |
8428 | if (is_params < 0) |
8429 | dom = isl_union_set_free(dom); |
8430 | else if (is_params) |
8431 | isl_die(isl_union_set_get_ctx(dom), isl_error_invalid,do { isl_handle_error(isl_union_set_get_ctx(dom), isl_error_invalid , "cannot create union map from expression without " "explicit domain elements" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8434); dom = isl_union_set_free(dom); } while (0) |
8432 | "cannot create union map from expression without "do { isl_handle_error(isl_union_set_get_ctx(dom), isl_error_invalid , "cannot create union map from expression without " "explicit domain elements" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8434); dom = isl_union_set_free(dom); } while (0) |
8433 | "explicit domain elements",do { isl_handle_error(isl_union_set_get_ctx(dom), isl_error_invalid , "cannot create union map from expression without " "explicit domain elements" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8434); dom = isl_union_set_free(dom); } while (0) |
8434 | dom = isl_union_set_free(dom))do { isl_handle_error(isl_union_set_get_ctx(dom), isl_error_invalid , "cannot create union map from expression without " "explicit domain elements" , "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8434); dom = isl_union_set_free(dom); } while (0); |
8435 | |
8436 | return isl_union_map_from_domain_and_range(dom, ran); |
8437 | } |
8438 | |
8439 | /* Construct a union map mapping the shared domain |
8440 | * of the union piecewise affine expressions to the range of "mupa" |
8441 | * with each dimension in the range equated to the |
8442 | * corresponding union piecewise affine expression. |
8443 | * |
8444 | * If the input is zero-dimensional, then construct a mapping |
8445 | * from its explicit domain. |
8446 | */ |
8447 | __isl_give isl_union_map *isl_union_map_from_multi_union_pw_aff( |
8448 | __isl_take isl_multi_union_pw_aff *mupa) |
8449 | { |
8450 | int i, n; |
8451 | isl_space *space; |
8452 | isl_union_map *umap; |
8453 | isl_union_pw_aff *upa; |
8454 | |
8455 | if (!mupa) |
8456 | return NULL((void*)0); |
8457 | |
8458 | n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); |
8459 | if (n == 0) |
8460 | return isl_union_map_from_multi_union_pw_aff_0D(mupa); |
8461 | |
8462 | upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0); |
8463 | umap = isl_union_map_from_union_pw_aff(upa); |
8464 | |
8465 | for (i = 1; i < n; ++i) { |
8466 | isl_union_map *umap_i; |
8467 | |
8468 | upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); |
8469 | umap_i = isl_union_map_from_union_pw_aff(upa); |
8470 | umap = isl_union_map_flat_range_product(umap, umap_i); |
8471 | } |
8472 | |
8473 | space = isl_multi_union_pw_aff_get_space(mupa); |
8474 | umap = isl_union_map_reset_range_space(umap, space); |
8475 | |
8476 | isl_multi_union_pw_aff_free(mupa); |
8477 | return umap; |
8478 | } |
8479 | |
8480 | /* Internal data structure for isl_union_pw_multi_aff_reset_range_space. |
8481 | * "range" is the space from which to set the range space. |
8482 | * "res" collects the results. |
8483 | */ |
8484 | struct isl_union_pw_multi_aff_reset_range_space_data { |
8485 | isl_space *range; |
8486 | isl_union_pw_multi_aff *res; |
8487 | }; |
8488 | |
8489 | /* Replace the range space of "pma" by the range space of data->range and |
8490 | * add the result to data->res. |
8491 | */ |
8492 | static isl_stat reset_range_space(__isl_take isl_pw_multi_aff *pma, void *user) |
8493 | { |
8494 | struct isl_union_pw_multi_aff_reset_range_space_data *data = user; |
8495 | isl_space *space; |
8496 | |
8497 | space = isl_pw_multi_aff_get_space(pma); |
8498 | space = isl_space_domain(space); |
8499 | space = isl_space_extend_domain_with_range(space, |
8500 | isl_space_copy(data->range)); |
8501 | pma = isl_pw_multi_aff_reset_space(pma, space); |
8502 | data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma); |
8503 | |
8504 | return data->res ? isl_stat_ok : isl_stat_error; |
8505 | } |
8506 | |
8507 | /* Replace the range space of all the piecewise affine expressions in "upma" by |
8508 | * the range space of "space". |
8509 | * |
8510 | * This assumes that all these expressions have the same output dimension. |
8511 | * |
8512 | * Since the spaces of the expressions change, so do their hash values. |
8513 | * We therefore need to create a new isl_union_pw_multi_aff. |
8514 | * Note that the hash value is currently computed based on the entire |
8515 | * space even though there can only be a single expression with a given |
8516 | * domain space. |
8517 | */ |
8518 | static __isl_give isl_union_pw_multi_aff * |
8519 | isl_union_pw_multi_aff_reset_range_space( |
8520 | __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_space *space) |
8521 | { |
8522 | struct isl_union_pw_multi_aff_reset_range_space_data data = { space }; |
8523 | isl_space *space_upma; |
8524 | |
8525 | space_upma = isl_union_pw_multi_aff_get_space(upma); |
8526 | data.res = isl_union_pw_multi_aff_empty(space_upma); |
8527 | if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, |
8528 | &reset_range_space, &data) < 0) |
8529 | data.res = isl_union_pw_multi_aff_free(data.res); |
8530 | |
8531 | isl_space_free(space); |
8532 | isl_union_pw_multi_aff_free(upma); |
8533 | return data.res; |
8534 | } |
8535 | |
8536 | /* Construct and return a union piecewise multi affine expression |
8537 | * that is equal to the given multi union piecewise affine expression, |
8538 | * in the special case of a 0D multi union piecewise affine expression. |
8539 | * |
8540 | * Construct a union piecewise multi affine expression |
8541 | * on top of the explicit domain of the input. |
8542 | */ |
8543 | __isl_give isl_union_pw_multi_aff * |
8544 | isl_union_pw_multi_aff_from_multi_union_pw_aff_0D( |
8545 | __isl_take isl_multi_union_pw_aff *mupa) |
8546 | { |
8547 | isl_space *space; |
8548 | isl_multi_val *mv; |
8549 | isl_union_setisl_union_map *domain; |
8550 | |
8551 | space = isl_multi_union_pw_aff_get_space(mupa); |
8552 | mv = isl_multi_val_zero(space); |
8553 | domain = isl_multi_union_pw_aff_domain(mupa); |
8554 | return isl_union_pw_multi_aff_multi_val_on_domain(domain, mv); |
8555 | } |
8556 | |
8557 | /* Construct and return a union piecewise multi affine expression |
8558 | * that is equal to the given multi union piecewise affine expression. |
8559 | * |
8560 | * If the input is zero-dimensional, then |
8561 | * construct a union piecewise multi affine expression |
8562 | * on top of the explicit domain of the input. |
8563 | */ |
8564 | __isl_give isl_union_pw_multi_aff * |
8565 | isl_union_pw_multi_aff_from_multi_union_pw_aff( |
8566 | __isl_take isl_multi_union_pw_aff *mupa) |
8567 | { |
8568 | int i, n; |
8569 | isl_space *space; |
8570 | isl_union_pw_multi_aff *upma; |
8571 | isl_union_pw_aff *upa; |
8572 | |
8573 | if (!mupa) |
8574 | return NULL((void*)0); |
8575 | |
8576 | n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); |
8577 | if (n == 0) |
8578 | return isl_union_pw_multi_aff_from_multi_union_pw_aff_0D(mupa); |
8579 | |
8580 | space = isl_multi_union_pw_aff_get_space(mupa); |
8581 | upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0); |
8582 | upma = isl_union_pw_multi_aff_from_union_pw_aff(upa); |
8583 | |
8584 | for (i = 1; i < n; ++i) { |
8585 | isl_union_pw_multi_aff *upma_i; |
8586 | |
8587 | upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); |
8588 | upma_i = isl_union_pw_multi_aff_from_union_pw_aff(upa); |
8589 | upma = isl_union_pw_multi_aff_flat_range_product(upma, upma_i); |
8590 | } |
8591 | |
8592 | upma = isl_union_pw_multi_aff_reset_range_space(upma, space); |
8593 | |
8594 | isl_multi_union_pw_aff_free(mupa); |
8595 | return upma; |
8596 | } |
8597 | |
8598 | /* Intersect the range of "mupa" with "range", |
8599 | * in the special case where "mupa" is 0D. |
8600 | * |
8601 | * Intersect the domain of "mupa" with the constraints on the parameters |
8602 | * of "range". |
8603 | */ |
8604 | static __isl_give isl_multi_union_pw_aff *mupa_intersect_range_0D( |
8605 | __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_setisl_map *range) |
8606 | { |
8607 | range = isl_set_params(range); |
8608 | mupa = isl_multi_union_pw_aff_intersect_params(mupa, range); |
8609 | return mupa; |
8610 | } |
8611 | |
8612 | /* Intersect the range of "mupa" with "range". |
8613 | * That is, keep only those domain elements that have a function value |
8614 | * in "range". |
8615 | */ |
8616 | __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_intersect_range( |
8617 | __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_setisl_map *range) |
8618 | { |
8619 | isl_union_pw_multi_aff *upma; |
8620 | isl_union_setisl_union_map *domain; |
8621 | isl_space *space; |
8622 | int n; |
8623 | int match; |
8624 | |
8625 | if (!mupa || !range) |
8626 | goto error; |
8627 | |
8628 | space = isl_set_get_space(range); |
8629 | match = isl_space_tuple_is_equal(mupa->space, isl_dim_set, |
8630 | space, isl_dim_set); |
8631 | isl_space_free(space); |
8632 | if (match < 0) |
8633 | goto error; |
8634 | if (!match) |
8635 | isl_die(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid,do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid , "space don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8636); goto error; } while (0) |
8636 | "space don't match", goto error)do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid , "space don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8636); goto error; } while (0); |
8637 | n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); |
8638 | if (n == 0) |
8639 | return mupa_intersect_range_0D(mupa, range); |
8640 | |
8641 | upma = isl_union_pw_multi_aff_from_multi_union_pw_aff( |
8642 | isl_multi_union_pw_aff_copy(mupa)); |
8643 | domain = isl_union_set_from_set(range); |
8644 | domain = isl_union_set_preimage_union_pw_multi_aff(domain, upma); |
8645 | mupa = isl_multi_union_pw_aff_intersect_domain(mupa, domain); |
8646 | |
8647 | return mupa; |
8648 | error: |
8649 | isl_multi_union_pw_aff_free(mupa); |
8650 | isl_set_free(range); |
8651 | return NULL((void*)0); |
8652 | } |
8653 | |
8654 | /* Return the shared domain of the elements of "mupa", |
8655 | * in the special case where "mupa" is zero-dimensional. |
8656 | * |
8657 | * Return the explicit domain of "mupa". |
8658 | * Note that this domain may be a parameter set, either |
8659 | * because "mupa" is meant to live in a set space or |
8660 | * because no explicit domain has been set. |
8661 | */ |
8662 | __isl_give isl_union_setisl_union_map *isl_multi_union_pw_aff_domain_0D( |
8663 | __isl_take isl_multi_union_pw_aff *mupa) |
8664 | { |
8665 | isl_union_setisl_union_map *dom; |
8666 | |
8667 | dom = isl_multi_union_pw_aff_get_explicit_domain(mupa); |
8668 | isl_multi_union_pw_aff_free(mupa); |
8669 | |
8670 | return dom; |
8671 | } |
8672 | |
8673 | /* Return the shared domain of the elements of "mupa". |
8674 | * |
8675 | * If "mupa" is zero-dimensional, then return its explicit domain. |
8676 | */ |
8677 | __isl_give isl_union_setisl_union_map *isl_multi_union_pw_aff_domain( |
8678 | __isl_take isl_multi_union_pw_aff *mupa) |
8679 | { |
8680 | int i, n; |
8681 | isl_union_pw_aff *upa; |
8682 | isl_union_setisl_union_map *dom; |
8683 | |
8684 | if (!mupa) |
8685 | return NULL((void*)0); |
8686 | |
8687 | n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); |
8688 | if (n == 0) |
8689 | return isl_multi_union_pw_aff_domain_0D(mupa); |
8690 | |
8691 | upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0); |
8692 | dom = isl_union_pw_aff_domain(upa); |
8693 | for (i = 1; i < n; ++i) { |
8694 | isl_union_setisl_union_map *dom_i; |
8695 | |
8696 | upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); |
8697 | dom_i = isl_union_pw_aff_domain(upa); |
8698 | dom = isl_union_set_intersect(dom, dom_i); |
8699 | } |
8700 | |
8701 | isl_multi_union_pw_aff_free(mupa); |
8702 | return dom; |
8703 | } |
8704 | |
8705 | /* Apply "aff" to "mupa". The space of "mupa" is equal to the domain of "aff". |
8706 | * In particular, the spaces have been aligned. |
8707 | * The result is defined over the shared domain of the elements of "mupa" |
8708 | * |
8709 | * We first extract the parametric constant part of "aff" and |
8710 | * define that over the shared domain. |
8711 | * Then we iterate over all input dimensions of "aff" and add the corresponding |
8712 | * multiples of the elements of "mupa". |
8713 | * Finally, we consider the integer divisions, calling the function |
8714 | * recursively to obtain an isl_union_pw_aff corresponding to the |
8715 | * integer division argument. |
8716 | */ |
8717 | static __isl_give isl_union_pw_aff *multi_union_pw_aff_apply_aff( |
8718 | __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff) |
8719 | { |
8720 | int i, n_in, n_div; |
8721 | isl_union_pw_aff *upa; |
8722 | isl_union_setisl_union_map *uset; |
8723 | isl_val *v; |
8724 | isl_aff *cst; |
8725 | |
8726 | n_in = isl_aff_dim(aff, isl_dim_in); |
8727 | n_div = isl_aff_dim(aff, isl_dim_div); |
8728 | |
8729 | uset = isl_multi_union_pw_aff_domain(isl_multi_union_pw_aff_copy(mupa)); |
8730 | cst = isl_aff_copy(aff); |
8731 | cst = isl_aff_drop_dims(cst, isl_dim_div, 0, n_div); |
8732 | cst = isl_aff_drop_dims(cst, isl_dim_in, 0, n_in); |
8733 | cst = isl_aff_project_domain_on_params(cst); |
8734 | upa = isl_union_pw_aff_aff_on_domain(uset, cst); |
8735 | |
8736 | for (i = 0; i < n_in; ++i) { |
8737 | isl_union_pw_aff *upa_i; |
8738 | |
8739 | if (!isl_aff_involves_dims(aff, isl_dim_in, i, 1)) |
8740 | continue; |
8741 | v = isl_aff_get_coefficient_val(aff, isl_dim_in, i); |
8742 | upa_i = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); |
8743 | upa_i = isl_union_pw_aff_scale_val(upa_i, v); |
8744 | upa = isl_union_pw_aff_add(upa, upa_i); |
8745 | } |
8746 | |
8747 | for (i = 0; i < n_div; ++i) { |
8748 | isl_aff *div; |
8749 | isl_union_pw_aff *upa_i; |
8750 | |
8751 | if (!isl_aff_involves_dims(aff, isl_dim_div, i, 1)) |
8752 | continue; |
8753 | div = isl_aff_get_div(aff, i); |
8754 | upa_i = multi_union_pw_aff_apply_aff( |
8755 | isl_multi_union_pw_aff_copy(mupa), div); |
8756 | upa_i = isl_union_pw_aff_floor(upa_i); |
8757 | v = isl_aff_get_coefficient_val(aff, isl_dim_div, i); |
8758 | upa_i = isl_union_pw_aff_scale_val(upa_i, v); |
8759 | upa = isl_union_pw_aff_add(upa, upa_i); |
8760 | } |
8761 | |
8762 | isl_multi_union_pw_aff_free(mupa); |
8763 | isl_aff_free(aff); |
8764 | |
8765 | return upa; |
8766 | } |
8767 | |
8768 | /* Apply "aff" to "mupa". The space of "mupa" needs to be compatible |
8769 | * with the domain of "aff". |
8770 | * Furthermore, the dimension of this space needs to be greater than zero. |
8771 | * The result is defined over the shared domain of the elements of "mupa" |
8772 | * |
8773 | * We perform these checks and then hand over control to |
8774 | * multi_union_pw_aff_apply_aff. |
8775 | */ |
8776 | __isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_aff( |
8777 | __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff) |
8778 | { |
8779 | isl_space *space1, *space2; |
8780 | int equal; |
8781 | |
8782 | mupa = isl_multi_union_pw_aff_align_params(mupa, |
8783 | isl_aff_get_space(aff)); |
8784 | aff = isl_aff_align_params(aff, isl_multi_union_pw_aff_get_space(mupa)); |
8785 | if (!mupa || !aff) |
8786 | goto error; |
8787 | |
8788 | space1 = isl_multi_union_pw_aff_get_space(mupa); |
8789 | space2 = isl_aff_get_domain_space(aff); |
8790 | equal = isl_space_is_equal(space1, space2); |
8791 | isl_space_free(space1); |
8792 | isl_space_free(space2); |
8793 | if (equal < 0) |
8794 | goto error; |
8795 | if (!equal) |
8796 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "spaces don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8797); goto error; } while (0) |
8797 | "spaces don't match", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "spaces don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8797); goto error; } while (0); |
8798 | if (isl_aff_dim(aff, isl_dim_in) == 0) |
8799 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "cannot determine domains", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8800); goto error; } while (0) |
8800 | "cannot determine domains", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "cannot determine domains", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8800); goto error; } while (0); |
8801 | |
8802 | return multi_union_pw_aff_apply_aff(mupa, aff); |
8803 | error: |
8804 | isl_multi_union_pw_aff_free(mupa); |
8805 | isl_aff_free(aff); |
8806 | return NULL((void*)0); |
8807 | } |
8808 | |
8809 | /* Apply "ma" to "mupa", in the special case where "mupa" is 0D. |
8810 | * The space of "mupa" is known to be compatible with the domain of "ma". |
8811 | * |
8812 | * Construct an isl_multi_union_pw_aff that is equal to "ma" |
8813 | * on the domain of "mupa". |
8814 | */ |
8815 | static __isl_give isl_multi_union_pw_aff *mupa_apply_multi_aff_0D( |
8816 | __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma) |
8817 | { |
8818 | isl_union_setisl_union_map *dom; |
8819 | |
8820 | dom = isl_multi_union_pw_aff_domain(mupa); |
8821 | ma = isl_multi_aff_project_domain_on_params(ma); |
8822 | |
8823 | return isl_multi_union_pw_aff_multi_aff_on_domain(dom, ma); |
8824 | } |
8825 | |
8826 | /* Apply "ma" to "mupa". The space of "mupa" needs to be compatible |
8827 | * with the domain of "ma". |
8828 | * The result is defined over the shared domain of the elements of "mupa" |
8829 | */ |
8830 | __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_multi_aff( |
8831 | __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma) |
8832 | { |
8833 | isl_space *space1, *space2; |
8834 | isl_multi_union_pw_aff *res; |
8835 | int equal; |
8836 | int i, n_out; |
8837 | |
8838 | mupa = isl_multi_union_pw_aff_align_params(mupa, |
8839 | isl_multi_aff_get_space(ma)); |
8840 | ma = isl_multi_aff_align_params(ma, |
8841 | isl_multi_union_pw_aff_get_space(mupa)); |
8842 | if (!mupa || !ma) |
8843 | goto error; |
8844 | |
8845 | space1 = isl_multi_union_pw_aff_get_space(mupa); |
8846 | space2 = isl_multi_aff_get_domain_space(ma); |
8847 | equal = isl_space_is_equal(space1, space2); |
8848 | isl_space_free(space1); |
8849 | isl_space_free(space2); |
8850 | if (equal < 0) |
8851 | goto error; |
8852 | if (!equal) |
8853 | isl_die(isl_multi_aff_get_ctx(ma), isl_error_invalid,do { isl_handle_error(isl_multi_aff_get_ctx(ma), isl_error_invalid , "spaces don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8854); goto error; } while (0) |
8854 | "spaces don't match", goto error)do { isl_handle_error(isl_multi_aff_get_ctx(ma), isl_error_invalid , "spaces don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8854); goto error; } while (0); |
8855 | n_out = isl_multi_aff_dim(ma, isl_dim_out); |
8856 | if (isl_multi_aff_dim(ma, isl_dim_in) == 0) |
8857 | return mupa_apply_multi_aff_0D(mupa, ma); |
8858 | |
8859 | space1 = isl_space_range(isl_multi_aff_get_space(ma)); |
8860 | res = isl_multi_union_pw_aff_alloc(space1); |
8861 | |
8862 | for (i = 0; i < n_out; ++i) { |
8863 | isl_aff *aff; |
8864 | isl_union_pw_aff *upa; |
8865 | |
8866 | aff = isl_multi_aff_get_aff(ma, i); |
8867 | upa = multi_union_pw_aff_apply_aff( |
8868 | isl_multi_union_pw_aff_copy(mupa), aff); |
8869 | res = isl_multi_union_pw_aff_set_union_pw_aff(res, i, upa); |
8870 | } |
8871 | |
8872 | isl_multi_aff_free(ma); |
8873 | isl_multi_union_pw_aff_free(mupa); |
8874 | return res; |
8875 | error: |
8876 | isl_multi_union_pw_aff_free(mupa); |
8877 | isl_multi_aff_free(ma); |
8878 | return NULL((void*)0); |
8879 | } |
8880 | |
8881 | /* Apply "pa" to "mupa", in the special case where "mupa" is 0D. |
8882 | * The space of "mupa" is known to be compatible with the domain of "pa". |
8883 | * |
8884 | * Construct an isl_multi_union_pw_aff that is equal to "pa" |
8885 | * on the domain of "mupa". |
8886 | */ |
8887 | static __isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_pw_aff_0D( |
8888 | __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_pw_aff *pa) |
8889 | { |
8890 | isl_union_setisl_union_map *dom; |
8891 | |
8892 | dom = isl_multi_union_pw_aff_domain(mupa); |
8893 | pa = isl_pw_aff_project_domain_on_params(pa); |
8894 | |
8895 | return isl_union_pw_aff_pw_aff_on_domain(dom, pa); |
8896 | } |
8897 | |
8898 | /* Apply "pa" to "mupa". The space of "mupa" needs to be compatible |
8899 | * with the domain of "pa". |
8900 | * Furthermore, the dimension of this space needs to be greater than zero. |
8901 | * The result is defined over the shared domain of the elements of "mupa" |
8902 | */ |
8903 | __isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_pw_aff( |
8904 | __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_pw_aff *pa) |
8905 | { |
8906 | int i; |
8907 | int equal; |
8908 | isl_space *space, *space2; |
8909 | isl_union_pw_aff *upa; |
8910 | |
8911 | mupa = isl_multi_union_pw_aff_align_params(mupa, |
8912 | isl_pw_aff_get_space(pa)); |
8913 | pa = isl_pw_aff_align_params(pa, |
8914 | isl_multi_union_pw_aff_get_space(mupa)); |
8915 | if (!mupa || !pa) |
8916 | goto error; |
8917 | |
8918 | space = isl_multi_union_pw_aff_get_space(mupa); |
8919 | space2 = isl_pw_aff_get_domain_space(pa); |
8920 | equal = isl_space_is_equal(space, space2); |
8921 | isl_space_free(space); |
8922 | isl_space_free(space2); |
8923 | if (equal < 0) |
8924 | goto error; |
8925 | if (!equal) |
8926 | isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid , "spaces don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8927); goto error; } while (0) |
8927 | "spaces don't match", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid , "spaces don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 8927); goto error; } while (0); |
8928 | if (isl_pw_aff_dim(pa, isl_dim_in) == 0) |
8929 | return isl_multi_union_pw_aff_apply_pw_aff_0D(mupa, pa); |
8930 | |
8931 | space = isl_space_params(isl_multi_union_pw_aff_get_space(mupa)); |
8932 | upa = isl_union_pw_aff_empty(space); |
8933 | |
8934 | for (i = 0; i < pa->n; ++i) { |
8935 | isl_aff *aff; |
8936 | isl_setisl_map *domain; |
8937 | isl_multi_union_pw_aff *mupa_i; |
8938 | isl_union_pw_aff *upa_i; |
8939 | |
8940 | mupa_i = isl_multi_union_pw_aff_copy(mupa); |
8941 | domain = isl_set_copy(pa->p[i].set); |
8942 | mupa_i = isl_multi_union_pw_aff_intersect_range(mupa_i, domain); |
8943 | aff = isl_aff_copy(pa->p[i].aff); |
8944 | upa_i = multi_union_pw_aff_apply_aff(mupa_i, aff); |
8945 | upa = isl_union_pw_aff_union_add(upa, upa_i); |
8946 | } |
8947 | |
8948 | isl_multi_union_pw_aff_free(mupa); |
8949 | isl_pw_aff_free(pa); |
8950 | return upa; |
8951 | error: |
8952 | isl_multi_union_pw_aff_free(mupa); |
8953 | isl_pw_aff_free(pa); |
8954 | return NULL((void*)0); |
8955 | } |
8956 | |
8957 | /* Apply "pma" to "mupa", in the special case where "mupa" is 0D. |
8958 | * The space of "mupa" is known to be compatible with the domain of "pma". |
8959 | * |
8960 | * Construct an isl_multi_union_pw_aff that is equal to "pma" |
8961 | * on the domain of "mupa". |
8962 | */ |
8963 | static __isl_give isl_multi_union_pw_aff *mupa_apply_pw_multi_aff_0D( |
8964 | __isl_take isl_multi_union_pw_aff *mupa, |
8965 | __isl_take isl_pw_multi_aff *pma) |
8966 | { |
8967 | isl_union_setisl_union_map *dom; |
8968 | |
8969 | dom = isl_multi_union_pw_aff_domain(mupa); |
8970 | pma = isl_pw_multi_aff_project_domain_on_params(pma); |
8971 | |
8972 | return isl_multi_union_pw_aff_pw_multi_aff_on_domain(dom, pma); |
8973 | } |
8974 | |
8975 | /* Apply "pma" to "mupa". The space of "mupa" needs to be compatible |
8976 | * with the domain of "pma". |
8977 | * The result is defined over the shared domain of the elements of "mupa" |
8978 | */ |
8979 | __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_pw_multi_aff( |
8980 | __isl_take isl_multi_union_pw_aff *mupa, |
8981 | __isl_take isl_pw_multi_aff *pma) |
8982 | { |
8983 | isl_space *space1, *space2; |
8984 | isl_multi_union_pw_aff *res; |
8985 | int equal; |
8986 | int i, n_out; |
8987 | |
8988 | mupa = isl_multi_union_pw_aff_align_params(mupa, |
8989 | isl_pw_multi_aff_get_space(pma)); |
8990 | pma = isl_pw_multi_aff_align_params(pma, |
8991 | isl_multi_union_pw_aff_get_space(mupa)); |
8992 | if (!mupa || !pma) |
8993 | goto error; |
8994 | |
8995 | space1 = isl_multi_union_pw_aff_get_space(mupa); |
8996 | space2 = isl_pw_multi_aff_get_domain_space(pma); |
8997 | equal = isl_space_is_equal(space1, space2); |
8998 | isl_space_free(space1); |
8999 | isl_space_free(space2); |
9000 | if (equal < 0) |
9001 | goto error; |
9002 | if (!equal) |
9003 | isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid , "spaces don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 9004); goto error; } while (0) |
9004 | "spaces don't match", goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid , "spaces don't match", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 9004); goto error; } while (0); |
9005 | n_out = isl_pw_multi_aff_dim(pma, isl_dim_out); |
9006 | if (isl_pw_multi_aff_dim(pma, isl_dim_in) == 0) |
9007 | return mupa_apply_pw_multi_aff_0D(mupa, pma); |
9008 | |
9009 | space1 = isl_space_range(isl_pw_multi_aff_get_space(pma)); |
9010 | res = isl_multi_union_pw_aff_alloc(space1); |
9011 | |
9012 | for (i = 0; i < n_out; ++i) { |
9013 | isl_pw_aff *pa; |
9014 | isl_union_pw_aff *upa; |
9015 | |
9016 | pa = isl_pw_multi_aff_get_pw_aff(pma, i); |
9017 | upa = isl_multi_union_pw_aff_apply_pw_aff( |
9018 | isl_multi_union_pw_aff_copy(mupa), pa); |
9019 | res = isl_multi_union_pw_aff_set_union_pw_aff(res, i, upa); |
9020 | } |
9021 | |
9022 | isl_pw_multi_aff_free(pma); |
9023 | isl_multi_union_pw_aff_free(mupa); |
9024 | return res; |
9025 | error: |
9026 | isl_multi_union_pw_aff_free(mupa); |
9027 | isl_pw_multi_aff_free(pma); |
9028 | return NULL((void*)0); |
9029 | } |
9030 | |
9031 | /* Replace the explicit domain of "mupa" by its preimage under "upma". |
9032 | * If the explicit domain only keeps track of constraints on the parameters, |
9033 | * then only update those constraints. |
9034 | */ |
9035 | static __isl_give isl_multi_union_pw_aff *preimage_explicit_domain( |
9036 | __isl_take isl_multi_union_pw_aff *mupa, |
9037 | __isl_keep isl_union_pw_multi_aff *upma) |
9038 | { |
9039 | isl_bool is_params; |
9040 | |
9041 | if (isl_multi_union_pw_aff_check_has_explicit_domain(mupa) < 0) |
9042 | return isl_multi_union_pw_aff_free(mupa); |
9043 | |
9044 | mupa = isl_multi_union_pw_aff_cow(mupa); |
9045 | if (!mupa) |
9046 | return NULL((void*)0); |
9047 | |
9048 | is_params = isl_union_set_is_params(mupa->u.dom); |
9049 | if (is_params < 0) |
9050 | return isl_multi_union_pw_aff_free(mupa); |
9051 | |
9052 | upma = isl_union_pw_multi_aff_copy(upma); |
9053 | if (is_params) |
9054 | mupa->u.dom = isl_union_set_intersect_params(mupa->u.dom, |
9055 | isl_union_set_params(isl_union_pw_multi_aff_domain(upma))); |
9056 | else |
9057 | mupa->u.dom = isl_union_set_preimage_union_pw_multi_aff( |
9058 | mupa->u.dom, upma); |
9059 | if (!mupa->u.dom) |
9060 | return isl_multi_union_pw_aff_free(mupa); |
9061 | return mupa; |
9062 | } |
9063 | |
9064 | /* Compute the pullback of "mupa" by the function represented by "upma". |
9065 | * In other words, plug in "upma" in "mupa". The result contains |
9066 | * expressions defined over the domain space of "upma". |
9067 | * |
9068 | * Run over all elements of "mupa" and plug in "upma" in each of them. |
9069 | * |
9070 | * If "mupa" has an explicit domain, then it is this domain |
9071 | * that needs to undergo a pullback instead, i.e., a preimage. |
9072 | */ |
9073 | __isl_give isl_multi_union_pw_aff * |
9074 | isl_multi_union_pw_aff_pullback_union_pw_multi_aff( |
9075 | __isl_take isl_multi_union_pw_aff *mupa, |
9076 | __isl_take isl_union_pw_multi_aff *upma) |
9077 | { |
9078 | int i, n; |
9079 | |
9080 | mupa = isl_multi_union_pw_aff_align_params(mupa, |
9081 | isl_union_pw_multi_aff_get_space(upma)); |
9082 | upma = isl_union_pw_multi_aff_align_params(upma, |
9083 | isl_multi_union_pw_aff_get_space(mupa)); |
9084 | mupa = isl_multi_union_pw_aff_cow(mupa); |
9085 | if (!mupa || !upma) |
9086 | goto error; |
9087 | |
9088 | n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); |
9089 | for (i = 0; i < n; ++i) { |
9090 | isl_union_pw_aff *upa; |
9091 | |
9092 | upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); |
9093 | upa = isl_union_pw_aff_pullback_union_pw_multi_aff(upa, |
9094 | isl_union_pw_multi_aff_copy(upma)); |
9095 | mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa); |
9096 | } |
9097 | |
9098 | if (isl_multi_union_pw_aff_has_explicit_domain(mupa)) |
9099 | mupa = preimage_explicit_domain(mupa, upma); |
9100 | |
9101 | isl_union_pw_multi_aff_free(upma); |
9102 | return mupa; |
9103 | error: |
9104 | isl_multi_union_pw_aff_free(mupa); |
9105 | isl_union_pw_multi_aff_free(upma); |
9106 | return NULL((void*)0); |
9107 | } |
9108 | |
9109 | /* Extract the sequence of elements in "mupa" with domain space "space" |
9110 | * (ignoring parameters). |
9111 | * |
9112 | * For the elements of "mupa" that are not defined on the specified space, |
9113 | * the corresponding element in the result is empty. |
9114 | */ |
9115 | __isl_give isl_multi_pw_aff *isl_multi_union_pw_aff_extract_multi_pw_aff( |
9116 | __isl_keep isl_multi_union_pw_aff *mupa, __isl_take isl_space *space) |
9117 | { |
9118 | int i, n; |
9119 | isl_space *space_mpa; |
9120 | isl_multi_pw_aff *mpa; |
9121 | |
9122 | if (!mupa || !space) |
9123 | goto error; |
9124 | |
9125 | space_mpa = isl_multi_union_pw_aff_get_space(mupa); |
9126 | space = isl_space_replace_params(space, space_mpa); |
9127 | space_mpa = isl_space_map_from_domain_and_range(isl_space_copy(space), |
9128 | space_mpa); |
9129 | mpa = isl_multi_pw_aff_alloc(space_mpa); |
9130 | |
9131 | space = isl_space_from_domain(space); |
9132 | space = isl_space_add_dims(space, isl_dim_out, 1); |
9133 | n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set); |
9134 | for (i = 0; i < n; ++i) { |
9135 | isl_union_pw_aff *upa; |
9136 | isl_pw_aff *pa; |
9137 | |
9138 | upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i); |
9139 | pa = isl_union_pw_aff_extract_pw_aff(upa, |
9140 | isl_space_copy(space)); |
9141 | mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa); |
9142 | isl_union_pw_aff_free(upa); |
9143 | } |
9144 | |
9145 | isl_space_free(space); |
9146 | return mpa; |
9147 | error: |
9148 | isl_space_free(space); |
9149 | return NULL((void*)0); |
9150 | } |
9151 | |
9152 | /* Evaluate the affine function "aff" in the void point "pnt". |
9153 | * In particular, return the value NaN. |
9154 | */ |
9155 | static __isl_give isl_val *eval_void(__isl_take isl_aff *aff, |
9156 | __isl_take isl_point *pnt) |
9157 | { |
9158 | isl_ctx *ctx; |
9159 | |
9160 | ctx = isl_point_get_ctx(pnt); |
9161 | isl_aff_free(aff); |
9162 | isl_point_free(pnt); |
9163 | return isl_val_nan(ctx); |
9164 | } |
9165 | |
9166 | /* Evaluate the affine expression "aff" |
9167 | * in the coordinates (with denominator) "pnt". |
9168 | */ |
9169 | static __isl_give isl_val *eval(__isl_keep isl_vec *aff, |
9170 | __isl_keep isl_vec *pnt) |
9171 | { |
9172 | isl_int n, d; |
9173 | isl_ctx *ctx; |
9174 | isl_val *v; |
9175 | |
9176 | if (!aff || !pnt) |
9177 | return NULL((void*)0); |
9178 | |
9179 | ctx = isl_vec_get_ctx(aff); |
9180 | isl_int_init(n)isl_sioimath_init((n)); |
9181 | isl_int_init(d)isl_sioimath_init((d)); |
9182 | isl_seq_inner_product(aff->el + 1, pnt->el, pnt->size, &n); |
9183 | isl_int_mul(d, aff->el[0], pnt->el[0])isl_sioimath_mul((d), *(aff->el[0]), *(pnt->el[0])); |
9184 | v = isl_val_rat_from_isl_int(ctx, n, d); |
9185 | v = isl_val_normalize(v); |
9186 | isl_int_clear(n)isl_sioimath_clear((n)); |
9187 | isl_int_clear(d)isl_sioimath_clear((d)); |
9188 | |
9189 | return v; |
9190 | } |
9191 | |
9192 | /* Check that the domain space of "aff" is equal to "space". |
9193 | */ |
9194 | static isl_stat isl_aff_check_has_domain_space(__isl_keep isl_aff *aff, |
9195 | __isl_keep isl_space *space) |
9196 | { |
9197 | isl_bool ok; |
9198 | |
9199 | ok = isl_space_is_equal(isl_aff_peek_domain_space(aff), space); |
9200 | if (ok < 0) |
9201 | return isl_stat_error; |
9202 | if (!ok) |
9203 | isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "incompatible spaces", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 9204); return isl_stat_error; } while (0) |
9204 | "incompatible spaces", return isl_stat_error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid , "incompatible spaces", "/build/llvm-toolchain-snapshot-10~+20200102111109+a2976c490da/polly/lib/External/isl/isl_aff.c" , 9204); return isl_stat_error; } while (0); |
9205 | return isl_stat_ok; |
9206 | } |
9207 | |
9208 | /* Evaluate the affine function "aff" in "pnt". |
9209 | */ |
9210 | __isl_give isl_val *isl_aff_eval(__isl_take isl_aff *aff, |
9211 | __isl_take isl_point *pnt) |
9212 | { |
9213 | isl_bool is_void; |
9214 | isl_val *v; |
9215 | isl_local_space *ls; |
9216 | |
9217 | if (isl_aff_check_has_domain_space(aff, isl_point_peek_space(pnt)) < 0) |
9218 | goto error; |
9219 | is_void = isl_point_is_void(pnt); |
9220 | if (is_void < 0) |
9221 | goto error; |
9222 | if (is_void) |
9223 | return eval_void(aff, pnt); |
9224 | |
9225 | ls = isl_aff_get_domain_local_space(aff); |
9226 | pnt = isl_local_space_lift_point(ls, pnt); |
9227 | |
9228 | v = eval(aff->v, isl_point_peek_vec(pnt)); |
9229 | |
9230 | isl_aff_free(aff); |
9231 | isl_point_free(pnt); |
9232 | |
9233 | return v; |
9234 | error: |
9235 | isl_aff_free(aff); |
9236 | isl_point_free(pnt); |
9237 | return NULL((void*)0); |
9238 | } |