Bug Summary

File:polly/lib/External/isl/isl_aff.c
Location:line 2702, column 7
Description:Use of memory after it is freed

Annotated Source Code

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#define ISL_DIM_H
19#include <isl_map_private.h>
20#include <isl_union_map_private.h>
21#include <isl_aff_private.h>
22#include <isl_space_private.h>
23#include <isl_local_space_private.h>
24#include <isl_vec_private.h>
25#include <isl_mat_private.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/deprecated/aff_int.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 union_pw_aff
45
46#include <isl_list_templ.c>
47
48#undef BASEunion_pw_aff
49#define BASEunion_pw_aff union_pw_multi_aff
50
51#include <isl_list_templ.c>
52
53__isl_give isl_aff *isl_aff_alloc_vec(__isl_take isl_local_space *ls,
54 __isl_take isl_vec *v)
55{
56 isl_aff *aff;
57
58 if (!ls || !v)
59 goto error;
60
61 aff = isl_calloc_type(v->ctx, struct isl_aff)((struct isl_aff *)isl_calloc_or_die(v->ctx, 1, sizeof(struct
isl_aff)))
;
62 if (!aff)
63 goto error;
64
65 aff->ref = 1;
66 aff->ls = ls;
67 aff->v = v;
68
69 return aff;
70error:
71 isl_local_space_free(ls);
72 isl_vec_free(v);
73 return NULL((void*)0);
74}
75
76__isl_give isl_aff *isl_aff_alloc(__isl_take isl_local_space *ls)
77{
78 isl_ctx *ctx;
79 isl_vec *v;
80 unsigned total;
81
82 if (!ls)
83 return NULL((void*)0);
84
85 ctx = isl_local_space_get_ctx(ls);
86 if (!isl_local_space_divs_known(ls))
87 isl_die(ctx, isl_error_invalid, "local space has unknown divs",do { isl_handle_error(ctx, isl_error_invalid, "local space has unknown divs"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 88); goto error; } while (0)
88 goto error)do { isl_handle_error(ctx, isl_error_invalid, "local space has unknown divs"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 88); goto error; } while (0)
;
89 if (!isl_local_space_is_set(ls))
90 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "domain of affine expression should be a set"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 92); goto error; } while (0)
91 "domain of affine expression should be a set",do { isl_handle_error(ctx, isl_error_invalid, "domain of affine expression should be a set"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 92); goto error; } while (0)
92 goto error)do { isl_handle_error(ctx, isl_error_invalid, "domain of affine expression should be a set"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 92); goto error; } while (0)
;
93
94 total = isl_local_space_dim(ls, isl_dim_all);
95 v = isl_vec_alloc(ctx, 1 + 1 + total);
96 return isl_aff_alloc_vec(ls, v);
97error:
98 isl_local_space_free(ls);
99 return NULL((void*)0);
100}
101
102__isl_give isl_aff *isl_aff_zero_on_domain(__isl_take isl_local_space *ls)
103{
104 isl_aff *aff;
105
106 aff = isl_aff_alloc(ls);
107 if (!aff)
108 return NULL((void*)0);
109
110 isl_int_set_si(aff->v->el[0], 1)impz_set_si(aff->v->el[0],1);
111 isl_seq_clr(aff->v->el + 1, aff->v->size - 1);
112
113 return aff;
114}
115
116/* Return a piecewise affine expression defined on the specified domain
117 * that is equal to zero.
118 */
119__isl_give isl_pw_aff *isl_pw_aff_zero_on_domain(__isl_take isl_local_space *ls)
120{
121 return isl_pw_aff_from_aff(isl_aff_zero_on_domain(ls));
122}
123
124/* Return an affine expression defined on the specified domain
125 * that represents NaN.
126 */
127__isl_give isl_aff *isl_aff_nan_on_domain(__isl_take isl_local_space *ls)
128{
129 isl_aff *aff;
130
131 aff = isl_aff_alloc(ls);
132 if (!aff)
133 return NULL((void*)0);
134
135 isl_seq_clr(aff->v->el, aff->v->size);
136
137 return aff;
138}
139
140/* Return a piecewise affine expression defined on the specified domain
141 * that represents NaN.
142 */
143__isl_give isl_pw_aff *isl_pw_aff_nan_on_domain(__isl_take isl_local_space *ls)
144{
145 return isl_pw_aff_from_aff(isl_aff_nan_on_domain(ls));
146}
147
148/* Return an affine expression that is equal to "val" on
149 * domain local space "ls".
150 */
151__isl_give isl_aff *isl_aff_val_on_domain(__isl_take isl_local_space *ls,
152 __isl_take isl_val *val)
153{
154 isl_aff *aff;
155
156 if (!ls || !val)
157 goto error;
158 if (!isl_val_is_rat(val))
159 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 160); goto error; } while (0)
160 "expecting rational value", goto error)do { isl_handle_error(isl_val_get_ctx(val), isl_error_invalid
, "expecting rational value", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 160); goto error; } while (0)
;
161
162 aff = isl_aff_alloc(isl_local_space_copy(ls));
163 if (!aff)
164 goto error;
165
166 isl_seq_clr(aff->v->el + 2, aff->v->size - 2);
167 isl_int_set(aff->v->el[1], val->n)impz_set(aff->v->el[1],val->n);
168 isl_int_set(aff->v->el[0], val->d)impz_set(aff->v->el[0],val->d);
169
170 isl_local_space_free(ls);
171 isl_val_free(val);
172 return aff;
173error:
174 isl_local_space_free(ls);
175 isl_val_free(val);
176 return NULL((void*)0);
177}
178
179/* Return an affine expression that is equal to the specified dimension
180 * in "ls".
181 */
182__isl_give isl_aff *isl_aff_var_on_domain(__isl_take isl_local_space *ls,
183 enum isl_dim_type type, unsigned pos)
184{
185 isl_space *space;
186 isl_aff *aff;
187
188 if (!ls)
189 return NULL((void*)0);
190
191 space = isl_local_space_get_space(ls);
192 if (!space)
193 goto error;
194 if (isl_space_is_map(space))
195 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 196); goto error; } while (0)
196 "expecting (parameter) set space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "expecting (parameter) set space", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 196); goto error; } while (0)
;
197 if (pos >= isl_local_space_dim(ls, type))
198 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 199); goto error; } while (0)
199 "position out of bounds", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "position out of bounds", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 199); goto error; } while (0)
;
200
201 isl_space_free(space);
202 aff = isl_aff_alloc(ls);
203 if (!aff)
204 return NULL((void*)0);
205
206 pos += isl_local_space_offset(aff->ls, type);
207
208 isl_int_set_si(aff->v->el[0], 1)impz_set_si(aff->v->el[0],1);
209 isl_seq_clr(aff->v->el + 1, aff->v->size - 1);
210 isl_int_set_si(aff->v->el[1 + pos], 1)impz_set_si(aff->v->el[1 + pos],1);
211
212 return aff;
213error:
214 isl_local_space_free(ls);
215 isl_space_free(space);
216 return NULL((void*)0);
217}
218
219/* Return a piecewise affine expression that is equal to
220 * the specified dimension in "ls".
221 */
222__isl_give isl_pw_aff *isl_pw_aff_var_on_domain(__isl_take isl_local_space *ls,
223 enum isl_dim_type type, unsigned pos)
224{
225 return isl_pw_aff_from_aff(isl_aff_var_on_domain(ls, type, pos));
226}
227
228__isl_give isl_aff *isl_aff_copy(__isl_keep isl_aff *aff)
229{
230 if (!aff)
11
Assuming 'aff' is non-null
12
Taking false branch
231 return NULL((void*)0);
232
233 aff->ref++;
234 return aff;
235}
236
237__isl_give isl_aff *isl_aff_dup(__isl_keep isl_aff *aff)
238{
239 if (!aff)
240 return NULL((void*)0);
241
242 return isl_aff_alloc_vec(isl_local_space_copy(aff->ls),
243 isl_vec_copy(aff->v));
244}
245
246__isl_give isl_aff *isl_aff_cow(__isl_take isl_aff *aff)
247{
248 if (!aff)
249 return NULL((void*)0);
250
251 if (aff->ref == 1)
252 return aff;
253 aff->ref--;
254 return isl_aff_dup(aff);
255}
256
257__isl_null isl_aff *isl_aff_free(__isl_take isl_aff *aff)
258{
259 if (!aff)
27
Taking false branch
260 return NULL((void*)0);
261
262 if (--aff->ref > 0)
28
Taking false branch
263 return NULL((void*)0);
264
265 isl_local_space_free(aff->ls);
266 isl_vec_free(aff->v);
267
268 free(aff);
29
Memory is released
269
270 return NULL((void*)0);
271}
272
273isl_ctx *isl_aff_get_ctx(__isl_keep isl_aff *aff)
274{
275 return aff ? isl_local_space_get_ctx(aff->ls) : NULL((void*)0);
276}
277
278/* Externally, an isl_aff has a map space, but internally, the
279 * ls field corresponds to the domain of that space.
280 */
281int isl_aff_dim(__isl_keep isl_aff *aff, enum isl_dim_type type)
282{
283 if (!aff)
284 return 0;
285 if (type == isl_dim_out)
286 return 1;
287 if (type == isl_dim_in)
288 type = isl_dim_set;
289 return isl_local_space_dim(aff->ls, type);
290}
291
292/* Return the position of the dimension of the given type and name
293 * in "aff".
294 * Return -1 if no such dimension can be found.
295 */
296int isl_aff_find_dim_by_name(__isl_keep isl_aff *aff, enum isl_dim_type type,
297 const char *name)
298{
299 if (!aff)
300 return -1;
301 if (type == isl_dim_out)
302 return -1;
303 if (type == isl_dim_in)
304 type = isl_dim_set;
305 return isl_local_space_find_dim_by_name(aff->ls, type, name);
306}
307
308__isl_give isl_space *isl_aff_get_domain_space(__isl_keep isl_aff *aff)
309{
310 return aff ? isl_local_space_get_space(aff->ls) : NULL((void*)0);
311}
312
313__isl_give isl_space *isl_aff_get_space(__isl_keep isl_aff *aff)
314{
315 isl_space *space;
316 if (!aff)
317 return NULL((void*)0);
318 space = isl_local_space_get_space(aff->ls);
319 space = isl_space_from_domain(space);
320 space = isl_space_add_dims(space, isl_dim_out, 1);
321 return space;
322}
323
324__isl_give isl_local_space *isl_aff_get_domain_local_space(
325 __isl_keep isl_aff *aff)
326{
327 return aff ? isl_local_space_copy(aff->ls) : NULL((void*)0);
328}
329
330__isl_give isl_local_space *isl_aff_get_local_space(__isl_keep isl_aff *aff)
331{
332 isl_local_space *ls;
333 if (!aff)
334 return NULL((void*)0);
335 ls = isl_local_space_copy(aff->ls);
336 ls = isl_local_space_from_domain(ls);
337 ls = isl_local_space_add_dims(ls, isl_dim_out, 1);
338 return ls;
339}
340
341/* Externally, an isl_aff has a map space, but internally, the
342 * ls field corresponds to the domain of that space.
343 */
344const char *isl_aff_get_dim_name(__isl_keep isl_aff *aff,
345 enum isl_dim_type type, unsigned pos)
346{
347 if (!aff)
348 return NULL((void*)0);
349 if (type == isl_dim_out)
350 return NULL((void*)0);
351 if (type == isl_dim_in)
352 type = isl_dim_set;
353 return isl_local_space_get_dim_name(aff->ls, type, pos);
354}
355
356__isl_give isl_aff *isl_aff_reset_domain_space(__isl_take isl_aff *aff,
357 __isl_take isl_space *dim)
358{
359 aff = isl_aff_cow(aff);
360 if (!aff || !dim)
361 goto error;
362
363 aff->ls = isl_local_space_reset_space(aff->ls, dim);
364 if (!aff->ls)
365 return isl_aff_free(aff);
366
367 return aff;
368error:
369 isl_aff_free(aff);
370 isl_space_free(dim);
371 return NULL((void*)0);
372}
373
374/* Reset the space of "aff". This function is called from isl_pw_templ.c
375 * and doesn't know if the space of an element object is represented
376 * directly or through its domain. It therefore passes along both.
377 */
378__isl_give isl_aff *isl_aff_reset_space_and_domain(__isl_take isl_aff *aff,
379 __isl_take isl_space *space, __isl_take isl_space *domain)
380{
381 isl_space_free(space);
382 return isl_aff_reset_domain_space(aff, domain);
383}
384
385/* Reorder the coefficients of the affine expression based
386 * on the given reodering.
387 * The reordering r is assumed to have been extended with the local
388 * variables.
389 */
390static __isl_give isl_vec *vec_reorder(__isl_take isl_vec *vec,
391 __isl_take isl_reordering *r, int n_div)
392{
393 isl_vec *res;
394 int i;
395
396 if (!vec || !r)
397 goto error;
398
399 res = isl_vec_alloc(vec->ctx,
400 2 + isl_space_dim(r->dim, isl_dim_all) + n_div);
401 isl_seq_cpy(res->el, vec->el, 2);
402 isl_seq_clr(res->el + 2, res->size - 2);
403 for (i = 0; i < r->len; ++i)
404 isl_int_set(res->el[2 + r->pos[i]], vec->el[2 + i])impz_set(res->el[2 + r->pos[i]],vec->el[2 + i]);
405
406 isl_reordering_free(r);
407 isl_vec_free(vec);
408 return res;
409error:
410 isl_vec_free(vec);
411 isl_reordering_free(r);
412 return NULL((void*)0);
413}
414
415/* Reorder the dimensions of the domain of "aff" according
416 * to the given reordering.
417 */
418__isl_give isl_aff *isl_aff_realign_domain(__isl_take isl_aff *aff,
419 __isl_take isl_reordering *r)
420{
421 aff = isl_aff_cow(aff);
422 if (!aff)
423 goto error;
424
425 r = isl_reordering_extend(r, aff->ls->div->n_row);
426 aff->v = vec_reorder(aff->v, isl_reordering_copy(r),
427 aff->ls->div->n_row);
428 aff->ls = isl_local_space_realign(aff->ls, r);
429
430 if (!aff->v || !aff->ls)
431 return isl_aff_free(aff);
432
433 return aff;
434error:
435 isl_aff_free(aff);
436 isl_reordering_free(r);
437 return NULL((void*)0);
438}
439
440__isl_give isl_aff *isl_aff_align_params(__isl_take isl_aff *aff,
441 __isl_take isl_space *model)
442{
443 if (!aff || !model)
444 goto error;
445
446 if (!isl_space_match(aff->ls->dim, isl_dim_param,
447 model, isl_dim_param)) {
448 isl_reordering *exp;
449
450 model = isl_space_drop_dims(model, isl_dim_in,
451 0, isl_space_dim(model, isl_dim_in));
452 model = isl_space_drop_dims(model, isl_dim_out,
453 0, isl_space_dim(model, isl_dim_out));
454 exp = isl_parameter_alignment_reordering(aff->ls->dim, model);
455 exp = isl_reordering_extend_space(exp,
456 isl_aff_get_domain_space(aff));
457 aff = isl_aff_realign_domain(aff, exp);
458 }
459
460 isl_space_free(model);
461 return aff;
462error:
463 isl_space_free(model);
464 isl_aff_free(aff);
465 return NULL((void*)0);
466}
467
468/* Is "aff" obviously equal to zero?
469 *
470 * If the denominator is zero, then "aff" is not equal to zero.
471 */
472isl_bool isl_aff_plain_is_zero(__isl_keep isl_aff *aff)
473{
474 if (!aff)
475 return isl_bool_error;
476
477 if (isl_int_is_zero(aff->v->el[0])(impz_sgn(aff->v->el[0]) == 0))
478 return isl_bool_false;
479 return isl_seq_first_non_zero(aff->v->el + 1, aff->v->size - 1) < 0;
480}
481
482/* Does "aff" represent NaN?
483 */
484isl_bool isl_aff_is_nan(__isl_keep isl_aff *aff)
485{
486 if (!aff)
487 return isl_bool_error;
488
489 return isl_seq_first_non_zero(aff->v->el, 2) < 0;
490}
491
492/* Does "pa" involve any NaNs?
493 */
494isl_bool isl_pw_aff_involves_nan(__isl_keep isl_pw_aff *pa)
495{
496 int i;
497
498 if (!pa)
499 return isl_bool_error;
500 if (pa->n == 0)
501 return isl_bool_false;
502
503 for (i = 0; i < pa->n; ++i) {
504 isl_bool is_nan = isl_aff_is_nan(pa->p[i].aff);
505 if (is_nan < 0 || is_nan)
506 return is_nan;
507 }
508
509 return isl_bool_false;
510}
511
512/* Are "aff1" and "aff2" obviously equal?
513 *
514 * NaN is not equal to anything, not even to another NaN.
515 */
516isl_bool isl_aff_plain_is_equal(__isl_keep isl_aff *aff1,
517 __isl_keep isl_aff *aff2)
518{
519 isl_bool equal;
520
521 if (!aff1 || !aff2)
522 return isl_bool_error;
523
524 if (isl_aff_is_nan(aff1) || isl_aff_is_nan(aff2))
525 return isl_bool_false;
526
527 equal = isl_local_space_is_equal(aff1->ls, aff2->ls);
528 if (equal < 0 || !equal)
529 return equal;
530
531 return isl_vec_is_equal(aff1->v, aff2->v);
532}
533
534/* Return the common denominator of "aff" in "v".
535 *
536 * We cannot return anything meaningful in case of a NaN.
537 */
538int isl_aff_get_denominatorisl_gmp_aff_get_denominator(__isl_keep isl_aff *aff, isl_int *v)
539{
540 if (!aff)
541 return -1;
542 if (isl_aff_is_nan(aff))
543 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 544); return -1; } while (0)
544 "cannot get denominator of NaN", return -1)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot get denominator of NaN", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 544); return -1; } while (0)
;
545 isl_int_set(*v, aff->v->el[0])impz_set(*v,aff->v->el[0]);
546 return 0;
547}
548
549/* Return the common denominator of "aff".
550 */
551__isl_give isl_val *isl_aff_get_denominator_val(__isl_keep isl_aff *aff)
552{
553 isl_ctx *ctx;
554
555 if (!aff)
556 return NULL((void*)0);
557
558 ctx = isl_aff_get_ctx(aff);
559 if (isl_aff_is_nan(aff))
560 return isl_val_nan(ctx);
561 return isl_val_int_from_isl_intisl_gmp_val_int_from_isl_int(ctx, aff->v->el[0]);
562}
563
564/* Return the constant term of "aff" in "v".
565 *
566 * We cannot return anything meaningful in case of a NaN.
567 */
568int isl_aff_get_constantisl_gmp_aff_get_constant(__isl_keep isl_aff *aff, isl_int *v)
569{
570 if (!aff)
571 return -1;
572 if (isl_aff_is_nan(aff))
573 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot get constant term of NaN", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 574); return -1; } while (0)
574 "cannot get constant term of NaN", return -1)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot get constant term of NaN", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 574); return -1; } while (0)
;
575 isl_int_set(*v, aff->v->el[1])impz_set(*v,aff->v->el[1]);
576 return 0;
577}
578
579/* Return the constant term of "aff".
580 */
581__isl_give isl_val *isl_aff_get_constant_val(__isl_keep isl_aff *aff)
582{
583 isl_ctx *ctx;
584 isl_val *v;
585
586 if (!aff)
587 return NULL((void*)0);
588
589 ctx = isl_aff_get_ctx(aff);
590 if (isl_aff_is_nan(aff))
591 return isl_val_nan(ctx);
592 v = isl_val_rat_from_isl_int(ctx, aff->v->el[1], aff->v->el[0]);
593 return isl_val_normalize(v);
594}
595
596/* Return the coefficient of the variable of type "type" at position "pos"
597 * of "aff" in "v".
598 *
599 * We cannot return anything meaningful in case of a NaN.
600 */
601int isl_aff_get_coefficientisl_gmp_aff_get_coefficient(__isl_keep isl_aff *aff,
602 enum isl_dim_type type, int pos, isl_int *v)
603{
604 if (!aff)
605 return -1;
606
607 if (type == isl_dim_out)
608 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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 610); return -1; } while (0)
609 "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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 610); return -1; } while (0)
610 return -1)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 610); return -1; } while (0)
;
611 if (type == isl_dim_in)
612 type = isl_dim_set;
613
614 if (pos >= isl_local_space_dim(aff->ls, type))
615 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 616); return -1; } while (0)
616 "position out of bounds", return -1)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 616); return -1; } while (0)
;
617
618 if (isl_aff_is_nan(aff))
619 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot get coefficient of NaN", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 620); return -1; } while (0)
620 "cannot get coefficient of NaN", return -1)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot get coefficient of NaN", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 620); return -1; } while (0)
;
621 pos += isl_local_space_offset(aff->ls, type);
622 isl_int_set(*v, aff->v->el[1 + pos])impz_set(*v,aff->v->el[1 + pos]);
623
624 return 0;
625}
626
627/* Return the coefficient of the variable of type "type" at position "pos"
628 * of "aff".
629 */
630__isl_give isl_val *isl_aff_get_coefficient_val(__isl_keep isl_aff *aff,
631 enum isl_dim_type type, int pos)
632{
633 isl_ctx *ctx;
634 isl_val *v;
635
636 if (!aff)
637 return NULL((void*)0);
638
639 ctx = isl_aff_get_ctx(aff);
640 if (type == isl_dim_out)
641 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 643); return ((void*)0); } while (0)
642 "output/set dimension does not have a coefficient",do { isl_handle_error(ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 643); return ((void*)0); } while (0)
643 return NULL)do { isl_handle_error(ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 643); return ((void*)0); } while (0)
;
644 if (type == isl_dim_in)
645 type = isl_dim_set;
646
647 if (pos >= isl_local_space_dim(aff->ls, type))
648 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "position out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 649); return ((void*)0); } while (0)
649 "position out of bounds", return NULL)do { isl_handle_error(ctx, isl_error_invalid, "position out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 649); return ((void*)0); } while (0)
;
650
651 if (isl_aff_is_nan(aff))
652 return isl_val_nan(ctx);
653 pos += isl_local_space_offset(aff->ls, type);
654 v = isl_val_rat_from_isl_int(ctx, aff->v->el[1 + pos], aff->v->el[0]);
655 return isl_val_normalize(v);
656}
657
658/* Return the sign of the coefficient of the variable of type "type"
659 * at position "pos" of "aff".
660 */
661int isl_aff_coefficient_sgn(__isl_keep isl_aff *aff, enum isl_dim_type type,
662 int pos)
663{
664 isl_ctx *ctx;
665
666 if (!aff)
667 return 0;
668
669 ctx = isl_aff_get_ctx(aff);
670 if (type == isl_dim_out)
671 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 673); return 0; } while (0)
672 "output/set dimension does not have a coefficient",do { isl_handle_error(ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 673); return 0; } while (0)
673 return 0)do { isl_handle_error(ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 673); return 0; } while (0)
;
674 if (type == isl_dim_in)
675 type = isl_dim_set;
676
677 if (pos >= isl_local_space_dim(aff->ls, type))
678 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "position out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 679); return 0; } while (0)
679 "position out of bounds", return 0)do { isl_handle_error(ctx, isl_error_invalid, "position out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 679); return 0; } while (0)
;
680
681 pos += isl_local_space_offset(aff->ls, type);
682 return isl_int_sgn(aff->v->el[1 + pos])impz_sgn(aff->v->el[1 + pos]);
683}
684
685/* Replace the denominator of "aff" by "v".
686 *
687 * A NaN is unaffected by this operation.
688 */
689__isl_give isl_aff *isl_aff_set_denominatorisl_gmp_aff_set_denominator(__isl_take isl_aff *aff, isl_int v)
690{
691 if (!aff)
692 return NULL((void*)0);
693 if (isl_aff_is_nan(aff))
694 return aff;
695 aff = isl_aff_cow(aff);
696 if (!aff)
697 return NULL((void*)0);
698
699 aff->v = isl_vec_cow(aff->v);
700 if (!aff->v)
701 return isl_aff_free(aff);
702
703 isl_int_set(aff->v->el[0], v)impz_set(aff->v->el[0],v);
704
705 return aff;
706}
707
708/* Replace the numerator of the constant term of "aff" by "v".
709 *
710 * A NaN is unaffected by this operation.
711 */
712__isl_give isl_aff *isl_aff_set_constantisl_gmp_aff_set_constant(__isl_take isl_aff *aff, isl_int v)
713{
714 if (!aff)
715 return NULL((void*)0);
716 if (isl_aff_is_nan(aff))
717 return aff;
718 aff = isl_aff_cow(aff);
719 if (!aff)
720 return NULL((void*)0);
721
722 aff->v = isl_vec_cow(aff->v);
723 if (!aff->v)
724 return isl_aff_free(aff);
725
726 isl_int_set(aff->v->el[1], v)impz_set(aff->v->el[1],v);
727
728 return aff;
729}
730
731/* Replace the constant term of "aff" by "v".
732 *
733 * A NaN is unaffected by this operation.
734 */
735__isl_give isl_aff *isl_aff_set_constant_val(__isl_take isl_aff *aff,
736 __isl_take isl_val *v)
737{
738 if (!aff || !v)
739 goto error;
740
741 if (isl_aff_is_nan(aff)) {
742 isl_val_free(v);
743 return aff;
744 }
745
746 if (!isl_val_is_rat(v))
747 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 748); goto error; } while (0)
748 "expecting rational value", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting rational value", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 748); goto error; } while (0)
;
749
750 if (isl_int_eq(aff->v->el[1], v->n)(impz_cmp(aff->v->el[1],v->n) == 0) &&
751 isl_int_eq(aff->v->el[0], v->d)(impz_cmp(aff->v->el[0],v->d) == 0)) {
752 isl_val_free(v);
753 return aff;
754 }
755
756 aff = isl_aff_cow(aff);
757 if (!aff)
758 goto error;
759 aff->v = isl_vec_cow(aff->v);
760 if (!aff->v)
761 goto error;
762
763 if (isl_int_eq(aff->v->el[0], v->d)(impz_cmp(aff->v->el[0],v->d) == 0)) {
764 isl_int_set(aff->v->el[1], v->n)impz_set(aff->v->el[1],v->n);
765 } else if (isl_int_is_one(v->d)(impz_cmp_si(v->d,1) == 0)) {
766 isl_int_mul(aff->v->el[1], aff->v->el[0], v->n)impz_mul(aff->v->el[1],aff->v->el[0],v->n);
767 } else {
768 isl_seq_scale(aff->v->el + 1,
769 aff->v->el + 1, v->d, aff->v->size - 1);
770 isl_int_mul(aff->v->el[1], aff->v->el[0], v->n)impz_mul(aff->v->el[1],aff->v->el[0],v->n);
771 isl_int_mul(aff->v->el[0], aff->v->el[0], v->d)impz_mul(aff->v->el[0],aff->v->el[0],v->d);
772 aff->v = isl_vec_normalize(aff->v);
773 if (!aff->v)
774 goto error;
775 }
776
777 isl_val_free(v);
778 return aff;
779error:
780 isl_aff_free(aff);
781 isl_val_free(v);
782 return NULL((void*)0);
783}
784
785/* Add "v" to the constant term of "aff".
786 *
787 * A NaN is unaffected by this operation.
788 */
789__isl_give isl_aff *isl_aff_add_constantisl_gmp_aff_add_constant(__isl_take isl_aff *aff, isl_int v)
790{
791 if (isl_int_is_zero(v)(impz_sgn(v) == 0))
792 return aff;
793
794 if (!aff)
795 return NULL((void*)0);
796 if (isl_aff_is_nan(aff))
797 return aff;
798 aff = isl_aff_cow(aff);
799 if (!aff)
800 return NULL((void*)0);
801
802 aff->v = isl_vec_cow(aff->v);
803 if (!aff->v)
804 return isl_aff_free(aff);
805
806 isl_int_addmul(aff->v->el[1], aff->v->el[0], v)impz_addmul(aff->v->el[1],aff->v->el[0],v);
807
808 return aff;
809}
810
811/* Add "v" to the constant term of "aff".
812 *
813 * A NaN is unaffected by this operation.
814 */
815__isl_give isl_aff *isl_aff_add_constant_val(__isl_take isl_aff *aff,
816 __isl_take isl_val *v)
817{
818 if (!aff || !v)
819 goto error;
820
821 if (isl_aff_is_nan(aff) || isl_val_is_zero(v)) {
822 isl_val_free(v);
823 return aff;
824 }
825
826 if (!isl_val_is_rat(v))
827 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 828); goto error; } while (0)
828 "expecting rational value", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting rational value", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 828); goto error; } while (0)
;
829
830 aff = isl_aff_cow(aff);
831 if (!aff)
832 goto error;
833
834 aff->v = isl_vec_cow(aff->v);
835 if (!aff->v)
836 goto error;
837
838 if (isl_int_is_one(v->d)(impz_cmp_si(v->d,1) == 0)) {
839 isl_int_addmul(aff->v->el[1], aff->v->el[0], v->n)impz_addmul(aff->v->el[1],aff->v->el[0],v->n);
840 } else if (isl_int_eq(aff->v->el[0], v->d)(impz_cmp(aff->v->el[0],v->d) == 0)) {
841 isl_int_add(aff->v->el[1], aff->v->el[1], v->n)impz_add(aff->v->el[1],aff->v->el[1],v->n);
842 aff->v = isl_vec_normalize(aff->v);
843 if (!aff->v)
844 goto error;
845 } else {
846 isl_seq_scale(aff->v->el + 1,
847 aff->v->el + 1, v->d, aff->v->size - 1);
848 isl_int_addmul(aff->v->el[1], aff->v->el[0], v->n)impz_addmul(aff->v->el[1],aff->v->el[0],v->n);
849 isl_int_mul(aff->v->el[0], aff->v->el[0], v->d)impz_mul(aff->v->el[0],aff->v->el[0],v->d);
850 aff->v = isl_vec_normalize(aff->v);
851 if (!aff->v)
852 goto error;
853 }
854
855 isl_val_free(v);
856 return aff;
857error:
858 isl_aff_free(aff);
859 isl_val_free(v);
860 return NULL((void*)0);
861}
862
863__isl_give isl_aff *isl_aff_add_constant_si(__isl_take isl_aff *aff, int v)
864{
865 isl_int t;
866
867 isl_int_init(t)t = mp_int_alloc();
868 isl_int_set_si(t, v)impz_set_si(t,v);
869 aff = isl_aff_add_constantisl_gmp_aff_add_constant(aff, t);
870 isl_int_clear(t)mp_int_free(t);
871
872 return aff;
873}
874
875/* Add "v" to the numerator of the constant term of "aff".
876 *
877 * A NaN is unaffected by this operation.
878 */
879__isl_give isl_aff *isl_aff_add_constant_numisl_gmp_aff_add_constant_num(__isl_take isl_aff *aff, isl_int v)
880{
881 if (isl_int_is_zero(v)(impz_sgn(v) == 0))
882 return aff;
883
884 if (!aff)
885 return NULL((void*)0);
886 if (isl_aff_is_nan(aff))
887 return aff;
888 aff = isl_aff_cow(aff);
889 if (!aff)
890 return NULL((void*)0);
891
892 aff->v = isl_vec_cow(aff->v);
893 if (!aff->v)
894 return isl_aff_free(aff);
895
896 isl_int_add(aff->v->el[1], aff->v->el[1], v)impz_add(aff->v->el[1],aff->v->el[1],v);
897
898 return aff;
899}
900
901/* Add "v" to the numerator of the constant term of "aff".
902 *
903 * A NaN is unaffected by this operation.
904 */
905__isl_give isl_aff *isl_aff_add_constant_num_si(__isl_take isl_aff *aff, int v)
906{
907 isl_int t;
908
909 if (v == 0)
910 return aff;
911
912 isl_int_init(t)t = mp_int_alloc();
913 isl_int_set_si(t, v)impz_set_si(t,v);
914 aff = isl_aff_add_constant_numisl_gmp_aff_add_constant_num(aff, t);
915 isl_int_clear(t)mp_int_free(t);
916
917 return aff;
918}
919
920/* Replace the numerator of the constant term of "aff" by "v".
921 *
922 * A NaN is unaffected by this operation.
923 */
924__isl_give isl_aff *isl_aff_set_constant_si(__isl_take isl_aff *aff, int v)
925{
926 if (!aff)
927 return NULL((void*)0);
928 if (isl_aff_is_nan(aff))
929 return aff;
930 aff = isl_aff_cow(aff);
931 if (!aff)
932 return NULL((void*)0);
933
934 aff->v = isl_vec_cow(aff->v);
935 if (!aff->v)
936 return isl_aff_free(aff);
937
938 isl_int_set_si(aff->v->el[1], v)impz_set_si(aff->v->el[1],v);
939
940 return aff;
941}
942
943/* Replace the numerator of the coefficient of the variable of type "type"
944 * at position "pos" of "aff" by "v".
945 *
946 * A NaN is unaffected by this operation.
947 */
948__isl_give isl_aff *isl_aff_set_coefficientisl_gmp_aff_set_coefficient(__isl_take isl_aff *aff,
949 enum isl_dim_type type, int pos, isl_int v)
950{
951 if (!aff)
952 return NULL((void*)0);
953
954 if (type == isl_dim_out)
955 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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 957); return isl_aff_free(aff); } while (0)
956 "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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 957); return isl_aff_free(aff); } while (0)
957 return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 957); return isl_aff_free(aff); } while (0)
;
958 if (type == isl_dim_in)
959 type = isl_dim_set;
960
961 if (pos >= isl_local_space_dim(aff->ls, type))
962 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 963); return isl_aff_free(aff); } while (0)
963 "position out of bounds", return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 963); return isl_aff_free(aff); } while (0)
;
964
965 if (isl_aff_is_nan(aff))
966 return aff;
967 aff = isl_aff_cow(aff);
968 if (!aff)
969 return NULL((void*)0);
970
971 aff->v = isl_vec_cow(aff->v);
972 if (!aff->v)
973 return isl_aff_free(aff);
974
975 pos += isl_local_space_offset(aff->ls, type);
976 isl_int_set(aff->v->el[1 + pos], v)impz_set(aff->v->el[1 + pos],v);
977
978 return aff;
979}
980
981/* Replace the numerator of the coefficient of the variable of type "type"
982 * at position "pos" of "aff" by "v".
983 *
984 * A NaN is unaffected by this operation.
985 */
986__isl_give isl_aff *isl_aff_set_coefficient_si(__isl_take isl_aff *aff,
987 enum isl_dim_type type, int pos, int v)
988{
989 if (!aff)
990 return NULL((void*)0);
991
992 if (type == isl_dim_out)
993 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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 995); return isl_aff_free(aff); } while (0)
994 "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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 995); return isl_aff_free(aff); } while (0)
995 return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 995); return isl_aff_free(aff); } while (0)
;
996 if (type == isl_dim_in)
997 type = isl_dim_set;
998
999 if (pos < 0 || pos >= isl_local_space_dim(aff->ls, type))
1000 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1001); return isl_aff_free(aff); } while (0)
1001 "position out of bounds", return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1001); return isl_aff_free(aff); } while (0)
;
1002
1003 if (isl_aff_is_nan(aff))
1004 return aff;
1005 pos += isl_local_space_offset(aff->ls, type);
1006 if (isl_int_cmp_si(aff->v->el[1 + pos], v)impz_cmp_si(aff->v->el[1 + pos],v) == 0)
1007 return aff;
1008
1009 aff = isl_aff_cow(aff);
1010 if (!aff)
1011 return NULL((void*)0);
1012
1013 aff->v = isl_vec_cow(aff->v);
1014 if (!aff->v)
1015 return isl_aff_free(aff);
1016
1017 isl_int_set_si(aff->v->el[1 + pos], v)impz_set_si(aff->v->el[1 + pos],v);
1018
1019 return aff;
1020}
1021
1022/* Replace the coefficient of the variable of type "type" at position "pos"
1023 * of "aff" by "v".
1024 *
1025 * A NaN is unaffected by this operation.
1026 */
1027__isl_give isl_aff *isl_aff_set_coefficient_val(__isl_take isl_aff *aff,
1028 enum isl_dim_type type, int pos, __isl_take isl_val *v)
1029{
1030 if (!aff || !v)
1031 goto error;
1032
1033 if (type == isl_dim_out)
1034 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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1036); goto error; } while (0)
1035 "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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1036); goto error; } while (0)
1036 goto error)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1036); goto error; } while (0)
;
1037 if (type == isl_dim_in)
1038 type = isl_dim_set;
1039
1040 if (pos >= isl_local_space_dim(aff->ls, type))
1041 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1042); goto error; } while (0)
1042 "position out of bounds", goto error)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1042); goto error; } while (0)
;
1043
1044 if (isl_aff_is_nan(aff)) {
1045 isl_val_free(v);
1046 return aff;
1047 }
1048 if (!isl_val_is_rat(v))
1049 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1050); goto error; } while (0)
1050 "expecting rational value", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting rational value", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1050); goto error; } while (0)
;
1051
1052 pos += isl_local_space_offset(aff->ls, type);
1053 if (isl_int_eq(aff->v->el[1 + pos], v->n)(impz_cmp(aff->v->el[1 + pos],v->n) == 0) &&
1054 isl_int_eq(aff->v->el[0], v->d)(impz_cmp(aff->v->el[0],v->d) == 0)) {
1055 isl_val_free(v);
1056 return aff;
1057 }
1058
1059 aff = isl_aff_cow(aff);
1060 if (!aff)
1061 goto error;
1062 aff->v = isl_vec_cow(aff->v);
1063 if (!aff->v)
1064 goto error;
1065
1066 if (isl_int_eq(aff->v->el[0], v->d)(impz_cmp(aff->v->el[0],v->d) == 0)) {
1067 isl_int_set(aff->v->el[1 + pos], v->n)impz_set(aff->v->el[1 + pos],v->n);
1068 } else if (isl_int_is_one(v->d)(impz_cmp_si(v->d,1) == 0)) {
1069 isl_int_mul(aff->v->el[1 + pos], aff->v->el[0], v->n)impz_mul(aff->v->el[1 + pos],aff->v->el[0],v->
n)
;
1070 } else {
1071 isl_seq_scale(aff->v->el + 1,
1072 aff->v->el + 1, v->d, aff->v->size - 1);
1073 isl_int_mul(aff->v->el[1 + pos], aff->v->el[0], v->n)impz_mul(aff->v->el[1 + pos],aff->v->el[0],v->
n)
;
1074 isl_int_mul(aff->v->el[0], aff->v->el[0], v->d)impz_mul(aff->v->el[0],aff->v->el[0],v->d);
1075 aff->v = isl_vec_normalize(aff->v);
1076 if (!aff->v)
1077 goto error;
1078 }
1079
1080 isl_val_free(v);
1081 return aff;
1082error:
1083 isl_aff_free(aff);
1084 isl_val_free(v);
1085 return NULL((void*)0);
1086}
1087
1088/* Add "v" to the coefficient of the variable of type "type"
1089 * at position "pos" of "aff".
1090 *
1091 * A NaN is unaffected by this operation.
1092 */
1093__isl_give isl_aff *isl_aff_add_coefficientisl_gmp_aff_add_coefficient(__isl_take isl_aff *aff,
1094 enum isl_dim_type type, int pos, isl_int v)
1095{
1096 if (!aff)
1097 return NULL((void*)0);
1098
1099 if (type == isl_dim_out)
1100 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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1102); return isl_aff_free(aff); } while (0)
1101 "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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1102); return isl_aff_free(aff); } while (0)
1102 return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1102); return isl_aff_free(aff); } while (0)
;
1103 if (type == isl_dim_in)
1104 type = isl_dim_set;
1105
1106 if (pos >= isl_local_space_dim(aff->ls, type))
1107 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1108); return isl_aff_free(aff); } while (0)
1108 "position out of bounds", return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1108); return isl_aff_free(aff); } while (0)
;
1109
1110 if (isl_aff_is_nan(aff))
1111 return aff;
1112 aff = isl_aff_cow(aff);
1113 if (!aff)
1114 return NULL((void*)0);
1115
1116 aff->v = isl_vec_cow(aff->v);
1117 if (!aff->v)
1118 return isl_aff_free(aff);
1119
1120 pos += isl_local_space_offset(aff->ls, type);
1121 isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v)impz_addmul(aff->v->el[1 + pos],aff->v->el[0],v);
1122
1123 return aff;
1124}
1125
1126/* Add "v" to the coefficient of the variable of type "type"
1127 * at position "pos" of "aff".
1128 *
1129 * A NaN is unaffected by this operation.
1130 */
1131__isl_give isl_aff *isl_aff_add_coefficient_val(__isl_take isl_aff *aff,
1132 enum isl_dim_type type, int pos, __isl_take isl_val *v)
1133{
1134 if (!aff || !v)
1135 goto error;
1136
1137 if (isl_val_is_zero(v)) {
1138 isl_val_free(v);
1139 return aff;
1140 }
1141
1142 if (type == isl_dim_out)
1143 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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1145); goto error; } while (0)
1144 "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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1145); goto error; } while (0)
1145 goto error)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "output/set dimension does not have a coefficient"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1145); goto error; } while (0)
;
1146 if (type == isl_dim_in)
1147 type = isl_dim_set;
1148
1149 if (pos >= isl_local_space_dim(aff->ls, type))
1150 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1151); goto error; } while (0)
1151 "position out of bounds", goto error)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "position out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1151); goto error; } while (0)
;
1152
1153 if (isl_aff_is_nan(aff)) {
1154 isl_val_free(v);
1155 return aff;
1156 }
1157 if (!isl_val_is_rat(v))
1158 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1159); goto error; } while (0)
1159 "expecting rational value", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting rational value", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1159); goto error; } while (0)
;
1160
1161 aff = isl_aff_cow(aff);
1162 if (!aff)
1163 goto error;
1164
1165 aff->v = isl_vec_cow(aff->v);
1166 if (!aff->v)
1167 goto error;
1168
1169 pos += isl_local_space_offset(aff->ls, type);
1170 if (isl_int_is_one(v->d)(impz_cmp_si(v->d,1) == 0)) {
1171 isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v->n)impz_addmul(aff->v->el[1 + pos],aff->v->el[0],v->
n)
;
1172 } else if (isl_int_eq(aff->v->el[0], v->d)(impz_cmp(aff->v->el[0],v->d) == 0)) {
1173 isl_int_add(aff->v->el[1 + pos], aff->v->el[1 + pos], v->n)impz_add(aff->v->el[1 + pos],aff->v->el[1 + pos],
v->n)
;
1174 aff->v = isl_vec_normalize(aff->v);
1175 if (!aff->v)
1176 goto error;
1177 } else {
1178 isl_seq_scale(aff->v->el + 1,
1179 aff->v->el + 1, v->d, aff->v->size - 1);
1180 isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v->n)impz_addmul(aff->v->el[1 + pos],aff->v->el[0],v->
n)
;
1181 isl_int_mul(aff->v->el[0], aff->v->el[0], v->d)impz_mul(aff->v->el[0],aff->v->el[0],v->d);
1182 aff->v = isl_vec_normalize(aff->v);
1183 if (!aff->v)
1184 goto error;
1185 }
1186
1187 isl_val_free(v);
1188 return aff;
1189error:
1190 isl_aff_free(aff);
1191 isl_val_free(v);
1192 return NULL((void*)0);
1193}
1194
1195__isl_give isl_aff *isl_aff_add_coefficient_si(__isl_take isl_aff *aff,
1196 enum isl_dim_type type, int pos, int v)
1197{
1198 isl_int t;
1199
1200 isl_int_init(t)t = mp_int_alloc();
1201 isl_int_set_si(t, v)impz_set_si(t,v);
1202 aff = isl_aff_add_coefficientisl_gmp_aff_add_coefficient(aff, type, pos, t);
1203 isl_int_clear(t)mp_int_free(t);
1204
1205 return aff;
1206}
1207
1208__isl_give isl_aff *isl_aff_get_div(__isl_keep isl_aff *aff, int pos)
1209{
1210 if (!aff)
1211 return NULL((void*)0);
1212
1213 return isl_local_space_get_div(aff->ls, pos);
1214}
1215
1216/* Return the negation of "aff".
1217 *
1218 * As a special case, -NaN = NaN.
1219 */
1220__isl_give isl_aff *isl_aff_neg(__isl_take isl_aff *aff)
1221{
1222 if (!aff)
22
Taking false branch
1223 return NULL((void*)0);
1224 if (isl_aff_is_nan(aff))
23
Taking false branch
1225 return aff;
1226 aff = isl_aff_cow(aff);
1227 if (!aff)
24
Taking false branch
1228 return NULL((void*)0);
1229 aff->v = isl_vec_cow(aff->v);
1230 if (!aff->v)
25
Taking true branch
1231 return isl_aff_free(aff);
26
Calling 'isl_aff_free'
30
Returning; memory was released via 1st parameter
1232
1233 isl_seq_neg(aff->v->el + 1, aff->v->el + 1, aff->v->size - 1);
1234
1235 return aff;
1236}
1237
1238/* Remove divs from the local space that do not appear in the affine
1239 * expression.
1240 * We currently only remove divs at the end.
1241 * Some intermediate divs may also not appear directly in the affine
1242 * expression, but we would also need to check that no other divs are
1243 * defined in terms of them.
1244 */
1245__isl_give isl_aff *isl_aff_remove_unused_divs( __isl_take isl_aff *aff)
1246{
1247 int pos;
1248 int off;
1249 int n;
1250
1251 if (!aff)
1252 return NULL((void*)0);
1253
1254 n = isl_local_space_dim(aff->ls, isl_dim_div);
1255 off = isl_local_space_offset(aff->ls, isl_dim_div);
1256
1257 pos = isl_seq_last_non_zero(aff->v->el + 1 + off, n) + 1;
1258 if (pos == n)
1259 return aff;
1260
1261 aff = isl_aff_cow(aff);
1262 if (!aff)
1263 return NULL((void*)0);
1264
1265 aff->ls = isl_local_space_drop_dims(aff->ls, isl_dim_div, pos, n - pos);
1266 aff->v = isl_vec_drop_els(aff->v, 1 + off + pos, n - pos);
1267 if (!aff->ls || !aff->v)
1268 return isl_aff_free(aff);
1269
1270 return aff;
1271}
1272
1273/* Given two affine expressions "p" of length p_len (including the
1274 * denominator and the constant term) and "subs" of length subs_len,
1275 * plug in "subs" for the variable at position "pos".
1276 * The variables of "subs" and "p" are assumed to match up to subs_len,
1277 * but "p" may have additional variables.
1278 * "v" is an initialized isl_int that can be used internally.
1279 *
1280 * In particular, if "p" represents the expression
1281 *
1282 * (a i + g)/m
1283 *
1284 * with i the variable at position "pos" and "subs" represents the expression
1285 *
1286 * f/d
1287 *
1288 * then the result represents the expression
1289 *
1290 * (a f + d g)/(m d)
1291 *
1292 */
1293void isl_seq_substitute(isl_int *p, int pos, isl_int *subs,
1294 int p_len, int subs_len, isl_int v)
1295{
1296 isl_int_set(v, p[1 + pos])impz_set(v,p[1 + pos]);
1297 isl_int_set_si(p[1 + pos], 0)impz_set_si(p[1 + pos],0);
1298 isl_seq_combine(p + 1, subs[0], p + 1, v, subs + 1, subs_len - 1);
1299 isl_seq_scale(p + subs_len, p + subs_len, subs[0], p_len - subs_len);
1300 isl_int_mul(p[0], p[0], subs[0])impz_mul(p[0],p[0],subs[0]);
1301}
1302
1303/* Look for any divs in the aff->ls with a denominator equal to one
1304 * and plug them into the affine expression and any subsequent divs
1305 * that may reference the div.
1306 */
1307static __isl_give isl_aff *plug_in_integral_divs(__isl_take isl_aff *aff)
1308{
1309 int i, n;
1310 int len;
1311 isl_int v;
1312 isl_vec *vec;
1313 isl_local_space *ls;
1314 unsigned pos;
1315
1316 if (!aff)
1317 return NULL((void*)0);
1318
1319 n = isl_local_space_dim(aff->ls, isl_dim_div);
1320 len = aff->v->size;
1321 for (i = 0; i < n; ++i) {
1322 if (!isl_int_is_one(aff->ls->div->row[i][0])(impz_cmp_si(aff->ls->div->row[i][0],1) == 0))
1323 continue;
1324 ls = isl_local_space_copy(aff->ls);
1325 ls = isl_local_space_substitute_seq(ls, isl_dim_div, i,
1326 aff->ls->div->row[i], len, i + 1, n - (i + 1));
1327 vec = isl_vec_copy(aff->v);
1328 vec = isl_vec_cow(vec);
1329 if (!ls || !vec)
1330 goto error;
1331
1332 isl_int_init(v)v = mp_int_alloc();
1333
1334 pos = isl_local_space_offset(aff->ls, isl_dim_div) + i;
1335 isl_seq_substitute(vec->el, pos, aff->ls->div->row[i],
1336 len, len, v);
1337
1338 isl_int_clear(v)mp_int_free(v);
1339
1340 isl_vec_free(aff->v);
1341 aff->v = vec;
1342 isl_local_space_free(aff->ls);
1343 aff->ls = ls;
1344 }
1345
1346 return aff;
1347error:
1348 isl_vec_free(vec);
1349 isl_local_space_free(ls);
1350 return isl_aff_free(aff);
1351}
1352
1353/* Look for any divs j that appear with a unit coefficient inside
1354 * the definitions of other divs i and plug them into the definitions
1355 * of the divs i.
1356 *
1357 * In particular, an expression of the form
1358 *
1359 * floor((f(..) + floor(g(..)/n))/m)
1360 *
1361 * is simplified to
1362 *
1363 * floor((n * f(..) + g(..))/(n * m))
1364 *
1365 * This simplification is correct because we can move the expression
1366 * f(..) into the inner floor in the original expression to obtain
1367 *
1368 * floor(floor((n * f(..) + g(..))/n)/m)
1369 *
1370 * from which we can derive the simplified expression.
1371 */
1372static __isl_give isl_aff *plug_in_unit_divs(__isl_take isl_aff *aff)
1373{
1374 int i, j, n;
1375 int off;
1376
1377 if (!aff)
1378 return NULL((void*)0);
1379
1380 n = isl_local_space_dim(aff->ls, isl_dim_div);
1381 off = isl_local_space_offset(aff->ls, isl_dim_div);
1382 for (i = 1; i < n; ++i) {
1383 for (j = 0; j < i; ++j) {
1384 if (!isl_int_is_one(aff->ls->div->row[i][1 + off + j])(impz_cmp_si(aff->ls->div->row[i][1 + off + j],1) ==
0)
)
1385 continue;
1386 aff->ls = isl_local_space_substitute_seq(aff->ls,
1387 isl_dim_div, j, aff->ls->div->row[j],
1388 aff->v->size, i, 1);
1389 if (!aff->ls)
1390 return isl_aff_free(aff);
1391 }
1392 }
1393
1394 return aff;
1395}
1396
1397/* Swap divs "a" and "b" in "aff", which is assumed to be non-NULL.
1398 *
1399 * Even though this function is only called on isl_affs with a single
1400 * reference, we are careful to only change aff->v and aff->ls together.
1401 */
1402static __isl_give isl_aff *swap_div(__isl_take isl_aff *aff, int a, int b)
1403{
1404 unsigned off = isl_local_space_offset(aff->ls, isl_dim_div);
1405 isl_local_space *ls;
1406 isl_vec *v;
1407
1408 ls = isl_local_space_copy(aff->ls);
1409 ls = isl_local_space_swap_div(ls, a, b);
1410 v = isl_vec_copy(aff->v);
1411 v = isl_vec_cow(v);
1412 if (!ls || !v)
1413 goto error;
1414
1415 isl_int_swap(v->el[1 + off + a], v->el[1 + off + b])impz_swap(v->el[1 + off + a],v->el[1 + off + b]);
1416 isl_vec_free(aff->v);
1417 aff->v = v;
1418 isl_local_space_free(aff->ls);
1419 aff->ls = ls;
1420
1421 return aff;
1422error:
1423 isl_vec_free(v);
1424 isl_local_space_free(ls);
1425 return isl_aff_free(aff);
1426}
1427
1428/* Merge divs "a" and "b" in "aff", which is assumed to be non-NULL.
1429 *
1430 * We currently do not actually remove div "b", but simply add its
1431 * coefficient to that of "a" and then zero it out.
1432 */
1433static __isl_give isl_aff *merge_divs(__isl_take isl_aff *aff, int a, int b)
1434{
1435 unsigned off = isl_local_space_offset(aff->ls, isl_dim_div);
1436
1437 if (isl_int_is_zero(aff->v->el[1 + off + b])(impz_sgn(aff->v->el[1 + off + b]) == 0))
1438 return aff;
1439
1440 aff->v = isl_vec_cow(aff->v);
1441 if (!aff->v)
1442 return isl_aff_free(aff);
1443
1444 isl_int_add(aff->v->el[1 + off + a],impz_add(aff->v->el[1 + off + a],aff->v->el[1 + off
+ a],aff->v->el[1 + off + b])
1445 aff->v->el[1 + off + a], aff->v->el[1 + off + b])impz_add(aff->v->el[1 + off + a],aff->v->el[1 + off
+ a],aff->v->el[1 + off + b])
;
1446 isl_int_set_si(aff->v->el[1 + off + b], 0)impz_set_si(aff->v->el[1 + off + b],0);
1447
1448 return aff;
1449}
1450
1451/* Sort the divs in the local space of "aff" according to
1452 * the comparison function "cmp_row" in isl_local_space.c,
1453 * combining the coefficients of identical divs.
1454 *
1455 * Reordering divs does not change the semantics of "aff",
1456 * so there is no need to call isl_aff_cow.
1457 * Moreover, this function is currently only called on isl_affs
1458 * with a single reference.
1459 */
1460static __isl_give isl_aff *sort_divs(__isl_take isl_aff *aff)
1461{
1462 int i, j, n;
1463
1464 if (!aff)
1465 return NULL((void*)0);
1466
1467 n = isl_aff_dim(aff, isl_dim_div);
1468 for (i = 1; i < n; ++i) {
1469 for (j = i - 1; j >= 0; --j) {
1470 int cmp = isl_mat_cmp_div(aff->ls->div, j, j + 1);
1471 if (cmp < 0)
1472 break;
1473 if (cmp == 0)
1474 aff = merge_divs(aff, j, j + 1);
1475 else
1476 aff = swap_div(aff, j, j + 1);
1477 if (!aff)
1478 return NULL((void*)0);
1479 }
1480 }
1481
1482 return aff;
1483}
1484
1485/* Normalize the representation of "aff".
1486 *
1487 * This function should only be called of "new" isl_affs, i.e.,
1488 * with only a single reference. We therefore do not need to
1489 * worry about affecting other instances.
1490 */
1491__isl_give isl_aff *isl_aff_normalize(__isl_take isl_aff *aff)
1492{
1493 if (!aff)
1494 return NULL((void*)0);
1495 aff->v = isl_vec_normalize(aff->v);
1496 if (!aff->v)
1497 return isl_aff_free(aff);
1498 aff = plug_in_integral_divs(aff);
1499 aff = plug_in_unit_divs(aff);
1500 aff = sort_divs(aff);
1501 aff = isl_aff_remove_unused_divs(aff);
1502 return aff;
1503}
1504
1505/* Given f, return floor(f).
1506 * If f is an integer expression, then just return f.
1507 * If f is a constant, then return the constant floor(f).
1508 * Otherwise, if f = g/m, write g = q m + r,
1509 * create a new div d = [r/m] and return the expression q + d.
1510 * The coefficients in r are taken to lie between -m/2 and m/2.
1511 *
1512 * As a special case, floor(NaN) = NaN.
1513 */
1514__isl_give isl_aff *isl_aff_floor(__isl_take isl_aff *aff)
1515{
1516 int i;
1517 int size;
1518 isl_ctx *ctx;
1519 isl_vec *div;
1520
1521 if (!aff)
1522 return NULL((void*)0);
1523
1524 if (isl_aff_is_nan(aff))
1525 return aff;
1526 if (isl_int_is_one(aff->v->el[0])(impz_cmp_si(aff->v->el[0],1) == 0))
1527 return aff;
1528
1529 aff = isl_aff_cow(aff);
1530 if (!aff)
1531 return NULL((void*)0);
1532
1533 aff->v = isl_vec_cow(aff->v);
1534 if (!aff->v)
1535 return isl_aff_free(aff);
1536
1537 if (isl_aff_is_cst(aff)) {
1538 isl_int_fdiv_q(aff->v->el[1], aff->v->el[1], aff->v->el[0])impz_fdiv_q(aff->v->el[1],aff->v->el[1],aff->v
->el[0])
;
1539 isl_int_set_si(aff->v->el[0], 1)impz_set_si(aff->v->el[0],1);
1540 return aff;
1541 }
1542
1543 div = isl_vec_copy(aff->v);
1544 div = isl_vec_cow(div);
1545 if (!div)
1546 return isl_aff_free(aff);
1547
1548 ctx = isl_aff_get_ctx(aff);
1549 isl_int_fdiv_q(aff->v->el[0], aff->v->el[0], ctx->two)impz_fdiv_q(aff->v->el[0],aff->v->el[0],ctx->two
)
;
1550 for (i = 1; i < aff->v->size; ++i) {
1551 isl_int_fdiv_r(div->el[i], div->el[i], div->el[0])impz_fdiv_r(div->el[i],div->el[i],div->el[0]);
1552 isl_int_fdiv_q(aff->v->el[i], aff->v->el[i], div->el[0])impz_fdiv_q(aff->v->el[i],aff->v->el[i],div->el
[0])
;
1553 if (isl_int_gt(div->el[i], aff->v->el[0])(impz_cmp(div->el[i],aff->v->el[0]) > 0)) {
1554 isl_int_sub(div->el[i], div->el[i], div->el[0])impz_sub(div->el[i],div->el[i],div->el[0]);
1555 isl_int_add_ui(aff->v->el[i], aff->v->el[i], 1)impz_add_ui(aff->v->el[i],aff->v->el[i],1);
1556 }
1557 }
1558
1559 aff->ls = isl_local_space_add_div(aff->ls, div);
1560 if (!aff->ls)
1561 return isl_aff_free(aff);
1562
1563 size = aff->v->size;
1564 aff->v = isl_vec_extend(aff->v, size + 1);
1565 if (!aff->v)
1566 return isl_aff_free(aff);
1567 isl_int_set_si(aff->v->el[0], 1)impz_set_si(aff->v->el[0],1);
1568 isl_int_set_si(aff->v->el[size], 1)impz_set_si(aff->v->el[size],1);
1569
1570 aff = isl_aff_normalize(aff);
1571
1572 return aff;
1573}
1574
1575/* Compute
1576 *
1577 * aff mod m = aff - m * floor(aff/m)
1578 */
1579__isl_give isl_aff *isl_aff_modisl_gmp_aff_mod(__isl_take isl_aff *aff, isl_int m)
1580{
1581 isl_aff *res;
1582
1583 res = isl_aff_copy(aff);
1584 aff = isl_aff_scale_downisl_gmp_aff_scale_down(aff, m);
1585 aff = isl_aff_floor(aff);
1586 aff = isl_aff_scaleisl_gmp_aff_scale(aff, m);
1587 res = isl_aff_sub(res, aff);
1588
1589 return res;
1590}
1591
1592/* Compute
1593 *
1594 * aff mod m = aff - m * floor(aff/m)
1595 *
1596 * with m an integer value.
1597 */
1598__isl_give isl_aff *isl_aff_mod_val(__isl_take isl_aff *aff,
1599 __isl_take isl_val *m)
1600{
1601 isl_aff *res;
1602
1603 if (!aff || !m)
1604 goto error;
1605
1606 if (!isl_val_is_int(m))
1607 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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1608); goto error; } while (0)
1608 "expecting integer modulo", goto error)do { isl_handle_error(isl_val_get_ctx(m), isl_error_invalid, "expecting integer modulo"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1608); goto error; } while (0)
;
1609
1610 res = isl_aff_copy(aff);
1611 aff = isl_aff_scale_down_val(aff, isl_val_copy(m));
1612 aff = isl_aff_floor(aff);
1613 aff = isl_aff_scale_val(aff, m);
1614 res = isl_aff_sub(res, aff);
1615
1616 return res;
1617error:
1618 isl_aff_free(aff);
1619 isl_val_free(m);
1620 return NULL((void*)0);
1621}
1622
1623/* Compute
1624 *
1625 * pwaff mod m = pwaff - m * floor(pwaff/m)
1626 */
1627__isl_give isl_pw_aff *isl_pw_aff_modisl_gmp_pw_aff_mod(__isl_take isl_pw_aff *pwaff, isl_int m)
1628{
1629 isl_pw_aff *res;
1630
1631 res = isl_pw_aff_copy(pwaff);
1632 pwaff = isl_pw_aff_scale_downisl_gmp_pw_aff_scale_down(pwaff, m);
1633 pwaff = isl_pw_aff_floor(pwaff);
1634 pwaff = isl_pw_aff_scaleisl_gmp_pw_aff_scale(pwaff, m);
1635 res = isl_pw_aff_sub(res, pwaff);
1636
1637 return res;
1638}
1639
1640/* Compute
1641 *
1642 * pa mod m = pa - m * floor(pa/m)
1643 *
1644 * with m an integer value.
1645 */
1646__isl_give isl_pw_aff *isl_pw_aff_mod_val(__isl_take isl_pw_aff *pa,
1647 __isl_take isl_val *m)
1648{
1649 if (!pa || !m)
1650 goto error;
1651 if (!isl_val_is_int(m))
1652 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1653); goto error; } while (0)
1653 "expecting integer modulo", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid
, "expecting integer modulo", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1653); goto error; } while (0)
;
1654 pa = isl_pw_aff_modisl_gmp_pw_aff_mod(pa, m->n);
1655 isl_val_free(m);
1656 return pa;
1657error:
1658 isl_pw_aff_free(pa);
1659 isl_val_free(m);
1660 return NULL((void*)0);
1661}
1662
1663/* Given f, return ceil(f).
1664 * If f is an integer expression, then just return f.
1665 * Otherwise, let f be the expression
1666 *
1667 * e/m
1668 *
1669 * then return
1670 *
1671 * floor((e + m - 1)/m)
1672 *
1673 * As a special case, ceil(NaN) = NaN.
1674 */
1675__isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff)
1676{
1677 if (!aff)
1678 return NULL((void*)0);
1679
1680 if (isl_aff_is_nan(aff))
1681 return aff;
1682 if (isl_int_is_one(aff->v->el[0])(impz_cmp_si(aff->v->el[0],1) == 0))
1683 return aff;
1684
1685 aff = isl_aff_cow(aff);
1686 if (!aff)
1687 return NULL((void*)0);
1688 aff->v = isl_vec_cow(aff->v);
1689 if (!aff->v)
1690 return isl_aff_free(aff);
1691
1692 isl_int_add(aff->v->el[1], aff->v->el[1], aff->v->el[0])impz_add(aff->v->el[1],aff->v->el[1],aff->v->
el[0])
;
1693 isl_int_sub_ui(aff->v->el[1], aff->v->el[1], 1)impz_sub_ui(aff->v->el[1],aff->v->el[1],1);
1694 aff = isl_aff_floor(aff);
1695
1696 return aff;
1697}
1698
1699/* Apply the expansion computed by isl_merge_divs.
1700 * The expansion itself is given by "exp" while the resulting
1701 * list of divs is given by "div".
1702 */
1703__isl_give isl_aff *isl_aff_expand_divs( __isl_take isl_aff *aff,
1704 __isl_take isl_mat *div, int *exp)
1705{
1706 int i, j;
1707 int old_n_div;
1708 int new_n_div;
1709 int offset;
1710
1711 aff = isl_aff_cow(aff);
1712 if (!aff || !div)
1713 goto error;
1714
1715 old_n_div = isl_local_space_dim(aff->ls, isl_dim_div);
1716 new_n_div = isl_mat_rows(div);
1717 if (new_n_div < old_n_div)
1718 isl_die(isl_mat_get_ctx(div), isl_error_invalid,do { isl_handle_error(isl_mat_get_ctx(div), isl_error_invalid
, "not an expansion", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1719); goto error; } while (0)
1719 "not an expansion", goto error)do { isl_handle_error(isl_mat_get_ctx(div), isl_error_invalid
, "not an expansion", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1719); goto error; } while (0)
;
1720
1721 aff->v = isl_vec_extend(aff->v, aff->v->size + new_n_div - old_n_div);
1722 if (!aff->v)
1723 goto error;
1724
1725 offset = 1 + isl_local_space_offset(aff->ls, isl_dim_div);
1726 j = old_n_div - 1;
1727 for (i = new_n_div - 1; i >= 0; --i) {
1728 if (j >= 0 && exp[j] == i) {
1729 if (i != j)
1730 isl_int_swap(aff->v->el[offset + i],impz_swap(aff->v->el[offset + i],aff->v->el[offset
+ j])
1731 aff->v->el[offset + j])impz_swap(aff->v->el[offset + i],aff->v->el[offset
+ j])
;
1732 j--;
1733 } else
1734 isl_int_set_si(aff->v->el[offset + i], 0)impz_set_si(aff->v->el[offset + i],0);
1735 }
1736
1737 aff->ls = isl_local_space_replace_divs(aff->ls, isl_mat_copy(div));
1738 if (!aff->ls)
1739 goto error;
1740 isl_mat_free(div);
1741 return aff;
1742error:
1743 isl_aff_free(aff);
1744 isl_mat_free(div);
1745 return NULL((void*)0);
1746}
1747
1748/* Add two affine expressions that live in the same local space.
1749 */
1750static __isl_give isl_aff *add_expanded(__isl_take isl_aff *aff1,
1751 __isl_take isl_aff *aff2)
1752{
1753 isl_int gcd, f;
1754
1755 aff1 = isl_aff_cow(aff1);
1756 if (!aff1 || !aff2)
1757 goto error;
1758
1759 aff1->v = isl_vec_cow(aff1->v);
1760 if (!aff1->v)
1761 goto error;
1762
1763 isl_int_init(gcd)gcd = mp_int_alloc();
1764 isl_int_init(f)f = mp_int_alloc();
1765 isl_int_gcd(gcd, aff1->v->el[0], aff2->v->el[0])impz_gcd(gcd,aff1->v->el[0],aff2->v->el[0]);
1766 isl_int_divexact(f, aff2->v->el[0], gcd)impz_divexact(f,aff2->v->el[0],gcd);
1767 isl_seq_scale(aff1->v->el + 1, aff1->v->el + 1, f, aff1->v->size - 1);
1768 isl_int_divexact(f, aff1->v->el[0], gcd)impz_divexact(f,aff1->v->el[0],gcd);
1769 isl_seq_addmul(aff1->v->el + 1, f, aff2->v->el + 1, aff1->v->size - 1);
1770 isl_int_divexact(f, aff2->v->el[0], gcd)impz_divexact(f,aff2->v->el[0],gcd);
1771 isl_int_mul(aff1->v->el[0], aff1->v->el[0], f)impz_mul(aff1->v->el[0],aff1->v->el[0],f);
1772 isl_int_clear(f)mp_int_free(f);
1773 isl_int_clear(gcd)mp_int_free(gcd);
1774
1775 isl_aff_free(aff2);
1776 return aff1;
1777error:
1778 isl_aff_free(aff1);
1779 isl_aff_free(aff2);
1780 return NULL((void*)0);
1781}
1782
1783/* Return the sum of "aff1" and "aff2".
1784 *
1785 * If either of the two is NaN, then the result is NaN.
1786 */
1787__isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1,
1788 __isl_take isl_aff *aff2)
1789{
1790 isl_ctx *ctx;
1791 int *exp1 = NULL((void*)0);
1792 int *exp2 = NULL((void*)0);
1793 isl_mat *div;
1794 int n_div1, n_div2;
1795
1796 if (!aff1 || !aff2)
1797 goto error;
1798
1799 ctx = isl_aff_get_ctx(aff1);
1800 if (!isl_space_is_equal(aff1->ls->dim, aff2->ls->dim))
1801 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1802); goto error; } while (0)
1802 "spaces don't match", goto error)do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1802); goto error; } while (0)
;
1803
1804 if (isl_aff_is_nan(aff1)) {
1805 isl_aff_free(aff2);
1806 return aff1;
1807 }
1808 if (isl_aff_is_nan(aff2)) {
1809 isl_aff_free(aff1);
1810 return aff2;
1811 }
1812
1813 n_div1 = isl_aff_dim(aff1, isl_dim_div);
1814 n_div2 = isl_aff_dim(aff2, isl_dim_div);
1815 if (n_div1 == 0 && n_div2 == 0)
1816 return add_expanded(aff1, aff2);
1817
1818 exp1 = isl_alloc_array(ctx, int, n_div1)((int *)isl_malloc_or_die(ctx, (n_div1)*sizeof(int)));
1819 exp2 = isl_alloc_array(ctx, int, n_div2)((int *)isl_malloc_or_die(ctx, (n_div2)*sizeof(int)));
1820 if ((n_div1 && !exp1) || (n_div2 && !exp2))
1821 goto error;
1822
1823 div = isl_merge_divs(aff1->ls->div, aff2->ls->div, exp1, exp2);
1824 aff1 = isl_aff_expand_divs(aff1, isl_mat_copy(div), exp1);
1825 aff2 = isl_aff_expand_divs(aff2, div, exp2);
1826 free(exp1);
1827 free(exp2);
1828
1829 return add_expanded(aff1, aff2);
1830error:
1831 free(exp1);
1832 free(exp2);
1833 isl_aff_free(aff1);
1834 isl_aff_free(aff2);
1835 return NULL((void*)0);
1836}
1837
1838__isl_give isl_aff *isl_aff_sub(__isl_take isl_aff *aff1,
1839 __isl_take isl_aff *aff2)
1840{
1841 return isl_aff_add(aff1, isl_aff_neg(aff2));
21
Calling 'isl_aff_neg'
31
Returning; memory was released via 1st parameter
1842}
1843
1844/* Return the result of scaling "aff" by a factor of "f".
1845 *
1846 * As a special case, f * NaN = NaN.
1847 */
1848__isl_give isl_aff *isl_aff_scaleisl_gmp_aff_scale(__isl_take isl_aff *aff, isl_int f)
1849{
1850 isl_int gcd;
1851
1852 if (!aff)
1853 return NULL((void*)0);
1854 if (isl_aff_is_nan(aff))
1855 return aff;
1856
1857 if (isl_int_is_one(f)(impz_cmp_si(f,1) == 0))
1858 return aff;
1859
1860 aff = isl_aff_cow(aff);
1861 if (!aff)
1862 return NULL((void*)0);
1863 aff->v = isl_vec_cow(aff->v);
1864 if (!aff->v)
1865 return isl_aff_free(aff);
1866
1867 if (isl_int_is_pos(f)(impz_sgn(f) > 0) && isl_int_is_divisible_by(aff->v->el[0], f)impz_divisible_p(aff->v->el[0],f)) {
1868 isl_int_divexact(aff->v->el[0], aff->v->el[0], f)impz_divexact(aff->v->el[0],aff->v->el[0],f);
1869 return aff;
1870 }
1871
1872 isl_int_init(gcd)gcd = mp_int_alloc();
1873 isl_int_gcd(gcd, aff->v->el[0], f)impz_gcd(gcd,aff->v->el[0],f);
1874 isl_int_divexact(aff->v->el[0], aff->v->el[0], gcd)impz_divexact(aff->v->el[0],aff->v->el[0],gcd);
1875 isl_int_divexact(gcd, f, gcd)impz_divexact(gcd,f,gcd);
1876 isl_seq_scale(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1);
1877 isl_int_clear(gcd)mp_int_free(gcd);
1878
1879 return aff;
1880}
1881
1882/* Multiple "aff" by "v".
1883 */
1884__isl_give isl_aff *isl_aff_scale_val(__isl_take isl_aff *aff,
1885 __isl_take isl_val *v)
1886{
1887 if (!aff || !v)
1888 goto error;
1889
1890 if (isl_val_is_one(v)) {
1891 isl_val_free(v);
1892 return aff;
1893 }
1894
1895 if (!isl_val_is_rat(v))
1896 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1897); goto error; } while (0)
1897 "expecting rational factor", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting rational factor", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1897); goto error; } while (0)
;
1898
1899 aff = isl_aff_scaleisl_gmp_aff_scale(aff, v->n);
1900 aff = isl_aff_scale_downisl_gmp_aff_scale_down(aff, v->d);
1901
1902 isl_val_free(v);
1903 return aff;
1904error:
1905 isl_aff_free(aff);
1906 isl_val_free(v);
1907 return NULL((void*)0);
1908}
1909
1910/* Return the result of scaling "aff" down by a factor of "f".
1911 *
1912 * As a special case, NaN/f = NaN.
1913 */
1914__isl_give isl_aff *isl_aff_scale_downisl_gmp_aff_scale_down(__isl_take isl_aff *aff, isl_int f)
1915{
1916 isl_int gcd;
1917
1918 if (!aff)
1919 return NULL((void*)0);
1920 if (isl_aff_is_nan(aff))
1921 return aff;
1922
1923 if (isl_int_is_one(f)(impz_cmp_si(f,1) == 0))
1924 return aff;
1925
1926 aff = isl_aff_cow(aff);
1927 if (!aff)
1928 return NULL((void*)0);
1929
1930 if (isl_int_is_zero(f)(impz_sgn(f) == 0))
1931 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1932); return isl_aff_free(aff); } while (0)
1932 "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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1932); return isl_aff_free(aff); } while (0)
;
1933
1934 aff->v = isl_vec_cow(aff->v);
1935 if (!aff->v)
1936 return isl_aff_free(aff);
1937
1938 isl_int_init(gcd)gcd = mp_int_alloc();
1939 isl_seq_gcd(aff->v->el + 1, aff->v->size - 1, &gcd);
1940 isl_int_gcd(gcd, gcd, f)impz_gcd(gcd,gcd,f);
1941 isl_seq_scale_down(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1);
1942 isl_int_divexact(gcd, f, gcd)impz_divexact(gcd,f,gcd);
1943 isl_int_mul(aff->v->el[0], aff->v->el[0], gcd)impz_mul(aff->v->el[0],aff->v->el[0],gcd);
1944 isl_int_clear(gcd)mp_int_free(gcd);
1945
1946 return aff;
1947}
1948
1949/* Divide "aff" by "v".
1950 */
1951__isl_give isl_aff *isl_aff_scale_down_val(__isl_take isl_aff *aff,
1952 __isl_take isl_val *v)
1953{
1954 if (!aff || !v)
1955 goto error;
1956
1957 if (isl_val_is_one(v)) {
1958 isl_val_free(v);
1959 return aff;
1960 }
1961
1962 if (!isl_val_is_rat(v))
1963 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1964); goto error; } while (0)
1964 "expecting rational factor", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting rational factor", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1964); goto error; } while (0)
;
1965 if (!isl_val_is_pos(v))
1966 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1967); goto error; } while (0)
1967 "factor needs to be positive", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "factor needs to be positive", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 1967); goto error; } while (0)
;
1968
1969 aff = isl_aff_scaleisl_gmp_aff_scale(aff, v->d);
1970 aff = isl_aff_scale_downisl_gmp_aff_scale_down(aff, v->n);
1971
1972 isl_val_free(v);
1973 return aff;
1974error:
1975 isl_aff_free(aff);
1976 isl_val_free(v);
1977 return NULL((void*)0);
1978}
1979
1980__isl_give isl_aff *isl_aff_scale_down_ui(__isl_take isl_aff *aff, unsigned f)
1981{
1982 isl_int v;
1983
1984 if (f == 1)
1985 return aff;
1986
1987 isl_int_init(v)v = mp_int_alloc();
1988 isl_int_set_ui(v, f)impz_set_ui(v,f);
1989 aff = isl_aff_scale_downisl_gmp_aff_scale_down(aff, v);
1990 isl_int_clear(v)mp_int_free(v);
1991
1992 return aff;
1993}
1994
1995__isl_give isl_aff *isl_aff_set_dim_name(__isl_take isl_aff *aff,
1996 enum isl_dim_type type, unsigned pos, const char *s)
1997{
1998 aff = isl_aff_cow(aff);
1999 if (!aff)
2000 return NULL((void*)0);
2001 if (type == isl_dim_out)
2002 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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2004); return isl_aff_free(aff); } while (0)
2003 "cannot set name of output/set dimension",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot set name of output/set dimension"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2004); return isl_aff_free(aff); } while (0)
2004 return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot set name of output/set dimension"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2004); return isl_aff_free(aff); } while (0)
;
2005 if (type == isl_dim_in)
2006 type = isl_dim_set;
2007 aff->ls = isl_local_space_set_dim_name(aff->ls, type, pos, s);
2008 if (!aff->ls)
2009 return isl_aff_free(aff);
2010
2011 return aff;
2012}
2013
2014__isl_give isl_aff *isl_aff_set_dim_id(__isl_take isl_aff *aff,
2015 enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
2016{
2017 aff = isl_aff_cow(aff);
2018 if (!aff)
2019 goto error;
2020 if (type == isl_dim_out)
2021 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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2023); goto error; } while (0)
2022 "cannot set name of output/set dimension",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot set name of output/set dimension"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2023); goto error; } while (0)
2023 goto error)do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot set name of output/set dimension"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2023); goto error; } while (0)
;
2024 if (type == isl_dim_in)
2025 type = isl_dim_set;
2026 aff->ls = isl_local_space_set_dim_id(aff->ls, type, pos, id);
2027 if (!aff->ls)
2028 return isl_aff_free(aff);
2029
2030 return aff;
2031error:
2032 isl_id_free(id);
2033 isl_aff_free(aff);
2034 return NULL((void*)0);
2035}
2036
2037/* Replace the identifier of the input tuple of "aff" by "id".
2038 * type is currently required to be equal to isl_dim_in
2039 */
2040__isl_give isl_aff *isl_aff_set_tuple_id(__isl_take isl_aff *aff,
2041 enum isl_dim_type type, __isl_take isl_id *id)
2042{
2043 aff = isl_aff_cow(aff);
2044 if (!aff)
2045 goto error;
2046 if (type != isl_dim_out)
2047 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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2048); goto error; } while (0)
2048 "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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2048); goto error; } while (0)
;
2049 aff->ls = isl_local_space_set_tuple_id(aff->ls, isl_dim_set, id);
2050 if (!aff->ls)
2051 return isl_aff_free(aff);
2052
2053 return aff;
2054error:
2055 isl_id_free(id);
2056 isl_aff_free(aff);
2057 return NULL((void*)0);
2058}
2059
2060/* Exploit the equalities in "eq" to simplify the affine expression
2061 * and the expressions of the integer divisions in the local space.
2062 * The integer divisions in this local space are assumed to appear
2063 * as regular dimensions in "eq".
2064 */
2065static __isl_give isl_aff *isl_aff_substitute_equalities_lifted(
2066 __isl_take isl_aff *aff, __isl_take isl_basic_setisl_basic_map *eq)
2067{
2068 int i, j;
2069 unsigned total;
2070 unsigned n_div;
2071
2072 if (!eq)
2073 goto error;
2074 if (eq->n_eq == 0) {
2075 isl_basic_set_free(eq);
2076 return aff;
2077 }
2078
2079 aff = isl_aff_cow(aff);
2080 if (!aff)
2081 goto error;
2082
2083 aff->ls = isl_local_space_substitute_equalities(aff->ls,
2084 isl_basic_set_copy(eq));
2085 aff->v = isl_vec_cow(aff->v);
2086 if (!aff->ls || !aff->v)
2087 goto error;
2088
2089 total = 1 + isl_space_dim(eq->dim, isl_dim_all);
2090 n_div = eq->n_div;
2091 for (i = 0; i < eq->n_eq; ++i) {
2092 j = isl_seq_last_non_zero(eq->eq[i], total + n_div);
2093 if (j < 0 || j == 0 || j >= total)
2094 continue;
2095
2096 isl_seq_elim(aff->v->el + 1, eq->eq[i], j, total,
2097 &aff->v->el[0]);
2098 }
2099
2100 isl_basic_set_free(eq);
2101 aff = isl_aff_normalize(aff);
2102 return aff;
2103error:
2104 isl_basic_set_free(eq);
2105 isl_aff_free(aff);
2106 return NULL((void*)0);
2107}
2108
2109/* Exploit the equalities in "eq" to simplify the affine expression
2110 * and the expressions of the integer divisions in the local space.
2111 */
2112__isl_give isl_aff *isl_aff_substitute_equalities(__isl_take isl_aff *aff,
2113 __isl_take isl_basic_setisl_basic_map *eq)
2114{
2115 int n_div;
2116
2117 if (!aff || !eq)
2118 goto error;
2119 n_div = isl_local_space_dim(aff->ls, isl_dim_div);
2120 if (n_div > 0)
2121 eq = isl_basic_set_add_dims(eq, isl_dim_set, n_div);
2122 return isl_aff_substitute_equalities_lifted(aff, eq);
2123error:
2124 isl_basic_set_free(eq);
2125 isl_aff_free(aff);
2126 return NULL((void*)0);
2127}
2128
2129/* Look for equalities among the variables shared by context and aff
2130 * and the integer divisions of aff, if any.
2131 * The equalities are then used to eliminate coefficients and/or integer
2132 * divisions from aff.
2133 */
2134__isl_give isl_aff *isl_aff_gist(__isl_take isl_aff *aff,
2135 __isl_take isl_setisl_map *context)
2136{
2137 isl_basic_setisl_basic_map *hull;
2138 int n_div;
2139
2140 if (!aff)
2141 goto error;
2142 n_div = isl_local_space_dim(aff->ls, isl_dim_div);
2143 if (n_div > 0) {
2144 isl_basic_setisl_basic_map *bset;
2145 isl_local_space *ls;
2146 context = isl_set_add_dims(context, isl_dim_set, n_div);
2147 ls = isl_aff_get_domain_local_space(aff);
2148 bset = isl_basic_set_from_local_space(ls);
2149 bset = isl_basic_set_lift(bset);
2150 bset = isl_basic_set_flatten(bset);
2151 context = isl_set_intersect(context,
2152 isl_set_from_basic_set(bset));
2153 }
2154
2155 hull = isl_set_affine_hull(context);
2156 return isl_aff_substitute_equalities_lifted(aff, hull);
2157error:
2158 isl_aff_free(aff);
2159 isl_set_free(context);
2160 return NULL((void*)0);
2161}
2162
2163__isl_give isl_aff *isl_aff_gist_params(__isl_take isl_aff *aff,
2164 __isl_take isl_setisl_map *context)
2165{
2166 isl_setisl_map *dom_context = isl_set_universe(isl_aff_get_domain_space(aff));
2167 dom_context = isl_set_intersect_params(dom_context, context);
2168 return isl_aff_gist(aff, dom_context);
2169}
2170
2171/* Return a basic set containing those elements in the space
2172 * of aff where it is positive. "rational" should not be set.
2173 *
2174 * If "aff" is NaN, then it is not positive.
2175 */
2176static __isl_give isl_basic_setisl_basic_map *aff_pos_basic_set(__isl_take isl_aff *aff,
2177 int rational)
2178{
2179 isl_constraint *ineq;
2180 isl_basic_setisl_basic_map *bset;
2181 isl_val *c;
2182
2183 if (!aff)
2184 return NULL((void*)0);
2185 if (isl_aff_is_nan(aff)) {
2186 isl_space *space = isl_aff_get_domain_space(aff);
2187 isl_aff_free(aff);
2188 return isl_basic_set_empty(space);
2189 }
2190 if (rational)
2191 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2192); goto error; } while (0)
2192 "rational sets not supported", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_unsupported
, "rational sets not supported", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2192); goto error; } while (0)
;
2193
2194 ineq = isl_inequality_from_aff(aff);
2195 c = isl_constraint_get_constant_val(ineq);
2196 c = isl_val_sub_ui(c, 1);
2197 ineq = isl_constraint_set_constant_val(ineq, c);
2198
2199 bset = isl_basic_set_from_constraint(ineq);
2200 bset = isl_basic_set_simplify(bset);
2201 return bset;
2202error:
2203 isl_aff_free(aff);
2204 return NULL((void*)0);
2205}
2206
2207/* Return a basic set containing those elements in the space
2208 * of aff where it is non-negative.
2209 * If "rational" is set, then return a rational basic set.
2210 *
2211 * If "aff" is NaN, then it is not non-negative (it's not negative either).
2212 */
2213static __isl_give isl_basic_setisl_basic_map *aff_nonneg_basic_set(
2214 __isl_take isl_aff *aff, int rational)
2215{
2216 isl_constraint *ineq;
2217 isl_basic_setisl_basic_map *bset;
2218
2219 if (!aff)
2220 return NULL((void*)0);
2221 if (isl_aff_is_nan(aff)) {
2222 isl_space *space = isl_aff_get_domain_space(aff);
2223 isl_aff_free(aff);
2224 return isl_basic_set_empty(space);
2225 }
2226
2227 ineq = isl_inequality_from_aff(aff);
2228
2229 bset = isl_basic_set_from_constraint(ineq);
2230 if (rational)
2231 bset = isl_basic_set_set_rational(bset);
2232 bset = isl_basic_set_simplify(bset);
2233 return bset;
2234}
2235
2236/* Return a basic set containing those elements in the space
2237 * of aff where it is non-negative.
2238 */
2239__isl_give isl_basic_setisl_basic_map *isl_aff_nonneg_basic_set(__isl_take isl_aff *aff)
2240{
2241 return aff_nonneg_basic_set(aff, 0);
2242}
2243
2244/* Return a basic set containing those elements in the domain space
2245 * of aff where it is negative.
2246 */
2247__isl_give isl_basic_setisl_basic_map *isl_aff_neg_basic_set(__isl_take isl_aff *aff)
2248{
2249 aff = isl_aff_neg(aff);
2250 aff = isl_aff_add_constant_num_si(aff, -1);
2251 return isl_aff_nonneg_basic_set(aff);
2252}
2253
2254/* Return a basic set containing those elements in the space
2255 * of aff where it is zero.
2256 * If "rational" is set, then return a rational basic set.
2257 *
2258 * If "aff" is NaN, then it is not zero.
2259 */
2260static __isl_give isl_basic_setisl_basic_map *aff_zero_basic_set(__isl_take isl_aff *aff,
2261 int rational)
2262{
2263 isl_constraint *ineq;
2264 isl_basic_setisl_basic_map *bset;
2265
2266 if (!aff)
2267 return NULL((void*)0);
2268 if (isl_aff_is_nan(aff)) {
2269 isl_space *space = isl_aff_get_domain_space(aff);
2270 isl_aff_free(aff);
2271 return isl_basic_set_empty(space);
2272 }
2273
2274 ineq = isl_equality_from_aff(aff);
2275
2276 bset = isl_basic_set_from_constraint(ineq);
2277 if (rational)
2278 bset = isl_basic_set_set_rational(bset);
2279 bset = isl_basic_set_simplify(bset);
2280 return bset;
2281}
2282
2283/* Return a basic set containing those elements in the space
2284 * of aff where it is zero.
2285 */
2286__isl_give isl_basic_setisl_basic_map *isl_aff_zero_basic_set(__isl_take isl_aff *aff)
2287{
2288 return aff_zero_basic_set(aff, 0);
2289}
2290
2291/* Return a basic set containing those elements in the shared space
2292 * of aff1 and aff2 where aff1 is greater than or equal to aff2.
2293 */
2294__isl_give isl_basic_setisl_basic_map *isl_aff_ge_basic_set(__isl_take isl_aff *aff1,
2295 __isl_take isl_aff *aff2)
2296{
2297 aff1 = isl_aff_sub(aff1, aff2);
20
Calling 'isl_aff_sub'
32
Returning; memory was released via 2nd parameter
2298
2299 return isl_aff_nonneg_basic_set(aff1);
2300}
2301
2302/* Return a basic set containing those elements in the shared space
2303 * of aff1 and aff2 where aff1 is smaller than or equal to aff2.
2304 */
2305__isl_give isl_basic_setisl_basic_map *isl_aff_le_basic_set(__isl_take isl_aff *aff1,
2306 __isl_take isl_aff *aff2)
2307{
2308 return isl_aff_ge_basic_set(aff2, aff1);
19
Calling 'isl_aff_ge_basic_set'
33
Returning; memory was released via 2nd parameter
2309}
2310
2311__isl_give isl_aff *isl_aff_add_on_domain(__isl_keep isl_setisl_map *dom,
2312 __isl_take isl_aff *aff1, __isl_take isl_aff *aff2)
2313{
2314 aff1 = isl_aff_add(aff1, aff2);
2315 aff1 = isl_aff_gist(aff1, isl_set_copy(dom));
2316 return aff1;
2317}
2318
2319int isl_aff_is_empty(__isl_keep isl_aff *aff)
2320{
2321 if (!aff)
2322 return -1;
2323
2324 return 0;
2325}
2326
2327/* Check whether the given affine expression has non-zero coefficient
2328 * for any dimension in the given range or if any of these dimensions
2329 * appear with non-zero coefficients in any of the integer divisions
2330 * involved in the affine expression.
2331 */
2332isl_bool isl_aff_involves_dims(__isl_keep isl_aff *aff,
2333 enum isl_dim_type type, unsigned first, unsigned n)
2334{
2335 int i;
2336 isl_ctx *ctx;
2337 int *active = NULL((void*)0);
2338 isl_bool involves = isl_bool_false;
2339
2340 if (!aff)
2341 return isl_bool_error;
2342 if (n == 0)
2343 return isl_bool_false;
2344
2345 ctx = isl_aff_get_ctx(aff);
2346 if (first + n > isl_aff_dim(aff, type))
2347 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "range out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2348); return isl_bool_error; } while (0)
2348 "range out of bounds", return isl_bool_error)do { isl_handle_error(ctx, isl_error_invalid, "range out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2348); return isl_bool_error; } while (0)
;
2349
2350 active = isl_local_space_get_active(aff->ls, aff->v->el + 2);
2351 if (!active)
2352 goto error;
2353
2354 first += isl_local_space_offset(aff->ls, type) - 1;
2355 for (i = 0; i < n; ++i)
2356 if (active[first + i]) {
2357 involves = isl_bool_true;
2358 break;
2359 }
2360
2361 free(active);
2362
2363 return involves;
2364error:
2365 free(active);
2366 return isl_bool_error;
2367}
2368
2369__isl_give isl_aff *isl_aff_drop_dims(__isl_take isl_aff *aff,
2370 enum isl_dim_type type, unsigned first, unsigned n)
2371{
2372 isl_ctx *ctx;
2373
2374 if (!aff)
2375 return NULL((void*)0);
2376 if (type == isl_dim_out)
2377 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot drop output/set dimension"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2379); return isl_aff_free(aff); } while (0)
2378 "cannot drop output/set dimension",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot drop output/set dimension"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2379); return isl_aff_free(aff); } while (0)
2379 return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot drop output/set dimension"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2379); return isl_aff_free(aff); } while (0)
;
2380 if (type == isl_dim_in)
2381 type = isl_dim_set;
2382 if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
2383 return aff;
2384
2385 ctx = isl_aff_get_ctx(aff);
2386 if (first + n > isl_local_space_dim(aff->ls, type))
2387 isl_die(ctx, isl_error_invalid, "range out of bounds",do { isl_handle_error(ctx, isl_error_invalid, "range out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2388); return isl_aff_free(aff); } while (0)
2388 return isl_aff_free(aff))do { isl_handle_error(ctx, isl_error_invalid, "range out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2388); return isl_aff_free(aff); } while (0)
;
2389
2390 aff = isl_aff_cow(aff);
2391 if (!aff)
2392 return NULL((void*)0);
2393
2394 aff->ls = isl_local_space_drop_dims(aff->ls, type, first, n);
2395 if (!aff->ls)
2396 return isl_aff_free(aff);
2397
2398 first += 1 + isl_local_space_offset(aff->ls, type);
2399 aff->v = isl_vec_drop_els(aff->v, first, n);
2400 if (!aff->v)
2401 return isl_aff_free(aff);
2402
2403 return aff;
2404}
2405
2406/* Project the domain of the affine expression onto its parameter space.
2407 * The affine expression may not involve any of the domain dimensions.
2408 */
2409__isl_give isl_aff *isl_aff_project_domain_on_params(__isl_take isl_aff *aff)
2410{
2411 isl_space *space;
2412 unsigned n;
2413 int involves;
2414
2415 n = isl_aff_dim(aff, isl_dim_in);
2416 involves = isl_aff_involves_dims(aff, isl_dim_in, 0, n);
2417 if (involves < 0)
2418 return isl_aff_free(aff);
2419 if (involves)
2420 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",
"/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2422); return isl_aff_free(aff); } while (0)
2421 "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",
"/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2422); return isl_aff_free(aff); } while (0)
2422 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",
"/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2422); return isl_aff_free(aff); } while (0)
;
2423 aff = isl_aff_drop_dims(aff, isl_dim_in, 0, n);
2424 space = isl_aff_get_domain_space(aff);
2425 space = isl_space_params(space);
2426 aff = isl_aff_reset_domain_space(aff, space);
2427 return aff;
2428}
2429
2430__isl_give isl_aff *isl_aff_insert_dims(__isl_take isl_aff *aff,
2431 enum isl_dim_type type, unsigned first, unsigned n)
2432{
2433 isl_ctx *ctx;
2434
2435 if (!aff)
2436 return NULL((void*)0);
2437 if (type == isl_dim_out)
2438 isl_die(aff->v->ctx, isl_error_invalid,do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot insert output/set dimensions"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2440); return isl_aff_free(aff); } while (0)
2439 "cannot insert output/set dimensions",do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot insert output/set dimensions"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2440); return isl_aff_free(aff); } while (0)
2440 return isl_aff_free(aff))do { isl_handle_error(aff->v->ctx, isl_error_invalid, "cannot insert output/set dimensions"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2440); return isl_aff_free(aff); } while (0)
;
2441 if (type == isl_dim_in)
2442 type = isl_dim_set;
2443 if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
2444 return aff;
2445
2446 ctx = isl_aff_get_ctx(aff);
2447 if (first > isl_local_space_dim(aff->ls, type))
2448 isl_die(ctx, isl_error_invalid, "position out of bounds",do { isl_handle_error(ctx, isl_error_invalid, "position out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2449); return isl_aff_free(aff); } while (0)
2449 return isl_aff_free(aff))do { isl_handle_error(ctx, isl_error_invalid, "position out of bounds"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2449); return isl_aff_free(aff); } while (0)
;
2450
2451 aff = isl_aff_cow(aff);
2452 if (!aff)
2453 return NULL((void*)0);
2454
2455 aff->ls = isl_local_space_insert_dims(aff->ls, type, first, n);
2456 if (!aff->ls)
2457 return isl_aff_free(aff);
2458
2459 first += 1 + isl_local_space_offset(aff->ls, type);
2460 aff->v = isl_vec_insert_zero_els(aff->v, first, n);
2461 if (!aff->v)
2462 return isl_aff_free(aff);
2463
2464 return aff;
2465}
2466
2467__isl_give isl_aff *isl_aff_add_dims(__isl_take isl_aff *aff,
2468 enum isl_dim_type type, unsigned n)
2469{
2470 unsigned pos;
2471
2472 pos = isl_aff_dim(aff, type);
2473
2474 return isl_aff_insert_dims(aff, type, pos, n);
2475}
2476
2477__isl_give isl_pw_aff *isl_pw_aff_add_dims(__isl_take isl_pw_aff *pwaff,
2478 enum isl_dim_type type, unsigned n)
2479{
2480 unsigned pos;
2481
2482 pos = isl_pw_aff_dim(pwaff, type);
2483
2484 return isl_pw_aff_insert_dims(pwaff, type, pos, n);
2485}
2486
2487/* Move the "n" dimensions of "src_type" starting at "src_pos" of "aff"
2488 * to dimensions of "dst_type" at "dst_pos".
2489 *
2490 * We only support moving input dimensions to parameters and vice versa.
2491 */
2492__isl_give isl_aff *isl_aff_move_dims(__isl_take isl_aff *aff,
2493 enum isl_dim_type dst_type, unsigned dst_pos,
2494 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
2495{
2496 unsigned g_dst_pos;
2497 unsigned g_src_pos;
2498
2499 if (!aff)
2500 return NULL((void*)0);
2501 if (n == 0 &&
2502 !isl_local_space_is_named_or_nested(aff->ls, src_type) &&
2503 !isl_local_space_is_named_or_nested(aff->ls, dst_type))
2504 return aff;
2505
2506 if (dst_type == isl_dim_out || src_type == isl_dim_out)
2507 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2508); isl_aff_free(aff); } while (0)
2508 "cannot move output/set dimension", isl_aff_free(aff))do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot move output/set dimension", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2508); isl_aff_free(aff); } while (0)
;
2509 if (dst_type == isl_dim_div || src_type == isl_dim_div)
2510 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2511); isl_aff_free(aff); } while (0)
2511 "cannot move divs", isl_aff_free(aff))do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot move divs", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2511); isl_aff_free(aff); } while (0)
;
2512 if (dst_type == isl_dim_in)
2513 dst_type = isl_dim_set;
2514 if (src_type == isl_dim_in)
2515 src_type = isl_dim_set;
2516
2517 if (src_pos + n > isl_local_space_dim(aff->ls, src_type))
2518 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2519); isl_aff_free(aff); } while (0)
2519 "range out of bounds", isl_aff_free(aff))do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "range out of bounds", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2519); isl_aff_free(aff); } while (0)
;
2520 if (dst_type == src_type)
2521 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2523); isl_aff_free(aff); } while (0)
2522 "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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2523); isl_aff_free(aff); } while (0)
2523 isl_aff_free(aff))do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_unsupported
, "moving dims within the same type not supported", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2523); isl_aff_free(aff); } while (0)
;
2524
2525 aff = isl_aff_cow(aff);
2526 if (!aff)
2527 return NULL((void*)0);
2528
2529 g_src_pos = 1 + isl_local_space_offset(aff->ls, src_type) + src_pos;
2530 g_dst_pos = 1 + isl_local_space_offset(aff->ls, dst_type) + dst_pos;
2531 if (dst_type > src_type)
2532 g_dst_pos -= n;
2533
2534 aff->v = isl_vec_move_els(aff->v, g_dst_pos, g_src_pos, n);
2535 aff->ls = isl_local_space_move_dims(aff->ls, dst_type, dst_pos,
2536 src_type, src_pos, n);
2537 if (!aff->v || !aff->ls)
2538 return isl_aff_free(aff);
2539
2540 aff = sort_divs(aff);
2541
2542 return aff;
2543}
2544
2545__isl_give isl_pw_aff *isl_pw_aff_from_aff(__isl_take isl_aff *aff)
2546{
2547 isl_setisl_map *dom = isl_set_universe(isl_aff_get_domain_space(aff));
2548 return isl_pw_aff_alloc(dom, aff);
2549}
2550
2551#undef PWisl_pw_multi_aff
2552#define PWisl_pw_multi_aff isl_pw_aff
2553#undef ELisl_union_pw_aff
2554#define ELisl_union_pw_aff isl_aff
2555#undef EL_IS_ZEROis_empty
2556#define EL_IS_ZEROis_empty is_empty
2557#undef ZEROempty
2558#define ZEROempty empty
2559#undef IS_ZEROis_empty
2560#define IS_ZEROis_empty is_empty
2561#undef FIELDmaff
2562#define FIELDmaff aff
2563#undef DEFAULT_IS_ZERO0
2564#define DEFAULT_IS_ZERO0 0
2565
2566#define NO_EVAL
2567#define NO_OPT
2568#define NO_LIFT
2569#define NO_MORPH
2570
2571#include <isl_pw_templ.c>
2572
2573#undef UNIONisl_union_pw_multi_aff
2574#define UNIONisl_union_pw_multi_aff isl_union_pw_aff
2575#undef PARTisl_pw_multi_aff
2576#define PARTisl_pw_multi_aff isl_pw_aff
2577#undef PARTSpw_multi_aff
2578#define PARTSpw_multi_aff pw_aff
2579
2580#define NO_EVAL
2581
2582#include <isl_union_templ.c>
2583
2584static __isl_give isl_setisl_map *align_params_pw_pw_set_and(
2585 __isl_take isl_pw_aff *pwaff1, __isl_take isl_pw_aff *pwaff2,
2586 __isl_give isl_setisl_map *(*fn)(__isl_take isl_pw_aff *pwaff1,
2587 __isl_take isl_pw_aff *pwaff2))
2588{
2589 if (!pwaff1 || !pwaff2)
2590 goto error;
2591 if (isl_space_match(pwaff1->dim, isl_dim_param,
2592 pwaff2->dim, isl_dim_param))
2593 return fn(pwaff1, pwaff2);
2594 if (!isl_space_has_named_params(pwaff1->dim) ||
2595 !isl_space_has_named_params(pwaff2->dim))
2596 isl_die(isl_pw_aff_get_ctx(pwaff1), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pwaff1), isl_error_invalid
, "unaligned unnamed parameters", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2597); goto error; } while (0)
2597 "unaligned unnamed parameters", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pwaff1), isl_error_invalid
, "unaligned unnamed parameters", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2597); goto error; } while (0)
;
2598 pwaff1 = isl_pw_aff_align_params(pwaff1, isl_pw_aff_get_space(pwaff2));
2599 pwaff2 = isl_pw_aff_align_params(pwaff2, isl_pw_aff_get_space(pwaff1));
2600 return fn(pwaff1, pwaff2);
2601error:
2602 isl_pw_aff_free(pwaff1);
2603 isl_pw_aff_free(pwaff2);
2604 return NULL((void*)0);
2605}
2606
2607/* Align the parameters of the to isl_pw_aff arguments and
2608 * then apply a function "fn" on them that returns an isl_map.
2609 */
2610static __isl_give isl_map *align_params_pw_pw_map_and(
2611 __isl_take isl_pw_aff *pa1, __isl_take isl_pw_aff *pa2,
2612 __isl_give isl_map *(*fn)(__isl_take isl_pw_aff *pa1,
2613 __isl_take isl_pw_aff *pa2))
2614{
2615 if (!pa1 || !pa2)
2616 goto error;
2617 if (isl_space_match(pa1->dim, isl_dim_param, pa2->dim, isl_dim_param))
2618 return fn(pa1, pa2);
2619 if (!isl_space_has_named_params(pa1->dim) ||
2620 !isl_space_has_named_params(pa2->dim))
2621 isl_die(isl_pw_aff_get_ctx(pa1), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa1), isl_error_invalid
, "unaligned unnamed parameters", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2622); goto error; } while (0)
2622 "unaligned unnamed parameters", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa1), isl_error_invalid
, "unaligned unnamed parameters", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2622); goto error; } while (0)
;
2623 pa1 = isl_pw_aff_align_params(pa1, isl_pw_aff_get_space(pa2));
2624 pa2 = isl_pw_aff_align_params(pa2, isl_pw_aff_get_space(pa1));
2625 return fn(pa1, pa2);
2626error:
2627 isl_pw_aff_free(pa1);
2628 isl_pw_aff_free(pa2);
2629 return NULL((void*)0);
2630}
2631
2632/* Compute a piecewise quasi-affine expression with a domain that
2633 * is the union of those of pwaff1 and pwaff2 and such that on each
2634 * cell, the quasi-affine expression is the better (according to cmp)
2635 * of those of pwaff1 and pwaff2. If only one of pwaff1 or pwaff2
2636 * is defined on a given cell, then the associated expression
2637 * is the defined one.
2638 */
2639static __isl_give isl_pw_aff *pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1,
2640 __isl_take isl_pw_aff *pwaff2,
2641 __isl_give isl_basic_setisl_basic_map *(*cmp)(__isl_take isl_aff *aff1,
2642 __isl_take isl_aff *aff2))
2643{
2644 int i, j, n;
2645 isl_pw_aff *res;
2646 isl_ctx *ctx;
2647 isl_setisl_map *set;
2648
2649 if (!pwaff1 || !pwaff2)
2
Assuming 'pwaff1' is non-null
3
Assuming 'pwaff2' is non-null
4
Taking false branch
2650 goto error;
2651
2652 ctx = isl_space_get_ctx(pwaff1->dim);
2653 if (!isl_space_is_equal(pwaff1->dim, pwaff2->dim))
5
Taking false branch
2654 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "arguments should live in same space"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2655); goto error; } while (0)
2655 "arguments should live in same space", goto error)do { isl_handle_error(ctx, isl_error_invalid, "arguments should live in same space"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2655); goto error; } while (0)
;
2656
2657 if (isl_pw_aff_is_empty(pwaff1)) {
6
Taking false branch
2658 isl_pw_aff_free(pwaff1);
2659 return pwaff2;
2660 }
2661
2662 if (isl_pw_aff_is_empty(pwaff2)) {
7
Taking false branch
2663 isl_pw_aff_free(pwaff2);
2664 return pwaff1;
2665 }
2666
2667 n = 2 * (pwaff1->n + 1) * (pwaff2->n + 1);
2668 res = isl_pw_aff_alloc_size(isl_space_copy(pwaff1->dim), n);
2669
2670 for (i = 0; i < pwaff1->n; ++i) {
8
Loop condition is true. Entering loop body
16
Loop condition is true. Entering loop body
38
Loop condition is false. Execution continues on line 2696
2671 set = isl_set_copy(pwaff1->p[i].set);
2672 for (j = 0; j < pwaff2->n; ++j) {
9
Loop condition is true. Entering loop body
15
Loop condition is false. Execution continues on line 2692
17
Loop condition is true. Entering loop body
37
Loop condition is false. Execution continues on line 2692
2673 struct isl_setisl_map *common;
2674 isl_setisl_map *better;
2675
2676 common = isl_set_intersect(
2677 isl_set_copy(pwaff1->p[i].set),
2678 isl_set_copy(pwaff2->p[j].set));
2679 better = isl_set_from_basic_set(cmp(
18
Calling 'isl_aff_le_basic_set'
34
Returning; memory was released via 1st parameter
2680 isl_aff_copy(pwaff2->p[j].aff),
10
Calling 'isl_aff_copy'
13
Returning from 'isl_aff_copy'
2681 isl_aff_copy(pwaff1->p[i].aff)));
2682 better = isl_set_intersect(common, better);
2683 if (isl_set_plain_is_empty(better)) {
14
Taking false branch
35
Taking true branch
2684 isl_set_free(better);
2685 continue;
36
Execution continues on line 2672
2686 }
2687 set = isl_set_subtract(set, isl_set_copy(better));
2688
2689 res = isl_pw_aff_add_piece(res, better,
2690 isl_aff_copy(pwaff2->p[j].aff));
2691 }
2692 res = isl_pw_aff_add_piece(res, set,
2693 isl_aff_copy(pwaff1->p[i].aff));
2694 }
2695
2696 for (j = 0; j < pwaff2->n; ++j) {
39
Loop condition is true. Entering loop body
2697 set = isl_set_copy(pwaff2->p[j].set);
2698 for (i = 0; i < pwaff1->n; ++i)
40
Loop condition is true. Entering loop body
41
Loop condition is true. Entering loop body
42
Loop condition is false. Execution continues on line 2701
2699 set = isl_set_subtract(set,
2700 isl_set_copy(pwaff1->p[i].set));
2701 res = isl_pw_aff_add_piece(res, set,
2702 isl_aff_copy(pwaff2->p[j].aff));
43
Use of memory after it is freed
2703 }
2704
2705 isl_pw_aff_free(pwaff1);
2706 isl_pw_aff_free(pwaff2);
2707
2708 return res;
2709error:
2710 isl_pw_aff_free(pwaff1);
2711 isl_pw_aff_free(pwaff2);
2712 return NULL((void*)0);
2713}
2714
2715/* Compute a piecewise quasi-affine expression with a domain that
2716 * is the union of those of pwaff1 and pwaff2 and such that on each
2717 * cell, the quasi-affine expression is the maximum of those of pwaff1
2718 * and pwaff2. If only one of pwaff1 or pwaff2 is defined on a given
2719 * cell, then the associated expression is the defined one.
2720 */
2721static __isl_give isl_pw_aff *pw_aff_union_max(__isl_take isl_pw_aff *pwaff1,
2722 __isl_take isl_pw_aff *pwaff2)
2723{
2724 return pw_aff_union_opt(pwaff1, pwaff2, &isl_aff_ge_basic_set);
2725}
2726
2727__isl_give isl_pw_aff *isl_pw_aff_union_max(__isl_take isl_pw_aff *pwaff1,
2728 __isl_take isl_pw_aff *pwaff2)
2729{
2730 return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2,
2731 &pw_aff_union_max);
2732}
2733
2734/* Compute a piecewise quasi-affine expression with a domain that
2735 * is the union of those of pwaff1 and pwaff2 and such that on each
2736 * cell, the quasi-affine expression is the minimum of those of pwaff1
2737 * and pwaff2. If only one of pwaff1 or pwaff2 is defined on a given
2738 * cell, then the associated expression is the defined one.
2739 */
2740static __isl_give isl_pw_aff *pw_aff_union_min(__isl_take isl_pw_aff *pwaff1,
2741 __isl_take isl_pw_aff *pwaff2)
2742{
2743 return pw_aff_union_opt(pwaff1, pwaff2, &isl_aff_le_basic_set);
1
Calling 'pw_aff_union_opt'
2744}
2745
2746__isl_give isl_pw_aff *isl_pw_aff_union_min(__isl_take isl_pw_aff *pwaff1,
2747 __isl_take isl_pw_aff *pwaff2)
2748{
2749 return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2,
2750 &pw_aff_union_min);
2751}
2752
2753__isl_give isl_pw_aff *isl_pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1,
2754 __isl_take isl_pw_aff *pwaff2, int max)
2755{
2756 if (max)
2757 return isl_pw_aff_union_max(pwaff1, pwaff2);
2758 else
2759 return isl_pw_aff_union_min(pwaff1, pwaff2);
2760}
2761
2762/* Construct a map with as domain the domain of pwaff and
2763 * one-dimensional range corresponding to the affine expressions.
2764 */
2765static __isl_give isl_map *map_from_pw_aff(__isl_take isl_pw_aff *pwaff)
2766{
2767 int i;
2768 isl_space *dim;
2769 isl_map *map;
2770
2771 if (!pwaff)
2772 return NULL((void*)0);
2773
2774 dim = isl_pw_aff_get_space(pwaff);
2775 map = isl_map_empty(dim);
2776
2777 for (i = 0; i < pwaff->n; ++i) {
2778 isl_basic_map *bmap;
2779 isl_map *map_i;
2780
2781 bmap = isl_basic_map_from_aff(isl_aff_copy(pwaff->p[i].aff));
2782 map_i = isl_map_from_basic_map(bmap);
2783 map_i = isl_map_intersect_domain(map_i,
2784 isl_set_copy(pwaff->p[i].set));
2785 map = isl_map_union_disjoint(map, map_i);
2786 }
2787
2788 isl_pw_aff_free(pwaff);
2789
2790 return map;
2791}
2792
2793/* Construct a map with as domain the domain of pwaff and
2794 * one-dimensional range corresponding to the affine expressions.
2795 */
2796__isl_give isl_map *isl_map_from_pw_aff(__isl_take isl_pw_aff *pwaff)
2797{
2798 if (!pwaff)
2799 return NULL((void*)0);
2800 if (isl_space_is_set(pwaff->dim))
2801 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pwaff), isl_error_invalid
, "space of input is not a map", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2802); goto error; } while (0)
2802 "space of input is not a map", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pwaff), isl_error_invalid
, "space of input is not a map", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2802); goto error; } while (0)
;
2803 return map_from_pw_aff(pwaff);
2804error:
2805 isl_pw_aff_free(pwaff);
2806 return NULL((void*)0);
2807}
2808
2809/* Construct a one-dimensional set with as parameter domain
2810 * the domain of pwaff and the single set dimension
2811 * corresponding to the affine expressions.
2812 */
2813__isl_give isl_setisl_map *isl_set_from_pw_aff(__isl_take isl_pw_aff *pwaff)
2814{
2815 if (!pwaff)
2816 return NULL((void*)0);
2817 if (!isl_space_is_set(pwaff->dim))
2818 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pwaff), isl_error_invalid
, "space of input is not a set", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2819); goto error; } while (0)
2819 "space of input is not a set", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pwaff), isl_error_invalid
, "space of input is not a set", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 2819); goto error; } while (0)
;
2820 return map_from_pw_aff(pwaff);
2821error:
2822 isl_pw_aff_free(pwaff);
2823 return NULL((void*)0);
2824}
2825
2826/* Return a set containing those elements in the domain
2827 * of "pwaff" where it satisfies "fn" (if complement is 0) or
2828 * does not satisfy "fn" (if complement is 1).
2829 *
2830 * The pieces with a NaN never belong to the result since
2831 * NaN does not satisfy any property.
2832 */
2833static __isl_give isl_setisl_map *pw_aff_locus(__isl_take isl_pw_aff *pwaff,
2834 __isl_give isl_basic_setisl_basic_map *(*fn)(__isl_take isl_aff *aff, int rational),
2835 int complement)
2836{
2837 int i;
2838 isl_setisl_map *set;
2839
2840 if (!pwaff)
2841 return NULL((void*)0);
2842
2843 set = isl_set_empty(isl_pw_aff_get_domain_space(pwaff));
2844
2845 for (i = 0; i < pwaff->n; ++i) {
2846 isl_basic_setisl_basic_map *bset;
2847 isl_setisl_map *set_i, *locus;
2848 int rational;
2849
2850 if (isl_aff_is_nan(pwaff->p[i].aff))
2851 continue;
2852
2853 rational = isl_set_has_rational(pwaff->p[i].set);
2854 bset = fn(isl_aff_copy(pwaff->p[i].aff), rational);
2855 locus = isl_set_from_basic_set(bset);
2856 set_i = isl_set_copy(pwaff->p[i].set);
2857 if (complement)
2858 set_i = isl_set_subtract(set_i, locus);
2859 else
2860 set_i = isl_set_intersect(set_i, locus);
2861 set = isl_set_union_disjoint(set, set_i);
2862 }
2863
2864 isl_pw_aff_free(pwaff);
2865
2866 return set;
2867}
2868
2869/* Return a set containing those elements in the domain
2870 * of "pa" where it is positive.
2871 */
2872__isl_give isl_setisl_map *isl_pw_aff_pos_set(__isl_take isl_pw_aff *pa)
2873{
2874 return pw_aff_locus(pa, &aff_pos_basic_set, 0);
2875}
2876
2877/* Return a set containing those elements in the domain
2878 * of pwaff where it is non-negative.
2879 */
2880__isl_give isl_setisl_map *isl_pw_aff_nonneg_set(__isl_take isl_pw_aff *pwaff)
2881{
2882 return pw_aff_locus(pwaff, &aff_nonneg_basic_set, 0);
2883}
2884
2885/* Return a set containing those elements in the domain
2886 * of pwaff where it is zero.
2887 */
2888__isl_give isl_setisl_map *isl_pw_aff_zero_set(__isl_take isl_pw_aff *pwaff)
2889{
2890 return pw_aff_locus(pwaff, &aff_zero_basic_set, 0);
2891}
2892
2893/* Return a set containing those elements in the domain
2894 * of pwaff where it is not zero.
2895 */
2896__isl_give isl_setisl_map *isl_pw_aff_non_zero_set(__isl_take isl_pw_aff *pwaff)
2897{
2898 return pw_aff_locus(pwaff, &aff_zero_basic_set, 1);
2899}
2900
2901/* Return a set containing those elements in the shared domain
2902 * of pwaff1 and pwaff2 where pwaff1 is greater than (or equal) to pwaff2.
2903 *
2904 * We compute the difference on the shared domain and then construct
2905 * the set of values where this difference is non-negative.
2906 * If strict is set, we first subtract 1 from the difference.
2907 * If equal is set, we only return the elements where pwaff1 and pwaff2
2908 * are equal.
2909 */
2910static __isl_give isl_setisl_map *pw_aff_gte_set(__isl_take isl_pw_aff *pwaff1,
2911 __isl_take isl_pw_aff *pwaff2, int strict, int equal)
2912{
2913 isl_setisl_map *set1, *set2;
2914
2915 set1 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff1));
2916 set2 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff2));
2917 set1 = isl_set_intersect(set1, set2);
2918 pwaff1 = isl_pw_aff_intersect_domain(pwaff1, isl_set_copy(set1));
2919 pwaff2 = isl_pw_aff_intersect_domain(pwaff2, isl_set_copy(set1));
2920 pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_neg(pwaff2));
2921
2922 if (strict) {
2923 isl_space *dim = isl_set_get_space(set1);
2924 isl_aff *aff;
2925 aff = isl_aff_zero_on_domain(isl_local_space_from_space(dim));
2926 aff = isl_aff_add_constant_si(aff, -1);
2927 pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_alloc(set1, aff));
2928 } else
2929 isl_set_free(set1);
2930
2931 if (equal)
2932 return isl_pw_aff_zero_set(pwaff1);
2933 return isl_pw_aff_nonneg_set(pwaff1);
2934}
2935
2936/* Return a set containing those elements in the shared domain
2937 * of pwaff1 and pwaff2 where pwaff1 is equal to pwaff2.
2938 */
2939static __isl_give isl_setisl_map *pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1,
2940 __isl_take isl_pw_aff *pwaff2)
2941{
2942 return pw_aff_gte_set(pwaff1, pwaff2, 0, 1);
2943}
2944
2945__isl_give isl_setisl_map *isl_pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1,
2946 __isl_take isl_pw_aff *pwaff2)
2947{
2948 return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_eq_set);
2949}
2950
2951/* Return a set containing those elements in the shared domain
2952 * of pwaff1 and pwaff2 where pwaff1 is greater than or equal to pwaff2.
2953 */
2954static __isl_give isl_setisl_map *pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1,
2955 __isl_take isl_pw_aff *pwaff2)
2956{
2957 return pw_aff_gte_set(pwaff1, pwaff2, 0, 0);
2958}
2959
2960__isl_give isl_setisl_map *isl_pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1,
2961 __isl_take isl_pw_aff *pwaff2)
2962{
2963 return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_ge_set);
2964}
2965
2966/* Return a set containing those elements in the shared domain
2967 * of pwaff1 and pwaff2 where pwaff1 is strictly greater than pwaff2.
2968 */
2969static __isl_give isl_setisl_map *pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1,
2970 __isl_take isl_pw_aff *pwaff2)
2971{
2972 return pw_aff_gte_set(pwaff1, pwaff2, 1, 0);
2973}
2974
2975__isl_give isl_setisl_map *isl_pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1,
2976 __isl_take isl_pw_aff *pwaff2)
2977{
2978 return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_gt_set);
2979}
2980
2981__isl_give isl_setisl_map *isl_pw_aff_le_set(__isl_take isl_pw_aff *pwaff1,
2982 __isl_take isl_pw_aff *pwaff2)
2983{
2984 return isl_pw_aff_ge_set(pwaff2, pwaff1);
2985}
2986
2987__isl_give isl_setisl_map *isl_pw_aff_lt_set(__isl_take isl_pw_aff *pwaff1,
2988 __isl_take isl_pw_aff *pwaff2)
2989{
2990 return isl_pw_aff_gt_set(pwaff2, pwaff1);
2991}
2992
2993/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
2994 * where the function values are ordered in the same way as "order",
2995 * which returns a set in the shared domain of its two arguments.
2996 * The parameters of "pa1" and "pa2" are assumed to have been aligned.
2997 *
2998 * Let "pa1" and "pa2" be defined on domains A and B respectively.
2999 * We first pull back the two functions such that they are defined on
3000 * the domain [A -> B]. Then we apply "order", resulting in a set
3001 * in the space [A -> B]. Finally, we unwrap this set to obtain
3002 * a map in the space A -> B.
3003 */
3004static __isl_give isl_map *isl_pw_aff_order_map_aligned(
3005 __isl_take isl_pw_aff *pa1, __isl_take isl_pw_aff *pa2,
3006 __isl_give isl_setisl_map *(*order)(__isl_take isl_pw_aff *pa1,
3007 __isl_take isl_pw_aff *pa2))
3008{
3009 isl_space *space1, *space2;
3010 isl_multi_aff *ma;
3011 isl_setisl_map *set;
3012
3013 space1 = isl_space_domain(isl_pw_aff_get_space(pa1));
3014 space2 = isl_space_domain(isl_pw_aff_get_space(pa2));
3015 space1 = isl_space_map_from_domain_and_range(space1, space2);
3016 ma = isl_multi_aff_domain_map(isl_space_copy(space1));
3017 pa1 = isl_pw_aff_pullback_multi_aff(pa1, ma);
3018 ma = isl_multi_aff_range_map(space1);
3019 pa2 = isl_pw_aff_pullback_multi_aff(pa2, ma);
3020 set = order(pa1, pa2);
3021
3022 return isl_set_unwrap(set);
3023}
3024
3025/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
3026 * where the function values are equal.
3027 * The parameters of "pa1" and "pa2" are assumed to have been aligned.
3028 */
3029static __isl_give isl_map *isl_pw_aff_eq_map_aligned(__isl_take isl_pw_aff *pa1,
3030 __isl_take isl_pw_aff *pa2)
3031{
3032 return isl_pw_aff_order_map_aligned(pa1, pa2, &isl_pw_aff_eq_set);
3033}
3034
3035/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
3036 * where the function values are equal.
3037 */
3038__isl_give isl_map *isl_pw_aff_eq_map(__isl_take isl_pw_aff *pa1,
3039 __isl_take isl_pw_aff *pa2)
3040{
3041 return align_params_pw_pw_map_and(pa1, pa2, &isl_pw_aff_eq_map_aligned);
3042}
3043
3044/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
3045 * where the function value of "pa1" is less than the function value of "pa2".
3046 * The parameters of "pa1" and "pa2" are assumed to have been aligned.
3047 */
3048static __isl_give isl_map *isl_pw_aff_lt_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_lt_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 less than the function value of "pa2".
3056 */
3057__isl_give isl_map *isl_pw_aff_lt_map(__isl_take isl_pw_aff *pa1,
3058 __isl_take isl_pw_aff *pa2)
3059{
3060 return align_params_pw_pw_map_and(pa1, pa2, &isl_pw_aff_lt_map_aligned);
3061}
3062
3063/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
3064 * where the function value of "pa1" is greater than the function value
3065 * of "pa2".
3066 * The parameters of "pa1" and "pa2" are assumed to have been aligned.
3067 */
3068static __isl_give isl_map *isl_pw_aff_gt_map_aligned(__isl_take isl_pw_aff *pa1,
3069 __isl_take isl_pw_aff *pa2)
3070{
3071 return isl_pw_aff_order_map_aligned(pa1, pa2, &isl_pw_aff_gt_set);
3072}
3073
3074/* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
3075 * where the function value of "pa1" is greater than the function value
3076 * of "pa2".
3077 */
3078__isl_give isl_map *isl_pw_aff_gt_map(__isl_take isl_pw_aff *pa1,
3079 __isl_take isl_pw_aff *pa2)
3080{
3081 return align_params_pw_pw_map_and(pa1, pa2, &isl_pw_aff_gt_map_aligned);
3082}
3083
3084/* Return a set containing those elements in the shared domain
3085 * of the elements of list1 and list2 where each element in list1
3086 * has the relation specified by "fn" with each element in list2.
3087 */
3088static __isl_give isl_setisl_map *pw_aff_list_set(__isl_take isl_pw_aff_list *list1,
3089 __isl_take isl_pw_aff_list *list2,
3090 __isl_give isl_setisl_map *(*fn)(__isl_take isl_pw_aff *pwaff1,
3091 __isl_take isl_pw_aff *pwaff2))
3092{
3093 int i, j;
3094 isl_ctx *ctx;
3095 isl_setisl_map *set;
3096
3097 if (!list1 || !list2)
3098 goto error;
3099
3100 ctx = isl_pw_aff_list_get_ctx(list1);
3101 if (list1->n < 1 || list2->n < 1)
3102 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "list should contain at least one element"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3103); goto error; } while (0)
3103 "list should contain at least one element", goto error)do { isl_handle_error(ctx, isl_error_invalid, "list should contain at least one element"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3103); goto error; } while (0)
;
3104
3105 set = isl_set_universe(isl_pw_aff_get_domain_space(list1->p[0]));
3106 for (i = 0; i < list1->n; ++i)
3107 for (j = 0; j < list2->n; ++j) {
3108 isl_setisl_map *set_ij;
3109
3110 set_ij = fn(isl_pw_aff_copy(list1->p[i]),
3111 isl_pw_aff_copy(list2->p[j]));
3112 set = isl_set_intersect(set, set_ij);
3113 }
3114
3115 isl_pw_aff_list_free(list1);
3116 isl_pw_aff_list_free(list2);
3117 return set;
3118error:
3119 isl_pw_aff_list_free(list1);
3120 isl_pw_aff_list_free(list2);
3121 return NULL((void*)0);
3122}
3123
3124/* Return a set containing those elements in the shared domain
3125 * of the elements of list1 and list2 where each element in list1
3126 * is equal to each element in list2.
3127 */
3128__isl_give isl_setisl_map *isl_pw_aff_list_eq_set(__isl_take isl_pw_aff_list *list1,
3129 __isl_take isl_pw_aff_list *list2)
3130{
3131 return pw_aff_list_set(list1, list2, &isl_pw_aff_eq_set);
3132}
3133
3134__isl_give isl_setisl_map *isl_pw_aff_list_ne_set(__isl_take isl_pw_aff_list *list1,
3135 __isl_take isl_pw_aff_list *list2)
3136{
3137 return pw_aff_list_set(list1, list2, &isl_pw_aff_ne_set);
3138}
3139
3140/* Return a set containing those elements in the shared domain
3141 * of the elements of list1 and list2 where each element in list1
3142 * is less than or equal to each element in list2.
3143 */
3144__isl_give isl_setisl_map *isl_pw_aff_list_le_set(__isl_take isl_pw_aff_list *list1,
3145 __isl_take isl_pw_aff_list *list2)
3146{
3147 return pw_aff_list_set(list1, list2, &isl_pw_aff_le_set);
3148}
3149
3150__isl_give isl_setisl_map *isl_pw_aff_list_lt_set(__isl_take isl_pw_aff_list *list1,
3151 __isl_take isl_pw_aff_list *list2)
3152{
3153 return pw_aff_list_set(list1, list2, &isl_pw_aff_lt_set);
3154}
3155
3156__isl_give isl_setisl_map *isl_pw_aff_list_ge_set(__isl_take isl_pw_aff_list *list1,
3157 __isl_take isl_pw_aff_list *list2)
3158{
3159 return pw_aff_list_set(list1, list2, &isl_pw_aff_ge_set);
3160}
3161
3162__isl_give isl_setisl_map *isl_pw_aff_list_gt_set(__isl_take isl_pw_aff_list *list1,
3163 __isl_take isl_pw_aff_list *list2)
3164{
3165 return pw_aff_list_set(list1, list2, &isl_pw_aff_gt_set);
3166}
3167
3168
3169/* Return a set containing those elements in the shared domain
3170 * of pwaff1 and pwaff2 where pwaff1 is not equal to pwaff2.
3171 */
3172static __isl_give isl_setisl_map *pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1,
3173 __isl_take isl_pw_aff *pwaff2)
3174{
3175 isl_setisl_map *set_lt, *set_gt;
3176
3177 set_lt = isl_pw_aff_lt_set(isl_pw_aff_copy(pwaff1),
3178 isl_pw_aff_copy(pwaff2));
3179 set_gt = isl_pw_aff_gt_set(pwaff1, pwaff2);
3180 return isl_set_union_disjoint(set_lt, set_gt);
3181}
3182
3183__isl_give isl_setisl_map *isl_pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1,
3184 __isl_take isl_pw_aff *pwaff2)
3185{
3186 return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_ne_set);
3187}
3188
3189__isl_give isl_pw_aff *isl_pw_aff_scale_downisl_gmp_pw_aff_scale_down(__isl_take isl_pw_aff *pwaff,
3190 isl_int v)
3191{
3192 int i;
3193
3194 if (isl_int_is_one(v)(impz_cmp_si(v,1) == 0))
3195 return pwaff;
3196 if (!isl_int_is_pos(v)(impz_sgn(v) > 0))
3197 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3199); return isl_pw_aff_free(pwaff); } while (0)
3198 "factor needs to be positive",do { isl_handle_error(isl_pw_aff_get_ctx(pwaff), isl_error_invalid
, "factor needs to be positive", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3199); return isl_pw_aff_free(pwaff); } while (0)
3199 return isl_pw_aff_free(pwaff))do { isl_handle_error(isl_pw_aff_get_ctx(pwaff), isl_error_invalid
, "factor needs to be positive", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3199); return isl_pw_aff_free(pwaff); } while (0)
;
3200 pwaff = isl_pw_aff_cow(pwaff);
3201 if (!pwaff)
3202 return NULL((void*)0);
3203 if (pwaff->n == 0)
3204 return pwaff;
3205
3206 for (i = 0; i < pwaff->n; ++i) {
3207 pwaff->p[i].aff = isl_aff_scale_downisl_gmp_aff_scale_down(pwaff->p[i].aff, v);
3208 if (!pwaff->p[i].aff)
3209 return isl_pw_aff_free(pwaff);
3210 }
3211
3212 return pwaff;
3213}
3214
3215__isl_give isl_pw_aff *isl_pw_aff_floor(__isl_take isl_pw_aff *pwaff)
3216{
3217 int i;
3218
3219 pwaff = isl_pw_aff_cow(pwaff);
3220 if (!pwaff)
3221 return NULL((void*)0);
3222 if (pwaff->n == 0)
3223 return pwaff;
3224
3225 for (i = 0; i < pwaff->n; ++i) {
3226 pwaff->p[i].aff = isl_aff_floor(pwaff->p[i].aff);
3227 if (!pwaff->p[i].aff)
3228 return isl_pw_aff_free(pwaff);
3229 }
3230
3231 return pwaff;
3232}
3233
3234__isl_give isl_pw_aff *isl_pw_aff_ceil(__isl_take isl_pw_aff *pwaff)
3235{
3236 int i;
3237
3238 pwaff = isl_pw_aff_cow(pwaff);
3239 if (!pwaff)
3240 return NULL((void*)0);
3241 if (pwaff->n == 0)
3242 return pwaff;
3243
3244 for (i = 0; i < pwaff->n; ++i) {
3245 pwaff->p[i].aff = isl_aff_ceil(pwaff->p[i].aff);
3246 if (!pwaff->p[i].aff)
3247 return isl_pw_aff_free(pwaff);
3248 }
3249
3250 return pwaff;
3251}
3252
3253/* Assuming that "cond1" and "cond2" are disjoint,
3254 * return an affine expression that is equal to pwaff1 on cond1
3255 * and to pwaff2 on cond2.
3256 */
3257static __isl_give isl_pw_aff *isl_pw_aff_select(
3258 __isl_take isl_setisl_map *cond1, __isl_take isl_pw_aff *pwaff1,
3259 __isl_take isl_setisl_map *cond2, __isl_take isl_pw_aff *pwaff2)
3260{
3261 pwaff1 = isl_pw_aff_intersect_domain(pwaff1, cond1);
3262 pwaff2 = isl_pw_aff_intersect_domain(pwaff2, cond2);
3263
3264 return isl_pw_aff_add_disjoint(pwaff1, pwaff2);
3265}
3266
3267/* Return an affine expression that is equal to pwaff_true for elements
3268 * where "cond" is non-zero and to pwaff_false for elements where "cond"
3269 * is zero.
3270 * That is, return cond ? pwaff_true : pwaff_false;
3271 *
3272 * If "cond" involves and NaN, then we conservatively return a NaN
3273 * on its entire domain. In principle, we could consider the pieces
3274 * where it is NaN separately from those where it is not.
3275 */
3276__isl_give isl_pw_aff *isl_pw_aff_cond(__isl_take isl_pw_aff *cond,
3277 __isl_take isl_pw_aff *pwaff_true, __isl_take isl_pw_aff *pwaff_false)
3278{
3279 isl_setisl_map *cond_true, *cond_false;
3280
3281 if (!cond)
3282 goto error;
3283 if (isl_pw_aff_involves_nan(cond)) {
3284 isl_space *space = isl_pw_aff_get_domain_space(cond);
3285 isl_local_space *ls = isl_local_space_from_space(space);
3286 isl_pw_aff_free(cond);
3287 isl_pw_aff_free(pwaff_true);
3288 isl_pw_aff_free(pwaff_false);
3289 return isl_pw_aff_nan_on_domain(ls);
3290 }
3291
3292 cond_true = isl_pw_aff_non_zero_set(isl_pw_aff_copy(cond));
3293 cond_false = isl_pw_aff_zero_set(cond);
3294 return isl_pw_aff_select(cond_true, pwaff_true,
3295 cond_false, pwaff_false);
3296error:
3297 isl_pw_aff_free(cond);
3298 isl_pw_aff_free(pwaff_true);
3299 isl_pw_aff_free(pwaff_false);
3300 return NULL((void*)0);
3301}
3302
3303isl_bool isl_aff_is_cst(__isl_keep isl_aff *aff)
3304{
3305 if (!aff)
3306 return isl_bool_error;
3307
3308 return isl_seq_first_non_zero(aff->v->el + 2, aff->v->size - 2) == -1;
3309}
3310
3311/* Check whether pwaff is a piecewise constant.
3312 */
3313isl_bool isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff)
3314{
3315 int i;
3316
3317 if (!pwaff)
3318 return isl_bool_error;
3319
3320 for (i = 0; i < pwaff->n; ++i) {
3321 isl_bool is_cst = isl_aff_is_cst(pwaff->p[i].aff);
3322 if (is_cst < 0 || !is_cst)
3323 return is_cst;
3324 }
3325
3326 return isl_bool_true;
3327}
3328
3329/* Return the product of "aff1" and "aff2".
3330 *
3331 * If either of the two is NaN, then the result is NaN.
3332 *
3333 * Otherwise, at least one of "aff1" or "aff2" needs to be a constant.
3334 */
3335__isl_give isl_aff *isl_aff_mul(__isl_take isl_aff *aff1,
3336 __isl_take isl_aff *aff2)
3337{
3338 if (!aff1 || !aff2)
3339 goto error;
3340
3341 if (isl_aff_is_nan(aff1)) {
3342 isl_aff_free(aff2);
3343 return aff1;
3344 }
3345 if (isl_aff_is_nan(aff2)) {
3346 isl_aff_free(aff1);
3347 return aff2;
3348 }
3349
3350 if (!isl_aff_is_cst(aff2) && isl_aff_is_cst(aff1))
3351 return isl_aff_mul(aff2, aff1);
3352
3353 if (!isl_aff_is_cst(aff2))
3354 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3356); goto error; } while (0)
3355 "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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3356); goto error; } while (0)
3356 goto error)do { isl_handle_error(isl_aff_get_ctx(aff1), isl_error_invalid
, "at least one affine expression should be constant", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3356); goto error; } while (0)
;
3357
3358 aff1 = isl_aff_cow(aff1);
3359 if (!aff1 || !aff2)
3360 goto error;
3361
3362 aff1 = isl_aff_scaleisl_gmp_aff_scale(aff1, aff2->v->el[1]);
3363 aff1 = isl_aff_scale_downisl_gmp_aff_scale_down(aff1, aff2->v->el[0]);
3364
3365 isl_aff_free(aff2);
3366 return aff1;
3367error:
3368 isl_aff_free(aff1);
3369 isl_aff_free(aff2);
3370 return NULL((void*)0);
3371}
3372
3373/* Divide "aff1" by "aff2", assuming "aff2" is a constant.
3374 *
3375 * If either of the two is NaN, then the result is NaN.
3376 */
3377__isl_give isl_aff *isl_aff_div(__isl_take isl_aff *aff1,
3378 __isl_take isl_aff *aff2)
3379{
3380 int is_cst;
3381 int neg;
3382
3383 if (!aff1 || !aff2)
3384 goto error;
3385
3386 if (isl_aff_is_nan(aff1)) {
3387 isl_aff_free(aff2);
3388 return aff1;
3389 }
3390 if (isl_aff_is_nan(aff2)) {
3391 isl_aff_free(aff1);
3392 return aff2;
3393 }
3394
3395 is_cst = isl_aff_is_cst(aff2);
3396 if (is_cst < 0)
3397 goto error;
3398 if (!is_cst)
3399 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3400); goto error; } while (0)
3400 "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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3400); goto error; } while (0)
;
3401
3402 if (!aff2)
3403 goto error;
3404
3405 neg = isl_int_is_neg(aff2->v->el[1])(impz_sgn(aff2->v->el[1]) < 0);
3406 if (neg) {
3407 isl_int_neg(aff2->v->el[0], aff2->v->el[0])impz_neg(aff2->v->el[0],aff2->v->el[0]);
3408 isl_int_neg(aff2->v->el[1], aff2->v->el[1])impz_neg(aff2->v->el[1],aff2->v->el[1]);
3409 }
3410
3411 aff1 = isl_aff_scaleisl_gmp_aff_scale(aff1, aff2->v->el[0]);
3412 aff1 = isl_aff_scale_downisl_gmp_aff_scale_down(aff1, aff2->v->el[1]);
3413
3414 if (neg) {
3415 isl_int_neg(aff2->v->el[0], aff2->v->el[0])impz_neg(aff2->v->el[0],aff2->v->el[0]);
3416 isl_int_neg(aff2->v->el[1], aff2->v->el[1])impz_neg(aff2->v->el[1],aff2->v->el[1]);
3417 }
3418
3419 isl_aff_free(aff2);
3420 return aff1;
3421error:
3422 isl_aff_free(aff1);
3423 isl_aff_free(aff2);
3424 return NULL((void*)0);
3425}
3426
3427static __isl_give isl_pw_aff *pw_aff_add(__isl_take isl_pw_aff *pwaff1,
3428 __isl_take isl_pw_aff *pwaff2)
3429{
3430 return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_add);
3431}
3432
3433__isl_give isl_pw_aff *isl_pw_aff_add(__isl_take isl_pw_aff *pwaff1,
3434 __isl_take isl_pw_aff *pwaff2)
3435{
3436 return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_add);
3437}
3438
3439__isl_give isl_pw_aff *isl_pw_aff_union_add(__isl_take isl_pw_aff *pwaff1,
3440 __isl_take isl_pw_aff *pwaff2)
3441{
3442 return isl_pw_aff_union_add_(pwaff1, pwaff2);
3443}
3444
3445static __isl_give isl_pw_aff *pw_aff_mul(__isl_take isl_pw_aff *pwaff1,
3446 __isl_take isl_pw_aff *pwaff2)
3447{
3448 return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_mul);
3449}
3450
3451__isl_give isl_pw_aff *isl_pw_aff_mul(__isl_take isl_pw_aff *pwaff1,
3452 __isl_take isl_pw_aff *pwaff2)
3453{
3454 return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_mul);
3455}
3456
3457static __isl_give isl_pw_aff *pw_aff_div(__isl_take isl_pw_aff *pa1,
3458 __isl_take isl_pw_aff *pa2)
3459{
3460 return isl_pw_aff_on_shared_domain(pa1, pa2, &isl_aff_div);
3461}
3462
3463/* Divide "pa1" by "pa2", assuming "pa2" is a piecewise constant.
3464 */
3465__isl_give isl_pw_aff *isl_pw_aff_div(__isl_take isl_pw_aff *pa1,
3466 __isl_take isl_pw_aff *pa2)
3467{
3468 int is_cst;
3469
3470 is_cst = isl_pw_aff_is_cst(pa2);
3471 if (is_cst < 0)
3472 goto error;
3473 if (!is_cst)
3474 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3476); goto error; } while (0)
3475 "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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3476); goto error; } while (0)
3476 goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid
, "second argument should be a piecewise constant", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3476); goto error; } while (0)
;
3477 return isl_pw_aff_align_params_pw_pw_and(pa1, pa2, &pw_aff_div);
3478error:
3479 isl_pw_aff_free(pa1);
3480 isl_pw_aff_free(pa2);
3481 return NULL((void*)0);
3482}
3483
3484/* Compute the quotient of the integer division of "pa1" by "pa2"
3485 * with rounding towards zero.
3486 * "pa2" is assumed to be a piecewise constant.
3487 *
3488 * In particular, return
3489 *
3490 * pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2)
3491 *
3492 */
3493__isl_give isl_pw_aff *isl_pw_aff_tdiv_q(__isl_take isl_pw_aff *pa1,
3494 __isl_take isl_pw_aff *pa2)
3495{
3496 int is_cst;
3497 isl_setisl_map *cond;
3498 isl_pw_aff *f, *c;
3499
3500 is_cst = isl_pw_aff_is_cst(pa2);
3501 if (is_cst < 0)
3502 goto error;
3503 if (!is_cst)
3504 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3506); goto error; } while (0)
3505 "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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3506); goto error; } while (0)
3506 goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid
, "second argument should be a piecewise constant", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3506); goto error; } while (0)
;
3507
3508 pa1 = isl_pw_aff_div(pa1, pa2);
3509
3510 cond = isl_pw_aff_nonneg_set(isl_pw_aff_copy(pa1));
3511 f = isl_pw_aff_floor(isl_pw_aff_copy(pa1));
3512 c = isl_pw_aff_ceil(pa1);
3513 return isl_pw_aff_cond(isl_set_indicator_function(cond), f, c);
3514error:
3515 isl_pw_aff_free(pa1);
3516 isl_pw_aff_free(pa2);
3517 return NULL((void*)0);
3518}
3519
3520/* Compute the remainder of the integer division of "pa1" by "pa2"
3521 * with rounding towards zero.
3522 * "pa2" is assumed to be a piecewise constant.
3523 *
3524 * In particular, return
3525 *
3526 * pa1 - pa2 * (pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2))
3527 *
3528 */
3529__isl_give isl_pw_aff *isl_pw_aff_tdiv_r(__isl_take isl_pw_aff *pa1,
3530 __isl_take isl_pw_aff *pa2)
3531{
3532 int is_cst;
3533 isl_pw_aff *res;
3534
3535 is_cst = isl_pw_aff_is_cst(pa2);
3536 if (is_cst < 0)
3537 goto error;
3538 if (!is_cst)
3539 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3541); goto error; } while (0)
3540 "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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3541); goto error; } while (0)
3541 goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa2), isl_error_invalid
, "second argument should be a piecewise constant", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3541); goto error; } while (0)
;
3542 res = isl_pw_aff_tdiv_q(isl_pw_aff_copy(pa1), isl_pw_aff_copy(pa2));
3543 res = isl_pw_aff_mul(pa2, res);
3544 res = isl_pw_aff_sub(pa1, res);
3545 return res;
3546error:
3547 isl_pw_aff_free(pa1);
3548 isl_pw_aff_free(pa2);
3549 return NULL((void*)0);
3550}
3551
3552static __isl_give isl_pw_aff *pw_aff_min(__isl_take isl_pw_aff *pwaff1,
3553 __isl_take isl_pw_aff *pwaff2)
3554{
3555 isl_setisl_map *le;
3556 isl_setisl_map *dom;
3557
3558 dom = isl_set_intersect(isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)),
3559 isl_pw_aff_domain(isl_pw_aff_copy(pwaff2)));
3560 le = isl_pw_aff_le_set(isl_pw_aff_copy(pwaff1),
3561 isl_pw_aff_copy(pwaff2));
3562 dom = isl_set_subtract(dom, isl_set_copy(le));
3563 return isl_pw_aff_select(le, pwaff1, dom, pwaff2);
3564}
3565
3566__isl_give isl_pw_aff *isl_pw_aff_min(__isl_take isl_pw_aff *pwaff1,
3567 __isl_take isl_pw_aff *pwaff2)
3568{
3569 return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_min);
3570}
3571
3572static __isl_give isl_pw_aff *pw_aff_max(__isl_take isl_pw_aff *pwaff1,
3573 __isl_take isl_pw_aff *pwaff2)
3574{
3575 isl_setisl_map *ge;
3576 isl_setisl_map *dom;
3577
3578 dom = isl_set_intersect(isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)),
3579 isl_pw_aff_domain(isl_pw_aff_copy(pwaff2)));
3580 ge = isl_pw_aff_ge_set(isl_pw_aff_copy(pwaff1),
3581 isl_pw_aff_copy(pwaff2));
3582 dom = isl_set_subtract(dom, isl_set_copy(ge));
3583 return isl_pw_aff_select(ge, pwaff1, dom, pwaff2);
3584}
3585
3586__isl_give isl_pw_aff *isl_pw_aff_max(__isl_take isl_pw_aff *pwaff1,
3587 __isl_take isl_pw_aff *pwaff2)
3588{
3589 return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_max);
3590}
3591
3592static __isl_give isl_pw_aff *pw_aff_list_reduce(
3593 __isl_take isl_pw_aff_list *list,
3594 __isl_give isl_pw_aff *(*fn)(__isl_take isl_pw_aff *pwaff1,
3595 __isl_take isl_pw_aff *pwaff2))
3596{
3597 int i;
3598 isl_ctx *ctx;
3599 isl_pw_aff *res;
3600
3601 if (!list)
3602 return NULL((void*)0);
3603
3604 ctx = isl_pw_aff_list_get_ctx(list);
3605 if (list->n < 1)
3606 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "list should contain at least one element"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3607); goto error; } while (0)
3607 "list should contain at least one element", goto error)do { isl_handle_error(ctx, isl_error_invalid, "list should contain at least one element"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3607); goto error; } while (0)
;
3608
3609 res = isl_pw_aff_copy(list->p[0]);
3610 for (i = 1; i < list->n; ++i)
3611 res = fn(res, isl_pw_aff_copy(list->p[i]));
3612
3613 isl_pw_aff_list_free(list);
3614 return res;
3615error:
3616 isl_pw_aff_list_free(list);
3617 return NULL((void*)0);
3618}
3619
3620/* Return an isl_pw_aff that maps each element in the intersection of the
3621 * domains of the elements of list to the minimal corresponding affine
3622 * expression.
3623 */
3624__isl_give isl_pw_aff *isl_pw_aff_list_min(__isl_take isl_pw_aff_list *list)
3625{
3626 return pw_aff_list_reduce(list, &isl_pw_aff_min);
3627}
3628
3629/* Return an isl_pw_aff that maps each element in the intersection of the
3630 * domains of the elements of list to the maximal corresponding affine
3631 * expression.
3632 */
3633__isl_give isl_pw_aff *isl_pw_aff_list_max(__isl_take isl_pw_aff_list *list)
3634{
3635 return pw_aff_list_reduce(list, &isl_pw_aff_max);
3636}
3637
3638/* Mark the domains of "pwaff" as rational.
3639 */
3640__isl_give isl_pw_aff *isl_pw_aff_set_rational(__isl_take isl_pw_aff *pwaff)
3641{
3642 int i;
3643
3644 pwaff = isl_pw_aff_cow(pwaff);
3645 if (!pwaff)
3646 return NULL((void*)0);
3647 if (pwaff->n == 0)
3648 return pwaff;
3649
3650 for (i = 0; i < pwaff->n; ++i) {
3651 pwaff->p[i].set = isl_set_set_rational(pwaff->p[i].set);
3652 if (!pwaff->p[i].set)
3653 return isl_pw_aff_free(pwaff);
3654 }
3655
3656 return pwaff;
3657}
3658
3659/* Mark the domains of the elements of "list" as rational.
3660 */
3661__isl_give isl_pw_aff_list *isl_pw_aff_list_set_rational(
3662 __isl_take isl_pw_aff_list *list)
3663{
3664 int i, n;
3665
3666 if (!list)
3667 return NULL((void*)0);
3668 if (list->n == 0)
3669 return list;
3670
3671 n = list->n;
3672 for (i = 0; i < n; ++i) {
3673 isl_pw_aff *pa;
3674
3675 pa = isl_pw_aff_list_get_pw_aff(list, i);
3676 pa = isl_pw_aff_set_rational(pa);
3677 list = isl_pw_aff_list_set_pw_aff(list, i, pa);
3678 }
3679
3680 return list;
3681}
3682
3683/* Do the parameters of "aff" match those of "space"?
3684 */
3685int isl_aff_matching_params(__isl_keep isl_aff *aff,
3686 __isl_keep isl_space *space)
3687{
3688 isl_space *aff_space;
3689 int match;
3690
3691 if (!aff || !space)
3692 return -1;
3693
3694 aff_space = isl_aff_get_domain_space(aff);
3695
3696 match = isl_space_match(space, isl_dim_param, aff_space, isl_dim_param);
3697
3698 isl_space_free(aff_space);
3699 return match;
3700}
3701
3702/* Check that the domain space of "aff" matches "space".
3703 *
3704 * Return 0 on success and -1 on error.
3705 */
3706int isl_aff_check_match_domain_space(__isl_keep isl_aff *aff,
3707 __isl_keep isl_space *space)
3708{
3709 isl_space *aff_space;
3710 int match;
3711
3712 if (!aff || !space)
3713 return -1;
3714
3715 aff_space = isl_aff_get_domain_space(aff);
3716
3717 match = isl_space_match(space, isl_dim_param, aff_space, isl_dim_param);
3718 if (match < 0)
3719 goto error;
3720 if (!match)
3721 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3722); goto error; } while (0)
3722 "parameters don't match", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "parameters don't match", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3722); goto error; } while (0)
;
3723 match = isl_space_tuple_is_equal(space, isl_dim_in,
3724 aff_space, isl_dim_set);
3725 if (match < 0)
3726 goto error;
3727 if (!match)
3728 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3729); goto error; } while (0)
3729 "domains don't match", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "domains don't match", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3729); goto error; } while (0)
;
3730 isl_space_free(aff_space);
3731 return 0;
3732error:
3733 isl_space_free(aff_space);
3734 return -1;
3735}
3736
3737#undef BASEunion_pw_aff
3738#define BASEunion_pw_aff aff
3739#undef DOMBASEunion_set
3740#define DOMBASEunion_set set
3741#define NO_DOMAIN
3742
3743#include <isl_multi_templ.c>
3744#include <isl_multi_apply_set.c>
3745#include <isl_multi_floor.c>
3746#include <isl_multi_gist.c>
3747
3748#undef NO_DOMAIN
3749
3750/* Remove any internal structure of the domain of "ma".
3751 * If there is any such internal structure in the input,
3752 * then the name of the corresponding space is also removed.
3753 */
3754__isl_give isl_multi_aff *isl_multi_aff_flatten_domain(
3755 __isl_take isl_multi_aff *ma)
3756{
3757 isl_space *space;
3758
3759 if (!ma)
3760 return NULL((void*)0);
3761
3762 if (!ma->space->nested[0])
3763 return ma;
3764
3765 space = isl_multi_aff_get_space(ma);
3766 space = isl_space_flatten_domain(space);
3767 ma = isl_multi_aff_reset_space(ma, space);
3768
3769 return ma;
3770}
3771
3772/* Given a map space, return an isl_multi_aff that maps a wrapped copy
3773 * of the space to its domain.
3774 */
3775__isl_give isl_multi_aff *isl_multi_aff_domain_map(__isl_take isl_space *space)
3776{
3777 int i, n_in;
3778 isl_local_space *ls;
3779 isl_multi_aff *ma;
3780
3781 if (!space)
3782 return NULL((void*)0);
3783 if (!isl_space_is_map(space))
3784 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3785); goto error; } while (0)
3785 "not a map space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "not a map space", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3785); goto error; } while (0)
;
3786
3787 n_in = isl_space_dim(space, isl_dim_in);
3788 space = isl_space_domain_map(space);
3789
3790 ma = isl_multi_aff_alloc(isl_space_copy(space));
3791 if (n_in == 0) {
3792 isl_space_free(space);
3793 return ma;
3794 }
3795
3796 space = isl_space_domain(space);
3797 ls = isl_local_space_from_space(space);
3798 for (i = 0; i < n_in; ++i) {
3799 isl_aff *aff;
3800
3801 aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
3802 isl_dim_set, i);
3803 ma = isl_multi_aff_set_aff(ma, i, aff);
3804 }
3805 isl_local_space_free(ls);
3806 return ma;
3807error:
3808 isl_space_free(space);
3809 return NULL((void*)0);
3810}
3811
3812/* Given a map space, return an isl_multi_aff that maps a wrapped copy
3813 * of the space to its range.
3814 */
3815__isl_give isl_multi_aff *isl_multi_aff_range_map(__isl_take isl_space *space)
3816{
3817 int i, n_in, n_out;
3818 isl_local_space *ls;
3819 isl_multi_aff *ma;
3820
3821 if (!space)
3822 return NULL((void*)0);
3823 if (!isl_space_is_map(space))
3824 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3825); goto error; } while (0)
3825 "not a map space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "not a map space", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3825); goto error; } while (0)
;
3826
3827 n_in = isl_space_dim(space, isl_dim_in);
3828 n_out = isl_space_dim(space, isl_dim_out);
3829 space = isl_space_range_map(space);
3830
3831 ma = isl_multi_aff_alloc(isl_space_copy(space));
3832 if (n_out == 0) {
3833 isl_space_free(space);
3834 return ma;
3835 }
3836
3837 space = isl_space_domain(space);
3838 ls = isl_local_space_from_space(space);
3839 for (i = 0; i < n_out; ++i) {
3840 isl_aff *aff;
3841
3842 aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
3843 isl_dim_set, n_in + i);
3844 ma = isl_multi_aff_set_aff(ma, i, aff);
3845 }
3846 isl_local_space_free(ls);
3847 return ma;
3848error:
3849 isl_space_free(space);
3850 return NULL((void*)0);
3851}
3852
3853/* Given a map space, return an isl_pw_multi_aff that maps a wrapped copy
3854 * of the space to its range.
3855 */
3856__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map(
3857 __isl_take isl_space *space)
3858{
3859 return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_range_map(space));
3860}
3861
3862/* Given the space of a set and a range of set dimensions,
3863 * construct an isl_multi_aff that projects out those dimensions.
3864 */
3865__isl_give isl_multi_aff *isl_multi_aff_project_out_map(
3866 __isl_take isl_space *space, enum isl_dim_type type,
3867 unsigned first, unsigned n)
3868{
3869 int i, dim;
3870 isl_local_space *ls;
3871 isl_multi_aff *ma;
3872
3873 if (!space)
3874 return NULL((void*)0);
3875 if (!isl_space_is_set(space))
3876 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3877); goto error; } while (0)
3877 "expecting set space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_unsupported
, "expecting set space", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3877); goto error; } while (0)
;
3878 if (type != isl_dim_set)
3879 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3880); goto error; } while (0)
3880 "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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3880); goto error; } while (0)
;
3881
3882 dim = isl_space_dim(space, isl_dim_set);
3883 if (first + n > dim)
3884 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3885); goto error; } while (0)
3885 "range out of bounds", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "range out of bounds", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 3885); goto error; } while (0)
;
3886
3887 space = isl_space_from_domain(space);
3888 space = isl_space_add_dims(space, isl_dim_out, dim - n);
3889
3890 if (dim == n)
3891 return isl_multi_aff_alloc(space);
3892
3893 ma = isl_multi_aff_alloc(isl_space_copy(space));
3894 space = isl_space_domain(space);
3895 ls = isl_local_space_from_space(space);
3896
3897 for (i = 0; i < first; ++i) {
3898 isl_aff *aff;
3899
3900 aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
3901 isl_dim_set, i);
3902 ma = isl_multi_aff_set_aff(ma, i, aff);
3903 }
3904
3905 for (i = 0; i < dim - (first + n); ++i) {
3906 isl_aff *aff;
3907
3908 aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
3909 isl_dim_set, first + n + i);
3910 ma = isl_multi_aff_set_aff(ma, first + i, aff);
3911 }
3912
3913 isl_local_space_free(ls);
3914 return ma;
3915error:
3916 isl_space_free(space);
3917 return NULL((void*)0);
3918}
3919
3920/* Given the space of a set and a range of set dimensions,
3921 * construct an isl_pw_multi_aff that projects out those dimensions.
3922 */
3923__isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_out_map(
3924 __isl_take isl_space *space, enum isl_dim_type type,
3925 unsigned first, unsigned n)
3926{
3927 isl_multi_aff *ma;
3928
3929 ma = isl_multi_aff_project_out_map(space, type, first, n);
3930 return isl_pw_multi_aff_from_multi_aff(ma);
3931}
3932
3933/* Create an isl_pw_multi_aff with the given isl_multi_aff on a universe
3934 * domain.
3935 */
3936__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_aff(
3937 __isl_take isl_multi_aff *ma)
3938{
3939 isl_setisl_map *dom = isl_set_universe(isl_multi_aff_get_domain_space(ma));
3940 return isl_pw_multi_aff_alloc(dom, ma);
3941}
3942
3943/* Create a piecewise multi-affine expression in the given space that maps each
3944 * input dimension to the corresponding output dimension.
3945 */
3946__isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity(
3947 __isl_take isl_space *space)
3948{
3949 return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_identity(space));
3950}
3951
3952/* Add "ma2" to "ma1" and return the result.
3953 *
3954 * The parameters of "ma1" and "ma2" are assumed to have been aligned.
3955 */
3956static __isl_give isl_multi_aff *isl_multi_aff_add_aligned(
3957 __isl_take isl_multi_aff *maff1, __isl_take isl_multi_aff *maff2)
3958{
3959 return isl_multi_aff_bin_op(maff1, maff2, &isl_aff_add);
3960}
3961
3962/* Add "ma2" to "ma1" and return the result.
3963 */
3964__isl_give isl_multi_aff *isl_multi_aff_add(__isl_take isl_multi_aff *ma1,
3965 __isl_take isl_multi_aff *ma2)
3966{
3967 return isl_multi_aff_align_params_multi_multi_and(ma1, ma2,
3968 &isl_multi_aff_add_aligned);
3969}
3970
3971/* Exploit the equalities in "eq" to simplify the affine expressions.
3972 */
3973static __isl_give isl_multi_aff *isl_multi_aff_substitute_equalities(
3974 __isl_take isl_multi_aff *maff, __isl_take isl_basic_setisl_basic_map *eq)
3975{
3976 int i;
3977
3978 maff = isl_multi_aff_cow(maff);
3979 if (!maff || !eq)
3980 goto error;
3981
3982 for (i = 0; i < maff->n; ++i) {
3983 maff->p[i] = isl_aff_substitute_equalities(maff->p[i],
3984 isl_basic_set_copy(eq));
3985 if (!maff->p[i])
3986 goto error;
3987 }
3988
3989 isl_basic_set_free(eq);
3990 return maff;
3991error:
3992 isl_basic_set_free(eq);
3993 isl_multi_aff_free(maff);
3994 return NULL((void*)0);
3995}
3996
3997__isl_give isl_multi_aff *isl_multi_aff_scaleisl_gmp_multi_aff_scale(__isl_take isl_multi_aff *maff,
3998 isl_int f)
3999{
4000 int i;
4001
4002 maff = isl_multi_aff_cow(maff);
4003 if (!maff)
4004 return NULL((void*)0);
4005
4006 for (i = 0; i < maff->n; ++i) {
4007 maff->p[i] = isl_aff_scaleisl_gmp_aff_scale(maff->p[i], f);
4008 if (!maff->p[i])
4009 return isl_multi_aff_free(maff);
4010 }
4011
4012 return maff;
4013}
4014
4015__isl_give isl_multi_aff *isl_multi_aff_add_on_domain(__isl_keep isl_setisl_map *dom,
4016 __isl_take isl_multi_aff *maff1, __isl_take isl_multi_aff *maff2)
4017{
4018 maff1 = isl_multi_aff_add(maff1, maff2);
4019 maff1 = isl_multi_aff_gist(maff1, isl_set_copy(dom));
4020 return maff1;
4021}
4022
4023int isl_multi_aff_is_empty(__isl_keep isl_multi_aff *maff)
4024{
4025 if (!maff)
4026 return -1;
4027
4028 return 0;
4029}
4030
4031/* Return the set of domain elements where "ma1" is lexicographically
4032 * smaller than or equal to "ma2".
4033 */
4034__isl_give isl_setisl_map *isl_multi_aff_lex_le_set(__isl_take isl_multi_aff *ma1,
4035 __isl_take isl_multi_aff *ma2)
4036{
4037 return isl_multi_aff_lex_ge_set(ma2, ma1);
4038}
4039
4040/* Return the set of domain elements where "ma1" is lexicographically
4041 * greater than or equal to "ma2".
4042 */
4043__isl_give isl_setisl_map *isl_multi_aff_lex_ge_set(__isl_take isl_multi_aff *ma1,
4044 __isl_take isl_multi_aff *ma2)
4045{
4046 isl_space *space;
4047 isl_map *map1, *map2;
4048 isl_map *map, *ge;
4049
4050 map1 = isl_map_from_multi_aff(ma1);
4051 map2 = isl_map_from_multi_aff(ma2);
4052 map = isl_map_range_product(map1, map2);
4053 space = isl_space_range(isl_map_get_space(map));
4054 space = isl_space_domain(isl_space_unwrap(space));
4055 ge = isl_map_lex_ge(space);
4056 map = isl_map_intersect_range(map, isl_map_wrap(ge));
4057
4058 return isl_map_domain(map);
4059}
4060
4061#undef PWisl_pw_multi_aff
4062#define PWisl_pw_multi_aff isl_pw_multi_aff
4063#undef ELisl_union_pw_aff
4064#define ELisl_union_pw_aff isl_multi_aff
4065#undef EL_IS_ZEROis_empty
4066#define EL_IS_ZEROis_empty is_empty
4067#undef ZEROempty
4068#define ZEROempty empty
4069#undef IS_ZEROis_empty
4070#define IS_ZEROis_empty is_empty
4071#undef FIELDmaff
4072#define FIELDmaff maff
4073#undef DEFAULT_IS_ZERO0
4074#define DEFAULT_IS_ZERO0 0
4075
4076#define NO_SUB
4077#define NO_EVAL
4078#define NO_OPT
4079#define NO_INVOLVES_DIMS
4080#define NO_INSERT_DIMS
4081#define NO_LIFT
4082#define NO_MORPH
4083
4084#include <isl_pw_templ.c>
4085
4086#undef NO_SUB
4087
4088#undef UNIONisl_union_pw_multi_aff
4089#define UNIONisl_union_pw_multi_aff isl_union_pw_multi_aff
4090#undef PARTisl_pw_multi_aff
4091#define PARTisl_pw_multi_aff isl_pw_multi_aff
4092#undef PARTSpw_multi_aff
4093#define PARTSpw_multi_aff pw_multi_aff
4094
4095#define NO_EVAL
4096
4097#include <isl_union_templ.c>
4098
4099/* Given a function "cmp" that returns the set of elements where
4100 * "ma1" is "better" than "ma2", return the intersection of this
4101 * set with "dom1" and "dom2".
4102 */
4103static __isl_give isl_setisl_map *shared_and_better(__isl_keep isl_setisl_map *dom1,
4104 __isl_keep isl_setisl_map *dom2, __isl_keep isl_multi_aff *ma1,
4105 __isl_keep isl_multi_aff *ma2,
4106 __isl_give isl_setisl_map *(*cmp)(__isl_take isl_multi_aff *ma1,
4107 __isl_take isl_multi_aff *ma2))
4108{
4109 isl_setisl_map *common;
4110 isl_setisl_map *better;
4111 int is_empty;
4112
4113 common = isl_set_intersect(isl_set_copy(dom1), isl_set_copy(dom2));
4114 is_empty = isl_set_plain_is_empty(common);
4115 if (is_empty >= 0 && is_empty)
4116 return common;
4117 if (is_empty < 0)
4118 return isl_set_free(common);
4119 better = cmp(isl_multi_aff_copy(ma1), isl_multi_aff_copy(ma2));
4120 better = isl_set_intersect(common, better);
4121
4122 return better;
4123}
4124
4125/* Given a function "cmp" that returns the set of elements where
4126 * "ma1" is "better" than "ma2", return a piecewise multi affine
4127 * expression defined on the union of the definition domains
4128 * of "pma1" and "pma2" that maps to the "best" of "pma1" and
4129 * "pma2" on each cell. If only one of the two input functions
4130 * is defined on a given cell, then it is considered the best.
4131 */
4132static __isl_give isl_pw_multi_aff *pw_multi_aff_union_opt(
4133 __isl_take isl_pw_multi_aff *pma1,
4134 __isl_take isl_pw_multi_aff *pma2,
4135 __isl_give isl_setisl_map *(*cmp)(__isl_take isl_multi_aff *ma1,
4136 __isl_take isl_multi_aff *ma2))
4137{
4138 int i, j, n;
4139 isl_pw_multi_aff *res = NULL((void*)0);
4140 isl_ctx *ctx;
4141 isl_setisl_map *set = NULL((void*)0);
4142
4143 if (!pma1 || !pma2)
4144 goto error;
4145
4146 ctx = isl_space_get_ctx(pma1->dim);
4147 if (!isl_space_is_equal(pma1->dim, pma2->dim))
4148 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "arguments should live in the same space"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 4149); goto error; } while (0)
4149 "arguments should live in the same space", goto error)do { isl_handle_error(ctx, isl_error_invalid, "arguments should live in the same space"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 4149); goto error; } while (0)
;
4150
4151 if (isl_pw_multi_aff_is_empty(pma1)) {
4152 isl_pw_multi_aff_free(pma1);
4153 return pma2;
4154 }
4155
4156 if (isl_pw_multi_aff_is_empty(pma2)) {
4157 isl_pw_multi_aff_free(pma2);
4158 return pma1;
4159 }
4160
4161 n = 2 * (pma1->n + 1) * (pma2->n + 1);
4162 res = isl_pw_multi_aff_alloc_size(isl_space_copy(pma1->dim), n);
4163
4164 for (i = 0; i < pma1->n; ++i) {
4165 set = isl_set_copy(pma1->p[i].set);
4166 for (j = 0; j < pma2->n; ++j) {
4167 isl_setisl_map *better;
4168 int is_empty;
4169
4170 better = shared_and_better(pma2->p[j].set,
4171 pma1->p[i].set, pma2->p[j].maff,
4172 pma1->p[i].maff, cmp);
4173 is_empty = isl_set_plain_is_empty(better);
4174 if (is_empty < 0 || is_empty) {
4175 isl_set_free(better);
4176 if (is_empty < 0)
4177 goto error;
4178 continue;
4179 }
4180 set = isl_set_subtract(set, isl_set_copy(better));
4181
4182 res = isl_pw_multi_aff_add_piece(res, better,
4183 isl_multi_aff_copy(pma2->p[j].maff));
4184 }
4185 res = isl_pw_multi_aff_add_piece(res, set,
4186 isl_multi_aff_copy(pma1->p[i].maff));
4187 }
4188
4189 for (j = 0; j < pma2->n; ++j) {
4190 set = isl_set_copy(pma2->p[j].set);
4191 for (i = 0; i < pma1->n; ++i)
4192 set = isl_set_subtract(set,
4193 isl_set_copy(pma1->p[i].set));
4194 res = isl_pw_multi_aff_add_piece(res, set,
4195 isl_multi_aff_copy(pma2->p[j].maff));
4196 }
4197
4198 isl_pw_multi_aff_free(pma1);
4199 isl_pw_multi_aff_free(pma2);
4200
4201 return res;
4202error:
4203 isl_pw_multi_aff_free(pma1);
4204 isl_pw_multi_aff_free(pma2);
4205 isl_set_free(set);
4206 return isl_pw_multi_aff_free(res);
4207}
4208
4209static __isl_give isl_pw_multi_aff *pw_multi_aff_union_lexmax(
4210 __isl_take isl_pw_multi_aff *pma1,
4211 __isl_take isl_pw_multi_aff *pma2)
4212{
4213 return pw_multi_aff_union_opt(pma1, pma2, &isl_multi_aff_lex_ge_set);
4214}
4215
4216/* Given two piecewise multi affine expressions, return a piecewise
4217 * multi-affine expression defined on the union of the definition domains
4218 * of the inputs that is equal to the lexicographic maximum of the two
4219 * inputs on each cell. If only one of the two inputs is defined on
4220 * a given cell, then it is considered to be the maximum.
4221 */
4222__isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmax(
4223 __isl_take isl_pw_multi_aff *pma1,
4224 __isl_take isl_pw_multi_aff *pma2)
4225{
4226 return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
4227 &pw_multi_aff_union_lexmax);
4228}
4229
4230static __isl_give isl_pw_multi_aff *pw_multi_aff_union_lexmin(
4231 __isl_take isl_pw_multi_aff *pma1,
4232 __isl_take isl_pw_multi_aff *pma2)
4233{
4234 return pw_multi_aff_union_opt(pma1, pma2, &isl_multi_aff_lex_le_set);
4235}
4236
4237/* Given two piecewise multi affine expressions, return a piecewise
4238 * multi-affine expression defined on the union of the definition domains
4239 * of the inputs that is equal to the lexicographic minimum of the two
4240 * inputs on each cell. If only one of the two inputs is defined on
4241 * a given cell, then it is considered to be the minimum.
4242 */
4243__isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmin(
4244 __isl_take isl_pw_multi_aff *pma1,
4245 __isl_take isl_pw_multi_aff *pma2)
4246{
4247 return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
4248 &pw_multi_aff_union_lexmin);
4249}
4250
4251static __isl_give isl_pw_multi_aff *pw_multi_aff_add(
4252 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4253{
4254 return isl_pw_multi_aff_on_shared_domain(pma1, pma2,
4255 &isl_multi_aff_add);
4256}
4257
4258__isl_give isl_pw_multi_aff *isl_pw_multi_aff_add(
4259 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4260{
4261 return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
4262 &pw_multi_aff_add);
4263}
4264
4265static __isl_give isl_pw_multi_aff *pw_multi_aff_sub(
4266 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4267{
4268 return isl_pw_multi_aff_on_shared_domain(pma1, pma2,
4269 &isl_multi_aff_sub);
4270}
4271
4272/* Subtract "pma2" from "pma1" and return the result.
4273 */
4274__isl_give isl_pw_multi_aff *isl_pw_multi_aff_sub(
4275 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4276{
4277 return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
4278 &pw_multi_aff_sub);
4279}
4280
4281__isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_add(
4282 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4283{
4284 return isl_pw_multi_aff_union_add_(pma1, pma2);
4285}
4286
4287/* Compute the sum of "upa1" and "upa2" on the union of their domains,
4288 * with the actual sum on the shared domain and
4289 * the defined expression on the symmetric difference of the domains.
4290 */
4291__isl_give isl_union_pw_aff *isl_union_pw_aff_union_add(
4292 __isl_take isl_union_pw_aff *upa1, __isl_take isl_union_pw_aff *upa2)
4293{
4294 return isl_union_pw_aff_union_add_(upa1, upa2);
4295}
4296
4297/* Compute the sum of "upma1" and "upma2" on the union of their domains,
4298 * with the actual sum on the shared domain and
4299 * the defined expression on the symmetric difference of the domains.
4300 */
4301__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_union_add(
4302 __isl_take isl_union_pw_multi_aff *upma1,
4303 __isl_take isl_union_pw_multi_aff *upma2)
4304{
4305 return isl_union_pw_multi_aff_union_add_(upma1, upma2);
4306}
4307
4308/* Given two piecewise multi-affine expressions A -> B and C -> D,
4309 * construct a piecewise multi-affine expression [A -> C] -> [B -> D].
4310 */
4311static __isl_give isl_pw_multi_aff *pw_multi_aff_product(
4312 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4313{
4314 int i, j, n;
4315 isl_space *space;
4316 isl_pw_multi_aff *res;
4317
4318 if (!pma1 || !pma2)
4319 goto error;
4320
4321 n = pma1->n * pma2->n;
4322 space = isl_space_product(isl_space_copy(pma1->dim),
4323 isl_space_copy(pma2->dim));
4324 res = isl_pw_multi_aff_alloc_size(space, n);
4325
4326 for (i = 0; i < pma1->n; ++i) {
4327 for (j = 0; j < pma2->n; ++j) {
4328 isl_setisl_map *domain;
4329 isl_multi_aff *ma;
4330
4331 domain = isl_set_product(isl_set_copy(pma1->p[i].set),
4332 isl_set_copy(pma2->p[j].set));
4333 ma = isl_multi_aff_product(
4334 isl_multi_aff_copy(pma1->p[i].maff),
4335 isl_multi_aff_copy(pma2->p[j].maff));
4336 res = isl_pw_multi_aff_add_piece(res, domain, ma);
4337 }
4338 }
4339
4340 isl_pw_multi_aff_free(pma1);
4341 isl_pw_multi_aff_free(pma2);
4342 return res;
4343error:
4344 isl_pw_multi_aff_free(pma1);
4345 isl_pw_multi_aff_free(pma2);
4346 return NULL((void*)0);
4347}
4348
4349__isl_give isl_pw_multi_aff *isl_pw_multi_aff_product(
4350 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
4351{
4352 return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
4353 &pw_multi_aff_product);
4354}
4355
4356/* Construct a map mapping the domain of the piecewise multi-affine expression
4357 * to its range, with each dimension in the range equated to the
4358 * corresponding affine expression on its cell.
4359 */
4360__isl_give isl_map *isl_map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma)
4361{
4362 int i;
4363 isl_map *map;
4364
4365 if (!pma)
4366 return NULL((void*)0);
4367
4368 map = isl_map_empty(isl_pw_multi_aff_get_space(pma));
4369
4370 for (i = 0; i < pma->n; ++i) {
4371 isl_multi_aff *maff;
4372 isl_basic_map *bmap;
4373 isl_map *map_i;
4374
4375 maff = isl_multi_aff_copy(pma->p[i].maff);
4376 bmap = isl_basic_map_from_multi_aff(maff);
4377 map_i = isl_map_from_basic_map(bmap);
4378 map_i = isl_map_intersect_domain(map_i,
4379 isl_set_copy(pma->p[i].set));
4380 map = isl_map_union_disjoint(map, map_i);
4381 }
4382
4383 isl_pw_multi_aff_free(pma);
4384 return map;
4385}
4386
4387__isl_give isl_setisl_map *isl_set_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma)
4388{
4389 if (!pma)
4390 return NULL((void*)0);
4391
4392 if (!isl_space_is_set(pma->dim))
4393 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
, "isl_pw_multi_aff cannot be converted into an isl_set", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 4395); goto error; } while (0)
4394 "isl_pw_multi_aff cannot be converted into an isl_set",do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "isl_pw_multi_aff cannot be converted into an isl_set", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 4395); goto error; } while (0)
4395 goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "isl_pw_multi_aff cannot be converted into an isl_set", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 4395); goto error; } while (0)
;
4396
4397 return isl_map_from_pw_multi_aff(pma);
4398error:
4399 isl_pw_multi_aff_free(pma);
4400 return NULL((void*)0);
4401}
4402
4403/* Given a basic map with a single output dimension that is defined
4404 * in terms of the parameters and input dimensions using an equality,
4405 * extract an isl_aff that expresses the output dimension in terms
4406 * of the parameters and input dimensions.
4407 * Note that this expression may involve integer divisions defined
4408 * in terms of parameters and input dimensions.
4409 *
4410 * This function shares some similarities with
4411 * isl_basic_map_has_defining_equality and isl_constraint_get_bound.
4412 */
4413static __isl_give isl_aff *extract_isl_aff_from_basic_map(
4414 __isl_take isl_basic_map *bmap)
4415{
4416 int eq;
4417 unsigned offset;
4418 unsigned n_div;
4419 isl_local_space *ls;
4420 isl_aff *aff;
4421
4422 if (!bmap)
4423 return NULL((void*)0);
4424 if (isl_basic_map_dim(bmap, isl_dim_out) != 1)
4425 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "basic map should have a single output dimension", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 4427); goto error; } while (0)
4426 "basic map should have a single output dimension",do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "basic map should have a single output dimension", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 4427); goto error; } while (0)
4427 goto error)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "basic map should have a single output dimension", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 4427); goto error; } while (0)
;
4428 eq = isl_basic_map_output_defining_equality(bmap, 0);
4429 if (eq >= bmap->n_eq)
4430 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 4431); goto error; } while (0)
4431 "unable to find suitable equality", goto error)do { isl_handle_error(isl_basic_map_get_ctx(bmap), isl_error_invalid
, "unable to find suitable equality", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 4431); goto error; } while (0)
;
4432 ls = isl_basic_map_get_local_space(bmap);
4433 aff = isl_aff_alloc(isl_local_space_domain(ls));
4434 if (!aff)
4435 goto error;
4436 offset = isl_basic_map_offset(bmap, isl_dim_out);
4437 n_div = isl_basic_map_dim(bmap, isl_dim_div);
4438 if (isl_int_is_neg(bmap->eq[eq][offset])(impz_sgn(bmap->eq[eq][offset]) < 0)) {
4439 isl_seq_cpy(aff->v->el + 1, bmap->eq[eq], offset);
4440 isl_seq_cpy(aff->v->el + 1 + offset, bmap->eq[eq] + offset + 1,
4441 n_div);
4442 } else {
4443 isl_seq_neg(aff->v->el + 1, bmap->eq[eq], offset);
4444 isl_seq_neg(aff->v->el + 1 + offset, bmap->eq[eq] + offset + 1,
4445 n_div);
4446 }
4447 isl_int_abs(aff->v->el[0], bmap->eq[eq][offset])impz_abs(aff->v->el[0],bmap->eq[eq][offset]);
4448 isl_basic_map_free(bmap);
4449
4450 aff = isl_aff_remove_unused_divs(aff);
4451 return aff;
4452error:
4453 isl_basic_map_free(bmap);
4454 return NULL((void*)0);
4455}
4456
4457/* Given a basic map where each output dimension is defined
4458 * in terms of the parameters and input dimensions using an equality,
4459 * extract an isl_multi_aff that expresses the output dimensions in terms
4460 * of the parameters and input dimensions.
4461 */
4462static __isl_give isl_multi_aff *extract_isl_multi_aff_from_basic_map(
4463 __isl_take isl_basic_map *bmap)
4464{
4465 int i;
4466 unsigned n_out;
4467 isl_multi_aff *ma;
4468
4469 if (!bmap)
4470 return NULL((void*)0);
4471
4472 ma = isl_multi_aff_alloc(isl_basic_map_get_space(bmap));
4473 n_out = isl_basic_map_dim(bmap, isl_dim_out);
4474
4475 for (i = 0; i < n_out; ++i) {
4476 isl_basic_map *bmap_i;
4477 isl_aff *aff;
4478
4479 bmap_i = isl_basic_map_copy(bmap);
4480 bmap_i = isl_basic_map_project_out(bmap_i, isl_dim_out,
4481 i + 1, n_out - (1 + i));
4482 bmap_i = isl_basic_map_project_out(bmap_i, isl_dim_out, 0, i);
4483 aff = extract_isl_aff_from_basic_map(bmap_i);
4484 ma = isl_multi_aff_set_aff(ma, i, aff);
4485 }
4486
4487 isl_basic_map_free(bmap);
4488
4489 return ma;
4490}
4491
4492/* Given a basic set where each set dimension is defined
4493 * in terms of the parameters using an equality,
4494 * extract an isl_multi_aff that expresses the set dimensions in terms
4495 * of the parameters.
4496 */
4497__isl_give isl_multi_aff *isl_multi_aff_from_basic_set_equalities(
4498 __isl_take isl_basic_setisl_basic_map *bset)
4499{
4500 return extract_isl_multi_aff_from_basic_map(bset);
4501}
4502
4503/* Create an isl_pw_multi_aff that is equivalent to
4504 * isl_map_intersect_domain(isl_map_from_basic_map(bmap), domain).
4505 * The given basic map is such that each output dimension is defined
4506 * in terms of the parameters and input dimensions using an equality.
4507 *
4508 * Since some applications expect the result of isl_pw_multi_aff_from_map
4509 * to only contain integer affine expressions, we compute the floor
4510 * of the expression before returning.
4511 */
4512static __isl_give isl_pw_multi_aff *plain_pw_multi_aff_from_map(
4513 __isl_take isl_setisl_map *domain, __isl_take isl_basic_map *bmap)
4514{
4515 isl_multi_aff *ma;
4516
4517 ma = extract_isl_multi_aff_from_basic_map(bmap);
4518 ma = isl_multi_aff_floor(ma);
4519 return isl_pw_multi_aff_alloc(domain, ma);
4520}
4521
4522/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
4523 * This obviously only works if the input "map" is single-valued.
4524 * If so, we compute the lexicographic minimum of the image in the form
4525 * of an isl_pw_multi_aff. Since the image is unique, it is equal
4526 * to its lexicographic minimum.
4527 * If the input is not single-valued, we produce an error.
4528 */
4529static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_base(
4530 __isl_take isl_map *map)
4531{
4532 int i;
4533 int sv;
4534 isl_pw_multi_aff *pma;
4535
4536 sv = isl_map_is_single_valued(map);
4537 if (sv < 0)
4538 goto error;
4539 if (!sv)
4540 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 4541); goto error; } while (0)
4541 "map is not single-valued", goto error)do { isl_handle_error(isl_map_get_ctx(map), isl_error_invalid
, "map is not single-valued", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 4541); goto error; } while (0)
;
4542 map = isl_map_make_disjoint(map);
4543 if (!map)
4544 return NULL((void*)0);
4545
4546 pma = isl_pw_multi_aff_empty(isl_map_get_space(map));
4547
4548 for (i = 0; i < map->n; ++i) {
4549 isl_pw_multi_aff *pma_i;
4550 isl_basic_map *bmap;
4551 bmap = isl_basic_map_copy(map->p[i]);
4552 pma_i = isl_basic_map_lexmin_pw_multi_aff(bmap);
4553 pma = isl_pw_multi_aff_add_disjoint(pma, pma_i);
4554 }
4555
4556 isl_map_free(map);
4557 return pma;
4558error:
4559 isl_map_free(map);
4560 return NULL((void*)0);
4561}
4562
4563/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map,
4564 * taking into account that the output dimension at position "d"
4565 * can be represented as
4566 *
4567 * x = floor((e(...) + c1) / m)
4568 *
4569 * given that constraint "i" is of the form
4570 *
4571 * e(...) + c1 - m x >= 0
4572 *
4573 *
4574 * Let "map" be of the form
4575 *
4576 * A -> B
4577 *
4578 * We construct a mapping
4579 *
4580 * A -> [A -> x = floor(...)]
4581 *
4582 * apply that to the map, obtaining
4583 *
4584 * [A -> x = floor(...)] -> B
4585 *
4586 * and equate dimension "d" to x.
4587 * We then compute a isl_pw_multi_aff representation of the resulting map
4588 * and plug in the mapping above.
4589 */
4590static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_div(
4591 __isl_take isl_map *map, __isl_take isl_basic_map *hull, int d, int i)
4592{
4593 isl_ctx *ctx;
4594 isl_space *space;
4595 isl_local_space *ls;
4596 isl_multi_aff *ma;
4597 isl_aff *aff;
4598 isl_vec *v;
4599 isl_map *insert;
4600 int offset;
4601 int n;
4602 int n_in;
4603 isl_pw_multi_aff *pma;
4604 int is_set;
4605
4606 is_set = isl_map_is_set(map);
4607
4608 offset = isl_basic_map_offset(hull, isl_dim_out);
4609 ctx = isl_map_get_ctx(map);
4610 space = isl_space_domain(isl_map_get_space(map));
4611 n_in = isl_space_dim(space, isl_dim_set);
4612 n = isl_space_dim(space, isl_dim_all);
4613
4614 v = isl_vec_alloc(ctx, 1 + 1 + n);
4615 if (v) {
4616 isl_int_neg(v->el[0], hull->ineq[i][offset + d])impz_neg(v->el[0],hull->ineq[i][offset + d]);
4617 isl_seq_cpy(v->el + 1, hull->ineq[i], 1 + n);
4618 }
4619 isl_basic_map_free(hull);
4620
4621 ls = isl_local_space_from_space(isl_space_copy(space));
4622 aff = isl_aff_alloc_vec(ls, v);
4623 aff = isl_aff_floor(aff);
4624 if (is_set) {
4625 isl_space_free(space);
4626 ma = isl_multi_aff_from_aff(aff);
4627 } else {
4628 ma = isl_multi_aff_identity(isl_space_map_from_set(space));
4629 ma = isl_multi_aff_range_product(ma,
4630 isl_multi_aff_from_aff(aff));
4631 }
4632
4633 insert = isl_map_from_multi_aff(isl_multi_aff_copy(ma));
4634 map = isl_map_apply_domain(map, insert);
4635 map = isl_map_equate(map, isl_dim_in, n_in, isl_dim_out, d);
4636 pma = isl_pw_multi_aff_from_map(map);
4637 pma = isl_pw_multi_aff_pullback_multi_aff(pma, ma);
4638
4639 return pma;
4640}
4641
4642/* Is constraint "c" of the form
4643 *
4644 * e(...) + c1 - m x >= 0
4645 *
4646 * or
4647 *
4648 * -e(...) + c2 + m x >= 0
4649 *
4650 * where m > 1 and e only depends on parameters and input dimemnsions?
4651 *
4652 * "offset" is the offset of the output dimensions
4653 * "pos" is the position of output dimension x.
4654 */
4655static int is_potential_div_constraint(isl_int *c, int offset, int d, int total)
4656{
4657 if (isl_int_is_zero(c[offset + d])(impz_sgn(c[offset + d]) == 0))
4658 return 0;
4659 if (isl_int_is_one(c[offset + d])(impz_cmp_si(c[offset + d],1) == 0))
4660 return 0;
4661 if (isl_int_is_negone(c[offset + d])(impz_cmp_si(c[offset + d],-1) == 0))
4662 return 0;
4663 if (isl_seq_first_non_zero(c + offset, d) != -1)
4664 return 0;
4665 if (isl_seq_first_non_zero(c + offset + d + 1,
4666 total - (offset + d + 1)) != -1)
4667 return 0;
4668 return 1;
4669}
4670
4671/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
4672 *
4673 * As a special case, we first check if there is any pair of constraints,
4674 * shared by all the basic maps in "map" that force a given dimension
4675 * to be equal to the floor of some affine combination of the input dimensions.
4676 *
4677 * In particular, if we can find two constraints
4678 *
4679 * e(...) + c1 - m x >= 0 i.e., m x <= e(...) + c1
4680 *
4681 * and
4682 *
4683 * -e(...) + c2 + m x >= 0 i.e., m x >= e(...) - c2
4684 *
4685 * where m > 1 and e only depends on parameters and input dimemnsions,
4686 * and such that
4687 *
4688 * c1 + c2 < m i.e., -c2 >= c1 - (m - 1)
4689 *
4690 * then we know that we can take
4691 *
4692 * x = floor((e(...) + c1) / m)
4693 *
4694 * without having to perform any computation.
4695 *
4696 * Note that we know that
4697 *
4698 * c1 + c2 >= 1
4699 *
4700 * If c1 + c2 were 0, then we would have detected an equality during
4701 * simplification. If c1 + c2 were negative, then we would have detected
4702 * a contradiction.
4703 */
4704static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_check_div(
4705 __isl_take isl_map *map)
4706{
4707 int d, dim;
4708 int i, j, n;
4709 int offset, total;
4710 isl_int sum;
4711 isl_basic_map *hull;
4712
4713 hull = isl_map_unshifted_simple_hull(isl_map_copy(map));
4714 if (!hull)
4715 goto error;
4716
4717 isl_int_init(sum)sum = mp_int_alloc();
4718 dim = isl_map_dim(map, isl_dim_out);
4719 offset = isl_basic_map_offset(hull, isl_dim_out);
4720 total = 1 + isl_basic_map_total_dim(hull);
4721 n = hull->n_ineq;
4722 for (d = 0; d < dim; ++d) {
4723 for (i = 0; i < n; ++i) {
4724 if (!is_potential_div_constraint(hull->ineq[i],
4725 offset, d, total))
4726 continue;
4727 for (j = i + 1; j < n; ++j) {
4728 if (!isl_seq_is_neg(hull->ineq[i] + 1,
4729 hull->ineq[j] + 1, total - 1))
4730 continue;
4731 isl_int_add(sum, hull->ineq[i][0],impz_add(sum,hull->ineq[i][0],hull->ineq[j][0])
4732 hull->ineq[j][0])impz_add(sum,hull->ineq[i][0],hull->ineq[j][0]);
4733 if (isl_int_abs_lt(sum,(impz_cmpabs(sum,hull->ineq[i][offset + d]) < 0)
4734 hull->ineq[i][offset + d])(impz_cmpabs(sum,hull->ineq[i][offset + d]) < 0))
4735 break;
4736
4737 }
4738 if (j >= n)
4739 continue;
4740 isl_int_clear(sum)mp_int_free(sum);
4741 if (isl_int_is_pos(hull->ineq[j][offset + d])(impz_sgn(hull->ineq[j][offset + d]) > 0))
4742 j = i;
4743 return pw_multi_aff_from_map_div(map, hull, d, j);
4744 }
4745 }
4746 isl_int_clear(sum)mp_int_free(sum);
4747 isl_basic_map_free(hull);
4748 return pw_multi_aff_from_map_base(map);
4749error:
4750 isl_map_free(map);
4751 isl_basic_map_free(hull);
4752 return NULL((void*)0);
4753}
4754
4755/* Given an affine expression
4756 *
4757 * [A -> B] -> f(A,B)
4758 *
4759 * construct an isl_multi_aff
4760 *
4761 * [A -> B] -> B'
4762 *
4763 * such that dimension "d" in B' is set to "aff" and the remaining
4764 * dimensions are set equal to the corresponding dimensions in B.
4765 * "n_in" is the dimension of the space A.
4766 * "n_out" is the dimension of the space B.
4767 *
4768 * If "is_set" is set, then the affine expression is of the form
4769 *
4770 * [B] -> f(B)
4771 *
4772 * and we construct an isl_multi_aff
4773 *
4774 * B -> B'
4775 */
4776static __isl_give isl_multi_aff *range_map(__isl_take isl_aff *aff, int d,
4777 unsigned n_in, unsigned n_out, int is_set)
4778{
4779 int i;
4780 isl_multi_aff *ma;
4781 isl_space *space, *space2;
4782 isl_local_space *ls;
4783
4784 space = isl_aff_get_domain_space(aff);
4785 ls = isl_local_space_from_space(isl_space_copy(space));
4786 space2 = isl_space_copy(space);
4787 if (!is_set)
4788 space2 = isl_space_range(isl_space_unwrap(space2));
4789 space = isl_space_map_from_domain_and_range(space, space2);
4790 ma = isl_multi_aff_alloc(space);
4791 ma = isl_multi_aff_set_aff(ma, d, aff);
4792
4793 for (i = 0; i < n_out; ++i) {
4794 if (i == d)
4795 continue;
4796 aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
4797 isl_dim_set, n_in + i);
4798 ma = isl_multi_aff_set_aff(ma, i, aff);
4799 }
4800
4801 isl_local_space_free(ls);
4802
4803 return ma;
4804}
4805
4806/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map,
4807 * taking into account that the dimension at position "d" can be written as
4808 *
4809 * x = m a + f(..) (1)
4810 *
4811 * where m is equal to "gcd".
4812 * "i" is the index of the equality in "hull" that defines f(..).
4813 * In particular, the equality is of the form
4814 *
4815 * f(..) - x + m g(existentials) = 0
4816 *
4817 * or
4818 *
4819 * -f(..) + x + m g(existentials) = 0
4820 *
4821 * We basically plug (1) into "map", resulting in a map with "a"
4822 * in the range instead of "x". The corresponding isl_pw_multi_aff
4823 * defining "a" is then plugged back into (1) to obtain a definition fro "x".
4824 *
4825 * Specifically, given the input map
4826 *
4827 * A -> B
4828 *
4829 * We first wrap it into a set
4830 *
4831 * [A -> B]
4832 *
4833 * and define (1) on top of the corresponding space, resulting in "aff".
4834 * We use this to create an isl_multi_aff that maps the output position "d"
4835 * from "a" to "x", leaving all other (intput and output) dimensions unchanged.
4836 * We plug this into the wrapped map, unwrap the result and compute the
4837 * corresponding isl_pw_multi_aff.
4838 * The result is an expression
4839 *
4840 * A -> T(A)
4841 *
4842 * We adjust that to
4843 *
4844 * A -> [A -> T(A)]
4845 *
4846 * so that we can plug that into "aff", after extending the latter to
4847 * a mapping
4848 *
4849 * [A -> B] -> B'
4850 *
4851 *
4852 * If "map" is actually a set, then there is no "A" space, meaning
4853 * that we do not need to perform any wrapping, and that the result
4854 * of the recursive call is of the form
4855 *
4856 * [T]
4857 *
4858 * which is plugged into a mapping of the form
4859 *
4860 * B -> B'
4861 */
4862static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_stride(
4863 __isl_take isl_map *map, __isl_take isl_basic_map *hull, int d, int i,
4864 isl_int gcd)
4865{
4866 isl_setisl_map *set;
4867 isl_space *space;
4868 isl_local_space *ls;
4869 isl_aff *aff;
4870 isl_multi_aff *ma;
4871 isl_pw_multi_aff *pma, *id;
4872 unsigned n_in;
4873 unsigned o_out;
4874 unsigned n_out;
4875 int is_set;
4876
4877 is_set = isl_map_is_set(map);
4878
4879 n_in = isl_basic_map_dim(hull, isl_dim_in);
4880 n_out = isl_basic_map_dim(hull, isl_dim_out);
4881 o_out = isl_basic_map_offset(hull, isl_dim_out);
4882
4883 if (is_set)
4884 set = map;
4885 else
4886 set = isl_map_wrap(map);
4887 space = isl_space_map_from_set(isl_set_get_space(set));
4888 ma = isl_multi_aff_identity(space);
4889 ls = isl_local_space_from_space(isl_set_get_space(set));
4890 aff = isl_aff_alloc(ls);
4891 if (aff) {
4892 isl_int_set_si(aff->v->el[0], 1)impz_set_si(aff->v->el[0],1);
4893 if (isl_int_is_one(hull->eq[i][o_out + d])(impz_cmp_si(hull->eq[i][o_out + d],1) == 0))
4894 isl_seq_neg(aff->v->el + 1, hull->eq[i],
4895 aff->v->size - 1);
4896 else
4897 isl_seq_cpy(aff->v->el + 1, hull->eq[i],
4898 aff->v->size - 1);
4899 isl_int_set(aff->v->el[1 + o_out + d], gcd)impz_set(aff->v->el[1 + o_out + d],gcd);
4900 }
4901 ma = isl_multi_aff_set_aff(ma, n_in + d, isl_aff_copy(aff));
4902 set = isl_set_preimage_multi_aff(set, ma);
4903
4904 ma = range_map(aff, d, n_in, n_out, is_set);
4905
4906 if (is_set)
4907 map = set;
4908 else
4909 map = isl_set_unwrap(set);
4910 pma = isl_pw_multi_aff_from_map(map);
4911
4912 if (!is_set) {
4913 space = isl_pw_multi_aff_get_domain_space(pma);
4914 space = isl_space_map_from_set(space);
4915 id = isl_pw_multi_aff_identity(space);
4916 pma = isl_pw_multi_aff_range_product(id, pma);
4917 }
4918 id = isl_pw_multi_aff_from_multi_aff(ma);
4919 pma = isl_pw_multi_aff_pullback_pw_multi_aff(id, pma);
4920
4921 isl_basic_map_free(hull);
4922 return pma;
4923}
4924
4925/* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
4926 *
4927 * As a special case, we first check if all output dimensions are uniquely
4928 * defined in terms of the parameters and input dimensions over the entire
4929 * domain. If so, we extract the desired isl_pw_multi_aff directly
4930 * from the affine hull of "map" and its domain.
4931 *
4932 * Otherwise, we check if any of the output dimensions is "strided".
4933 * That is, we check if can be written as
4934 *
4935 * x = m a + f(..)
4936 *
4937 * with m greater than 1, a some combination of existentiall quantified
4938 * variables and f and expression in the parameters and input dimensions.
4939 * If so, we remove the stride in pw_multi_aff_from_map_stride.
4940 *
4941 * Otherwise, we continue with pw_multi_aff_from_map_check_div for a further
4942 * special case.
4943 */
4944__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map)
4945{
4946 int i, j;
4947 int sv;
4948 isl_basic_map *hull;
4949 unsigned n_out;
4950 unsigned o_out;
4951 unsigned n_div;
4952 unsigned o_div;
4953 isl_int gcd;
4954
4955 if (!map)
4956 return NULL((void*)0);
4957
4958 hull = isl_map_affine_hull(isl_map_copy(map));
4959 sv = isl_basic_map_plain_is_single_valued(hull);
4960 if (sv >= 0 && sv)
4961 return plain_pw_multi_aff_from_map(isl_map_domain(map), hull);
4962 if (sv < 0)
4963 hull = isl_basic_map_free(hull);
4964 if (!hull)
4965 goto error;
4966
4967 n_div = isl_basic_map_dim(hull, isl_dim_div);
4968 o_div = isl_basic_map_offset(hull, isl_dim_div);
4969
4970 if (n_div == 0) {
4971 isl_basic_map_free(hull);
4972 return pw_multi_aff_from_map_check_div(map);
4973 }
4974
4975 isl_int_init(gcd)gcd = mp_int_alloc();
4976
4977 n_out = isl_basic_map_dim(hull, isl_dim_out);
4978 o_out = isl_basic_map_offset(hull, isl_dim_out);
4979
4980 for (i = 0; i < n_out; ++i) {
4981 for (j = 0; j < hull->n_eq; ++j) {
4982 isl_int *eq = hull->eq[j];
4983 isl_pw_multi_aff *res;
4984
4985 if (!isl_int_is_one(eq[o_out + i])(impz_cmp_si(eq[o_out + i],1) == 0) &&
4986 !isl_int_is_negone(eq[o_out + i])(impz_cmp_si(eq[o_out + i],-1) == 0))
4987 continue;
4988 if (isl_seq_first_non_zero(eq + o_out, i) != -1)
4989 continue;
4990 if (isl_seq_first_non_zero(eq + o_out + i + 1,
4991 n_out - (i + 1)) != -1)
4992 continue;
4993 isl_seq_gcd(eq + o_div, n_div, &gcd);
4994 if (isl_int_is_zero(gcd)(impz_sgn(gcd) == 0))
4995 continue;
4996 if (isl_int_is_one(gcd)(impz_cmp_si(gcd,1) == 0))
4997 continue;
4998
4999 res = pw_multi_aff_from_map_stride(map, hull,
5000 i, j, gcd);
5001 isl_int_clear(gcd)mp_int_free(gcd);
5002 return res;
5003 }
5004 }
5005
5006 isl_int_clear(gcd)mp_int_free(gcd);
5007 isl_basic_map_free(hull);
5008 return pw_multi_aff_from_map_check_div(map);
5009error:
5010 isl_map_free(map);
5011 return NULL((void*)0);
5012}
5013
5014__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(__isl_take isl_setisl_map *set)
5015{
5016 return isl_pw_multi_aff_from_map(set);
5017}
5018
5019/* Convert "map" into an isl_pw_multi_aff (if possible) and
5020 * add it to *user.
5021 */
5022static isl_stat pw_multi_aff_from_map(__isl_take isl_map *map, void *user)
5023{
5024 isl_union_pw_multi_aff **upma = user;
5025 isl_pw_multi_aff *pma;
5026
5027 pma = isl_pw_multi_aff_from_map(map);
5028 *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
5029
5030 return *upma ? isl_stat_ok : isl_stat_error;
5031}
5032
5033/* Create an isl_union_pw_multi_aff with the given isl_aff on a universe
5034 * domain.
5035 */
5036__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_aff(
5037 __isl_take isl_aff *aff)
5038{
5039 isl_multi_aff *ma;
5040 isl_pw_multi_aff *pma;
5041
5042 ma = isl_multi_aff_from_aff(aff);
5043 pma = isl_pw_multi_aff_from_multi_aff(ma);
5044 return isl_union_pw_multi_aff_from_pw_multi_aff(pma);
5045}
5046
5047/* Try and create an isl_union_pw_multi_aff that is equivalent
5048 * to the given isl_union_map.
5049 * The isl_union_map is required to be single-valued in each space.
5050 * Otherwise, an error is produced.
5051 */
5052__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_map(
5053 __isl_take isl_union_map *umap)
5054{
5055 isl_space *space;
5056 isl_union_pw_multi_aff *upma;
5057
5058 space = isl_union_map_get_space(umap);
5059 upma = isl_union_pw_multi_aff_empty(space);
5060 if (isl_union_map_foreach_map(umap, &pw_multi_aff_from_map, &upma) < 0)
5061 upma = isl_union_pw_multi_aff_free(upma);
5062 isl_union_map_free(umap);
5063
5064 return upma;
5065}
5066
5067/* Try and create an isl_union_pw_multi_aff that is equivalent
5068 * to the given isl_union_set.
5069 * The isl_union_set is required to be a singleton in each space.
5070 * Otherwise, an error is produced.
5071 */
5072__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_set(
5073 __isl_take isl_union_setisl_union_map *uset)
5074{
5075 return isl_union_pw_multi_aff_from_union_map(uset);
5076}
5077
5078/* Return the piecewise affine expression "set ? 1 : 0".
5079 */
5080__isl_give isl_pw_aff *isl_set_indicator_function(__isl_take isl_setisl_map *set)
5081{
5082 isl_pw_aff *pa;
5083 isl_space *space = isl_set_get_space(set);
5084 isl_local_space *ls = isl_local_space_from_space(space);
5085 isl_aff *zero = isl_aff_zero_on_domain(isl_local_space_copy(ls));
5086 isl_aff *one = isl_aff_zero_on_domain(ls);
5087
5088 one = isl_aff_add_constant_si(one, 1);
5089 pa = isl_pw_aff_alloc(isl_set_copy(set), one);
5090 set = isl_set_complement(set);
5091 pa = isl_pw_aff_add_disjoint(pa, isl_pw_aff_alloc(set, zero));
5092
5093 return pa;
5094}
5095
5096/* Plug in "subs" for dimension "type", "pos" of "aff".
5097 *
5098 * Let i be the dimension to replace and let "subs" be of the form
5099 *
5100 * f/d
5101 *
5102 * and "aff" of the form
5103 *
5104 * (a i + g)/m
5105 *
5106 * The result is
5107 *
5108 * (a f + d g')/(m d)
5109 *
5110 * where g' is the result of plugging in "subs" in each of the integer
5111 * divisions in g.
5112 */
5113__isl_give isl_aff *isl_aff_substitute(__isl_take isl_aff *aff,
5114 enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
5115{
5116 isl_ctx *ctx;
5117 isl_int v;
5118
5119 aff = isl_aff_cow(aff);
5120 if (!aff || !subs)
5121 return isl_aff_free(aff);
5122
5123 ctx = isl_aff_get_ctx(aff);
5124 if (!isl_space_is_equal(aff->ls->dim, subs->ls->dim))
5125 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 5126); return isl_aff_free(aff); } while (0)
5126 "spaces don't match", return isl_aff_free(aff))do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 5126); return isl_aff_free(aff); } while (0)
;
5127 if (isl_local_space_dim(subs->ls, isl_dim_div) != 0)
5128 isl_die(ctx, isl_error_unsupported,do { isl_handle_error(ctx, isl_error_unsupported, "cannot handle divs yet"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 5129); return isl_aff_free(aff); } while (0)
5129 "cannot handle divs yet", return isl_aff_free(aff))do { isl_handle_error(ctx, isl_error_unsupported, "cannot handle divs yet"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 5129); return isl_aff_free(aff); } while (0)
;
5130
5131 aff->ls = isl_local_space_substitute(aff->ls, type, pos, subs);
5132 if (!aff->ls)
5133 return isl_aff_free(aff);
5134
5135 aff->v = isl_vec_cow(aff->v);
5136 if (!aff->v)
5137 return isl_aff_free(aff);
5138
5139 pos += isl_local_space_offset(aff->ls, type);
5140
5141 isl_int_init(v)v = mp_int_alloc();
5142 isl_seq_substitute(aff->v->el, pos, subs->v->el,
5143 aff->v->size, subs->v->size, v);
5144 isl_int_clear(v)mp_int_free(v);
5145
5146 return aff;
5147}
5148
5149/* Plug in "subs" for dimension "type", "pos" in each of the affine
5150 * expressions in "maff".
5151 */
5152__isl_give isl_multi_aff *isl_multi_aff_substitute(
5153 __isl_take isl_multi_aff *maff, enum isl_dim_type type, unsigned pos,
5154 __isl_keep isl_aff *subs)
5155{
5156 int i;
5157
5158 maff = isl_multi_aff_cow(maff);
5159 if (!maff || !subs)
5160 return isl_multi_aff_free(maff);
5161
5162 if (type == isl_dim_in)
5163 type = isl_dim_set;
5164
5165 for (i = 0; i < maff->n; ++i) {
5166 maff->p[i] = isl_aff_substitute(maff->p[i], type, pos, subs);
5167 if (!maff->p[i])
5168 return isl_multi_aff_free(maff);
5169 }
5170
5171 return maff;
5172}
5173
5174/* Plug in "subs" for dimension "type", "pos" of "pma".
5175 *
5176 * pma is of the form
5177 *
5178 * A_i(v) -> M_i(v)
5179 *
5180 * while subs is of the form
5181 *
5182 * v' = B_j(v) -> S_j
5183 *
5184 * Each pair i,j such that C_ij = A_i \cap B_i is non-empty
5185 * has a contribution in the result, in particular
5186 *
5187 * C_ij(S_j) -> M_i(S_j)
5188 *
5189 * Note that plugging in S_j in C_ij may also result in an empty set
5190 * and this contribution should simply be discarded.
5191 */
5192__isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute(
5193 __isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, unsigned pos,
5194 __isl_keep isl_pw_aff *subs)
5195{
5196 int i, j, n;
5197 isl_pw_multi_aff *res;
5198
5199 if (!pma || !subs)
5200 return isl_pw_multi_aff_free(pma);
5201
5202 n = pma->n * subs->n;
5203 res = isl_pw_multi_aff_alloc_size(isl_space_copy(pma->dim), n);
5204
5205 for (i = 0; i < pma->n; ++i) {
5206 for (j = 0; j < subs->n; ++j) {
5207 isl_setisl_map *common;
5208 isl_multi_aff *res_ij;
5209 int empty;
5210
5211 common = isl_set_intersect(
5212 isl_set_copy(pma->p[i].set),
5213 isl_set_copy(subs->p[j].set));
5214 common = isl_set_substitute(common,
5215 type, pos, subs->p[j].aff);
5216 empty = isl_set_plain_is_empty(common);
5217 if (empty < 0 || empty) {
5218 isl_set_free(common);
5219 if (empty < 0)
5220 goto error;
5221 continue;
5222 }
5223
5224 res_ij = isl_multi_aff_substitute(
5225 isl_multi_aff_copy(pma->p[i].maff),
5226 type, pos, subs->p[j].aff);
5227
5228 res = isl_pw_multi_aff_add_piece(res, common, res_ij);
5229 }
5230 }
5231
5232 isl_pw_multi_aff_free(pma);
5233 return res;
5234error:
5235 isl_pw_multi_aff_free(pma);
5236 isl_pw_multi_aff_free(res);
5237 return NULL((void*)0);
5238}
5239
5240/* Compute the preimage of a range of dimensions in the affine expression "src"
5241 * under "ma" and put the result in "dst". The number of dimensions in "src"
5242 * that precede the range is given by "n_before". The number of dimensions
5243 * in the range is given by the number of output dimensions of "ma".
5244 * The number of dimensions that follow the range is given by "n_after".
5245 * If "has_denom" is set (to one),
5246 * then "src" and "dst" have an extra initial denominator.
5247 * "n_div_ma" is the number of existentials in "ma"
5248 * "n_div_bset" is the number of existentials in "src"
5249 * The resulting "dst" (which is assumed to have been allocated by
5250 * the caller) contains coefficients for both sets of existentials,
5251 * first those in "ma" and then those in "src".
5252 * f, c1, c2 and g are temporary objects that have been initialized
5253 * by the caller.
5254 *
5255 * Let src represent the expression
5256 *
5257 * (a(p) + f_u u + b v + f_w w + c(divs))/d
5258 *
5259 * and let ma represent the expressions
5260 *
5261 * v_i = (r_i(p) + s_i(y) + t_i(divs'))/m_i
5262 *
5263 * We start out with the following expression for dst:
5264 *
5265 * (a(p) + f_u u + 0 y + f_w w + 0 divs' + c(divs) + f \sum_i b_i v_i)/d
5266 *
5267 * with the multiplication factor f initially equal to 1
5268 * and f \sum_i b_i v_i kept separately.
5269 * For each x_i that we substitute, we multiply the numerator
5270 * (and denominator) of dst by c_1 = m_i and add the numerator
5271 * of the x_i expression multiplied by c_2 = f b_i,
5272 * after removing the common factors of c_1 and c_2.
5273 * The multiplication factor f also needs to be multiplied by c_1
5274 * for the next x_j, j > i.
5275 */
5276void isl_seq_preimage(isl_int *dst, isl_int *src,
5277 __isl_keep isl_multi_aff *ma, int n_before, int n_after,
5278 int n_div_ma, int n_div_bmap,
5279 isl_int f, isl_int c1, isl_int c2, isl_int g, int has_denom)
5280{
5281 int i;
5282 int n_param, n_in, n_out;
5283 int o_dst, o_src;
5284
5285 n_param = isl_multi_aff_dim(ma, isl_dim_param);
5286 n_in = isl_multi_aff_dim(ma, isl_dim_in);
5287 n_out = isl_multi_aff_dim(ma, isl_dim_out);
5288
5289 isl_seq_cpy(dst, src, has_denom + 1 + n_param + n_before);
5290 o_dst = o_src = has_denom + 1 + n_param + n_before;
5291 isl_seq_clr(dst + o_dst, n_in);
5292 o_dst += n_in;
5293 o_src += n_out;
5294 isl_seq_cpy(dst + o_dst, src + o_src, n_after);
5295 o_dst += n_after;
5296 o_src += n_after;
5297 isl_seq_clr(dst + o_dst, n_div_ma);
5298 o_dst += n_div_ma;
5299 isl_seq_cpy(dst + o_dst, src + o_src, n_div_bmap);
5300
5301 isl_int_set_si(f, 1)impz_set_si(f,1);
5302
5303 for (i = 0; i < n_out; ++i) {
5304 int offset = has_denom + 1 + n_param + n_before + i;
5305
5306 if (isl_int_is_zero(src[offset])(impz_sgn(src[offset]) == 0))
5307 continue;
5308 isl_int_set(c1, ma->p[i]->v->el[0])impz_set(c1,ma->p[i]->v->el[0]);
5309 isl_int_mul(c2, f, src[offset])impz_mul(c2,f,src[offset]);
5310 isl_int_gcd(g, c1, c2)impz_gcd(g,c1,c2);
5311 isl_int_divexact(c1, c1, g)impz_divexact(c1,c1,g);
5312 isl_int_divexact(c2, c2, g)impz_divexact(c2,c2,g);
5313
5314 isl_int_mul(f, f, c1)impz_mul(f,f,c1);
5315 o_dst = has_denom;
5316 o_src = 1;
5317 isl_seq_combine(dst + o_dst, c1, dst + o_dst,
5318 c2, ma->p[i]->v->el + o_src, 1 + n_param);
5319 o_dst += 1 + n_param;
5320 o_src += 1 + n_param;
5321 isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_before);
5322 o_dst += n_before;
5323 isl_seq_combine(dst + o_dst, c1, dst + o_dst,
5324 c2, ma->p[i]->v->el + o_src, n_in);
5325 o_dst += n_in;
5326 o_src += n_in;
5327 isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_after);
5328 o_dst += n_after;
5329 isl_seq_combine(dst + o_dst, c1, dst + o_dst,
5330 c2, ma->p[i]->v->el + o_src, n_div_ma);
5331 o_dst += n_div_ma;
5332 o_src += n_div_ma;
5333 isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_div_bmap);
5334 if (has_denom)
5335 isl_int_mul(dst[0], dst[0], c1)impz_mul(dst[0],dst[0],c1);
5336 }
5337}
5338
5339/* Compute the pullback of "aff" by the function represented by "ma".
5340 * In other words, plug in "ma" in "aff". The result is an affine expression
5341 * defined over the domain space of "ma".
5342 *
5343 * If "aff" is represented by
5344 *
5345 * (a(p) + b x + c(divs))/d
5346 *
5347 * and ma is represented by
5348 *
5349 * x = D(p) + F(y) + G(divs')
5350 *
5351 * then the result is
5352 *
5353 * (a(p) + b D(p) + b F(y) + b G(divs') + c(divs))/d
5354 *
5355 * The divs in the local space of the input are similarly adjusted
5356 * through a call to isl_local_space_preimage_multi_aff.
5357 */
5358__isl_give isl_aff *isl_aff_pullback_multi_aff(__isl_take isl_aff *aff,
5359 __isl_take isl_multi_aff *ma)
5360{
5361 isl_aff *res = NULL((void*)0);
5362 isl_local_space *ls;
5363 int n_div_aff, n_div_ma;
5364 isl_int f, c1, c2, g;
5365
5366 ma = isl_multi_aff_align_divs(ma);
5367 if (!aff || !ma)
5368 goto error;
5369
5370 n_div_aff = isl_aff_dim(aff, isl_dim_div);
5371 n_div_ma = ma->n ? isl_aff_dim(ma->p[0], isl_dim_div) : 0;
5372
5373 ls = isl_aff_get_domain_local_space(aff);
5374 ls = isl_local_space_preimage_multi_aff(ls, isl_multi_aff_copy(ma));
5375 res = isl_aff_alloc(ls);
5376 if (!res)
5377 goto error;
5378
5379 isl_int_init(f)f = mp_int_alloc();
5380 isl_int_init(c1)c1 = mp_int_alloc();
5381 isl_int_init(c2)c2 = mp_int_alloc();
5382 isl_int_init(g)g = mp_int_alloc();
5383
5384 isl_seq_preimage(res->v->el, aff->v->el, ma, 0, 0, n_div_ma, n_div_aff,
5385 f, c1, c2, g, 1);
5386
5387 isl_int_clear(f)mp_int_free(f);
5388 isl_int_clear(c1)mp_int_free(c1);
5389 isl_int_clear(c2)mp_int_free(c2);
5390 isl_int_clear(g)mp_int_free(g);
5391
5392 isl_aff_free(aff);
5393 isl_multi_aff_free(ma);
5394 res = isl_aff_normalize(res);
5395 return res;
5396error:
5397 isl_aff_free(aff);
5398 isl_multi_aff_free(ma);
5399 isl_aff_free(res);
5400 return NULL((void*)0);
5401}
5402
5403/* Compute the pullback of "aff1" by the function represented by "aff2".
5404 * In other words, plug in "aff2" in "aff1". The result is an affine expression
5405 * defined over the domain space of "aff1".
5406 *
5407 * The domain of "aff1" should match the range of "aff2", which means
5408 * that it should be single-dimensional.
5409 */
5410__isl_give isl_aff *isl_aff_pullback_aff(__isl_take isl_aff *aff1,
5411 __isl_take isl_aff *aff2)
5412{
5413 isl_multi_aff *ma;
5414
5415 ma = isl_multi_aff_from_aff(aff2);
5416 return isl_aff_pullback_multi_aff(aff1, ma);
5417}
5418
5419/* Compute the pullback of "ma1" by the function represented by "ma2".
5420 * In other words, plug in "ma2" in "ma1".
5421 *
5422 * The parameters of "ma1" and "ma2" are assumed to have been aligned.
5423 */
5424static __isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff_aligned(
5425 __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2)
5426{
5427 int i;
5428 isl_space *space = NULL((void*)0);
5429
5430 ma2 = isl_multi_aff_align_divs(ma2);
5431 ma1 = isl_multi_aff_cow(ma1);
5432 if (!ma1 || !ma2)
5433 goto error;
5434
5435 space = isl_space_join(isl_multi_aff_get_space(ma2),
5436 isl_multi_aff_get_space(ma1));
5437
5438 for (i = 0; i < ma1->n; ++i) {
5439 ma1->p[i] = isl_aff_pullback_multi_aff(ma1->p[i],
5440 isl_multi_aff_copy(ma2));
5441 if (!ma1->p[i])
5442 goto error;
5443 }
5444
5445 ma1 = isl_multi_aff_reset_space(ma1, space);
5446 isl_multi_aff_free(ma2);
5447 return ma1;
5448error:
5449 isl_space_free(space);
5450 isl_multi_aff_free(ma2);
5451 isl_multi_aff_free(ma1);
5452 return NULL((void*)0);
5453}
5454
5455/* Compute the pullback of "ma1" by the function represented by "ma2".
5456 * In other words, plug in "ma2" in "ma1".
5457 */
5458__isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff(
5459 __isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2)
5460{
5461 return isl_multi_aff_align_params_multi_multi_and(ma1, ma2,
5462 &isl_multi_aff_pullback_multi_aff_aligned);
5463}
5464
5465/* Extend the local space of "dst" to include the divs
5466 * in the local space of "src".
5467 */
5468__isl_give isl_aff *isl_aff_align_divs(__isl_take isl_aff *dst,
5469 __isl_keep isl_aff *src)
5470{
5471 isl_ctx *ctx;
5472 int *exp1 = NULL((void*)0);
5473 int *exp2 = NULL((void*)0);
5474 isl_mat *div;
5475
5476 if (!src || !dst)
5477 return isl_aff_free(dst);
5478
5479 ctx = isl_aff_get_ctx(src);
5480 if (!isl_space_is_equal(src->ls->dim, dst->ls->dim))
5481 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 5482); goto error; } while (0)
5482 "spaces don't match", goto error)do { isl_handle_error(ctx, isl_error_invalid, "spaces don't match"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 5482); goto error; } while (0)
;
5483
5484 if (src->ls->div->n_row == 0)
5485 return dst;
5486
5487 exp1 = isl_alloc_array(ctx, int, src->ls->div->n_row)((int *)isl_malloc_or_die(ctx, (src->ls->div->n_row)
*sizeof(int)))
;
5488 exp2 = isl_alloc_array(ctx, int, dst->ls->div->n_row)((int *)isl_malloc_or_die(ctx, (dst->ls->div->n_row)
*sizeof(int)))
;
5489 if (!exp1 || (dst->ls->div->n_row && !exp2))
5490 goto error;
5491
5492 div = isl_merge_divs(src->ls->div, dst->ls->div, exp1, exp2);
5493 dst = isl_aff_expand_divs(dst, div, exp2);
5494 free(exp1);
5495 free(exp2);
5496
5497 return dst;
5498error:
5499 free(exp1);
5500 free(exp2);
5501 return isl_aff_free(dst);
5502}
5503
5504/* Adjust the local spaces of the affine expressions in "maff"
5505 * such that they all have the save divs.
5506 */
5507__isl_give isl_multi_aff *isl_multi_aff_align_divs(
5508 __isl_take isl_multi_aff *maff)
5509{
5510 int i;
5511
5512 if (!maff)
5513 return NULL((void*)0);
5514 if (maff->n == 0)
5515 return maff;
5516 maff = isl_multi_aff_cow(maff);
5517 if (!maff)
5518 return NULL((void*)0);
5519
5520 for (i = 1; i < maff->n; ++i)
5521 maff->p[0] = isl_aff_align_divs(maff->p[0], maff->p[i]);
5522 for (i = 1; i < maff->n; ++i) {
5523 maff->p[i] = isl_aff_align_divs(maff->p[i], maff->p[0]);
5524 if (!maff->p[i])
5525 return isl_multi_aff_free(maff);
5526 }
5527
5528 return maff;
5529}
5530
5531__isl_give isl_aff *isl_aff_lift(__isl_take isl_aff *aff)
5532{
5533 aff = isl_aff_cow(aff);
5534 if (!aff)
5535 return NULL((void*)0);
5536
5537 aff->ls = isl_local_space_lift(aff->ls);
5538 if (!aff->ls)
5539 return isl_aff_free(aff);
5540
5541 return aff;
5542}
5543
5544/* Lift "maff" to a space with extra dimensions such that the result
5545 * has no more existentially quantified variables.
5546 * If "ls" is not NULL, then *ls is assigned the local space that lies
5547 * at the basis of the lifting applied to "maff".
5548 */
5549__isl_give isl_multi_aff *isl_multi_aff_lift(__isl_take isl_multi_aff *maff,
5550 __isl_give isl_local_space **ls)
5551{
5552 int i;
5553 isl_space *space;
5554 unsigned n_div;
5555
5556 if (ls)
5557 *ls = NULL((void*)0);
5558
5559 if (!maff)
5560 return NULL((void*)0);
5561
5562 if (maff->n == 0) {
5563 if (ls) {
5564 isl_space *space = isl_multi_aff_get_domain_space(maff);
5565 *ls = isl_local_space_from_space(space);
5566 if (!*ls)
5567 return isl_multi_aff_free(maff);
5568 }
5569 return maff;
5570 }
5571
5572 maff = isl_multi_aff_cow(maff);
5573 maff = isl_multi_aff_align_divs(maff);
5574 if (!maff)
5575 return NULL((void*)0);
5576
5577 n_div = isl_aff_dim(maff->p[0], isl_dim_div);
5578 space = isl_multi_aff_get_space(maff);
5579 space = isl_space_lift(isl_space_domain(space), n_div);
5580 space = isl_space_extend_domain_with_range(space,
5581 isl_multi_aff_get_space(maff));
5582 if (!space)
5583 return isl_multi_aff_free(maff);
5584 isl_space_free(maff->space);
5585 maff->space = space;
5586
5587 if (ls) {
5588 *ls = isl_aff_get_domain_local_space(maff->p[0]);
5589 if (!*ls)
5590 return isl_multi_aff_free(maff);
5591 }
5592
5593 for (i = 0; i < maff->n; ++i) {
5594 maff->p[i] = isl_aff_lift(maff->p[i]);
5595 if (!maff->p[i])
5596 goto error;
5597 }
5598
5599 return maff;
5600error:
5601 if (ls)
5602 isl_local_space_free(*ls);
5603 return isl_multi_aff_free(maff);
5604}
5605
5606
5607/* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma".
5608 */
5609__isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff(
5610 __isl_keep isl_pw_multi_aff *pma, int pos)
5611{
5612 int i;
5613 int n_out;
5614 isl_space *space;
5615 isl_pw_aff *pa;
5616
5617 if (!pma)
5618 return NULL((void*)0);
5619
5620 n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
5621 if (pos < 0 || pos >= n_out)
5622 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 5623); return ((void*)0); } while (0)
5623 "index out of bounds", return NULL)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "index out of bounds", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 5623); return ((void*)0); } while (0)
;
5624
5625 space = isl_pw_multi_aff_get_space(pma);
5626 space = isl_space_drop_dims(space, isl_dim_out,
5627 pos + 1, n_out - pos - 1);
5628 space = isl_space_drop_dims(space, isl_dim_out, 0, pos);
5629
5630 pa = isl_pw_aff_alloc_size(space, pma->n);
5631 for (i = 0; i < pma->n; ++i) {
5632 isl_aff *aff;
5633 aff = isl_multi_aff_get_aff(pma->p[i].maff, pos);
5634 pa = isl_pw_aff_add_piece(pa, isl_set_copy(pma->p[i].set), aff);
5635 }
5636
5637 return pa;
5638}
5639
5640/* Return an isl_pw_multi_aff with the given "set" as domain and
5641 * an unnamed zero-dimensional range.
5642 */
5643__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_domain(
5644 __isl_take isl_setisl_map *set)
5645{
5646 isl_multi_aff *ma;
5647 isl_space *space;
5648
5649 space = isl_set_get_space(set);
5650 space = isl_space_from_domain(space);
5651 ma = isl_multi_aff_zero(space);
5652 return isl_pw_multi_aff_alloc(set, ma);
5653}
5654
5655/* Add an isl_pw_multi_aff with the given "set" as domain and
5656 * an unnamed zero-dimensional range to *user.
5657 */
5658static isl_stat add_pw_multi_aff_from_domain(__isl_take isl_setisl_map *set,
5659 void *user)
5660{
5661 isl_union_pw_multi_aff **upma = user;
5662 isl_pw_multi_aff *pma;
5663
5664 pma = isl_pw_multi_aff_from_domain(set);
5665 *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
5666
5667 return isl_stat_ok;
5668}
5669
5670/* Return an isl_union_pw_multi_aff with the given "uset" as domain and
5671 * an unnamed zero-dimensional range.
5672 */
5673__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_domain(
5674 __isl_take isl_union_setisl_union_map *uset)
5675{
5676 isl_space *space;
5677 isl_union_pw_multi_aff *upma;
5678
5679 if (!uset)
5680 return NULL((void*)0);
5681
5682 space = isl_union_set_get_space(uset);
5683 upma = isl_union_pw_multi_aff_empty(space);
5684
5685 if (isl_union_set_foreach_set(uset,
5686 &add_pw_multi_aff_from_domain, &upma) < 0)
5687 goto error;
5688
5689 isl_union_set_free(uset);
5690 return upma;
5691error:
5692 isl_union_set_free(uset);
5693 isl_union_pw_multi_aff_free(upma);
5694 return NULL((void*)0);
5695}
5696
5697/* Convert "pma" to an isl_map and add it to *umap.
5698 */
5699static isl_stat map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma,
5700 void *user)
5701{
5702 isl_union_map **umap = user;
5703 isl_map *map;
5704
5705 map = isl_map_from_pw_multi_aff(pma);
5706 *umap = isl_union_map_add_map(*umap, map);
5707
5708 return isl_stat_ok;
5709}
5710
5711/* Construct a union map mapping the domain of the union
5712 * piecewise multi-affine expression to its range, with each dimension
5713 * in the range equated to the corresponding affine expression on its cell.
5714 */
5715__isl_give isl_union_map *isl_union_map_from_union_pw_multi_aff(
5716 __isl_take isl_union_pw_multi_aff *upma)
5717{
5718 isl_space *space;
5719 isl_union_map *umap;
5720
5721 if (!upma)
5722 return NULL((void*)0);
5723
5724 space = isl_union_pw_multi_aff_get_space(upma);
5725 umap = isl_union_map_empty(space);
5726
5727 if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
5728 &map_from_pw_multi_aff, &umap) < 0)
5729 goto error;
5730
5731 isl_union_pw_multi_aff_free(upma);
5732 return umap;
5733error:
5734 isl_union_pw_multi_aff_free(upma);
5735 isl_union_map_free(umap);
5736 return NULL((void*)0);
5737}
5738
5739/* Local data for bin_entry and the callback "fn".
5740 */
5741struct isl_union_pw_multi_aff_bin_data {
5742 isl_union_pw_multi_aff *upma2;
5743 isl_union_pw_multi_aff *res;
5744 isl_pw_multi_aff *pma;
5745 isl_stat (*fn)(void **entry, void *user);
5746};
5747
5748/* Given an isl_pw_multi_aff from upma1, store it in data->pma
5749 * and call data->fn for each isl_pw_multi_aff in data->upma2.
5750 */
5751static isl_stat bin_entry(void **entry, void *user)
5752{
5753 struct isl_union_pw_multi_aff_bin_data *data = user;
5754 isl_pw_multi_aff *pma = *entry;
5755
5756 data->pma = pma;
5757 if (isl_hash_table_foreach(data->upma2->space->ctx, &data->upma2->table,
5758 data->fn, data) < 0)
5759 return isl_stat_error;
5760
5761 return isl_stat_ok;
5762}
5763
5764/* Call "fn" on each pair of isl_pw_multi_affs in "upma1" and "upma2".
5765 * The isl_pw_multi_aff from upma1 is stored in data->pma (where data is
5766 * passed as user field) and the isl_pw_multi_aff from upma2 is available
5767 * as *entry. The callback should adjust data->res if desired.
5768 */
5769static __isl_give isl_union_pw_multi_aff *bin_op(
5770 __isl_take isl_union_pw_multi_aff *upma1,
5771 __isl_take isl_union_pw_multi_aff *upma2,
5772 isl_stat (*fn)(void **entry, void *user))
5773{
5774 isl_space *space;
5775 struct isl_union_pw_multi_aff_bin_data data = { NULL((void*)0), NULL((void*)0), NULL((void*)0), fn };
5776
5777 space = isl_union_pw_multi_aff_get_space(upma2);
5778 upma1 = isl_union_pw_multi_aff_align_params(upma1, space);
5779 space = isl_union_pw_multi_aff_get_space(upma1);
5780 upma2 = isl_union_pw_multi_aff_align_params(upma2, space);
5781
5782 if (!upma1 || !upma2)
5783 goto error;
5784
5785 data.upma2 = upma2;
5786 data.res = isl_union_pw_multi_aff_alloc(isl_space_copy(upma1->space),
5787 upma1->table.n);
5788 if (isl_hash_table_foreach(upma1->space->ctx, &upma1->table,
5789 &bin_entry, &data) < 0)
5790 goto error;
5791
5792 isl_union_pw_multi_aff_free(upma1);
5793 isl_union_pw_multi_aff_free(upma2);
5794 return data.res;
5795error:
5796 isl_union_pw_multi_aff_free(upma1);
5797 isl_union_pw_multi_aff_free(upma2);
5798 isl_union_pw_multi_aff_free(data.res);
5799 return NULL((void*)0);
5800}
5801
5802/* Given two aligned isl_pw_multi_affs A -> B and C -> D,
5803 * construct an isl_pw_multi_aff (A * C) -> [B -> D].
5804 */
5805static __isl_give isl_pw_multi_aff *pw_multi_aff_range_product(
5806 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
5807{
5808 isl_space *space;
5809
5810 space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1),
5811 isl_pw_multi_aff_get_space(pma2));
5812 return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space,
5813 &isl_multi_aff_range_product);
5814}
5815
5816/* Given two isl_pw_multi_affs A -> B and C -> D,
5817 * construct an isl_pw_multi_aff (A * C) -> [B -> D].
5818 */
5819__isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_product(
5820 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
5821{
5822 return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
5823 &pw_multi_aff_range_product);
5824}
5825
5826/* Given two aligned isl_pw_multi_affs A -> B and C -> D,
5827 * construct an isl_pw_multi_aff (A * C) -> (B, D).
5828 */
5829static __isl_give isl_pw_multi_aff *pw_multi_aff_flat_range_product(
5830 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
5831{
5832 isl_space *space;
5833
5834 space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1),
5835 isl_pw_multi_aff_get_space(pma2));
5836 space = isl_space_flatten_range(space);
5837 return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space,
5838 &isl_multi_aff_flat_range_product);
5839}
5840
5841/* Given two isl_pw_multi_affs A -> B and C -> D,
5842 * construct an isl_pw_multi_aff (A * C) -> (B, D).
5843 */
5844__isl_give isl_pw_multi_aff *isl_pw_multi_aff_flat_range_product(
5845 __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
5846{
5847 return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
5848 &pw_multi_aff_flat_range_product);
5849}
5850
5851/* If data->pma and *entry have the same domain space, then compute
5852 * their flat range product and the result to data->res.
5853 */
5854static isl_stat flat_range_product_entry(void **entry, void *user)
5855{
5856 struct isl_union_pw_multi_aff_bin_data *data = user;
5857 isl_pw_multi_aff *pma2 = *entry;
5858
5859 if (!isl_space_tuple_is_equal(data->pma->dim, isl_dim_in,
5860 pma2->dim, isl_dim_in))
5861 return isl_stat_ok;
5862
5863 pma2 = isl_pw_multi_aff_flat_range_product(
5864 isl_pw_multi_aff_copy(data->pma),
5865 isl_pw_multi_aff_copy(pma2));
5866
5867 data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2);
5868
5869 return isl_stat_ok;
5870}
5871
5872/* Given two isl_union_pw_multi_affs A -> B and C -> D,
5873 * construct an isl_union_pw_multi_aff (A * C) -> (B, D).
5874 */
5875__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_flat_range_product(
5876 __isl_take isl_union_pw_multi_aff *upma1,
5877 __isl_take isl_union_pw_multi_aff *upma2)
5878{
5879 return bin_op(upma1, upma2, &flat_range_product_entry);
5880}
5881
5882/* Replace the affine expressions at position "pos" in "pma" by "pa".
5883 * The parameters are assumed to have been aligned.
5884 *
5885 * The implementation essentially performs an isl_pw_*_on_shared_domain,
5886 * except that it works on two different isl_pw_* types.
5887 */
5888static __isl_give isl_pw_multi_aff *pw_multi_aff_set_pw_aff(
5889 __isl_take isl_pw_multi_aff *pma, unsigned pos,
5890 __isl_take isl_pw_aff *pa)
5891{
5892 int i, j, n;
5893 isl_pw_multi_aff *res = NULL((void*)0);
5894
5895 if (!pma || !pa)
5896 goto error;
5897
5898 if (!isl_space_tuple_is_equal(pma->dim, isl_dim_in,
5899 pa->dim, isl_dim_in))
5900 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 5901); goto error; } while (0)
5901 "domains don't match", goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "domains don't match", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 5901); goto error; } while (0)
;
5902 if (pos >= isl_pw_multi_aff_dim(pma, isl_dim_out))
5903 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 5904); goto error; } while (0)
5904 "index out of bounds", goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "index out of bounds", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 5904); goto error; } while (0)
;
5905
5906 n = pma->n * pa->n;
5907 res = isl_pw_multi_aff_alloc_size(isl_pw_multi_aff_get_space(pma), n);
5908
5909 for (i = 0; i < pma->n; ++i) {
5910 for (j = 0; j < pa->n; ++j) {
5911 isl_setisl_map *common;
5912 isl_multi_aff *res_ij;
5913 int empty;
5914
5915 common = isl_set_intersect(isl_set_copy(pma->p[i].set),
5916 isl_set_copy(pa->p[j].set));
5917 empty = isl_set_plain_is_empty(common);
5918 if (empty < 0 || empty) {
5919 isl_set_free(common);
5920 if (empty < 0)
5921 goto error;
5922 continue;
5923 }
5924
5925 res_ij = isl_multi_aff_set_aff(
5926 isl_multi_aff_copy(pma->p[i].maff), pos,
5927 isl_aff_copy(pa->p[j].aff));
5928 res_ij = isl_multi_aff_gist(res_ij,
5929 isl_set_copy(common));
5930
5931 res = isl_pw_multi_aff_add_piece(res, common, res_ij);
5932 }
5933 }
5934
5935 isl_pw_multi_aff_free(pma);
5936 isl_pw_aff_free(pa);
5937 return res;
5938error:
5939 isl_pw_multi_aff_free(pma);
5940 isl_pw_aff_free(pa);
5941 return isl_pw_multi_aff_free(res);
5942}
5943
5944/* Replace the affine expressions at position "pos" in "pma" by "pa".
5945 */
5946__isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_pw_aff(
5947 __isl_take isl_pw_multi_aff *pma, unsigned pos,
5948 __isl_take isl_pw_aff *pa)
5949{
5950 if (!pma || !pa)
5951 goto error;
5952 if (isl_space_match(pma->dim, isl_dim_param, pa->dim, isl_dim_param))
5953 return pw_multi_aff_set_pw_aff(pma, pos, pa);
5954 if (!isl_space_has_named_params(pma->dim) ||
5955 !isl_space_has_named_params(pa->dim))
5956 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
, "unaligned unnamed parameters", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 5957); goto error; } while (0)
5957 "unaligned unnamed parameters", goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "unaligned unnamed parameters", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 5957); goto error; } while (0)
;
5958 pma = isl_pw_multi_aff_align_params(pma, isl_pw_aff_get_space(pa));
5959 pa = isl_pw_aff_align_params(pa, isl_pw_multi_aff_get_space(pma));
5960 return pw_multi_aff_set_pw_aff(pma, pos, pa);
5961error:
5962 isl_pw_multi_aff_free(pma);
5963 isl_pw_aff_free(pa);
5964 return NULL((void*)0);
5965}
5966
5967/* Do the parameters of "pa" match those of "space"?
5968 */
5969int isl_pw_aff_matching_params(__isl_keep isl_pw_aff *pa,
5970 __isl_keep isl_space *space)
5971{
5972 isl_space *pa_space;
5973 int match;
5974
5975 if (!pa || !space)
5976 return -1;
5977
5978 pa_space = isl_pw_aff_get_space(pa);
5979
5980 match = isl_space_match(space, isl_dim_param, pa_space, isl_dim_param);
5981
5982 isl_space_free(pa_space);
5983 return match;
5984}
5985
5986/* Check that the domain space of "pa" matches "space".
5987 *
5988 * Return 0 on success and -1 on error.
5989 */
5990int isl_pw_aff_check_match_domain_space(__isl_keep isl_pw_aff *pa,
5991 __isl_keep isl_space *space)
5992{
5993 isl_space *pa_space;
5994 int match;
5995
5996 if (!pa || !space)
5997 return -1;
5998
5999 pa_space = isl_pw_aff_get_space(pa);
6000
6001 match = isl_space_match(space, isl_dim_param, pa_space, isl_dim_param);
6002 if (match < 0)
6003 goto error;
6004 if (!match)
6005 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 6006); goto error; } while (0)
6006 "parameters don't match", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid
, "parameters don't match", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 6006); goto error; } while (0)
;
6007 match = isl_space_tuple_is_equal(space, isl_dim_in,
6008 pa_space, isl_dim_in);
6009 if (match < 0)
6010 goto error;
6011 if (!match)
6012 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 6013); goto error; } while (0)
6013 "domains don't match", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid
, "domains don't match", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 6013); goto error; } while (0)
;
6014 isl_space_free(pa_space);
6015 return 0;
6016error:
6017 isl_space_free(pa_space);
6018 return -1;
6019}
6020
6021#undef BASEunion_pw_aff
6022#define BASEunion_pw_aff pw_aff
6023#undef DOMBASEunion_set
6024#define DOMBASEunion_set set
6025
6026#include <isl_multi_templ.c>
6027#include <isl_multi_apply_set.c>
6028#include <isl_multi_gist.c>
6029#include <isl_multi_intersect.c>
6030
6031/* Scale the elements of "pma" by the corresponding elements of "mv".
6032 */
6033__isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_multi_val(
6034 __isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv)
6035{
6036 int i;
6037
6038 pma = isl_pw_multi_aff_cow(pma);
6039 if (!pma || !mv)
6040 goto error;
6041 if (!isl_space_tuple_is_equal(pma->dim, isl_dim_out,
6042 mv->space, isl_dim_set))
6043 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 6044); goto error; } while (0)
6044 "spaces don't match", goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "spaces don't match", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 6044); goto error; } while (0)
;
6045 if (!isl_space_match(pma->dim, isl_dim_param,
6046 mv->space, isl_dim_param)) {
6047 pma = isl_pw_multi_aff_align_params(pma,
6048 isl_multi_val_get_space(mv));
6049 mv = isl_multi_val_align_params(mv,
6050 isl_pw_multi_aff_get_space(pma));
6051 if (!pma || !mv)
6052 goto error;
6053 }
6054
6055 for (i = 0; i < pma->n; ++i) {
6056 pma->p[i].maff = isl_multi_aff_scale_multi_val(pma->p[i].maff,
6057 isl_multi_val_copy(mv));
6058 if (!pma->p[i].maff)
6059 goto error;
6060 }
6061
6062 isl_multi_val_free(mv);
6063 return pma;
6064error:
6065 isl_multi_val_free(mv);
6066 isl_pw_multi_aff_free(pma);
6067 return NULL((void*)0);
6068}
6069
6070/* Internal data structure for isl_union_pw_multi_aff_scale_multi_val.
6071 * mv contains the mv argument.
6072 * res collects the results.
6073 */
6074struct isl_union_pw_multi_aff_scale_multi_val_data {
6075 isl_multi_val *mv;
6076 isl_union_pw_multi_aff *res;
6077};
6078
6079/* This function is called for each entry of an isl_union_pw_multi_aff.
6080 * If the space of the entry matches that of data->mv,
6081 * then apply isl_pw_multi_aff_scale_multi_val and add the result
6082 * to data->res.
6083 */
6084static isl_stat union_pw_multi_aff_scale_multi_val_entry(void **entry,
6085 void *user)
6086{
6087 struct isl_union_pw_multi_aff_scale_multi_val_data *data = user;
6088 isl_pw_multi_aff *pma = *entry;
6089
6090 if (!pma)
6091 return isl_stat_error;
6092 if (!isl_space_tuple_is_equal(pma->dim, isl_dim_out,
6093 data->mv->space, isl_dim_set))
6094 return isl_stat_ok;
6095
6096 pma = isl_pw_multi_aff_copy(pma);
6097 pma = isl_pw_multi_aff_scale_multi_val(pma,
6098 isl_multi_val_copy(data->mv));
6099 data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma);
6100 if (!data->res)
6101 return isl_stat_error;
6102
6103 return isl_stat_ok;
6104}
6105
6106/* Scale the elements of "upma" by the corresponding elements of "mv",
6107 * for those entries that match the space of "mv".
6108 */
6109__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_scale_multi_val(
6110 __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_multi_val *mv)
6111{
6112 struct isl_union_pw_multi_aff_scale_multi_val_data data;
6113
6114 upma = isl_union_pw_multi_aff_align_params(upma,
6115 isl_multi_val_get_space(mv));
6116 mv = isl_multi_val_align_params(mv,
6117 isl_union_pw_multi_aff_get_space(upma));
6118 if (!upma || !mv)
6119 goto error;
6120
6121 data.mv = mv;
6122 data.res = isl_union_pw_multi_aff_alloc(isl_space_copy(upma->space),
6123 upma->table.n);
6124 if (isl_hash_table_foreach(upma->space->ctx, &upma->table,
6125 &union_pw_multi_aff_scale_multi_val_entry, &data) < 0)
6126 goto error;
6127
6128 isl_multi_val_free(mv);
6129 isl_union_pw_multi_aff_free(upma);
6130 return data.res;
6131error:
6132 isl_multi_val_free(mv);
6133 isl_union_pw_multi_aff_free(upma);
6134 return NULL((void*)0);
6135}
6136
6137/* Construct and return a piecewise multi affine expression
6138 * in the given space with value zero in each of the output dimensions and
6139 * a universe domain.
6140 */
6141__isl_give isl_pw_multi_aff *isl_pw_multi_aff_zero(__isl_take isl_space *space)
6142{
6143 return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_zero(space));
6144}
6145
6146/* Construct and return a piecewise multi affine expression
6147 * that is equal to the given piecewise affine expression.
6148 */
6149__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_pw_aff(
6150 __isl_take isl_pw_aff *pa)
6151{
6152 int i;
6153 isl_space *space;
6154 isl_pw_multi_aff *pma;
6155
6156 if (!pa)
6157 return NULL((void*)0);
6158
6159 space = isl_pw_aff_get_space(pa);
6160 pma = isl_pw_multi_aff_alloc_size(space, pa->n);
6161
6162 for (i = 0; i < pa->n; ++i) {
6163 isl_setisl_map *set;
6164 isl_multi_aff *ma;
6165
6166 set = isl_set_copy(pa->p[i].set);
6167 ma = isl_multi_aff_from_aff(isl_aff_copy(pa->p[i].aff));
6168 pma = isl_pw_multi_aff_add_piece(pma, set, ma);
6169 }
6170
6171 isl_pw_aff_free(pa);
6172 return pma;
6173}
6174
6175/* Construct a set or map mapping the shared (parameter) domain
6176 * of the piecewise affine expressions to the range of "mpa"
6177 * with each dimension in the range equated to the
6178 * corresponding piecewise affine expression.
6179 */
6180static __isl_give isl_map *map_from_multi_pw_aff(
6181 __isl_take isl_multi_pw_aff *mpa)
6182{
6183 int i;
6184 isl_space *space;
6185 isl_map *map;
6186
6187 if (!mpa)
6188 return NULL((void*)0);
6189
6190 if (isl_space_dim(mpa->space, isl_dim_out) != mpa->n)
6191 isl_die(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal,do { isl_handle_error(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal
, "invalid space", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 6192); goto error; } while (0)
6192 "invalid space", goto error)do { isl_handle_error(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal
, "invalid space", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 6192); goto error; } while (0)
;
6193
6194 space = isl_multi_pw_aff_get_domain_space(mpa);
6195 map = isl_map_universe(isl_space_from_domain(space));
6196
6197 for (i = 0; i < mpa->n; ++i) {
6198 isl_pw_aff *pa;
6199 isl_map *map_i;
6200
6201 pa = isl_pw_aff_copy(mpa->p[i]);
6202 map_i = map_from_pw_aff(pa);
6203
6204 map = isl_map_flat_range_product(map, map_i);
6205 }
6206
6207 map = isl_map_reset_space(map, isl_multi_pw_aff_get_space(mpa));
6208
6209 isl_multi_pw_aff_free(mpa);
6210 return map;
6211error:
6212 isl_multi_pw_aff_free(mpa);
6213 return NULL((void*)0);
6214}
6215
6216/* Construct a map mapping the shared domain
6217 * of the piecewise affine expressions to the range of "mpa"
6218 * with each dimension in the range equated to the
6219 * corresponding piecewise affine expression.
6220 */
6221__isl_give isl_map *isl_map_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa)
6222{
6223 if (!mpa)
6224 return NULL((void*)0);
6225 if (isl_space_is_set(mpa->space))
6226 isl_die(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal,do { isl_handle_error(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal
, "space of input is not a map", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 6227); goto error; } while (0)
6227 "space of input is not a map", goto error)do { isl_handle_error(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal
, "space of input is not a map", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 6227); goto error; } while (0)
;
6228
6229 return map_from_multi_pw_aff(mpa);
6230error:
6231 isl_multi_pw_aff_free(mpa);
6232 return NULL((void*)0);
6233}
6234
6235/* Construct a set mapping the shared parameter domain
6236 * of the piecewise affine expressions to the space of "mpa"
6237 * with each dimension in the range equated to the
6238 * corresponding piecewise affine expression.
6239 */
6240__isl_give isl_setisl_map *isl_set_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa)
6241{
6242 if (!mpa)
6243 return NULL((void*)0);
6244 if (!isl_space_is_set(mpa->space))
6245 isl_die(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal,do { isl_handle_error(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal
, "space of input is not a set", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 6246); goto error; } while (0)
6246 "space of input is not a set", goto error)do { isl_handle_error(isl_multi_pw_aff_get_ctx(mpa), isl_error_internal
, "space of input is not a set", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 6246); goto error; } while (0)
;
6247
6248 return map_from_multi_pw_aff(mpa);
6249error:
6250 isl_multi_pw_aff_free(mpa);
6251 return NULL((void*)0);
6252}
6253
6254/* Construct and return a piecewise multi affine expression
6255 * that is equal to the given multi piecewise affine expression
6256 * on the shared domain of the piecewise affine expressions.
6257 */
6258__isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff(
6259 __isl_take isl_multi_pw_aff *mpa)
6260{
6261 int i;
6262 isl_space *space;
6263 isl_pw_aff *pa;
6264 isl_pw_multi_aff *pma;
6265
6266 if (!mpa)
6267 return NULL((void*)0);
6268
6269 space = isl_multi_pw_aff_get_space(mpa);
6270
6271 if (mpa->n == 0) {
6272 isl_multi_pw_aff_free(mpa);
6273 return isl_pw_multi_aff_zero(space);
6274 }
6275
6276 pa = isl_multi_pw_aff_get_pw_aff(mpa, 0);
6277 pma = isl_pw_multi_aff_from_pw_aff(pa);
6278
6279 for (i = 1; i < mpa->n; ++i) {
6280 isl_pw_multi_aff *pma_i;
6281
6282 pa = isl_multi_pw_aff_get_pw_aff(mpa, i);
6283 pma_i = isl_pw_multi_aff_from_pw_aff(pa);
6284 pma = isl_pw_multi_aff_range_product(pma, pma_i);
6285 }
6286
6287 pma = isl_pw_multi_aff_reset_space(pma, space);
6288
6289 isl_multi_pw_aff_free(mpa);
6290 return pma;
6291}
6292
6293/* Construct and return a multi piecewise affine expression
6294 * that is equal to the given multi affine expression.
6295 */
6296__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_multi_aff(
6297 __isl_take isl_multi_aff *ma)
6298{
6299 int i, n;
6300 isl_multi_pw_aff *mpa;
6301
6302 if (!ma)
6303 return NULL((void*)0);
6304
6305 n = isl_multi_aff_dim(ma, isl_dim_out);
6306 mpa = isl_multi_pw_aff_alloc(isl_multi_aff_get_space(ma));
6307
6308 for (i = 0; i < n; ++i) {
6309 isl_pw_aff *pa;
6310
6311 pa = isl_pw_aff_from_aff(isl_multi_aff_get_aff(ma, i));
6312 mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa);
6313 }
6314
6315 isl_multi_aff_free(ma);
6316 return mpa;
6317}
6318
6319/* Construct and return a multi piecewise affine expression
6320 * that is equal to the given piecewise multi affine expression.
6321 */
6322__isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_multi_aff(
6323 __isl_take isl_pw_multi_aff *pma)
6324{
6325 int i, n;
6326 isl_space *space;
6327 isl_multi_pw_aff *mpa;
6328
6329 if (!pma)
6330 return NULL((void*)0);
6331
6332 n = isl_pw_multi_aff_dim(pma, isl_dim_out);
6333 space = isl_pw_multi_aff_get_space(pma);
6334 mpa = isl_multi_pw_aff_alloc(space);
6335
6336 for (i = 0; i < n; ++i) {
6337 isl_pw_aff *pa;
6338
6339 pa = isl_pw_multi_aff_get_pw_aff(pma, i);
6340 mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa);
6341 }
6342
6343 isl_pw_multi_aff_free(pma);
6344 return mpa;
6345}
6346
6347/* Do "pa1" and "pa2" represent the same function?
6348 *
6349 * We first check if they are obviously equal.
6350 * If not, we convert them to maps and check if those are equal.
6351 */
6352int isl_pw_aff_is_equal(__isl_keep isl_pw_aff *pa1, __isl_keep isl_pw_aff *pa2)
6353{
6354 int equal;
6355 isl_map *map1, *map2;
6356
6357 if (!pa1 || !pa2)
6358 return -1;
6359
6360 equal = isl_pw_aff_plain_is_equal(pa1, pa2);
6361 if (equal < 0 || equal)
6362 return equal;
6363
6364 map1 = map_from_pw_aff(isl_pw_aff_copy(pa1));
6365 map2 = map_from_pw_aff(isl_pw_aff_copy(pa2));
6366 equal = isl_map_is_equal(map1, map2);
6367 isl_map_free(map1);
6368 isl_map_free(map2);
6369
6370 return equal;
6371}
6372
6373/* Do "mpa1" and "mpa2" represent the same function?
6374 *
6375 * Note that we cannot convert the entire isl_multi_pw_aff
6376 * to a map because the domains of the piecewise affine expressions
6377 * may not be the same.
6378 */
6379isl_bool isl_multi_pw_aff_is_equal(__isl_keep isl_multi_pw_aff *mpa1,
6380 __isl_keep isl_multi_pw_aff *mpa2)
6381{
6382 int i;
6383 isl_bool equal;
6384
6385 if (!mpa1 || !mpa2)
6386 return isl_bool_error;
6387
6388 if (!isl_space_match(mpa1->space, isl_dim_param,
6389 mpa2->space, isl_dim_param)) {
6390 if (!isl_space_has_named_params(mpa1->space))
6391 return isl_bool_false;
6392 if (!isl_space_has_named_params(mpa2->space))
6393 return isl_bool_false;
6394 mpa1 = isl_multi_pw_aff_copy(mpa1);
6395 mpa2 = isl_multi_pw_aff_copy(mpa2);
6396 mpa1 = isl_multi_pw_aff_align_params(mpa1,
6397 isl_multi_pw_aff_get_space(mpa2));
6398 mpa2 = isl_multi_pw_aff_align_params(mpa2,
6399 isl_multi_pw_aff_get_space(mpa1));
6400 equal = isl_multi_pw_aff_is_equal(mpa1, mpa2);
6401 isl_multi_pw_aff_free(mpa1);
6402 isl_multi_pw_aff_free(mpa2);
6403 return equal;
6404 }
6405
6406 equal = isl_space_is_equal(mpa1->space, mpa2->space);
6407 if (equal < 0 || !equal)
6408 return equal;
6409
6410 for (i = 0; i < mpa1->n; ++i) {
6411 equal = isl_pw_aff_is_equal(mpa1->p[i], mpa2->p[i]);
6412 if (equal < 0 || !equal)
6413 return equal;
6414 }
6415
6416 return isl_bool_true;
6417}
6418
6419/* Coalesce the elements of "mpa".
6420 *
6421 * Note that such coalescing does not change the meaning of "mpa"
6422 * so there is no need to cow. We do need to be careful not to
6423 * destroy any other copies of "mpa" in case of failure.
6424 */
6425__isl_give isl_multi_pw_aff *isl_multi_pw_aff_coalesce(
6426 __isl_take isl_multi_pw_aff *mpa)
6427{
6428 int i;
6429
6430 if (!mpa)
6431 return NULL((void*)0);
6432
6433 for (i = 0; i < mpa->n; ++i) {
6434 isl_pw_aff *pa = isl_pw_aff_copy(mpa->p[i]);
6435 pa = isl_pw_aff_coalesce(pa);
6436 if (!pa)
6437 return isl_multi_pw_aff_free(mpa);
6438 isl_pw_aff_free(mpa->p[i]);
6439 mpa->p[i] = pa;
6440 }
6441
6442 return mpa;
6443}
6444
6445/* Compute the pullback of "mpa" by the function represented by "ma".
6446 * In other words, plug in "ma" in "mpa".
6447 *
6448 * The parameters of "mpa" and "ma" are assumed to have been aligned.
6449 */
6450static __isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_aff_aligned(
6451 __isl_take isl_multi_pw_aff *mpa, __isl_take isl_multi_aff *ma)
6452{
6453 int i;
6454 isl_space *space = NULL((void*)0);
6455
6456 mpa = isl_multi_pw_aff_cow(mpa);
6457 if (!mpa || !ma)
6458 goto error;
6459
6460 space = isl_space_join(isl_multi_aff_get_space(ma),
6461 isl_multi_pw_aff_get_space(mpa));
6462 if (!space)
6463 goto error;
6464
6465 for (i = 0; i < mpa->n; ++i) {
6466 mpa->p[i] = isl_pw_aff_pullback_multi_aff(mpa->p[i],
6467 isl_multi_aff_copy(ma));
6468 if (!mpa->p[i])
6469 goto error;
6470 }
6471
6472 isl_multi_aff_free(ma);
6473 isl_space_free(mpa->space);
6474 mpa->space = space;
6475 return mpa;
6476error:
6477 isl_space_free(space);
6478 isl_multi_pw_aff_free(mpa);
6479 isl_multi_aff_free(ma);
6480 return NULL((void*)0);
6481}
6482
6483/* Compute the pullback of "mpa" by the function represented by "ma".
6484 * In other words, plug in "ma" in "mpa".
6485 */
6486__isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_aff(
6487 __isl_take isl_multi_pw_aff *mpa, __isl_take isl_multi_aff *ma)
6488{
6489 if (!mpa || !ma)
6490 goto error;
6491 if (isl_space_match(mpa->space, isl_dim_param,
6492 ma->space, isl_dim_param))
6493 return isl_multi_pw_aff_pullback_multi_aff_aligned(mpa, ma);
6494 mpa = isl_multi_pw_aff_align_params(mpa, isl_multi_aff_get_space(ma));
6495 ma = isl_multi_aff_align_params(ma, isl_multi_pw_aff_get_space(mpa));
6496 return isl_multi_pw_aff_pullback_multi_aff_aligned(mpa, ma);
6497error:
6498 isl_multi_pw_aff_free(mpa);
6499 isl_multi_aff_free(ma);
6500 return NULL((void*)0);
6501}
6502
6503/* Compute the pullback of "mpa" by the function represented by "pma".
6504 * In other words, plug in "pma" in "mpa".
6505 *
6506 * The parameters of "mpa" and "mpa" are assumed to have been aligned.
6507 */
6508static __isl_give isl_multi_pw_aff *
6509isl_multi_pw_aff_pullback_pw_multi_aff_aligned(
6510 __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_multi_aff *pma)
6511{
6512 int i;
6513 isl_space *space = NULL((void*)0);
6514
6515 mpa = isl_multi_pw_aff_cow(mpa);
6516 if (!mpa || !pma)
6517 goto error;
6518
6519 space = isl_space_join(isl_pw_multi_aff_get_space(pma),
6520 isl_multi_pw_aff_get_space(mpa));
6521
6522 for (i = 0; i < mpa->n; ++i) {
6523 mpa->p[i] = isl_pw_aff_pullback_pw_multi_aff_aligned(mpa->p[i],
6524 isl_pw_multi_aff_copy(pma));
6525 if (!mpa->p[i])
6526 goto error;
6527 }
6528
6529 isl_pw_multi_aff_free(pma);
6530 isl_space_free(mpa->space);
6531 mpa->space = space;
6532 return mpa;
6533error:
6534 isl_space_free(space);
6535 isl_multi_pw_aff_free(mpa);
6536 isl_pw_multi_aff_free(pma);
6537 return NULL((void*)0);
6538}
6539
6540/* Compute the pullback of "mpa" by the function represented by "pma".
6541 * In other words, plug in "pma" in "mpa".
6542 */
6543__isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_pw_multi_aff(
6544 __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_multi_aff *pma)
6545{
6546 if (!mpa || !pma)
6547 goto error;
6548 if (isl_space_match(mpa->space, isl_dim_param, pma->dim, isl_dim_param))
6549 return isl_multi_pw_aff_pullback_pw_multi_aff_aligned(mpa, pma);
6550 mpa = isl_multi_pw_aff_align_params(mpa,
6551 isl_pw_multi_aff_get_space(pma));
6552 pma = isl_pw_multi_aff_align_params(pma,
6553 isl_multi_pw_aff_get_space(mpa));
6554 return isl_multi_pw_aff_pullback_pw_multi_aff_aligned(mpa, pma);
6555error:
6556 isl_multi_pw_aff_free(mpa);
6557 isl_pw_multi_aff_free(pma);
6558 return NULL((void*)0);
6559}
6560
6561/* Apply "aff" to "mpa". The range of "mpa" needs to be compatible
6562 * with the domain of "aff". The domain of the result is the same
6563 * as that of "mpa".
6564 * "mpa" and "aff" are assumed to have been aligned.
6565 *
6566 * We first extract the parametric constant from "aff", defined
6567 * over the correct domain.
6568 * Then we add the appropriate combinations of the members of "mpa".
6569 * Finally, we add the integer divisions through recursive calls.
6570 */
6571static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff_aligned(
6572 __isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff)
6573{
6574 int i, n_in, n_div;
6575 isl_space *space;
6576 isl_val *v;
6577 isl_pw_aff *pa;
6578 isl_aff *tmp;
6579
6580 n_in = isl_aff_dim(aff, isl_dim_in);
6581 n_div = isl_aff_dim(aff, isl_dim_div);
6582
6583 space = isl_space_domain(isl_multi_pw_aff_get_space(mpa));
6584 tmp = isl_aff_copy(aff);
6585 tmp = isl_aff_drop_dims(tmp, isl_dim_div, 0, n_div);
6586 tmp = isl_aff_drop_dims(tmp, isl_dim_in, 0, n_in);
6587 tmp = isl_aff_add_dims(tmp, isl_dim_in,
6588 isl_space_dim(space, isl_dim_set));
6589 tmp = isl_aff_reset_domain_space(tmp, space);
6590 pa = isl_pw_aff_from_aff(tmp);
6591
6592 for (i = 0; i < n_in; ++i) {
6593 isl_pw_aff *pa_i;
6594
6595 if (!isl_aff_involves_dims(aff, isl_dim_in, i, 1))
6596 continue;
6597 v = isl_aff_get_coefficient_val(aff, isl_dim_in, i);
6598 pa_i = isl_multi_pw_aff_get_pw_aff(mpa, i);
6599 pa_i = isl_pw_aff_scale_val(pa_i, v);
6600 pa = isl_pw_aff_add(pa, pa_i);
6601 }
6602
6603 for (i = 0; i < n_div; ++i) {
6604 isl_aff *div;
6605 isl_pw_aff *pa_i;
6606
6607 if (!isl_aff_involves_dims(aff, isl_dim_div, i, 1))
6608 continue;
6609 div = isl_aff_get_div(aff, i);
6610 pa_i = isl_multi_pw_aff_apply_aff_aligned(
6611 isl_multi_pw_aff_copy(mpa), div);
6612 pa_i = isl_pw_aff_floor(pa_i);
6613 v = isl_aff_get_coefficient_val(aff, isl_dim_div, i);
6614 pa_i = isl_pw_aff_scale_val(pa_i, v);
6615 pa = isl_pw_aff_add(pa, pa_i);
6616 }
6617
6618 isl_multi_pw_aff_free(mpa);
6619 isl_aff_free(aff);
6620
6621 return pa;
6622}
6623
6624/* Apply "aff" to "mpa". The range of "mpa" needs to be compatible
6625 * with the domain of "aff". The domain of the result is the same
6626 * as that of "mpa".
6627 */
6628__isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff(
6629 __isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff)
6630{
6631 if (!aff || !mpa)
6632 goto error;
6633 if (isl_space_match(aff->ls->dim, isl_dim_param,
6634 mpa->space, isl_dim_param))
6635 return isl_multi_pw_aff_apply_aff_aligned(mpa, aff);
6636
6637 aff = isl_aff_align_params(aff, isl_multi_pw_aff_get_space(mpa));
6638 mpa = isl_multi_pw_aff_align_params(mpa, isl_aff_get_space(aff));
6639
6640 return isl_multi_pw_aff_apply_aff_aligned(mpa, aff);
6641error:
6642 isl_aff_free(aff);
6643 isl_multi_pw_aff_free(mpa);
6644 return NULL((void*)0);
6645}
6646
6647/* Apply "pa" to "mpa". The range of "mpa" needs to be compatible
6648 * with the domain of "pa". The domain of the result is the same
6649 * as that of "mpa".
6650 * "mpa" and "pa" are assumed to have been aligned.
6651 *
6652 * We consider each piece in turn. Note that the domains of the
6653 * pieces are assumed to be disjoint and they remain disjoint
6654 * after taking the preimage (over the same function).
6655 */
6656static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_pw_aff_aligned(
6657 __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *pa)
6658{
6659 isl_space *space;
6660 isl_pw_aff *res;
6661 int i;
6662
6663 if (!mpa || !pa)
6664 goto error;
6665
6666 space = isl_space_join(isl_multi_pw_aff_get_space(mpa),
6667 isl_pw_aff_get_space(pa));
6668 res = isl_pw_aff_empty(space);
6669
6670 for (i = 0; i < pa->n; ++i) {
6671 isl_pw_aff *pa_i;
6672 isl_setisl_map *domain;
6673
6674 pa_i = isl_multi_pw_aff_apply_aff_aligned(
6675 isl_multi_pw_aff_copy(mpa),
6676 isl_aff_copy(pa->p[i].aff));
6677 domain = isl_set_copy(pa->p[i].set);
6678 domain = isl_set_preimage_multi_pw_aff(domain,
6679 isl_multi_pw_aff_copy(mpa));
6680 pa_i = isl_pw_aff_intersect_domain(pa_i, domain);
6681 res = isl_pw_aff_add_disjoint(res, pa_i);
6682 }
6683
6684 isl_pw_aff_free(pa);
6685 isl_multi_pw_aff_free(mpa);
6686 return res;
6687error:
6688 isl_pw_aff_free(pa);
6689 isl_multi_pw_aff_free(mpa);
6690 return NULL((void*)0);
6691}
6692
6693/* Apply "pa" to "mpa". The range of "mpa" needs to be compatible
6694 * with the domain of "pa". The domain of the result is the same
6695 * as that of "mpa".
6696 */
6697__isl_give isl_pw_aff *isl_multi_pw_aff_apply_pw_aff(
6698 __isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *pa)
6699{
6700 if (!pa || !mpa)
6701 goto error;
6702 if (isl_space_match(pa->dim, isl_dim_param, mpa->space, isl_dim_param))
6703 return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa);
6704
6705 pa = isl_pw_aff_align_params(pa, isl_multi_pw_aff_get_space(mpa));
6706 mpa = isl_multi_pw_aff_align_params(mpa, isl_pw_aff_get_space(pa));
6707
6708 return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa);
6709error:
6710 isl_pw_aff_free(pa);
6711 isl_multi_pw_aff_free(mpa);
6712 return NULL((void*)0);
6713}
6714
6715/* Compute the pullback of "pa" by the function represented by "mpa".
6716 * In other words, plug in "mpa" in "pa".
6717 * "pa" and "mpa" are assumed to have been aligned.
6718 *
6719 * The pullback is computed by applying "pa" to "mpa".
6720 */
6721static __isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff_aligned(
6722 __isl_take isl_pw_aff *pa, __isl_take isl_multi_pw_aff *mpa)
6723{
6724 return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa);
6725}
6726
6727/* Compute the pullback of "pa" by the function represented by "mpa".
6728 * In other words, plug in "mpa" in "pa".
6729 *
6730 * The pullback is computed by applying "pa" to "mpa".
6731 */
6732__isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff(
6733 __isl_take isl_pw_aff *pa, __isl_take isl_multi_pw_aff *mpa)
6734{
6735 return isl_multi_pw_aff_apply_pw_aff(mpa, pa);
6736}
6737
6738/* Compute the pullback of "mpa1" by the function represented by "mpa2".
6739 * In other words, plug in "mpa2" in "mpa1".
6740 *
6741 * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
6742 *
6743 * We pullback each member of "mpa1" in turn.
6744 */
6745static __isl_give isl_multi_pw_aff *
6746isl_multi_pw_aff_pullback_multi_pw_aff_aligned(
6747 __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2)
6748{
6749 int i;
6750 isl_space *space = NULL((void*)0);
6751
6752 mpa1 = isl_multi_pw_aff_cow(mpa1);
6753 if (!mpa1 || !mpa2)
6754 goto error;
6755
6756 space = isl_space_join(isl_multi_pw_aff_get_space(mpa2),
6757 isl_multi_pw_aff_get_space(mpa1));
6758
6759 for (i = 0; i < mpa1->n; ++i) {
6760 mpa1->p[i] = isl_pw_aff_pullback_multi_pw_aff_aligned(
6761 mpa1->p[i], isl_multi_pw_aff_copy(mpa2));
6762 if (!mpa1->p[i])
6763 goto error;
6764 }
6765
6766 mpa1 = isl_multi_pw_aff_reset_space(mpa1, space);
6767
6768 isl_multi_pw_aff_free(mpa2);
6769 return mpa1;
6770error:
6771 isl_space_free(space);
6772 isl_multi_pw_aff_free(mpa1);
6773 isl_multi_pw_aff_free(mpa2);
6774 return NULL((void*)0);
6775}
6776
6777/* Compute the pullback of "mpa1" by the function represented by "mpa2".
6778 * In other words, plug in "mpa2" in "mpa1".
6779 */
6780__isl_give isl_multi_pw_aff *isl_multi_pw_aff_pullback_multi_pw_aff(
6781 __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2)
6782{
6783 return isl_multi_pw_aff_align_params_multi_multi_and(mpa1, mpa2,
6784 &isl_multi_pw_aff_pullback_multi_pw_aff_aligned);
6785}
6786
6787/* Align the parameters of "mpa1" and "mpa2", check that the ranges
6788 * of "mpa1" and "mpa2" live in the same space, construct map space
6789 * between the domain spaces of "mpa1" and "mpa2" and call "order"
6790 * with this map space as extract argument.
6791 */
6792static __isl_give isl_map *isl_multi_pw_aff_order_map(
6793 __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2,
6794 __isl_give isl_map *(*order)(__isl_keep isl_multi_pw_aff *mpa1,
6795 __isl_keep isl_multi_pw_aff *mpa2, __isl_take isl_space *space))
6796{
6797 int match;
6798 isl_space *space1, *space2;
6799 isl_map *res;
6800
6801 mpa1 = isl_multi_pw_aff_align_params(mpa1,
6802 isl_multi_pw_aff_get_space(mpa2));
6803 mpa2 = isl_multi_pw_aff_align_params(mpa2,
6804 isl_multi_pw_aff_get_space(mpa1));
6805 if (!mpa1 || !mpa2)
6806 goto error;
6807 match = isl_space_tuple_is_equal(mpa1->space, isl_dim_out,
6808 mpa2->space, isl_dim_out);
6809 if (match < 0)
6810 goto error;
6811 if (!match)
6812 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 6813); goto error; } while (0)
6813 "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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 6813); goto error; } while (0)
;
6814 space1 = isl_space_domain(isl_multi_pw_aff_get_space(mpa1));
6815 space2 = isl_space_domain(isl_multi_pw_aff_get_space(mpa2));
6816 space1 = isl_space_map_from_domain_and_range(space1, space2);
6817
6818 res = order(mpa1, mpa2, space1);
6819 isl_multi_pw_aff_free(mpa1);
6820 isl_multi_pw_aff_free(mpa2);
6821 return res;
6822error:
6823 isl_multi_pw_aff_free(mpa1);
6824 isl_multi_pw_aff_free(mpa2);
6825 return NULL((void*)0);
6826}
6827
6828/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
6829 * where the function values are equal. "space" is the space of the result.
6830 * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
6831 *
6832 * "mpa1" and "mpa2" are equal when each of the pairs of elements
6833 * in the sequences are equal.
6834 */
6835static __isl_give isl_map *isl_multi_pw_aff_eq_map_on_space(
6836 __isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2,
6837 __isl_take isl_space *space)
6838{
6839 int i, n;
6840 isl_map *res;
6841
6842 res = isl_map_universe(space);
6843
6844 n = isl_multi_pw_aff_dim(mpa1, isl_dim_out);
6845 for (i = 0; i < n; ++i) {
6846 isl_pw_aff *pa1, *pa2;
6847 isl_map *map;
6848
6849 pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i);
6850 pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i);
6851 map = isl_pw_aff_eq_map(pa1, pa2);
6852 res = isl_map_intersect(res, map);
6853 }
6854
6855 return res;
6856}
6857
6858/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
6859 * where the function values are equal.
6860 */
6861__isl_give isl_map *isl_multi_pw_aff_eq_map(__isl_take isl_multi_pw_aff *mpa1,
6862 __isl_take isl_multi_pw_aff *mpa2)
6863{
6864 return isl_multi_pw_aff_order_map(mpa1, mpa2,
6865 &isl_multi_pw_aff_eq_map_on_space);
6866}
6867
6868/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
6869 * where the function values of "mpa1" is lexicographically satisfies "base"
6870 * compared to that of "mpa2". "space" is the space of the result.
6871 * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
6872 *
6873 * "mpa1" lexicographically satisfies "base" compared to "mpa2"
6874 * if its i-th element satisfies "base" when compared to
6875 * the i-th element of "mpa2" while all previous elements are
6876 * pairwise equal.
6877 */
6878static __isl_give isl_map *isl_multi_pw_aff_lex_map_on_space(
6879 __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2,
6880 __isl_give isl_map *(*base)(__isl_take isl_pw_aff *pa1,
6881 __isl_take isl_pw_aff *pa2),
6882 __isl_take isl_space *space)
6883{
6884 int i, n;
6885 isl_map *res, *rest;
6886
6887 res = isl_map_empty(isl_space_copy(space));
6888 rest = isl_map_universe(space);
6889
6890 n = isl_multi_pw_aff_dim(mpa1, isl_dim_out);
6891 for (i = 0; i < n; ++i) {
6892 isl_pw_aff *pa1, *pa2;
6893 isl_map *map;
6894
6895 pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i);
6896 pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i);
6897 map = base(pa1, pa2);
6898 map = isl_map_intersect(map, isl_map_copy(rest));
6899 res = isl_map_union(res, map);
6900
6901 if (i == n - 1)
6902 continue;
6903
6904 pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i);
6905 pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i);
6906 map = isl_pw_aff_eq_map(pa1, pa2);
6907 rest = isl_map_intersect(rest, map);
6908 }
6909
6910 isl_map_free(rest);
6911 return res;
6912}
6913
6914/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
6915 * where the function value of "mpa1" is lexicographically less than that
6916 * of "mpa2". "space" is the space of the result.
6917 * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
6918 *
6919 * "mpa1" is less than "mpa2" if its i-th element is smaller
6920 * than the i-th element of "mpa2" while all previous elements are
6921 * pairwise equal.
6922 */
6923__isl_give isl_map *isl_multi_pw_aff_lex_lt_map_on_space(
6924 __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2,
6925 __isl_take isl_space *space)
6926{
6927 return isl_multi_pw_aff_lex_map_on_space(mpa1, mpa2,
6928 &isl_pw_aff_lt_map, space);
6929}
6930
6931/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
6932 * where the function value of "mpa1" is lexicographically less than that
6933 * of "mpa2".
6934 */
6935__isl_give isl_map *isl_multi_pw_aff_lex_lt_map(
6936 __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2)
6937{
6938 return isl_multi_pw_aff_order_map(mpa1, mpa2,
6939 &isl_multi_pw_aff_lex_lt_map_on_space);
6940}
6941
6942/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
6943 * where the function value of "mpa1" is lexicographically greater than that
6944 * of "mpa2". "space" is the space of the result.
6945 * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
6946 *
6947 * "mpa1" is greater than "mpa2" if its i-th element is greater
6948 * than the i-th element of "mpa2" while all previous elements are
6949 * pairwise equal.
6950 */
6951__isl_give isl_map *isl_multi_pw_aff_lex_gt_map_on_space(
6952 __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2,
6953 __isl_take isl_space *space)
6954{
6955 return isl_multi_pw_aff_lex_map_on_space(mpa1, mpa2,
6956 &isl_pw_aff_gt_map, space);
6957}
6958
6959/* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
6960 * where the function value of "mpa1" is lexicographically greater than that
6961 * of "mpa2".
6962 */
6963__isl_give isl_map *isl_multi_pw_aff_lex_gt_map(
6964 __isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2)
6965{
6966 return isl_multi_pw_aff_order_map(mpa1, mpa2,
6967 &isl_multi_pw_aff_lex_gt_map_on_space);
6968}
6969
6970/* Compare two isl_affs.
6971 *
6972 * Return -1 if "aff1" is "smaller" than "aff2", 1 if "aff1" is "greater"
6973 * than "aff2" and 0 if they are equal.
6974 *
6975 * The order is fairly arbitrary. We do consider expressions that only involve
6976 * earlier dimensions as "smaller".
6977 */
6978int isl_aff_plain_cmp(__isl_keep isl_aff *aff1, __isl_keep isl_aff *aff2)
6979{
6980 int cmp;
6981 int last1, last2;
6982
6983 if (aff1 == aff2)
6984 return 0;
6985
6986 if (!aff1)
6987 return -1;
6988 if (!aff2)
6989 return 1;
6990
6991 cmp = isl_local_space_cmp(aff1->ls, aff2->ls);
6992 if (cmp != 0)
6993 return cmp;
6994
6995 last1 = isl_seq_last_non_zero(aff1->v->el + 1, aff1->v->size - 1);
6996 last2 = isl_seq_last_non_zero(aff2->v->el + 1, aff1->v->size - 1);
6997 if (last1 != last2)
6998 return last1 - last2;
6999
7000 return isl_seq_cmp(aff1->v->el, aff2->v->el, aff1->v->size);
7001}
7002
7003/* Compare two isl_pw_affs.
7004 *
7005 * Return -1 if "pa1" is "smaller" than "pa2", 1 if "pa1" is "greater"
7006 * than "pa2" and 0 if they are equal.
7007 *
7008 * The order is fairly arbitrary. We do consider expressions that only involve
7009 * earlier dimensions as "smaller".
7010 */
7011int isl_pw_aff_plain_cmp(__isl_keep isl_pw_aff *pa1,
7012 __isl_keep isl_pw_aff *pa2)
7013{
7014 int i;
7015 int cmp;
7016
7017 if (pa1 == pa2)
7018 return 0;
7019
7020 if (!pa1)
7021 return -1;
7022 if (!pa2)
7023 return 1;
7024
7025 cmp = isl_space_cmp(pa1->dim, pa2->dim);
7026 if (cmp != 0)
7027 return cmp;
7028
7029 if (pa1->n != pa2->n)
7030 return pa1->n - pa2->n;
7031
7032 for (i = 0; i < pa1->n; ++i) {
7033 cmp = isl_set_plain_cmp(pa1->p[i].set, pa2->p[i].set);
7034 if (cmp != 0)
7035 return cmp;
7036 cmp = isl_aff_plain_cmp(pa1->p[i].aff, pa2->p[i].aff);
7037 if (cmp != 0)
7038 return cmp;
7039 }
7040
7041 return 0;
7042}
7043
7044/* Return a piecewise affine expression that is equal to "v" on "domain".
7045 */
7046__isl_give isl_pw_aff *isl_pw_aff_val_on_domain(__isl_take isl_setisl_map *domain,
7047 __isl_take isl_val *v)
7048{
7049 isl_space *space;
7050 isl_local_space *ls;
7051 isl_aff *aff;
7052
7053 space = isl_set_get_space(domain);
7054 ls = isl_local_space_from_space(space);
7055 aff = isl_aff_val_on_domain(ls, v);
7056
7057 return isl_pw_aff_alloc(domain, aff);
7058}
7059
7060/* Return a multi affine expression that is equal to "mv" on domain
7061 * space "space".
7062 */
7063__isl_give isl_multi_aff *isl_multi_aff_multi_val_on_space(
7064 __isl_take isl_space *space, __isl_take isl_multi_val *mv)
7065{
7066 int i, n;
7067 isl_space *space2;
7068 isl_local_space *ls;
7069 isl_multi_aff *ma;
7070
7071 if (!space || !mv)
7072 goto error;
7073
7074 n = isl_multi_val_dim(mv, isl_dim_set);
7075 space2 = isl_multi_val_get_space(mv);
7076 space2 = isl_space_align_params(space2, isl_space_copy(space));
7077 space = isl_space_align_params(space, isl_space_copy(space2));
7078 space = isl_space_map_from_domain_and_range(space, space2);
7079 ma = isl_multi_aff_alloc(isl_space_copy(space));
7080 ls = isl_local_space_from_space(isl_space_domain(space));
7081 for (i = 0; i < n; ++i) {
7082 isl_val *v;
7083 isl_aff *aff;
7084
7085 v = isl_multi_val_get_val(mv, i);
7086 aff = isl_aff_val_on_domain(isl_local_space_copy(ls), v);
7087 ma = isl_multi_aff_set_aff(ma, i, aff);
7088 }
7089 isl_local_space_free(ls);
7090
7091 isl_multi_val_free(mv);
7092 return ma;
7093error:
7094 isl_space_free(space);
7095 isl_multi_val_free(mv);
7096 return NULL((void*)0);
7097}
7098
7099/* Return a piecewise multi-affine expression
7100 * that is equal to "mv" on "domain".
7101 */
7102__isl_give isl_pw_multi_aff *isl_pw_multi_aff_multi_val_on_domain(
7103 __isl_take isl_setisl_map *domain, __isl_take isl_multi_val *mv)
7104{
7105 isl_space *space;
7106 isl_multi_aff *ma;
7107
7108 space = isl_set_get_space(domain);
7109 ma = isl_multi_aff_multi_val_on_space(space, mv);
7110
7111 return isl_pw_multi_aff_alloc(domain, ma);
7112}
7113
7114/* Internal data structure for isl_union_pw_multi_aff_multi_val_on_domain.
7115 * mv is the value that should be attained on each domain set
7116 * res collects the results
7117 */
7118struct isl_union_pw_multi_aff_multi_val_on_domain_data {
7119 isl_multi_val *mv;
7120 isl_union_pw_multi_aff *res;
7121};
7122
7123/* Create an isl_pw_multi_aff equal to data->mv on "domain"
7124 * and add it to data->res.
7125 */
7126static isl_stat pw_multi_aff_multi_val_on_domain(__isl_take isl_setisl_map *domain,
7127 void *user)
7128{
7129 struct isl_union_pw_multi_aff_multi_val_on_domain_data *data = user;
7130 isl_pw_multi_aff *pma;
7131 isl_multi_val *mv;
7132
7133 mv = isl_multi_val_copy(data->mv);
7134 pma = isl_pw_multi_aff_multi_val_on_domain(domain, mv);
7135 data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma);
7136
7137 return data->res ? isl_stat_ok : isl_stat_error;
7138}
7139
7140/* Return a union piecewise multi-affine expression
7141 * that is equal to "mv" on "domain".
7142 */
7143__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_multi_val_on_domain(
7144 __isl_take isl_union_setisl_union_map *domain, __isl_take isl_multi_val *mv)
7145{
7146 struct isl_union_pw_multi_aff_multi_val_on_domain_data data;
7147 isl_space *space;
7148
7149 space = isl_union_set_get_space(domain);
7150 data.res = isl_union_pw_multi_aff_empty(space);
7151 data.mv = mv;
7152 if (isl_union_set_foreach_set(domain,
7153 &pw_multi_aff_multi_val_on_domain, &data) < 0)
7154 data.res = isl_union_pw_multi_aff_free(data.res);
7155 isl_union_set_free(domain);
7156 isl_multi_val_free(mv);
7157 return data.res;
7158}
7159
7160/* Compute the pullback of data->pma by the function represented by "pma2",
7161 * provided the spaces match, and add the results to data->res.
7162 */
7163static isl_stat pullback_entry(void **entry, void *user)
7164{
7165 struct isl_union_pw_multi_aff_bin_data *data = user;
7166 isl_pw_multi_aff *pma2 = *entry;
7167
7168 if (!isl_space_tuple_is_equal(data->pma->dim, isl_dim_in,
7169 pma2->dim, isl_dim_out))
7170 return isl_stat_ok;
7171
7172 pma2 = isl_pw_multi_aff_pullback_pw_multi_aff(
7173 isl_pw_multi_aff_copy(data->pma),
7174 isl_pw_multi_aff_copy(pma2));
7175
7176 data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2);
7177 if (!data->res)
7178 return isl_stat_error;
7179
7180 return isl_stat_ok;
7181}
7182
7183/* Compute the pullback of "upma1" by the function represented by "upma2".
7184 */
7185__isl_give isl_union_pw_multi_aff *
7186isl_union_pw_multi_aff_pullback_union_pw_multi_aff(
7187 __isl_take isl_union_pw_multi_aff *upma1,
7188 __isl_take isl_union_pw_multi_aff *upma2)
7189{
7190 return bin_op(upma1, upma2, &pullback_entry);
7191}
7192
7193/* Check that the domain space of "upa" matches "space".
7194 *
7195 * Return 0 on success and -1 on error.
7196 *
7197 * This function is called from isl_multi_union_pw_aff_set_union_pw_aff and
7198 * can in principle never fail since the space "space" is that
7199 * of the isl_multi_union_pw_aff and is a set space such that
7200 * there is no domain space to match.
7201 *
7202 * We check the parameters and double-check that "space" is
7203 * indeed that of a set.
7204 */
7205static int isl_union_pw_aff_check_match_domain_space(
7206 __isl_keep isl_union_pw_aff *upa, __isl_keep isl_space *space)
7207{
7208 isl_space *upa_space;
7209 int match;
7210
7211 if (!upa || !space)
7212 return -1;
7213
7214 match = isl_space_is_set(space);
7215 if (match < 0)
7216 return -1;
7217 if (!match)
7218 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7219); return -1; } while (0)
7219 "expecting set space", return -1)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "expecting set space", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7219); return -1; } while (0)
;
7220
7221 upa_space = isl_union_pw_aff_get_space(upa);
7222 match = isl_space_match(space, isl_dim_param, upa_space, isl_dim_param);
7223 if (match < 0)
7224 goto error;
7225 if (!match)
7226 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7227); goto error; } while (0)
7227 "parameters don't match", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "parameters don't match", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7227); goto error; } while (0)
;
7228
7229 isl_space_free(upa_space);
7230 return 0;
7231error:
7232 isl_space_free(upa_space);
7233 return -1;
7234}
7235
7236/* Do the parameters of "upa" match those of "space"?
7237 */
7238static int isl_union_pw_aff_matching_params(__isl_keep isl_union_pw_aff *upa,
7239 __isl_keep isl_space *space)
7240{
7241 isl_space *upa_space;
7242 int match;
7243
7244 if (!upa || !space)
7245 return -1;
7246
7247 upa_space = isl_union_pw_aff_get_space(upa);
7248
7249 match = isl_space_match(space, isl_dim_param, upa_space, isl_dim_param);
7250
7251 isl_space_free(upa_space);
7252 return match;
7253}
7254
7255/* Internal data structure for isl_union_pw_aff_reset_domain_space.
7256 * space represents the new parameters.
7257 * res collects the results.
7258 */
7259struct isl_union_pw_aff_reset_params_data {
7260 isl_space *space;
7261 isl_union_pw_aff *res;
7262};
7263
7264/* Replace the parameters of "pa" by data->space and
7265 * add the result to data->res.
7266 */
7267static isl_stat reset_params(__isl_take isl_pw_aff *pa, void *user)
7268{
7269 struct isl_union_pw_aff_reset_params_data *data = user;
7270 isl_space *space;
7271
7272 space = isl_pw_aff_get_space(pa);
7273 space = isl_space_replace(space, isl_dim_param, data->space);
7274 pa = isl_pw_aff_reset_space(pa, space);
7275 data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
7276
7277 return data->res ? isl_stat_ok : isl_stat_error;
7278}
7279
7280/* Replace the domain space of "upa" by "space".
7281 * Since a union expression does not have a (single) domain space,
7282 * "space" is necessarily a parameter space.
7283 *
7284 * Since the order and the names of the parameters determine
7285 * the hash value, we need to create a new hash table.
7286 */
7287static __isl_give isl_union_pw_aff *isl_union_pw_aff_reset_domain_space(
7288 __isl_take isl_union_pw_aff *upa, __isl_take isl_space *space)
7289{
7290 struct isl_union_pw_aff_reset_params_data data = { space };
7291 int match;
7292
7293 match = isl_union_pw_aff_matching_params(upa, space);
7294 if (match < 0)
7295 upa = isl_union_pw_aff_free(upa);
7296 else if (match) {
7297 isl_space_free(space);
7298 return upa;
7299 }
7300
7301 data.res = isl_union_pw_aff_empty(isl_space_copy(space));
7302 if (isl_union_pw_aff_foreach_pw_aff(upa, &reset_params, &data) < 0)
7303 data.res = isl_union_pw_aff_free(data.res);
7304
7305 isl_union_pw_aff_free(upa);
7306 isl_space_free(space);
7307 return data.res;
7308}
7309
7310/* Replace the entry of isl_union_pw_aff to which "entry" points
7311 * by its floor.
7312 */
7313static isl_stat floor_entry(void **entry, void *user)
7314{
7315 isl_pw_aff **pa = (isl_pw_aff **) entry;
7316
7317 *pa = isl_pw_aff_floor(*pa);
7318 if (!*pa)
7319 return isl_stat_error;
7320
7321 return isl_stat_ok;
7322}
7323
7324/* Given f, return floor(f).
7325 */
7326__isl_give isl_union_pw_aff *isl_union_pw_aff_floor(
7327 __isl_take isl_union_pw_aff *upa)
7328{
7329 isl_ctx *ctx;
7330
7331 upa = isl_union_pw_aff_cow(upa);
7332 if (!upa)
7333 return NULL((void*)0);
7334
7335 ctx = isl_union_pw_aff_get_ctx(upa);
7336 if (isl_hash_table_foreach(ctx, &upa->table, &floor_entry, NULL((void*)0)) < 0)
7337 upa = isl_union_pw_aff_free(upa);
7338
7339 return upa;
7340}
7341
7342/* Compute
7343 *
7344 * upa mod m = upa - m * floor(upa/m)
7345 *
7346 * with m an integer value.
7347 */
7348__isl_give isl_union_pw_aff *isl_union_pw_aff_mod_val(
7349 __isl_take isl_union_pw_aff *upa, __isl_take isl_val *m)
7350{
7351 isl_union_pw_aff *res;
7352
7353 if (!upa || !m)
7354 goto error;
7355
7356 if (!isl_val_is_int(m))
7357 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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7358); goto error; } while (0)
7358 "expecting integer modulo", goto error)do { isl_handle_error(isl_val_get_ctx(m), isl_error_invalid, "expecting integer modulo"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7358); goto error; } while (0)
;
7359 if (!isl_val_is_pos(m))
7360 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"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7361); goto error; } while (0)
7361 "expecting positive modulo", goto error)do { isl_handle_error(isl_val_get_ctx(m), isl_error_invalid, "expecting positive modulo"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7361); goto error; } while (0)
;
7362
7363 res = isl_union_pw_aff_copy(upa);
7364 upa = isl_union_pw_aff_scale_down_val(upa, isl_val_copy(m));
7365 upa = isl_union_pw_aff_floor(upa);
7366 upa = isl_union_pw_aff_scale_val(upa, m);
7367 res = isl_union_pw_aff_sub(res, upa);
7368
7369 return res;
7370error:
7371 isl_val_free(m);
7372 isl_union_pw_aff_free(upa);
7373 return NULL((void*)0);
7374}
7375
7376/* Internal data structure for isl_union_pw_aff_aff_on_domain.
7377 * "aff" is the symbolic value that the resulting isl_union_pw_aff
7378 * needs to attain.
7379 * "res" collects the results.
7380 */
7381struct isl_union_pw_aff_aff_on_domain_data {
7382 isl_aff *aff;
7383 isl_union_pw_aff *res;
7384};
7385
7386/* Construct a piecewise affine expression that is equal to data->aff
7387 * on "domain" and add the result to data->res.
7388 */
7389static isl_stat pw_aff_aff_on_domain(__isl_take isl_setisl_map *domain, void *user)
7390{
7391 struct isl_union_pw_aff_aff_on_domain_data *data = user;
7392 isl_pw_aff *pa;
7393 isl_aff *aff;
7394 int dim;
7395
7396 aff = isl_aff_copy(data->aff);
7397 dim = isl_set_dim(domain, isl_dim_set);
7398 aff = isl_aff_add_dims(aff, isl_dim_in, dim);
7399 aff = isl_aff_reset_domain_space(aff, isl_set_get_space(domain));
7400 pa = isl_pw_aff_alloc(domain, aff);
7401 data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
7402
7403 return data->res ? isl_stat_ok : isl_stat_error;
7404}
7405
7406/* Internal data structure for isl_union_pw_multi_aff_get_union_pw_aff.
7407 * pos is the output position that needs to be extracted.
7408 * res collects the results.
7409 */
7410struct isl_union_pw_multi_aff_get_union_pw_aff_data {
7411 int pos;
7412 isl_union_pw_aff *res;
7413};
7414
7415/* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma"
7416 * (assuming it has such a dimension) and add it to data->res.
7417 */
7418static isl_stat get_union_pw_aff(__isl_take isl_pw_multi_aff *pma, void *user)
7419{
7420 struct isl_union_pw_multi_aff_get_union_pw_aff_data *data = user;
7421 int n_out;
7422 isl_pw_aff *pa;
7423
7424 if (!pma)
7425 return isl_stat_error;
7426
7427 n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
7428 if (data->pos >= n_out) {
7429 isl_pw_multi_aff_free(pma);
7430 return isl_stat_ok;
7431 }
7432
7433 pa = isl_pw_multi_aff_get_pw_aff(pma, data->pos);
7434 isl_pw_multi_aff_free(pma);
7435
7436 data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
7437
7438 return data->res ? isl_stat_ok : isl_stat_error;
7439}
7440
7441/* Extract an isl_union_pw_aff corresponding to
7442 * output dimension "pos" of "upma".
7443 */
7444__isl_give isl_union_pw_aff *isl_union_pw_multi_aff_get_union_pw_aff(
7445 __isl_keep isl_union_pw_multi_aff *upma, int pos)
7446{
7447 struct isl_union_pw_multi_aff_get_union_pw_aff_data data;
7448 isl_space *space;
7449
7450 if (!upma)
7451 return NULL((void*)0);
7452
7453 if (pos < 0)
7454 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7455); return ((void*)0); } while (0)
7455 "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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7455); return ((void*)0); } while (0)
;
7456
7457 space = isl_union_pw_multi_aff_get_space(upma);
7458 data.res = isl_union_pw_aff_empty(space);
7459 data.pos = pos;
7460 if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
7461 &get_union_pw_aff, &data) < 0)
7462 data.res = isl_union_pw_aff_free(data.res);
7463
7464 return data.res;
7465}
7466
7467/* Return a union piecewise affine expression
7468 * that is equal to "aff" on "domain".
7469 *
7470 * Construct an isl_pw_aff on each of the sets in "domain" and
7471 * collect the results.
7472 */
7473__isl_give isl_union_pw_aff *isl_union_pw_aff_aff_on_domain(
7474 __isl_take isl_union_setisl_union_map *domain, __isl_take isl_aff *aff)
7475{
7476 struct isl_union_pw_aff_aff_on_domain_data data;
7477 isl_space *space;
7478
7479 if (!domain || !aff)
7480 goto error;
7481 if (!isl_local_space_is_params(aff->ls))
7482 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting parametric expression", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7483); goto error; } while (0)
7483 "expecting parametric expression", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "expecting parametric expression", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7483); goto error; } while (0)
;
7484
7485 space = isl_union_set_get_space(domain);
7486 data.res = isl_union_pw_aff_empty(space);
7487 data.aff = aff;
7488 if (isl_union_set_foreach_set(domain, &pw_aff_aff_on_domain, &data) < 0)
7489 data.res = isl_union_pw_aff_free(data.res);
7490 isl_union_set_free(domain);
7491 isl_aff_free(aff);
7492 return data.res;
7493error:
7494 isl_union_set_free(domain);
7495 isl_aff_free(aff);
7496 return NULL((void*)0);
7497}
7498
7499/* Internal data structure for isl_union_pw_aff_val_on_domain.
7500 * "v" is the value that the resulting isl_union_pw_aff needs to attain.
7501 * "res" collects the results.
7502 */
7503struct isl_union_pw_aff_val_on_domain_data {
7504 isl_val *v;
7505 isl_union_pw_aff *res;
7506};
7507
7508/* Construct a piecewise affine expression that is equal to data->v
7509 * on "domain" and add the result to data->res.
7510 */
7511static isl_stat pw_aff_val_on_domain(__isl_take isl_setisl_map *domain, void *user)
7512{
7513 struct isl_union_pw_aff_val_on_domain_data *data = user;
7514 isl_pw_aff *pa;
7515 isl_val *v;
7516
7517 v = isl_val_copy(data->v);
7518 pa = isl_pw_aff_val_on_domain(domain, v);
7519 data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
7520
7521 return data->res ? isl_stat_ok : isl_stat_error;
7522}
7523
7524/* Return a union piecewise affine expression
7525 * that is equal to "v" on "domain".
7526 *
7527 * Construct an isl_pw_aff on each of the sets in "domain" and
7528 * collect the results.
7529 */
7530__isl_give isl_union_pw_aff *isl_union_pw_aff_val_on_domain(
7531 __isl_take isl_union_setisl_union_map *domain, __isl_take isl_val *v)
7532{
7533 struct isl_union_pw_aff_val_on_domain_data data;
7534 isl_space *space;
7535
7536 space = isl_union_set_get_space(domain);
7537 data.res = isl_union_pw_aff_empty(space);
7538 data.v = v;
7539 if (isl_union_set_foreach_set(domain, &pw_aff_val_on_domain, &data) < 0)
7540 data.res = isl_union_pw_aff_free(data.res);
7541 isl_union_set_free(domain);
7542 isl_val_free(v);
7543 return data.res;
7544}
7545
7546/* Construct a piecewise multi affine expression
7547 * that is equal to "pa" and add it to upma.
7548 */
7549static isl_stat pw_multi_aff_from_pw_aff_entry(__isl_take isl_pw_aff *pa,
7550 void *user)
7551{
7552 isl_union_pw_multi_aff **upma = user;
7553 isl_pw_multi_aff *pma;
7554
7555 pma = isl_pw_multi_aff_from_pw_aff(pa);
7556 *upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
7557
7558 return *upma ? isl_stat_ok : isl_stat_error;
7559}
7560
7561/* Construct and return a union piecewise multi affine expression
7562 * that is equal to the given union piecewise affine expression.
7563 */
7564__isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_pw_aff(
7565 __isl_take isl_union_pw_aff *upa)
7566{
7567 isl_space *space;
7568 isl_union_pw_multi_aff *upma;
7569
7570 if (!upa)
7571 return NULL((void*)0);
7572
7573 space = isl_union_pw_aff_get_space(upa);
7574 upma = isl_union_pw_multi_aff_empty(space);
7575
7576 if (isl_union_pw_aff_foreach_pw_aff(upa,
7577 &pw_multi_aff_from_pw_aff_entry, &upma) < 0)
7578 upma = isl_union_pw_multi_aff_free(upma);
7579
7580 isl_union_pw_aff_free(upa);
7581 return upma;
7582}
7583
7584/* Compute the set of elements in the domain of "pa" where it is zero and
7585 * add this set to "uset".
7586 */
7587static isl_stat zero_union_set(__isl_take isl_pw_aff *pa, void *user)
7588{
7589 isl_union_setisl_union_map **uset = (isl_union_setisl_union_map **)user;
7590
7591 *uset = isl_union_set_add_set(*uset, isl_pw_aff_zero_set(pa));
7592
7593 return *uset ? isl_stat_ok : isl_stat_error;
7594}
7595
7596/* Return a union set containing those elements in the domain
7597 * of "upa" where it is zero.
7598 */
7599__isl_give isl_union_setisl_union_map *isl_union_pw_aff_zero_union_set(
7600 __isl_take isl_union_pw_aff *upa)
7601{
7602 isl_union_setisl_union_map *zero;
7603
7604 zero = isl_union_set_empty(isl_union_pw_aff_get_space(upa));
7605 if (isl_union_pw_aff_foreach_pw_aff(upa, &zero_union_set, &zero) < 0)
7606 zero = isl_union_set_free(zero);
7607
7608 isl_union_pw_aff_free(upa);
7609 return zero;
7610}
7611
7612/* Convert "pa" to an isl_map and add it to *umap.
7613 */
7614static isl_stat map_from_pw_aff_entry(__isl_take isl_pw_aff *pa, void *user)
7615{
7616 isl_union_map **umap = user;
7617 isl_map *map;
7618
7619 map = isl_map_from_pw_aff(pa);
7620 *umap = isl_union_map_add_map(*umap, map);
7621
7622 return *umap ? isl_stat_ok : isl_stat_error;
7623}
7624
7625/* Construct a union map mapping the domain of the union
7626 * piecewise affine expression to its range, with the single output dimension
7627 * equated to the corresponding affine expressions on their cells.
7628 */
7629__isl_give isl_union_map *isl_union_map_from_union_pw_aff(
7630 __isl_take isl_union_pw_aff *upa)
7631{
7632 isl_space *space;
7633 isl_union_map *umap;
7634
7635 if (!upa)
7636 return NULL((void*)0);
7637
7638 space = isl_union_pw_aff_get_space(upa);
7639 umap = isl_union_map_empty(space);
7640
7641 if (isl_union_pw_aff_foreach_pw_aff(upa, &map_from_pw_aff_entry,
7642 &umap) < 0)
7643 umap = isl_union_map_free(umap);
7644
7645 isl_union_pw_aff_free(upa);
7646 return umap;
7647}
7648
7649/* Internal data structure for isl_union_pw_aff_pullback_union_pw_multi_aff.
7650 * upma is the function that is plugged in.
7651 * pa is the current part of the function in which upma is plugged in.
7652 * res collects the results.
7653 */
7654struct isl_union_pw_aff_pullback_upma_data {
7655 isl_union_pw_multi_aff *upma;
7656 isl_pw_aff *pa;
7657 isl_union_pw_aff *res;
7658};
7659
7660/* Check if "pma" can be plugged into data->pa.
7661 * If so, perform the pullback and add the result to data->res.
7662 */
7663static isl_stat pa_pb_pma(void **entry, void *user)
7664{
7665 struct isl_union_pw_aff_pullback_upma_data *data = user;
7666 isl_pw_multi_aff *pma = *entry;
7667 isl_pw_aff *pa;
7668
7669 if (!isl_space_tuple_is_equal(data->pa->dim, isl_dim_in,
7670 pma->dim, isl_dim_out))
7671 return isl_stat_ok;
7672
7673 pma = isl_pw_multi_aff_copy(pma);
7674 pa = isl_pw_aff_copy(data->pa);
7675 pa = isl_pw_aff_pullback_pw_multi_aff(pa, pma);
7676
7677 data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
7678
7679 return data->res ? isl_stat_ok : isl_stat_error;
7680}
7681
7682/* Check if any of the elements of data->upma can be plugged into pa,
7683 * add if so add the result to data->res.
7684 */
7685static isl_stat upa_pb_upma(void **entry, void *user)
7686{
7687 struct isl_union_pw_aff_pullback_upma_data *data = user;
7688 isl_ctx *ctx;
7689 isl_pw_aff *pa = *entry;
7690
7691 data->pa = pa;
7692 ctx = isl_union_pw_multi_aff_get_ctx(data->upma);
7693 if (isl_hash_table_foreach(ctx, &data->upma->table,
7694 &pa_pb_pma, data) < 0)
7695 return isl_stat_error;
7696
7697 return isl_stat_ok;
7698}
7699
7700/* Compute the pullback of "upa" by the function represented by "upma".
7701 * In other words, plug in "upma" in "upa". The result contains
7702 * expressions defined over the domain space of "upma".
7703 *
7704 * Run over all pairs of elements in "upa" and "upma", perform
7705 * the pullback when appropriate and collect the results.
7706 * If the hash value were based on the domain space rather than
7707 * the function space, then we could run through all elements
7708 * of "upma" and directly pick out the corresponding element of "upa".
7709 */
7710__isl_give isl_union_pw_aff *isl_union_pw_aff_pullback_union_pw_multi_aff(
7711 __isl_take isl_union_pw_aff *upa,
7712 __isl_take isl_union_pw_multi_aff *upma)
7713{
7714 struct isl_union_pw_aff_pullback_upma_data data = { NULL((void*)0), NULL((void*)0) };
7715 isl_ctx *ctx;
7716 isl_space *space;
7717
7718 space = isl_union_pw_multi_aff_get_space(upma);
7719 upa = isl_union_pw_aff_align_params(upa, space);
7720 space = isl_union_pw_aff_get_space(upa);
7721 upma = isl_union_pw_multi_aff_align_params(upma, space);
7722
7723 if (!upa || !upma)
7724 goto error;
7725
7726 ctx = isl_union_pw_aff_get_ctx(upa);
7727 data.upma = upma;
7728 space = isl_union_pw_aff_get_space(upa);
7729 data.res = isl_union_pw_aff_alloc(space, upa->table.n);
7730 if (isl_hash_table_foreach(ctx, &upa->table, &upa_pb_upma, &data) < 0)
7731 data.res = isl_union_pw_aff_free(data.res);
7732
7733 isl_union_pw_aff_free(upa);
7734 isl_union_pw_multi_aff_free(upma);
7735 return data.res;
7736error:
7737 isl_union_pw_aff_free(upa);
7738 isl_union_pw_multi_aff_free(upma);
7739 return NULL((void*)0);
7740}
7741
7742#undef BASEunion_pw_aff
7743#define BASEunion_pw_aff union_pw_aff
7744#undef DOMBASEunion_set
7745#define DOMBASEunion_set union_set
7746
7747#define NO_MOVE_DIMS
7748#define NO_DIMS
7749#define NO_DOMAIN
7750#define NO_PRODUCT
7751#define NO_SPLICE
7752#define NO_ZERO
7753#define NO_IDENTITY
7754#define NO_GIST
7755
7756#include <isl_multi_templ.c>
7757#include <isl_multi_apply_set.c>
7758#include <isl_multi_apply_union_set.c>
7759#include <isl_multi_floor.c>
7760#include <isl_multi_gist.c>
7761#include <isl_multi_intersect.c>
7762
7763/* Construct a multiple union piecewise affine expression
7764 * in the given space with value zero in each of the output dimensions.
7765 *
7766 * Since there is no canonical zero value for
7767 * a union piecewise affine expression, we can only construct
7768 * zero-dimensional "zero" value.
7769 */
7770__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_zero(
7771 __isl_take isl_space *space)
7772{
7773 if (!space)
7774 return NULL((void*)0);
7775
7776 if (!isl_space_is_set(space))
7777 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7778); goto error; } while (0)
7778 "expecting set space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "expecting set space", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7778); goto error; } while (0)
;
7779 if (isl_space_dim(space , isl_dim_out) != 0)
7780 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7781); goto error; } while (0)
7781 "expecting 0D space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "expecting 0D space", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7781); goto error; } while (0)
;
7782
7783 return isl_multi_union_pw_aff_alloc(space);
7784error:
7785 isl_space_free(space);
7786 return NULL((void*)0);
7787}
7788
7789/* Compute the sum of "mupa1" and "mupa2" on the union of their domains,
7790 * with the actual sum on the shared domain and
7791 * the defined expression on the symmetric difference of the domains.
7792 *
7793 * We simply iterate over the elements in both arguments and
7794 * call isl_union_pw_aff_union_add on each of them.
7795 */
7796static __isl_give isl_multi_union_pw_aff *
7797isl_multi_union_pw_aff_union_add_aligned(
7798 __isl_take isl_multi_union_pw_aff *mupa1,
7799 __isl_take isl_multi_union_pw_aff *mupa2)
7800{
7801 return isl_multi_union_pw_aff_bin_op(mupa1, mupa2,
7802 &isl_union_pw_aff_union_add);
7803}
7804
7805/* Compute the sum of "mupa1" and "mupa2" on the union of their domains,
7806 * with the actual sum on the shared domain and
7807 * the defined expression on the symmetric difference of the domains.
7808 */
7809__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_union_add(
7810 __isl_take isl_multi_union_pw_aff *mupa1,
7811 __isl_take isl_multi_union_pw_aff *mupa2)
7812{
7813 return isl_multi_union_pw_aff_align_params_multi_multi_and(mupa1, mupa2,
7814 &isl_multi_union_pw_aff_union_add_aligned);
7815}
7816
7817/* Construct and return a multi union piecewise affine expression
7818 * that is equal to the given multi affine expression.
7819 */
7820__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_aff(
7821 __isl_take isl_multi_aff *ma)
7822{
7823 isl_multi_pw_aff *mpa;
7824
7825 mpa = isl_multi_pw_aff_from_multi_aff(ma);
7826 return isl_multi_union_pw_aff_from_multi_pw_aff(mpa);
7827}
7828
7829/* Construct and return a multi union piecewise affine expression
7830 * that is equal to the given multi piecewise affine expression.
7831 */
7832__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_pw_aff(
7833 __isl_take isl_multi_pw_aff *mpa)
7834{
7835 int i, n;
7836 isl_space *space;
7837 isl_multi_union_pw_aff *mupa;
7838
7839 if (!mpa)
7840 return NULL((void*)0);
7841
7842 space = isl_multi_pw_aff_get_space(mpa);
7843 space = isl_space_range(space);
7844 mupa = isl_multi_union_pw_aff_alloc(space);
7845
7846 n = isl_multi_pw_aff_dim(mpa, isl_dim_out);
7847 for (i = 0; i < n; ++i) {
7848 isl_pw_aff *pa;
7849 isl_union_pw_aff *upa;
7850
7851 pa = isl_multi_pw_aff_get_pw_aff(mpa, i);
7852 upa = isl_union_pw_aff_from_pw_aff(pa);
7853 mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
7854 }
7855
7856 isl_multi_pw_aff_free(mpa);
7857
7858 return mupa;
7859}
7860
7861/* Extract the range space of "pma" and assign it to *space.
7862 * If *space has already been set (through a previous call to this function),
7863 * then check that the range space is the same.
7864 */
7865static isl_stat extract_space(__isl_take isl_pw_multi_aff *pma, void *user)
7866{
7867 isl_space **space = user;
7868 isl_space *pma_space;
7869 isl_bool equal;
7870
7871 pma_space = isl_space_range(isl_pw_multi_aff_get_space(pma));
7872 isl_pw_multi_aff_free(pma);
7873
7874 if (!pma_space)
7875 return isl_stat_error;
7876 if (!*space) {
7877 *space = pma_space;
7878 return isl_stat_ok;
7879 }
7880
7881 equal = isl_space_is_equal(pma_space, *space);
7882 isl_space_free(pma_space);
7883
7884 if (equal < 0)
7885 return isl_stat_error;
7886 if (!equal)
7887 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7888); return isl_stat_error; } while (0)
7888 "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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7888); return isl_stat_error; } while (0)
;
7889 return isl_stat_ok;
7890}
7891
7892/* Construct and return a multi union piecewise affine expression
7893 * that is equal to the given union piecewise multi affine expression.
7894 *
7895 * In order to be able to perform the conversion, the input
7896 * needs to be non-empty and may only involve a single range space.
7897 */
7898__isl_give isl_multi_union_pw_aff *
7899isl_multi_union_pw_aff_from_union_pw_multi_aff(
7900 __isl_take isl_union_pw_multi_aff *upma)
7901{
7902 isl_space *space = NULL((void*)0);
7903 isl_multi_union_pw_aff *mupa;
7904 int i, n;
7905
7906 if (!upma)
7907 return NULL((void*)0);
7908 if (isl_union_pw_multi_aff_n_pw_multi_aff(upma) == 0)
7909 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7911); goto error; } while (0)
7910 "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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7911); goto error; } while (0)
7911 goto error)do { isl_handle_error(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid
, "cannot extract range space from empty input", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 7911); goto error; } while (0)
;
7912 if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, &extract_space,
7913 &space) < 0)
7914 goto error;
7915
7916 if (!space)
7917 goto error;
7918
7919 n = isl_space_dim(space, isl_dim_set);
7920 mupa = isl_multi_union_pw_aff_alloc(space);
7921
7922 for (i = 0; i < n; ++i) {
7923 isl_union_pw_aff *upa;
7924
7925 upa = isl_union_pw_multi_aff_get_union_pw_aff(upma, i);
7926 mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
7927 }
7928
7929 isl_union_pw_multi_aff_free(upma);
7930 return mupa;
7931error:
7932 isl_space_free(space);
7933 isl_union_pw_multi_aff_free(upma);
7934 return NULL((void*)0);
7935}
7936
7937/* Try and create an isl_multi_union_pw_aff that is equivalent
7938 * to the given isl_union_map.
7939 * The isl_union_map is required to be single-valued in each space.
7940 * Moreover, it cannot be empty and all range spaces need to be the same.
7941 * Otherwise, an error is produced.
7942 */
7943__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_map(
7944 __isl_take isl_union_map *umap)
7945{
7946 isl_union_pw_multi_aff *upma;
7947
7948 upma = isl_union_pw_multi_aff_from_union_map(umap);
7949 return isl_multi_union_pw_aff_from_union_pw_multi_aff(upma);
7950}
7951
7952/* Return a multiple union piecewise affine expression
7953 * that is equal to "mv" on "domain", assuming "domain" and "mv"
7954 * have been aligned.
7955 */
7956static __isl_give isl_multi_union_pw_aff *
7957isl_multi_union_pw_aff_multi_val_on_domain_aligned(
7958 __isl_take isl_union_setisl_union_map *domain, __isl_take isl_multi_val *mv)
7959{
7960 int i, n;
7961 isl_space *space;
7962 isl_multi_union_pw_aff *mupa;
7963
7964 if (!domain || !mv)
7965 goto error;
7966
7967 n = isl_multi_val_dim(mv, isl_dim_set);
7968 space = isl_multi_val_get_space(mv);
7969 mupa = isl_multi_union_pw_aff_alloc(space);
7970 for (i = 0; i < n; ++i) {
7971 isl_val *v;
7972 isl_union_pw_aff *upa;
7973
7974 v = isl_multi_val_get_val(mv, i);
7975 upa = isl_union_pw_aff_val_on_domain(isl_union_set_copy(domain),
7976 v);
7977 mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
7978 }
7979
7980 isl_union_set_free(domain);
7981 isl_multi_val_free(mv);
7982 return mupa;
7983error:
7984 isl_union_set_free(domain);
7985 isl_multi_val_free(mv);
7986 return NULL((void*)0);
7987}
7988
7989/* Return a multiple union piecewise affine expression
7990 * that is equal to "mv" on "domain".
7991 */
7992__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_val_on_domain(
7993 __isl_take isl_union_setisl_union_map *domain, __isl_take isl_multi_val *mv)
7994{
7995 if (!domain || !mv)
7996 goto error;
7997 if (isl_space_match(domain->dim, isl_dim_param,
7998 mv->space, isl_dim_param))
7999 return isl_multi_union_pw_aff_multi_val_on_domain_aligned(
8000 domain, mv);
8001 domain = isl_union_set_align_params(domain,
8002 isl_multi_val_get_space(mv));
8003 mv = isl_multi_val_align_params(mv, isl_union_set_get_space(domain));
8004 return isl_multi_union_pw_aff_multi_val_on_domain_aligned(domain, mv);
8005error:
8006 isl_union_set_free(domain);
8007 isl_multi_val_free(mv);
8008 return NULL((void*)0);
8009}
8010
8011/* Return a multiple union piecewise affine expression
8012 * that is equal to "ma" on "domain", assuming "domain" and "ma"
8013 * have been aligned.
8014 */
8015static __isl_give isl_multi_union_pw_aff *
8016isl_multi_union_pw_aff_multi_aff_on_domain_aligned(
8017 __isl_take isl_union_setisl_union_map *domain, __isl_take isl_multi_aff *ma)
8018{
8019 int i, n;
8020 isl_space *space;
8021 isl_multi_union_pw_aff *mupa;
8022
8023 if (!domain || !ma)
8024 goto error;
8025
8026 n = isl_multi_aff_dim(ma, isl_dim_set);
8027 space = isl_multi_aff_get_space(ma);
8028 mupa = isl_multi_union_pw_aff_alloc(space);
8029 for (i = 0; i < n; ++i) {
8030 isl_aff *aff;
8031 isl_union_pw_aff *upa;
8032
8033 aff = isl_multi_aff_get_aff(ma, i);
8034 upa = isl_union_pw_aff_aff_on_domain(isl_union_set_copy(domain),
8035 aff);
8036 mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
8037 }
8038
8039 isl_union_set_free(domain);
8040 isl_multi_aff_free(ma);
8041 return mupa;
8042error:
8043 isl_union_set_free(domain);
8044 isl_multi_aff_free(ma);
8045 return NULL((void*)0);
8046}
8047
8048/* Return a multiple union piecewise affine expression
8049 * that is equal to "ma" on "domain".
8050 */
8051__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_aff_on_domain(
8052 __isl_take isl_union_setisl_union_map *domain, __isl_take isl_multi_aff *ma)
8053{
8054 if (!domain || !ma)
8055 goto error;
8056 if (isl_space_match(domain->dim, isl_dim_param,
8057 ma->space, isl_dim_param))
8058 return isl_multi_union_pw_aff_multi_aff_on_domain_aligned(
8059 domain, ma);
8060 domain = isl_union_set_align_params(domain,
8061 isl_multi_aff_get_space(ma));
8062 ma = isl_multi_aff_align_params(ma, isl_union_set_get_space(domain));
8063 return isl_multi_union_pw_aff_multi_aff_on_domain_aligned(domain, ma);
8064error:
8065 isl_union_set_free(domain);
8066 isl_multi_aff_free(ma);
8067 return NULL((void*)0);
8068}
8069
8070/* Return a union set containing those elements in the domains
8071 * of the elements of "mupa" where they are all zero.
8072 */
8073__isl_give isl_union_setisl_union_map *isl_multi_union_pw_aff_zero_union_set(
8074 __isl_take isl_multi_union_pw_aff *mupa)
8075{
8076 int i, n;
8077 isl_union_pw_aff *upa;
8078 isl_union_setisl_union_map *zero;
8079
8080 if (!mupa)
8081 return NULL((void*)0);
8082
8083 n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
8084 if (n == 0)
8085 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
, "cannot determine zero set " "of zero-dimensional function"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8087); goto error; } while (0)
8086 "cannot determine zero set "do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot determine zero set " "of zero-dimensional function"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8087); goto error; } while (0)
8087 "of zero-dimensional function", goto error)do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot determine zero set " "of zero-dimensional function"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8087); goto error; } while (0)
;
8088
8089 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
8090 zero = isl_union_pw_aff_zero_union_set(upa);
8091
8092 for (i = 1; i < n; ++i) {
8093 isl_union_setisl_union_map *zero_i;
8094
8095 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
8096 zero_i = isl_union_pw_aff_zero_union_set(upa);
8097
8098 zero = isl_union_set_intersect(zero, zero_i);
8099 }
8100
8101 isl_multi_union_pw_aff_free(mupa);
8102 return zero;
8103error:
8104 isl_multi_union_pw_aff_free(mupa);
8105 return NULL((void*)0);
8106}
8107
8108/* Construct a union map mapping the shared domain
8109 * of the union piecewise affine expressions to the range of "mupa"
8110 * with each dimension in the range equated to the
8111 * corresponding union piecewise affine expression.
8112 *
8113 * The input cannot be zero-dimensional as there is
8114 * no way to extract a domain from a zero-dimensional isl_multi_union_pw_aff.
8115 */
8116__isl_give isl_union_map *isl_union_map_from_multi_union_pw_aff(
8117 __isl_take isl_multi_union_pw_aff *mupa)
8118{
8119 int i, n;
8120 isl_space *space;
8121 isl_union_map *umap;
8122 isl_union_pw_aff *upa;
8123
8124 if (!mupa)
8125 return NULL((void*)0);
8126
8127 n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
8128 if (n == 0)
8129 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
, "cannot determine domain of zero-dimensional " "isl_multi_union_pw_aff"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8131); goto error; } while (0)
8130 "cannot determine domain of zero-dimensional "do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot determine domain of zero-dimensional " "isl_multi_union_pw_aff"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8131); goto error; } while (0)
8131 "isl_multi_union_pw_aff", goto error)do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot determine domain of zero-dimensional " "isl_multi_union_pw_aff"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8131); goto error; } while (0)
;
8132
8133 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
8134 umap = isl_union_map_from_union_pw_aff(upa);
8135
8136 for (i = 1; i < n; ++i) {
8137 isl_union_map *umap_i;
8138
8139 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
8140 umap_i = isl_union_map_from_union_pw_aff(upa);
8141 umap = isl_union_map_flat_range_product(umap, umap_i);
8142 }
8143
8144 space = isl_multi_union_pw_aff_get_space(mupa);
8145 umap = isl_union_map_reset_range_space(umap, space);
8146
8147 isl_multi_union_pw_aff_free(mupa);
8148 return umap;
8149error:
8150 isl_multi_union_pw_aff_free(mupa);
8151 return NULL((void*)0);
8152}
8153
8154/* Internal data structure for isl_union_pw_multi_aff_reset_range_space.
8155 * "range" is the space from which to set the range space.
8156 * "res" collects the results.
8157 */
8158struct isl_union_pw_multi_aff_reset_range_space_data {
8159 isl_space *range;
8160 isl_union_pw_multi_aff *res;
8161};
8162
8163/* Replace the range space of "pma" by the range space of data->range and
8164 * add the result to data->res.
8165 */
8166static isl_stat reset_range_space(__isl_take isl_pw_multi_aff *pma, void *user)
8167{
8168 struct isl_union_pw_multi_aff_reset_range_space_data *data = user;
8169 isl_space *space;
8170
8171 space = isl_pw_multi_aff_get_space(pma);
8172 space = isl_space_domain(space);
8173 space = isl_space_extend_domain_with_range(space,
8174 isl_space_copy(data->range));
8175 pma = isl_pw_multi_aff_reset_space(pma, space);
8176 data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma);
8177
8178 return data->res ? isl_stat_ok : isl_stat_error;
8179}
8180
8181/* Replace the range space of all the piecewise affine expressions in "upma" by
8182 * the range space of "space".
8183 *
8184 * This assumes that all these expressions have the same output dimension.
8185 *
8186 * Since the spaces of the expressions change, so do their hash values.
8187 * We therefore need to create a new isl_union_pw_multi_aff.
8188 * Note that the hash value is currently computed based on the entire
8189 * space even though there can only be a single expression with a given
8190 * domain space.
8191 */
8192static __isl_give isl_union_pw_multi_aff *
8193isl_union_pw_multi_aff_reset_range_space(
8194 __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_space *space)
8195{
8196 struct isl_union_pw_multi_aff_reset_range_space_data data = { space };
8197 isl_space *space_upma;
8198
8199 space_upma = isl_union_pw_multi_aff_get_space(upma);
8200 data.res = isl_union_pw_multi_aff_empty(space_upma);
8201 if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
8202 &reset_range_space, &data) < 0)
8203 data.res = isl_union_pw_multi_aff_free(data.res);
8204
8205 isl_space_free(space);
8206 isl_union_pw_multi_aff_free(upma);
8207 return data.res;
8208}
8209
8210/* Construct and return a union piecewise multi affine expression
8211 * that is equal to the given multi union piecewise affine expression.
8212 *
8213 * In order to be able to perform the conversion, the input
8214 * needs to have a least one output dimension.
8215 */
8216__isl_give isl_union_pw_multi_aff *
8217isl_union_pw_multi_aff_from_multi_union_pw_aff(
8218 __isl_take isl_multi_union_pw_aff *mupa)
8219{
8220 int i, n;
8221 isl_space *space;
8222 isl_union_pw_multi_aff *upma;
8223 isl_union_pw_aff *upa;
8224
8225 if (!mupa)
8226 return NULL((void*)0);
8227
8228 space = isl_multi_union_pw_aff_get_space(mupa);
8229
8230 n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
8231 if (n == 0)
8232 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
, "cannot determine domain of zero-dimensional " "isl_multi_union_pw_aff"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8234); goto error; } while (0)
8233 "cannot determine domain of zero-dimensional "do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot determine domain of zero-dimensional " "isl_multi_union_pw_aff"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8234); goto error; } while (0)
8234 "isl_multi_union_pw_aff", goto error)do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot determine domain of zero-dimensional " "isl_multi_union_pw_aff"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8234); goto error; } while (0)
;
8235
8236 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
8237 upma = isl_union_pw_multi_aff_from_union_pw_aff(upa);
8238
8239 for (i = 1; i < n; ++i) {
8240 isl_union_pw_multi_aff *upma_i;
8241
8242 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
8243 upma_i = isl_union_pw_multi_aff_from_union_pw_aff(upa);
8244 upma = isl_union_pw_multi_aff_flat_range_product(upma, upma_i);
8245 }
8246
8247 upma = isl_union_pw_multi_aff_reset_range_space(upma, space);
8248
8249 isl_multi_union_pw_aff_free(mupa);
8250 return upma;
8251error:
8252 isl_multi_union_pw_aff_free(mupa);
8253 return NULL((void*)0);
8254}
8255
8256/* Intersect the range of "mupa" with "range".
8257 * That is, keep only those domain elements that have a function value
8258 * in "range".
8259 */
8260__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_intersect_range(
8261 __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_setisl_map *range)
8262{
8263 isl_union_pw_multi_aff *upma;
8264 isl_union_setisl_union_map *domain;
8265 isl_space *space;
8266 int n;
8267 int match;
8268
8269 if (!mupa || !range)
8270 goto error;
8271
8272 space = isl_set_get_space(range);
8273 match = isl_space_tuple_is_equal(mupa->space, isl_dim_set,
8274 space, isl_dim_set);
8275 isl_space_free(space);
8276 if (match < 0)
8277 goto error;
8278 if (!match)
8279 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8280); goto error; } while (0)
8280 "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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8280); goto error; } while (0)
;
8281 n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
8282 if (n == 0)
8283 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
, "cannot intersect range of zero-dimensional " "isl_multi_union_pw_aff"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8285); goto error; } while (0)
8284 "cannot intersect range of zero-dimensional "do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot intersect range of zero-dimensional " "isl_multi_union_pw_aff"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8285); goto error; } while (0)
8285 "isl_multi_union_pw_aff", goto error)do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot intersect range of zero-dimensional " "isl_multi_union_pw_aff"
, "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8285); goto error; } while (0)
;
8286
8287 upma = isl_union_pw_multi_aff_from_multi_union_pw_aff(
8288 isl_multi_union_pw_aff_copy(mupa));
8289 domain = isl_union_set_from_set(range);
8290 domain = isl_union_set_preimage_union_pw_multi_aff(domain, upma);
8291 mupa = isl_multi_union_pw_aff_intersect_domain(mupa, domain);
8292
8293 return mupa;
8294error:
8295 isl_multi_union_pw_aff_free(mupa);
8296 isl_set_free(range);
8297 return NULL((void*)0);
8298}
8299
8300/* Return the shared domain of the elements of "mupa".
8301 */
8302__isl_give isl_union_setisl_union_map *isl_multi_union_pw_aff_domain(
8303 __isl_take isl_multi_union_pw_aff *mupa)
8304{
8305 int i, n;
8306 isl_union_pw_aff *upa;
8307 isl_union_setisl_union_map *dom;
8308
8309 if (!mupa)
8310 return NULL((void*)0);
8311
8312 n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
8313 if (n == 0)
8314 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
, "cannot determine domain", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8315); goto error; } while (0)
8315 "cannot determine domain", goto error)do { isl_handle_error(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid
, "cannot determine domain", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8315); goto error; } while (0)
;
8316
8317 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
8318 dom = isl_union_pw_aff_domain(upa);
8319 for (i = 1; i < n; ++i) {
8320 isl_union_setisl_union_map *dom_i;
8321
8322 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
8323 dom_i = isl_union_pw_aff_domain(upa);
8324 dom = isl_union_set_intersect(dom, dom_i);
8325 }
8326
8327 isl_multi_union_pw_aff_free(mupa);
8328 return dom;
8329error:
8330 isl_multi_union_pw_aff_free(mupa);
8331 return NULL((void*)0);
8332}
8333
8334/* Apply "aff" to "mupa". The space of "mupa" is equal to the domain of "aff".
8335 * In particular, the spaces have been aligned.
8336 * The result is defined over the shared domain of the elements of "mupa"
8337 *
8338 * We first extract the parametric constant part of "aff" and
8339 * define that over the shared domain.
8340 * Then we iterate over all input dimensions of "aff" and add the corresponding
8341 * multiples of the elements of "mupa".
8342 * Finally, we consider the integer divisions, calling the function
8343 * recursively to obtain an isl_union_pw_aff corresponding to the
8344 * integer division argument.
8345 */
8346static __isl_give isl_union_pw_aff *multi_union_pw_aff_apply_aff(
8347 __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff)
8348{
8349 int i, n_in, n_div;
8350 isl_union_pw_aff *upa;
8351 isl_union_setisl_union_map *uset;
8352 isl_val *v;
8353 isl_aff *cst;
8354
8355 n_in = isl_aff_dim(aff, isl_dim_in);
8356 n_div = isl_aff_dim(aff, isl_dim_div);
8357
8358 uset = isl_multi_union_pw_aff_domain(isl_multi_union_pw_aff_copy(mupa));
8359 cst = isl_aff_copy(aff);
8360 cst = isl_aff_drop_dims(cst, isl_dim_div, 0, n_div);
8361 cst = isl_aff_drop_dims(cst, isl_dim_in, 0, n_in);
8362 cst = isl_aff_project_domain_on_params(cst);
8363 upa = isl_union_pw_aff_aff_on_domain(uset, cst);
8364
8365 for (i = 0; i < n_in; ++i) {
8366 isl_union_pw_aff *upa_i;
8367
8368 if (!isl_aff_involves_dims(aff, isl_dim_in, i, 1))
8369 continue;
8370 v = isl_aff_get_coefficient_val(aff, isl_dim_in, i);
8371 upa_i = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
8372 upa_i = isl_union_pw_aff_scale_val(upa_i, v);
8373 upa = isl_union_pw_aff_add(upa, upa_i);
8374 }
8375
8376 for (i = 0; i < n_div; ++i) {
8377 isl_aff *div;
8378 isl_union_pw_aff *upa_i;
8379
8380 if (!isl_aff_involves_dims(aff, isl_dim_div, i, 1))
8381 continue;
8382 div = isl_aff_get_div(aff, i);
8383 upa_i = multi_union_pw_aff_apply_aff(
8384 isl_multi_union_pw_aff_copy(mupa), div);
8385 upa_i = isl_union_pw_aff_floor(upa_i);
8386 v = isl_aff_get_coefficient_val(aff, isl_dim_div, i);
8387 upa_i = isl_union_pw_aff_scale_val(upa_i, v);
8388 upa = isl_union_pw_aff_add(upa, upa_i);
8389 }
8390
8391 isl_multi_union_pw_aff_free(mupa);
8392 isl_aff_free(aff);
8393
8394 return upa;
8395}
8396
8397/* Apply "aff" to "mupa". The space of "mupa" needs to be compatible
8398 * with the domain of "aff".
8399 * Furthermore, the dimension of this space needs to be greater than zero.
8400 * The result is defined over the shared domain of the elements of "mupa"
8401 *
8402 * We perform these checks and then hand over control to
8403 * multi_union_pw_aff_apply_aff.
8404 */
8405__isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_aff(
8406 __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff)
8407{
8408 isl_space *space1, *space2;
8409 int equal;
8410
8411 mupa = isl_multi_union_pw_aff_align_params(mupa,
8412 isl_aff_get_space(aff));
8413 aff = isl_aff_align_params(aff, isl_multi_union_pw_aff_get_space(mupa));
8414 if (!mupa || !aff)
8415 goto error;
8416
8417 space1 = isl_multi_union_pw_aff_get_space(mupa);
8418 space2 = isl_aff_get_domain_space(aff);
8419 equal = isl_space_is_equal(space1, space2);
8420 isl_space_free(space1);
8421 isl_space_free(space2);
8422 if (equal < 0)
8423 goto error;
8424 if (!equal)
8425 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8426); goto error; } while (0)
8426 "spaces don't match", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "spaces don't match", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8426); goto error; } while (0)
;
8427 if (isl_aff_dim(aff, isl_dim_in) == 0)
8428 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8429); goto error; } while (0)
8429 "cannot determine domains", goto error)do { isl_handle_error(isl_aff_get_ctx(aff), isl_error_invalid
, "cannot determine domains", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8429); goto error; } while (0)
;
8430
8431 return multi_union_pw_aff_apply_aff(mupa, aff);
8432error:
8433 isl_multi_union_pw_aff_free(mupa);
8434 isl_aff_free(aff);
8435 return NULL((void*)0);
8436}
8437
8438/* Apply "ma" to "mupa". The space of "mupa" needs to be compatible
8439 * with the domain of "ma".
8440 * Furthermore, the dimension of this space needs to be greater than zero,
8441 * unless the dimension of the target space of "ma" is also zero.
8442 * The result is defined over the shared domain of the elements of "mupa"
8443 */
8444__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_multi_aff(
8445 __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma)
8446{
8447 isl_space *space1, *space2;
8448 isl_multi_union_pw_aff *res;
8449 int equal;
8450 int i, n_out;
8451
8452 mupa = isl_multi_union_pw_aff_align_params(mupa,
8453 isl_multi_aff_get_space(ma));
8454 ma = isl_multi_aff_align_params(ma,
8455 isl_multi_union_pw_aff_get_space(mupa));
8456 if (!mupa || !ma)
8457 goto error;
8458
8459 space1 = isl_multi_union_pw_aff_get_space(mupa);
8460 space2 = isl_multi_aff_get_domain_space(ma);
8461 equal = isl_space_is_equal(space1, space2);
8462 isl_space_free(space1);
8463 isl_space_free(space2);
8464 if (equal < 0)
8465 goto error;
8466 if (!equal)
8467 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8468); goto error; } while (0)
8468 "spaces don't match", goto error)do { isl_handle_error(isl_multi_aff_get_ctx(ma), isl_error_invalid
, "spaces don't match", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8468); goto error; } while (0)
;
8469 n_out = isl_multi_aff_dim(ma, isl_dim_out);
8470 if (isl_multi_aff_dim(ma, isl_dim_in) == 0 && n_out != 0)
8471 isl_die(isl_multi_aff_get_ctx(ma), isl_error_invalid,do { isl_handle_error(isl_multi_aff_get_ctx(ma), isl_error_invalid
, "cannot determine domains", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8472); goto error; } while (0)
8472 "cannot determine domains", goto error)do { isl_handle_error(isl_multi_aff_get_ctx(ma), isl_error_invalid
, "cannot determine domains", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8472); goto error; } while (0)
;
8473
8474 space1 = isl_space_range(isl_multi_aff_get_space(ma));
8475 res = isl_multi_union_pw_aff_alloc(space1);
8476
8477 for (i = 0; i < n_out; ++i) {
8478 isl_aff *aff;
8479 isl_union_pw_aff *upa;
8480
8481 aff = isl_multi_aff_get_aff(ma, i);
8482 upa = multi_union_pw_aff_apply_aff(
8483 isl_multi_union_pw_aff_copy(mupa), aff);
8484 res = isl_multi_union_pw_aff_set_union_pw_aff(res, i, upa);
8485 }
8486
8487 isl_multi_aff_free(ma);
8488 isl_multi_union_pw_aff_free(mupa);
8489 return res;
8490error:
8491 isl_multi_union_pw_aff_free(mupa);
8492 isl_multi_aff_free(ma);
8493 return NULL((void*)0);
8494}
8495
8496/* Apply "pa" to "mupa". The space of "mupa" needs to be compatible
8497 * with the domain of "pa".
8498 * Furthermore, the dimension of this space needs to be greater than zero.
8499 * The result is defined over the shared domain of the elements of "mupa"
8500 */
8501__isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_pw_aff(
8502 __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_pw_aff *pa)
8503{
8504 int i;
8505 int equal;
8506 isl_space *space, *space2;
8507 isl_union_pw_aff *upa;
8508
8509 mupa = isl_multi_union_pw_aff_align_params(mupa,
8510 isl_pw_aff_get_space(pa));
8511 pa = isl_pw_aff_align_params(pa,
8512 isl_multi_union_pw_aff_get_space(mupa));
8513 if (!mupa || !pa)
8514 goto error;
8515
8516 space = isl_multi_union_pw_aff_get_space(mupa);
8517 space2 = isl_pw_aff_get_domain_space(pa);
8518 equal = isl_space_is_equal(space, space2);
8519 isl_space_free(space);
8520 isl_space_free(space2);
8521 if (equal < 0)
8522 goto error;
8523 if (!equal)
8524 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8525); goto error; } while (0)
8525 "spaces don't match", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid
, "spaces don't match", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8525); goto error; } while (0)
;
8526 if (isl_pw_aff_dim(pa, isl_dim_in) == 0)
8527 isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid
, "cannot determine domains", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8528); goto error; } while (0)
8528 "cannot determine domains", goto error)do { isl_handle_error(isl_pw_aff_get_ctx(pa), isl_error_invalid
, "cannot determine domains", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8528); goto error; } while (0)
;
8529
8530 space = isl_space_params(isl_multi_union_pw_aff_get_space(mupa));
8531 upa = isl_union_pw_aff_empty(space);
8532
8533 for (i = 0; i < pa->n; ++i) {
8534 isl_aff *aff;
8535 isl_setisl_map *domain;
8536 isl_multi_union_pw_aff *mupa_i;
8537 isl_union_pw_aff *upa_i;
8538
8539 mupa_i = isl_multi_union_pw_aff_copy(mupa);
8540 domain = isl_set_copy(pa->p[i].set);
8541 mupa_i = isl_multi_union_pw_aff_intersect_range(mupa_i, domain);
8542 aff = isl_aff_copy(pa->p[i].aff);
8543 upa_i = multi_union_pw_aff_apply_aff(mupa_i, aff);
8544 upa = isl_union_pw_aff_union_add(upa, upa_i);
8545 }
8546
8547 isl_multi_union_pw_aff_free(mupa);
8548 isl_pw_aff_free(pa);
8549 return upa;
8550error:
8551 isl_multi_union_pw_aff_free(mupa);
8552 isl_pw_aff_free(pa);
8553 return NULL((void*)0);
8554}
8555
8556/* Apply "pma" to "mupa". The space of "mupa" needs to be compatible
8557 * with the domain of "pma".
8558 * Furthermore, the dimension of this space needs to be greater than zero,
8559 * unless the dimension of the target space of "pma" is also zero.
8560 * The result is defined over the shared domain of the elements of "mupa"
8561 */
8562__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_pw_multi_aff(
8563 __isl_take isl_multi_union_pw_aff *mupa,
8564 __isl_take isl_pw_multi_aff *pma)
8565{
8566 isl_space *space1, *space2;
8567 isl_multi_union_pw_aff *res;
8568 int equal;
8569 int i, n_out;
8570
8571 mupa = isl_multi_union_pw_aff_align_params(mupa,
8572 isl_pw_multi_aff_get_space(pma));
8573 pma = isl_pw_multi_aff_align_params(pma,
8574 isl_multi_union_pw_aff_get_space(mupa));
8575 if (!mupa || !pma)
8576 goto error;
8577
8578 space1 = isl_multi_union_pw_aff_get_space(mupa);
8579 space2 = isl_pw_multi_aff_get_domain_space(pma);
8580 equal = isl_space_is_equal(space1, space2);
8581 isl_space_free(space1);
8582 isl_space_free(space2);
8583 if (equal < 0)
8584 goto error;
8585 if (!equal)
8586 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", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8587); goto error; } while (0)
8587 "spaces don't match", goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "spaces don't match", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8587); goto error; } while (0)
;
8588 n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
8589 if (isl_pw_multi_aff_dim(pma, isl_dim_in) == 0 && n_out != 0)
8590 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
, "cannot determine domains", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8591); goto error; } while (0)
8591 "cannot determine domains", goto error)do { isl_handle_error(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid
, "cannot determine domains", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn239931/polly/lib/External/isl/isl_aff.c"
, 8591); goto error; } while (0)
;
8592
8593 space1 = isl_space_range(isl_pw_multi_aff_get_space(pma));
8594 res = isl_multi_union_pw_aff_alloc(space1);
8595
8596 for (i = 0; i < n_out; ++i) {
8597 isl_pw_aff *pa;
8598 isl_union_pw_aff *upa;
8599
8600 pa = isl_pw_multi_aff_get_pw_aff(pma, i);
8601 upa = isl_multi_union_pw_aff_apply_pw_aff(
8602 isl_multi_union_pw_aff_copy(mupa), pa);
8603 res = isl_multi_union_pw_aff_set_union_pw_aff(res, i, upa);
8604 }
8605
8606 isl_pw_multi_aff_free(pma);
8607 isl_multi_union_pw_aff_free(mupa);
8608 return res;
8609error:
8610 isl_multi_union_pw_aff_free(mupa);
8611 isl_pw_multi_aff_free(pma);
8612 return NULL((void*)0);
8613}
8614
8615/* Compute the pullback of "mupa" by the function represented by "upma".
8616 * In other words, plug in "upma" in "mupa". The result contains
8617 * expressions defined over the domain space of "upma".
8618 *
8619 * Run over all elements of "mupa" and plug in "upma" in each of them.
8620 */
8621__isl_give isl_multi_union_pw_aff *
8622isl_multi_union_pw_aff_pullback_union_pw_multi_aff(
8623 __isl_take isl_multi_union_pw_aff *mupa,
8624 __isl_take isl_union_pw_multi_aff *upma)
8625{
8626 int i, n;
8627
8628 mupa = isl_multi_union_pw_aff_align_params(mupa,
8629 isl_union_pw_multi_aff_get_space(upma));
8630 upma = isl_union_pw_multi_aff_align_params(upma,
8631 isl_multi_union_pw_aff_get_space(mupa));
8632 if (!mupa || !upma)
8633 goto error;
8634
8635 n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
8636 for (i = 0; i < n; ++i) {
8637 isl_union_pw_aff *upa;
8638
8639 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
8640 upa = isl_union_pw_aff_pullback_union_pw_multi_aff(upa,
8641 isl_union_pw_multi_aff_copy(upma));
8642 mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
8643 }
8644
8645 isl_union_pw_multi_aff_free(upma);
8646 return mupa;
8647error:
8648 isl_multi_union_pw_aff_free(mupa);
8649 isl_union_pw_multi_aff_free(upma);
8650 return NULL((void*)0);
8651}
8652
8653/* Extract the sequence of elements in "mupa" with domain space "space"
8654 * (ignoring parameters).
8655 *
8656 * For the elements of "mupa" that are not defined on the specified space,
8657 * the corresponding element in the result is empty.
8658 */
8659__isl_give isl_multi_pw_aff *isl_multi_union_pw_aff_extract_multi_pw_aff(
8660 __isl_keep isl_multi_union_pw_aff *mupa, __isl_take isl_space *space)
8661{
8662 int i, n;
8663 isl_space *space_mpa = NULL((void*)0);
8664 isl_multi_pw_aff *mpa;
8665
8666 if (!mupa || !space)
8667 goto error;
8668
8669 space_mpa = isl_multi_union_pw_aff_get_space(mupa);
8670 if (!isl_space_match(space_mpa, isl_dim_param, space, isl_dim_param)) {
8671 space = isl_space_drop_dims(space, isl_dim_param,
8672 0, isl_space_dim(space, isl_dim_param));
8673 space = isl_space_align_params(space,
8674 isl_space_copy(space_mpa));
8675 if (!space)
8676 goto error;
8677 }
8678 space_mpa = isl_space_map_from_domain_and_range(isl_space_copy(space),
8679 space_mpa);
8680 mpa = isl_multi_pw_aff_alloc(space_mpa);
8681
8682 space = isl_space_from_domain(space);
8683 space = isl_space_add_dims(space, isl_dim_out, 1);
8684 n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
8685 for (i = 0; i < n; ++i) {
8686 isl_union_pw_aff *upa;
8687 isl_pw_aff *pa;
8688
8689 upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
8690 pa = isl_union_pw_aff_extract_pw_aff(upa,
8691 isl_space_copy(space));
8692 mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa);
8693 isl_union_pw_aff_free(upa);
8694 }
8695
8696 isl_space_free(space);
8697 return mpa;
8698error:
8699 isl_space_free(space_mpa);
8700 isl_space_free(space);
8701 return NULL((void*)0);
8702}