isl_pw_multi_aff_from_map: add a special case where result can be read off
[platform/upstream/isl.git] / isl_aff.c
1 /*
2  * Copyright 2011      INRIA Saclay
3  * Copyright 2011      Sven Verdoolaege
4  * Copyright 2012      Ecole Normale Superieure
5  *
6  * Use of this software is governed by the GNU LGPLv2.1 license
7  *
8  * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
9  * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
10  * 91893 Orsay, France
11  * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
12  */
13
14 #include <isl_ctx_private.h>
15 #include <isl_map_private.h>
16 #include <isl_aff_private.h>
17 #include <isl_space_private.h>
18 #include <isl_local_space_private.h>
19 #include <isl_mat_private.h>
20 #include <isl_list_private.h>
21 #include <isl/constraint.h>
22 #include <isl/seq.h>
23 #include <isl/set.h>
24 #include <isl_config.h>
25
26 __isl_give isl_aff *isl_aff_alloc_vec(__isl_take isl_local_space *ls,
27         __isl_take isl_vec *v)
28 {
29         isl_aff *aff;
30
31         if (!ls || !v)
32                 goto error;
33
34         aff = isl_calloc_type(v->ctx, struct isl_aff);
35         if (!aff)
36                 goto error;
37
38         aff->ref = 1;
39         aff->ls = ls;
40         aff->v = v;
41
42         return aff;
43 error:
44         isl_local_space_free(ls);
45         isl_vec_free(v);
46         return NULL;
47 }
48
49 __isl_give isl_aff *isl_aff_alloc(__isl_take isl_local_space *ls)
50 {
51         isl_ctx *ctx;
52         isl_vec *v;
53         unsigned total;
54
55         if (!ls)
56                 return NULL;
57
58         ctx = isl_local_space_get_ctx(ls);
59         if (!isl_local_space_divs_known(ls))
60                 isl_die(ctx, isl_error_invalid, "local space has unknown divs",
61                         goto error);
62         if (!isl_local_space_is_set(ls))
63                 isl_die(ctx, isl_error_invalid,
64                         "domain of affine expression should be a set",
65                         goto error);
66
67         total = isl_local_space_dim(ls, isl_dim_all);
68         v = isl_vec_alloc(ctx, 1 + 1 + total);
69         return isl_aff_alloc_vec(ls, v);
70 error:
71         isl_local_space_free(ls);
72         return NULL;
73 }
74
75 __isl_give isl_aff *isl_aff_zero_on_domain(__isl_take isl_local_space *ls)
76 {
77         isl_aff *aff;
78
79         aff = isl_aff_alloc(ls);
80         if (!aff)
81                 return NULL;
82
83         isl_int_set_si(aff->v->el[0], 1);
84         isl_seq_clr(aff->v->el + 1, aff->v->size - 1);
85
86         return aff;
87 }
88
89 __isl_give isl_aff *isl_aff_copy(__isl_keep isl_aff *aff)
90 {
91         if (!aff)
92                 return NULL;
93
94         aff->ref++;
95         return aff;
96 }
97
98 __isl_give isl_aff *isl_aff_dup(__isl_keep isl_aff *aff)
99 {
100         if (!aff)
101                 return NULL;
102
103         return isl_aff_alloc_vec(isl_local_space_copy(aff->ls),
104                                  isl_vec_copy(aff->v));
105 }
106
107 __isl_give isl_aff *isl_aff_cow(__isl_take isl_aff *aff)
108 {
109         if (!aff)
110                 return NULL;
111
112         if (aff->ref == 1)
113                 return aff;
114         aff->ref--;
115         return isl_aff_dup(aff);
116 }
117
118 void *isl_aff_free(__isl_take isl_aff *aff)
119 {
120         if (!aff)
121                 return NULL;
122
123         if (--aff->ref > 0)
124                 return NULL;
125
126         isl_local_space_free(aff->ls);
127         isl_vec_free(aff->v);
128
129         free(aff);
130
131         return NULL;
132 }
133
134 isl_ctx *isl_aff_get_ctx(__isl_keep isl_aff *aff)
135 {
136         return aff ? isl_local_space_get_ctx(aff->ls) : NULL;
137 }
138
139 /* Externally, an isl_aff has a map space, but internally, the
140  * ls field corresponds to the domain of that space.
141  */
142 int isl_aff_dim(__isl_keep isl_aff *aff, enum isl_dim_type type)
143 {
144         if (!aff)
145                 return 0;
146         if (type == isl_dim_out)
147                 return 1;
148         if (type == isl_dim_in)
149                 type = isl_dim_set;
150         return isl_local_space_dim(aff->ls, type);
151 }
152
153 __isl_give isl_space *isl_aff_get_domain_space(__isl_keep isl_aff *aff)
154 {
155         return aff ? isl_local_space_get_space(aff->ls) : NULL;
156 }
157
158 __isl_give isl_space *isl_aff_get_space(__isl_keep isl_aff *aff)
159 {
160         isl_space *space;
161         if (!aff)
162                 return NULL;
163         space = isl_local_space_get_space(aff->ls);
164         space = isl_space_from_domain(space);
165         space = isl_space_add_dims(space, isl_dim_out, 1);
166         return space;
167 }
168
169 __isl_give isl_local_space *isl_aff_get_domain_local_space(
170         __isl_keep isl_aff *aff)
171 {
172         return aff ? isl_local_space_copy(aff->ls) : NULL;
173 }
174
175 __isl_give isl_local_space *isl_aff_get_local_space(__isl_keep isl_aff *aff)
176 {
177         isl_local_space *ls;
178         if (!aff)
179                 return NULL;
180         ls = isl_local_space_copy(aff->ls);
181         ls = isl_local_space_from_domain(ls);
182         ls = isl_local_space_add_dims(ls, isl_dim_out, 1);
183         return ls;
184 }
185
186 /* Externally, an isl_aff has a map space, but internally, the
187  * ls field corresponds to the domain of that space.
188  */
189 const char *isl_aff_get_dim_name(__isl_keep isl_aff *aff,
190         enum isl_dim_type type, unsigned pos)
191 {
192         if (!aff)
193                 return NULL;
194         if (type == isl_dim_out)
195                 return NULL;
196         if (type == isl_dim_in)
197                 type = isl_dim_set;
198         return isl_local_space_get_dim_name(aff->ls, type, pos);
199 }
200
201 __isl_give isl_aff *isl_aff_reset_domain_space(__isl_take isl_aff *aff,
202         __isl_take isl_space *dim)
203 {
204         aff = isl_aff_cow(aff);
205         if (!aff || !dim)
206                 goto error;
207
208         aff->ls = isl_local_space_reset_space(aff->ls, dim);
209         if (!aff->ls)
210                 return isl_aff_free(aff);
211
212         return aff;
213 error:
214         isl_aff_free(aff);
215         isl_space_free(dim);
216         return NULL;
217 }
218
219 /* Reset the space of "aff".  This function is called from isl_pw_templ.c
220  * and doesn't know if the space of an element object is represented
221  * directly or through its domain.  It therefore passes along both.
222  */
223 __isl_give isl_aff *isl_aff_reset_space_and_domain(__isl_take isl_aff *aff,
224         __isl_take isl_space *space, __isl_take isl_space *domain)
225 {
226         isl_space_free(space);
227         return isl_aff_reset_domain_space(aff, domain);
228 }
229
230 /* Reorder the coefficients of the affine expression based
231  * on the given reodering.
232  * The reordering r is assumed to have been extended with the local
233  * variables.
234  */
235 static __isl_give isl_vec *vec_reorder(__isl_take isl_vec *vec,
236         __isl_take isl_reordering *r, int n_div)
237 {
238         isl_vec *res;
239         int i;
240
241         if (!vec || !r)
242                 goto error;
243
244         res = isl_vec_alloc(vec->ctx,
245                             2 + isl_space_dim(r->dim, isl_dim_all) + n_div);
246         isl_seq_cpy(res->el, vec->el, 2);
247         isl_seq_clr(res->el + 2, res->size - 2);
248         for (i = 0; i < r->len; ++i)
249                 isl_int_set(res->el[2 + r->pos[i]], vec->el[2 + i]);
250
251         isl_reordering_free(r);
252         isl_vec_free(vec);
253         return res;
254 error:
255         isl_vec_free(vec);
256         isl_reordering_free(r);
257         return NULL;
258 }
259
260 /* Reorder the dimensions of the domain of "aff" according
261  * to the given reordering.
262  */
263 __isl_give isl_aff *isl_aff_realign_domain(__isl_take isl_aff *aff,
264         __isl_take isl_reordering *r)
265 {
266         aff = isl_aff_cow(aff);
267         if (!aff)
268                 goto error;
269
270         r = isl_reordering_extend(r, aff->ls->div->n_row);
271         aff->v = vec_reorder(aff->v, isl_reordering_copy(r),
272                                 aff->ls->div->n_row);
273         aff->ls = isl_local_space_realign(aff->ls, r);
274
275         if (!aff->v || !aff->ls)
276                 return isl_aff_free(aff);
277
278         return aff;
279 error:
280         isl_aff_free(aff);
281         isl_reordering_free(r);
282         return NULL;
283 }
284
285 __isl_give isl_aff *isl_aff_align_params(__isl_take isl_aff *aff,
286         __isl_take isl_space *model)
287 {
288         if (!aff || !model)
289                 goto error;
290
291         if (!isl_space_match(aff->ls->dim, isl_dim_param,
292                              model, isl_dim_param)) {
293                 isl_reordering *exp;
294
295                 model = isl_space_drop_dims(model, isl_dim_in,
296                                         0, isl_space_dim(model, isl_dim_in));
297                 model = isl_space_drop_dims(model, isl_dim_out,
298                                         0, isl_space_dim(model, isl_dim_out));
299                 exp = isl_parameter_alignment_reordering(aff->ls->dim, model);
300                 exp = isl_reordering_extend_space(exp,
301                                         isl_aff_get_domain_space(aff));
302                 aff = isl_aff_realign_domain(aff, exp);
303         }
304
305         isl_space_free(model);
306         return aff;
307 error:
308         isl_space_free(model);
309         isl_aff_free(aff);
310         return NULL;
311 }
312
313 int isl_aff_plain_is_zero(__isl_keep isl_aff *aff)
314 {
315         if (!aff)
316                 return -1;
317
318         return isl_seq_first_non_zero(aff->v->el + 1, aff->v->size - 1) < 0;
319 }
320
321 int isl_aff_plain_is_equal(__isl_keep isl_aff *aff1, __isl_keep isl_aff *aff2)
322 {
323         int equal;
324
325         if (!aff1 || !aff2)
326                 return -1;
327
328         equal = isl_local_space_is_equal(aff1->ls, aff2->ls);
329         if (equal < 0 || !equal)
330                 return equal;
331
332         return isl_vec_is_equal(aff1->v, aff2->v);
333 }
334
335 int isl_aff_get_denominator(__isl_keep isl_aff *aff, isl_int *v)
336 {
337         if (!aff)
338                 return -1;
339         isl_int_set(*v, aff->v->el[0]);
340         return 0;
341 }
342
343 int isl_aff_get_constant(__isl_keep isl_aff *aff, isl_int *v)
344 {
345         if (!aff)
346                 return -1;
347         isl_int_set(*v, aff->v->el[1]);
348         return 0;
349 }
350
351 int isl_aff_get_coefficient(__isl_keep isl_aff *aff,
352         enum isl_dim_type type, int pos, isl_int *v)
353 {
354         if (!aff)
355                 return -1;
356
357         if (type == isl_dim_out)
358                 isl_die(aff->v->ctx, isl_error_invalid,
359                         "output/set dimension does not have a coefficient",
360                         return -1);
361         if (type == isl_dim_in)
362                 type = isl_dim_set;
363
364         if (pos >= isl_local_space_dim(aff->ls, type))
365                 isl_die(aff->v->ctx, isl_error_invalid,
366                         "position out of bounds", return -1);
367
368         pos += isl_local_space_offset(aff->ls, type);
369         isl_int_set(*v, aff->v->el[1 + pos]);
370
371         return 0;
372 }
373
374 __isl_give isl_aff *isl_aff_set_denominator(__isl_take isl_aff *aff, isl_int v)
375 {
376         aff = isl_aff_cow(aff);
377         if (!aff)
378                 return NULL;
379
380         aff->v = isl_vec_cow(aff->v);
381         if (!aff->v)
382                 return isl_aff_free(aff);
383
384         isl_int_set(aff->v->el[0], v);
385
386         return aff;
387 }
388
389 __isl_give isl_aff *isl_aff_set_constant(__isl_take isl_aff *aff, isl_int v)
390 {
391         aff = isl_aff_cow(aff);
392         if (!aff)
393                 return NULL;
394
395         aff->v = isl_vec_cow(aff->v);
396         if (!aff->v)
397                 return isl_aff_free(aff);
398
399         isl_int_set(aff->v->el[1], v);
400
401         return aff;
402 }
403
404 __isl_give isl_aff *isl_aff_add_constant(__isl_take isl_aff *aff, isl_int v)
405 {
406         if (isl_int_is_zero(v))
407                 return aff;
408
409         aff = isl_aff_cow(aff);
410         if (!aff)
411                 return NULL;
412
413         aff->v = isl_vec_cow(aff->v);
414         if (!aff->v)
415                 return isl_aff_free(aff);
416
417         isl_int_addmul(aff->v->el[1], aff->v->el[0], v);
418
419         return aff;
420 }
421
422 __isl_give isl_aff *isl_aff_add_constant_si(__isl_take isl_aff *aff, int v)
423 {
424         isl_int t;
425
426         isl_int_init(t);
427         isl_int_set_si(t, v);
428         aff = isl_aff_add_constant(aff, t);
429         isl_int_clear(t);
430
431         return aff;
432 }
433
434 __isl_give isl_aff *isl_aff_set_constant_si(__isl_take isl_aff *aff, int v)
435 {
436         aff = isl_aff_cow(aff);
437         if (!aff)
438                 return NULL;
439
440         aff->v = isl_vec_cow(aff->v);
441         if (!aff->v)
442                 return isl_aff_free(aff);
443
444         isl_int_set_si(aff->v->el[1], v);
445
446         return aff;
447 }
448
449 __isl_give isl_aff *isl_aff_set_coefficient(__isl_take isl_aff *aff,
450         enum isl_dim_type type, int pos, isl_int v)
451 {
452         if (!aff)
453                 return NULL;
454
455         if (type == isl_dim_out)
456                 isl_die(aff->v->ctx, isl_error_invalid,
457                         "output/set dimension does not have a coefficient",
458                         return isl_aff_free(aff));
459         if (type == isl_dim_in)
460                 type = isl_dim_set;
461
462         if (pos >= isl_local_space_dim(aff->ls, type))
463                 isl_die(aff->v->ctx, isl_error_invalid,
464                         "position out of bounds", return isl_aff_free(aff));
465
466         aff = isl_aff_cow(aff);
467         if (!aff)
468                 return NULL;
469
470         aff->v = isl_vec_cow(aff->v);
471         if (!aff->v)
472                 return isl_aff_free(aff);
473
474         pos += isl_local_space_offset(aff->ls, type);
475         isl_int_set(aff->v->el[1 + pos], v);
476
477         return aff;
478 }
479
480 __isl_give isl_aff *isl_aff_set_coefficient_si(__isl_take isl_aff *aff,
481         enum isl_dim_type type, int pos, int v)
482 {
483         if (!aff)
484                 return NULL;
485
486         if (type == isl_dim_out)
487                 isl_die(aff->v->ctx, isl_error_invalid,
488                         "output/set dimension does not have a coefficient",
489                         return isl_aff_free(aff));
490         if (type == isl_dim_in)
491                 type = isl_dim_set;
492
493         if (pos >= isl_local_space_dim(aff->ls, type))
494                 isl_die(aff->v->ctx, isl_error_invalid,
495                         "position out of bounds", return isl_aff_free(aff));
496
497         aff = isl_aff_cow(aff);
498         if (!aff)
499                 return NULL;
500
501         aff->v = isl_vec_cow(aff->v);
502         if (!aff->v)
503                 return isl_aff_free(aff);
504
505         pos += isl_local_space_offset(aff->ls, type);
506         isl_int_set_si(aff->v->el[1 + pos], v);
507
508         return aff;
509 }
510
511 __isl_give isl_aff *isl_aff_add_coefficient(__isl_take isl_aff *aff,
512         enum isl_dim_type type, int pos, isl_int v)
513 {
514         if (!aff)
515                 return NULL;
516
517         if (type == isl_dim_out)
518                 isl_die(aff->v->ctx, isl_error_invalid,
519                         "output/set dimension does not have a coefficient",
520                         return isl_aff_free(aff));
521         if (type == isl_dim_in)
522                 type = isl_dim_set;
523
524         if (pos >= isl_local_space_dim(aff->ls, type))
525                 isl_die(aff->v->ctx, isl_error_invalid,
526                         "position out of bounds", return isl_aff_free(aff));
527
528         aff = isl_aff_cow(aff);
529         if (!aff)
530                 return NULL;
531
532         aff->v = isl_vec_cow(aff->v);
533         if (!aff->v)
534                 return isl_aff_free(aff);
535
536         pos += isl_local_space_offset(aff->ls, type);
537         isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v);
538
539         return aff;
540 }
541
542 __isl_give isl_aff *isl_aff_add_coefficient_si(__isl_take isl_aff *aff,
543         enum isl_dim_type type, int pos, int v)
544 {
545         isl_int t;
546
547         isl_int_init(t);
548         isl_int_set_si(t, v);
549         aff = isl_aff_add_coefficient(aff, type, pos, t);
550         isl_int_clear(t);
551
552         return aff;
553 }
554
555 __isl_give isl_aff *isl_aff_get_div(__isl_keep isl_aff *aff, int pos)
556 {
557         if (!aff)
558                 return NULL;
559
560         return isl_local_space_get_div(aff->ls, pos);
561 }
562
563 __isl_give isl_aff *isl_aff_neg(__isl_take isl_aff *aff)
564 {
565         aff = isl_aff_cow(aff);
566         if (!aff)
567                 return NULL;
568         aff->v = isl_vec_cow(aff->v);
569         if (!aff->v)
570                 return isl_aff_free(aff);
571
572         isl_seq_neg(aff->v->el + 1, aff->v->el + 1, aff->v->size - 1);
573
574         return aff;
575 }
576
577 /* Remove divs from the local space that do not appear in the affine
578  * expression.
579  * We currently only remove divs at the end.
580  * Some intermediate divs may also not appear directly in the affine
581  * expression, but we would also need to check that no other divs are
582  * defined in terms of them.
583  */
584 __isl_give isl_aff *isl_aff_remove_unused_divs( __isl_take isl_aff *aff)
585 {
586         int pos;
587         int off;
588         int n;
589
590         if (!aff)
591                 return NULL;
592
593         n = isl_local_space_dim(aff->ls, isl_dim_div);
594         off = isl_local_space_offset(aff->ls, isl_dim_div);
595
596         pos = isl_seq_last_non_zero(aff->v->el + 1 + off, n) + 1;
597         if (pos == n)
598                 return aff;
599
600         aff = isl_aff_cow(aff);
601         if (!aff)
602                 return NULL;
603
604         aff->ls = isl_local_space_drop_dims(aff->ls, isl_dim_div, pos, n - pos);
605         aff->v = isl_vec_drop_els(aff->v, 1 + off + pos, n - pos);
606         if (!aff->ls || !aff->v)
607                 return isl_aff_free(aff);
608
609         return aff;
610 }
611
612 __isl_give isl_aff *isl_aff_normalize(__isl_take isl_aff *aff)
613 {
614         if (!aff)
615                 return NULL;
616         aff->v = isl_vec_normalize(aff->v);
617         if (!aff->v)
618                 return isl_aff_free(aff);
619         return aff;
620 }
621
622 /* Given f, return floor(f).
623  * If f is an integer expression, then just return f.
624  * Otherwise, if f = g/m, write g = q m + r,
625  * create a new div d = [r/m] and return the expression q + d.
626  * The coefficients in r are taken to lie between -m/2 and m/2.
627  */
628 __isl_give isl_aff *isl_aff_floor(__isl_take isl_aff *aff)
629 {
630         int i;
631         int size;
632         isl_ctx *ctx;
633         isl_vec *div;
634
635         if (!aff)
636                 return NULL;
637
638         if (isl_int_is_one(aff->v->el[0]))
639                 return aff;
640
641         aff = isl_aff_cow(aff);
642         if (!aff)
643                 return NULL;
644
645         aff->v = isl_vec_cow(aff->v);
646         div = isl_vec_copy(aff->v);
647         div = isl_vec_cow(div);
648         if (!div)
649                 return isl_aff_free(aff);
650
651         ctx = isl_aff_get_ctx(aff);
652         isl_int_fdiv_q(aff->v->el[0], aff->v->el[0], ctx->two);
653         for (i = 1; i < aff->v->size; ++i) {
654                 isl_int_fdiv_r(div->el[i], div->el[i], div->el[0]);
655                 isl_int_fdiv_q(aff->v->el[i], aff->v->el[i], div->el[0]);
656                 if (isl_int_gt(div->el[i], aff->v->el[0])) {
657                         isl_int_sub(div->el[i], div->el[i], div->el[0]);
658                         isl_int_add_ui(aff->v->el[i], aff->v->el[i], 1);
659                 }
660         }
661
662         aff->ls = isl_local_space_add_div(aff->ls, div);
663         if (!aff->ls)
664                 return isl_aff_free(aff);
665
666         size = aff->v->size;
667         aff->v = isl_vec_extend(aff->v, size + 1);
668         if (!aff->v)
669                 return isl_aff_free(aff);
670         isl_int_set_si(aff->v->el[0], 1);
671         isl_int_set_si(aff->v->el[size], 1);
672
673         return aff;
674 }
675
676 /* Compute
677  *
678  *      aff mod m = aff - m * floor(aff/m)
679  */
680 __isl_give isl_aff *isl_aff_mod(__isl_take isl_aff *aff, isl_int m)
681 {
682         isl_aff *res;
683
684         res = isl_aff_copy(aff);
685         aff = isl_aff_scale_down(aff, m);
686         aff = isl_aff_floor(aff);
687         aff = isl_aff_scale(aff, m);
688         res = isl_aff_sub(res, aff);
689
690         return res;
691 }
692
693 /* Compute
694  *
695  *      pwaff mod m = pwaff - m * floor(pwaff/m)
696  */
697 __isl_give isl_pw_aff *isl_pw_aff_mod(__isl_take isl_pw_aff *pwaff, isl_int m)
698 {
699         isl_pw_aff *res;
700
701         res = isl_pw_aff_copy(pwaff);
702         pwaff = isl_pw_aff_scale_down(pwaff, m);
703         pwaff = isl_pw_aff_floor(pwaff);
704         pwaff = isl_pw_aff_scale(pwaff, m);
705         res = isl_pw_aff_sub(res, pwaff);
706
707         return res;
708 }
709
710 /* Given f, return ceil(f).
711  * If f is an integer expression, then just return f.
712  * Otherwise, create a new div d = [-f] and return the expression -d.
713  */
714 __isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff)
715 {
716         if (!aff)
717                 return NULL;
718
719         if (isl_int_is_one(aff->v->el[0]))
720                 return aff;
721
722         aff = isl_aff_neg(aff);
723         aff = isl_aff_floor(aff);
724         aff = isl_aff_neg(aff);
725
726         return aff;
727 }
728
729 /* Apply the expansion computed by isl_merge_divs.
730  * The expansion itself is given by "exp" while the resulting
731  * list of divs is given by "div".
732  */
733 __isl_give isl_aff *isl_aff_expand_divs( __isl_take isl_aff *aff,
734         __isl_take isl_mat *div, int *exp)
735 {
736         int i, j;
737         int old_n_div;
738         int new_n_div;
739         int offset;
740
741         aff = isl_aff_cow(aff);
742         if (!aff || !div)
743                 goto error;
744
745         old_n_div = isl_local_space_dim(aff->ls, isl_dim_div);
746         new_n_div = isl_mat_rows(div);
747         if (new_n_div < old_n_div)
748                 isl_die(isl_mat_get_ctx(div), isl_error_invalid,
749                         "not an expansion", goto error);
750
751         aff->v = isl_vec_extend(aff->v, aff->v->size + new_n_div - old_n_div);
752         if (!aff->v)
753                 goto error;
754
755         offset = 1 + isl_local_space_offset(aff->ls, isl_dim_div);
756         j = old_n_div - 1;
757         for (i = new_n_div - 1; i >= 0; --i) {
758                 if (j >= 0 && exp[j] == i) {
759                         if (i != j)
760                                 isl_int_swap(aff->v->el[offset + i],
761                                              aff->v->el[offset + j]);
762                         j--;
763                 } else
764                         isl_int_set_si(aff->v->el[offset + i], 0);
765         }
766
767         aff->ls = isl_local_space_replace_divs(aff->ls, isl_mat_copy(div));
768         if (!aff->ls)
769                 goto error;
770         isl_mat_free(div);
771         return aff;
772 error:
773         isl_aff_free(aff);
774         isl_mat_free(div);
775         return NULL;
776 }
777
778 /* Add two affine expressions that live in the same local space.
779  */
780 static __isl_give isl_aff *add_expanded(__isl_take isl_aff *aff1,
781         __isl_take isl_aff *aff2)
782 {
783         isl_int gcd, f;
784
785         aff1 = isl_aff_cow(aff1);
786         if (!aff1 || !aff2)
787                 goto error;
788
789         aff1->v = isl_vec_cow(aff1->v);
790         if (!aff1->v)
791                 goto error;
792
793         isl_int_init(gcd);
794         isl_int_init(f);
795         isl_int_gcd(gcd, aff1->v->el[0], aff2->v->el[0]);
796         isl_int_divexact(f, aff2->v->el[0], gcd);
797         isl_seq_scale(aff1->v->el + 1, aff1->v->el + 1, f, aff1->v->size - 1);
798         isl_int_divexact(f, aff1->v->el[0], gcd);
799         isl_seq_addmul(aff1->v->el + 1, f, aff2->v->el + 1, aff1->v->size - 1);
800         isl_int_divexact(f, aff2->v->el[0], gcd);
801         isl_int_mul(aff1->v->el[0], aff1->v->el[0], f);
802         isl_int_clear(f);
803         isl_int_clear(gcd);
804
805         isl_aff_free(aff2);
806         return aff1;
807 error:
808         isl_aff_free(aff1);
809         isl_aff_free(aff2);
810         return NULL;
811 }
812
813 __isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1,
814         __isl_take isl_aff *aff2)
815 {
816         isl_ctx *ctx;
817         int *exp1 = NULL;
818         int *exp2 = NULL;
819         isl_mat *div;
820
821         if (!aff1 || !aff2)
822                 goto error;
823
824         ctx = isl_aff_get_ctx(aff1);
825         if (!isl_space_is_equal(aff1->ls->dim, aff2->ls->dim))
826                 isl_die(ctx, isl_error_invalid,
827                         "spaces don't match", goto error);
828
829         if (aff1->ls->div->n_row == 0 && aff2->ls->div->n_row == 0)
830                 return add_expanded(aff1, aff2);
831
832         exp1 = isl_alloc_array(ctx, int, aff1->ls->div->n_row);
833         exp2 = isl_alloc_array(ctx, int, aff2->ls->div->n_row);
834         if (!exp1 || !exp2)
835                 goto error;
836
837         div = isl_merge_divs(aff1->ls->div, aff2->ls->div, exp1, exp2);
838         aff1 = isl_aff_expand_divs(aff1, isl_mat_copy(div), exp1);
839         aff2 = isl_aff_expand_divs(aff2, div, exp2);
840         free(exp1);
841         free(exp2);
842
843         return add_expanded(aff1, aff2);
844 error:
845         free(exp1);
846         free(exp2);
847         isl_aff_free(aff1);
848         isl_aff_free(aff2);
849         return NULL;
850 }
851
852 __isl_give isl_aff *isl_aff_sub(__isl_take isl_aff *aff1,
853         __isl_take isl_aff *aff2)
854 {
855         return isl_aff_add(aff1, isl_aff_neg(aff2));
856 }
857
858 __isl_give isl_aff *isl_aff_scale(__isl_take isl_aff *aff, isl_int f)
859 {
860         isl_int gcd;
861
862         if (isl_int_is_one(f))
863                 return aff;
864
865         aff = isl_aff_cow(aff);
866         if (!aff)
867                 return NULL;
868         aff->v = isl_vec_cow(aff->v);
869         if (!aff->v)
870                 return isl_aff_free(aff);
871
872         isl_int_init(gcd);
873         isl_int_gcd(gcd, aff->v->el[0], f);
874         isl_int_divexact(aff->v->el[0], aff->v->el[0], gcd);
875         isl_int_divexact(gcd, f, gcd);
876         isl_seq_scale(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1);
877         isl_int_clear(gcd);
878
879         return aff;
880 }
881
882 __isl_give isl_aff *isl_aff_scale_down(__isl_take isl_aff *aff, isl_int f)
883 {
884         isl_int gcd;
885
886         if (isl_int_is_one(f))
887                 return aff;
888
889         aff = isl_aff_cow(aff);
890         if (!aff)
891                 return NULL;
892         aff->v = isl_vec_cow(aff->v);
893         if (!aff->v)
894                 return isl_aff_free(aff);
895
896         isl_int_init(gcd);
897         isl_seq_gcd(aff->v->el + 1, aff->v->size - 1, &gcd);
898         isl_int_gcd(gcd, gcd, f);
899         isl_seq_scale_down(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1);
900         isl_int_divexact(gcd, f, gcd);
901         isl_int_mul(aff->v->el[0], aff->v->el[0], gcd);
902         isl_int_clear(gcd);
903
904         return aff;
905 }
906
907 __isl_give isl_aff *isl_aff_scale_down_ui(__isl_take isl_aff *aff, unsigned f)
908 {
909         isl_int v;
910
911         if (f == 1)
912                 return aff;
913
914         isl_int_init(v);
915         isl_int_set_ui(v, f);
916         aff = isl_aff_scale_down(aff, v);
917         isl_int_clear(v);
918
919         return aff;
920 }
921
922 __isl_give isl_aff *isl_aff_set_dim_name(__isl_take isl_aff *aff,
923         enum isl_dim_type type, unsigned pos, const char *s)
924 {
925         aff = isl_aff_cow(aff);
926         if (!aff)
927                 return NULL;
928         if (type == isl_dim_out)
929                 isl_die(aff->v->ctx, isl_error_invalid,
930                         "cannot set name of output/set dimension",
931                         return isl_aff_free(aff));
932         if (type == isl_dim_in)
933                 type = isl_dim_set;
934         aff->ls = isl_local_space_set_dim_name(aff->ls, type, pos, s);
935         if (!aff->ls)
936                 return isl_aff_free(aff);
937
938         return aff;
939 }
940
941 __isl_give isl_aff *isl_aff_set_dim_id(__isl_take isl_aff *aff,
942         enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
943 {
944         aff = isl_aff_cow(aff);
945         if (!aff)
946                 return isl_id_free(id);
947         if (type == isl_dim_out)
948                 isl_die(aff->v->ctx, isl_error_invalid,
949                         "cannot set name of output/set dimension",
950                         goto error);
951         if (type == isl_dim_in)
952                 type = isl_dim_set;
953         aff->ls = isl_local_space_set_dim_id(aff->ls, type, pos, id);
954         if (!aff->ls)
955                 return isl_aff_free(aff);
956
957         return aff;
958 error:
959         isl_id_free(id);
960         isl_aff_free(aff);
961         return NULL;
962 }
963
964 /* Exploit the equalities in "eq" to simplify the affine expression
965  * and the expressions of the integer divisions in the local space.
966  * The integer divisions in this local space are assumed to appear
967  * as regular dimensions in "eq".
968  */
969 static __isl_give isl_aff *isl_aff_substitute_equalities_lifted(
970         __isl_take isl_aff *aff, __isl_take isl_basic_set *eq)
971 {
972         int i, j;
973         unsigned total;
974         unsigned n_div;
975
976         if (!eq)
977                 goto error;
978         if (eq->n_eq == 0) {
979                 isl_basic_set_free(eq);
980                 return aff;
981         }
982
983         aff = isl_aff_cow(aff);
984         if (!aff)
985                 goto error;
986
987         aff->ls = isl_local_space_substitute_equalities(aff->ls,
988                                                         isl_basic_set_copy(eq));
989         if (!aff->ls)
990                 goto error;
991
992         total = 1 + isl_space_dim(eq->dim, isl_dim_all);
993         n_div = eq->n_div;
994         for (i = 0; i < eq->n_eq; ++i) {
995                 j = isl_seq_last_non_zero(eq->eq[i], total + n_div);
996                 if (j < 0 || j == 0 || j >= total)
997                         continue;
998
999                 isl_seq_elim(aff->v->el + 1, eq->eq[i], j, total,
1000                                 &aff->v->el[0]);
1001         }
1002
1003         isl_basic_set_free(eq);
1004         aff = isl_aff_normalize(aff);
1005         return aff;
1006 error:
1007         isl_basic_set_free(eq);
1008         isl_aff_free(aff);
1009         return NULL;
1010 }
1011
1012 /* Exploit the equalities in "eq" to simplify the affine expression
1013  * and the expressions of the integer divisions in the local space.
1014  */
1015 static __isl_give isl_aff *isl_aff_substitute_equalities(
1016         __isl_take isl_aff *aff, __isl_take isl_basic_set *eq)
1017 {
1018         int n_div;
1019
1020         if (!aff || !eq)
1021                 goto error;
1022         n_div = isl_local_space_dim(aff->ls, isl_dim_div);
1023         if (n_div > 0)
1024                 eq = isl_basic_set_add(eq, isl_dim_set, n_div);
1025         return isl_aff_substitute_equalities_lifted(aff, eq);
1026 error:
1027         isl_basic_set_free(eq);
1028         isl_aff_free(aff);
1029         return NULL;
1030 }
1031
1032 /* Look for equalities among the variables shared by context and aff
1033  * and the integer divisions of aff, if any.
1034  * The equalities are then used to eliminate coefficients and/or integer
1035  * divisions from aff.
1036  */
1037 __isl_give isl_aff *isl_aff_gist(__isl_take isl_aff *aff,
1038         __isl_take isl_set *context)
1039 {
1040         isl_basic_set *hull;
1041         int n_div;
1042
1043         if (!aff)
1044                 goto error;
1045         n_div = isl_local_space_dim(aff->ls, isl_dim_div);
1046         if (n_div > 0) {
1047                 isl_basic_set *bset;
1048                 isl_local_space *ls;
1049                 context = isl_set_add_dims(context, isl_dim_set, n_div);
1050                 ls = isl_aff_get_domain_local_space(aff);
1051                 bset = isl_basic_set_from_local_space(ls);
1052                 bset = isl_basic_set_lift(bset);
1053                 bset = isl_basic_set_flatten(bset);
1054                 context = isl_set_intersect(context,
1055                                             isl_set_from_basic_set(bset));
1056         }
1057
1058         hull = isl_set_affine_hull(context);
1059         return isl_aff_substitute_equalities_lifted(aff, hull);
1060 error:
1061         isl_aff_free(aff);
1062         isl_set_free(context);
1063         return NULL;
1064 }
1065
1066 __isl_give isl_aff *isl_aff_gist_params(__isl_take isl_aff *aff,
1067         __isl_take isl_set *context)
1068 {
1069         isl_set *dom_context = isl_set_universe(isl_aff_get_domain_space(aff));
1070         dom_context = isl_set_intersect_params(dom_context, context);
1071         return isl_aff_gist(aff, dom_context);
1072 }
1073
1074 /* Return a basic set containing those elements in the space
1075  * of aff where it is non-negative.
1076  */
1077 __isl_give isl_basic_set *isl_aff_nonneg_basic_set(__isl_take isl_aff *aff)
1078 {
1079         isl_constraint *ineq;
1080         isl_basic_set *bset;
1081
1082         ineq = isl_inequality_from_aff(aff);
1083
1084         bset = isl_basic_set_from_constraint(ineq);
1085         bset = isl_basic_set_simplify(bset);
1086         return bset;
1087 }
1088
1089 /* Return a basic set containing those elements in the space
1090  * of aff where it is zero.
1091  */
1092 __isl_give isl_basic_set *isl_aff_zero_basic_set(__isl_take isl_aff *aff)
1093 {
1094         isl_constraint *ineq;
1095         isl_basic_set *bset;
1096
1097         ineq = isl_equality_from_aff(aff);
1098
1099         bset = isl_basic_set_from_constraint(ineq);
1100         bset = isl_basic_set_simplify(bset);
1101         return bset;
1102 }
1103
1104 /* Return a basic set containing those elements in the shared space
1105  * of aff1 and aff2 where aff1 is greater than or equal to aff2.
1106  */
1107 __isl_give isl_basic_set *isl_aff_ge_basic_set(__isl_take isl_aff *aff1,
1108         __isl_take isl_aff *aff2)
1109 {
1110         aff1 = isl_aff_sub(aff1, aff2);
1111
1112         return isl_aff_nonneg_basic_set(aff1);
1113 }
1114
1115 /* Return a basic set containing those elements in the shared space
1116  * of aff1 and aff2 where aff1 is smaller than or equal to aff2.
1117  */
1118 __isl_give isl_basic_set *isl_aff_le_basic_set(__isl_take isl_aff *aff1,
1119         __isl_take isl_aff *aff2)
1120 {
1121         return isl_aff_ge_basic_set(aff2, aff1);
1122 }
1123
1124 __isl_give isl_aff *isl_aff_add_on_domain(__isl_keep isl_set *dom,
1125         __isl_take isl_aff *aff1, __isl_take isl_aff *aff2)
1126 {
1127         aff1 = isl_aff_add(aff1, aff2);
1128         aff1 = isl_aff_gist(aff1, isl_set_copy(dom));
1129         return aff1;
1130 }
1131
1132 int isl_aff_is_empty(__isl_keep isl_aff *aff)
1133 {
1134         if (!aff)
1135                 return -1;
1136
1137         return 0;
1138 }
1139
1140 /* Check whether the given affine expression has non-zero coefficient
1141  * for any dimension in the given range or if any of these dimensions
1142  * appear with non-zero coefficients in any of the integer divisions
1143  * involved in the affine expression.
1144  */
1145 int isl_aff_involves_dims(__isl_keep isl_aff *aff,
1146         enum isl_dim_type type, unsigned first, unsigned n)
1147 {
1148         int i;
1149         isl_ctx *ctx;
1150         int *active = NULL;
1151         int involves = 0;
1152
1153         if (!aff)
1154                 return -1;
1155         if (n == 0)
1156                 return 0;
1157
1158         ctx = isl_aff_get_ctx(aff);
1159         if (first + n > isl_aff_dim(aff, type))
1160                 isl_die(ctx, isl_error_invalid,
1161                         "range out of bounds", return -1);
1162
1163         active = isl_local_space_get_active(aff->ls, aff->v->el + 2);
1164         if (!active)
1165                 goto error;
1166
1167         first += isl_local_space_offset(aff->ls, type) - 1;
1168         for (i = 0; i < n; ++i)
1169                 if (active[first + i]) {
1170                         involves = 1;
1171                         break;
1172                 }
1173
1174         free(active);
1175
1176         return involves;
1177 error:
1178         free(active);
1179         return -1;
1180 }
1181
1182 __isl_give isl_aff *isl_aff_drop_dims(__isl_take isl_aff *aff,
1183         enum isl_dim_type type, unsigned first, unsigned n)
1184 {
1185         isl_ctx *ctx;
1186
1187         if (!aff)
1188                 return NULL;
1189         if (type == isl_dim_out)
1190                 isl_die(aff->v->ctx, isl_error_invalid,
1191                         "cannot drop output/set dimension",
1192                         return isl_aff_free(aff));
1193         if (type == isl_dim_in)
1194                 type = isl_dim_set;
1195         if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
1196                 return aff;
1197
1198         ctx = isl_aff_get_ctx(aff);
1199         if (first + n > isl_local_space_dim(aff->ls, type))
1200                 isl_die(ctx, isl_error_invalid, "range out of bounds",
1201                         return isl_aff_free(aff));
1202
1203         aff = isl_aff_cow(aff);
1204         if (!aff)
1205                 return NULL;
1206
1207         aff->ls = isl_local_space_drop_dims(aff->ls, type, first, n);
1208         if (!aff->ls)
1209                 return isl_aff_free(aff);
1210
1211         first += 1 + isl_local_space_offset(aff->ls, type);
1212         aff->v = isl_vec_drop_els(aff->v, first, n);
1213         if (!aff->v)
1214                 return isl_aff_free(aff);
1215
1216         return aff;
1217 }
1218
1219 /* Project the domain of the affine expression onto its parameter space.
1220  * The affine expression may not involve any of the domain dimensions.
1221  */
1222 __isl_give isl_aff *isl_aff_project_domain_on_params(__isl_take isl_aff *aff)
1223 {
1224         isl_space *space;
1225         unsigned n;
1226         int involves;
1227
1228         n = isl_aff_dim(aff, isl_dim_in);
1229         involves = isl_aff_involves_dims(aff, isl_dim_in, 0, n);
1230         if (involves < 0)
1231                 return isl_aff_free(aff);
1232         if (involves)
1233                 isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
1234                     "affine expression involves some of the domain dimensions",
1235                     return isl_aff_free(aff));
1236         aff = isl_aff_drop_dims(aff, isl_dim_in, 0, n);
1237         space = isl_aff_get_domain_space(aff);
1238         space = isl_space_params(space);
1239         aff = isl_aff_reset_domain_space(aff, space);
1240         return aff;
1241 }
1242
1243 __isl_give isl_aff *isl_aff_insert_dims(__isl_take isl_aff *aff,
1244         enum isl_dim_type type, unsigned first, unsigned n)
1245 {
1246         isl_ctx *ctx;
1247
1248         if (!aff)
1249                 return NULL;
1250         if (type == isl_dim_out)
1251                 isl_die(aff->v->ctx, isl_error_invalid,
1252                         "cannot insert output/set dimensions",
1253                         return isl_aff_free(aff));
1254         if (type == isl_dim_in)
1255                 type = isl_dim_set;
1256         if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
1257                 return aff;
1258
1259         ctx = isl_aff_get_ctx(aff);
1260         if (first > isl_local_space_dim(aff->ls, type))
1261                 isl_die(ctx, isl_error_invalid, "position out of bounds",
1262                         return isl_aff_free(aff));
1263
1264         aff = isl_aff_cow(aff);
1265         if (!aff)
1266                 return NULL;
1267
1268         aff->ls = isl_local_space_insert_dims(aff->ls, type, first, n);
1269         if (!aff->ls)
1270                 return isl_aff_free(aff);
1271
1272         first += 1 + isl_local_space_offset(aff->ls, type);
1273         aff->v = isl_vec_insert_zero_els(aff->v, first, n);
1274         if (!aff->v)
1275                 return isl_aff_free(aff);
1276
1277         return aff;
1278 }
1279
1280 __isl_give isl_aff *isl_aff_add_dims(__isl_take isl_aff *aff,
1281         enum isl_dim_type type, unsigned n)
1282 {
1283         unsigned pos;
1284
1285         pos = isl_aff_dim(aff, type);
1286
1287         return isl_aff_insert_dims(aff, type, pos, n);
1288 }
1289
1290 __isl_give isl_pw_aff *isl_pw_aff_add_dims(__isl_take isl_pw_aff *pwaff,
1291         enum isl_dim_type type, unsigned n)
1292 {
1293         unsigned pos;
1294
1295         pos = isl_pw_aff_dim(pwaff, type);
1296
1297         return isl_pw_aff_insert_dims(pwaff, type, pos, n);
1298 }
1299
1300 __isl_give isl_pw_aff *isl_pw_aff_from_aff(__isl_take isl_aff *aff)
1301 {
1302         isl_set *dom = isl_set_universe(isl_aff_get_domain_space(aff));
1303         return isl_pw_aff_alloc(dom, aff);
1304 }
1305
1306 #undef PW
1307 #define PW isl_pw_aff
1308 #undef EL
1309 #define EL isl_aff
1310 #undef EL_IS_ZERO
1311 #define EL_IS_ZERO is_empty
1312 #undef ZERO
1313 #define ZERO empty
1314 #undef IS_ZERO
1315 #define IS_ZERO is_empty
1316 #undef FIELD
1317 #define FIELD aff
1318 #undef DEFAULT_IS_ZERO
1319 #define DEFAULT_IS_ZERO 0
1320
1321 #define NO_EVAL
1322 #define NO_OPT
1323 #define NO_MOVE_DIMS
1324 #define NO_LIFT
1325 #define NO_MORPH
1326
1327 #include <isl_pw_templ.c>
1328
1329 static __isl_give isl_set *align_params_pw_pw_set_and(
1330         __isl_take isl_pw_aff *pwaff1, __isl_take isl_pw_aff *pwaff2,
1331         __isl_give isl_set *(*fn)(__isl_take isl_pw_aff *pwaff1,
1332                                     __isl_take isl_pw_aff *pwaff2))
1333 {
1334         if (!pwaff1 || !pwaff2)
1335                 goto error;
1336         if (isl_space_match(pwaff1->dim, isl_dim_param,
1337                           pwaff2->dim, isl_dim_param))
1338                 return fn(pwaff1, pwaff2);
1339         if (!isl_space_has_named_params(pwaff1->dim) ||
1340             !isl_space_has_named_params(pwaff2->dim))
1341                 isl_die(isl_pw_aff_get_ctx(pwaff1), isl_error_invalid,
1342                         "unaligned unnamed parameters", goto error);
1343         pwaff1 = isl_pw_aff_align_params(pwaff1, isl_pw_aff_get_space(pwaff2));
1344         pwaff2 = isl_pw_aff_align_params(pwaff2, isl_pw_aff_get_space(pwaff1));
1345         return fn(pwaff1, pwaff2);
1346 error:
1347         isl_pw_aff_free(pwaff1);
1348         isl_pw_aff_free(pwaff2);
1349         return NULL;
1350 }
1351
1352 /* Compute a piecewise quasi-affine expression with a domain that
1353  * is the union of those of pwaff1 and pwaff2 and such that on each
1354  * cell, the quasi-affine expression is the better (according to cmp)
1355  * of those of pwaff1 and pwaff2.  If only one of pwaff1 or pwaff2
1356  * is defined on a given cell, then the associated expression
1357  * is the defined one.
1358  */
1359 static __isl_give isl_pw_aff *pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1,
1360         __isl_take isl_pw_aff *pwaff2,
1361         __isl_give isl_basic_set *(*cmp)(__isl_take isl_aff *aff1,
1362                                         __isl_take isl_aff *aff2))
1363 {
1364         int i, j, n;
1365         isl_pw_aff *res;
1366         isl_ctx *ctx;
1367         isl_set *set;
1368
1369         if (!pwaff1 || !pwaff2)
1370                 goto error;
1371
1372         ctx = isl_space_get_ctx(pwaff1->dim);
1373         if (!isl_space_is_equal(pwaff1->dim, pwaff2->dim))
1374                 isl_die(ctx, isl_error_invalid,
1375                         "arguments should live in same space", goto error);
1376
1377         if (isl_pw_aff_is_empty(pwaff1)) {
1378                 isl_pw_aff_free(pwaff1);
1379                 return pwaff2;
1380         }
1381
1382         if (isl_pw_aff_is_empty(pwaff2)) {
1383                 isl_pw_aff_free(pwaff2);
1384                 return pwaff1;
1385         }
1386
1387         n = 2 * (pwaff1->n + 1) * (pwaff2->n + 1);
1388         res = isl_pw_aff_alloc_size(isl_space_copy(pwaff1->dim), n);
1389
1390         for (i = 0; i < pwaff1->n; ++i) {
1391                 set = isl_set_copy(pwaff1->p[i].set);
1392                 for (j = 0; j < pwaff2->n; ++j) {
1393                         struct isl_set *common;
1394                         isl_set *better;
1395
1396                         common = isl_set_intersect(
1397                                         isl_set_copy(pwaff1->p[i].set),
1398                                         isl_set_copy(pwaff2->p[j].set));
1399                         better = isl_set_from_basic_set(cmp(
1400                                         isl_aff_copy(pwaff2->p[j].aff),
1401                                         isl_aff_copy(pwaff1->p[i].aff)));
1402                         better = isl_set_intersect(common, better);
1403                         if (isl_set_plain_is_empty(better)) {
1404                                 isl_set_free(better);
1405                                 continue;
1406                         }
1407                         set = isl_set_subtract(set, isl_set_copy(better));
1408
1409                         res = isl_pw_aff_add_piece(res, better,
1410                                                 isl_aff_copy(pwaff2->p[j].aff));
1411                 }
1412                 res = isl_pw_aff_add_piece(res, set,
1413                                                 isl_aff_copy(pwaff1->p[i].aff));
1414         }
1415
1416         for (j = 0; j < pwaff2->n; ++j) {
1417                 set = isl_set_copy(pwaff2->p[j].set);
1418                 for (i = 0; i < pwaff1->n; ++i)
1419                         set = isl_set_subtract(set,
1420                                         isl_set_copy(pwaff1->p[i].set));
1421                 res = isl_pw_aff_add_piece(res, set,
1422                                                 isl_aff_copy(pwaff2->p[j].aff));
1423         }
1424
1425         isl_pw_aff_free(pwaff1);
1426         isl_pw_aff_free(pwaff2);
1427
1428         return res;
1429 error:
1430         isl_pw_aff_free(pwaff1);
1431         isl_pw_aff_free(pwaff2);
1432         return NULL;
1433 }
1434
1435 /* Compute a piecewise quasi-affine expression with a domain that
1436  * is the union of those of pwaff1 and pwaff2 and such that on each
1437  * cell, the quasi-affine expression is the maximum of those of pwaff1
1438  * and pwaff2.  If only one of pwaff1 or pwaff2 is defined on a given
1439  * cell, then the associated expression is the defined one.
1440  */
1441 static __isl_give isl_pw_aff *pw_aff_union_max(__isl_take isl_pw_aff *pwaff1,
1442         __isl_take isl_pw_aff *pwaff2)
1443 {
1444         return pw_aff_union_opt(pwaff1, pwaff2, &isl_aff_ge_basic_set);
1445 }
1446
1447 __isl_give isl_pw_aff *isl_pw_aff_union_max(__isl_take isl_pw_aff *pwaff1,
1448         __isl_take isl_pw_aff *pwaff2)
1449 {
1450         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2,
1451                                                         &pw_aff_union_max);
1452 }
1453
1454 /* Compute a piecewise quasi-affine expression with a domain that
1455  * is the union of those of pwaff1 and pwaff2 and such that on each
1456  * cell, the quasi-affine expression is the minimum of those of pwaff1
1457  * and pwaff2.  If only one of pwaff1 or pwaff2 is defined on a given
1458  * cell, then the associated expression is the defined one.
1459  */
1460 static __isl_give isl_pw_aff *pw_aff_union_min(__isl_take isl_pw_aff *pwaff1,
1461         __isl_take isl_pw_aff *pwaff2)
1462 {
1463         return pw_aff_union_opt(pwaff1, pwaff2, &isl_aff_le_basic_set);
1464 }
1465
1466 __isl_give isl_pw_aff *isl_pw_aff_union_min(__isl_take isl_pw_aff *pwaff1,
1467         __isl_take isl_pw_aff *pwaff2)
1468 {
1469         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2,
1470                                                         &pw_aff_union_min);
1471 }
1472
1473 __isl_give isl_pw_aff *isl_pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1,
1474         __isl_take isl_pw_aff *pwaff2, int max)
1475 {
1476         if (max)
1477                 return isl_pw_aff_union_max(pwaff1, pwaff2);
1478         else
1479                 return isl_pw_aff_union_min(pwaff1, pwaff2);
1480 }
1481
1482 /* Construct a map with as domain the domain of pwaff and
1483  * one-dimensional range corresponding to the affine expressions.
1484  */
1485 static __isl_give isl_map *map_from_pw_aff(__isl_take isl_pw_aff *pwaff)
1486 {
1487         int i;
1488         isl_space *dim;
1489         isl_map *map;
1490
1491         if (!pwaff)
1492                 return NULL;
1493
1494         dim = isl_pw_aff_get_space(pwaff);
1495         map = isl_map_empty(dim);
1496
1497         for (i = 0; i < pwaff->n; ++i) {
1498                 isl_basic_map *bmap;
1499                 isl_map *map_i;
1500
1501                 bmap = isl_basic_map_from_aff(isl_aff_copy(pwaff->p[i].aff));
1502                 map_i = isl_map_from_basic_map(bmap);
1503                 map_i = isl_map_intersect_domain(map_i,
1504                                                 isl_set_copy(pwaff->p[i].set));
1505                 map = isl_map_union_disjoint(map, map_i);
1506         }
1507
1508         isl_pw_aff_free(pwaff);
1509
1510         return map;
1511 }
1512
1513 /* Construct a map with as domain the domain of pwaff and
1514  * one-dimensional range corresponding to the affine expressions.
1515  */
1516 __isl_give isl_map *isl_map_from_pw_aff(__isl_take isl_pw_aff *pwaff)
1517 {
1518         if (!pwaff)
1519                 return NULL;
1520         if (isl_space_is_set(pwaff->dim))
1521                 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
1522                         "space of input is not a map",
1523                         return isl_pw_aff_free(pwaff));
1524         return map_from_pw_aff(pwaff);
1525 }
1526
1527 /* Construct a one-dimensional set with as parameter domain
1528  * the domain of pwaff and the single set dimension
1529  * corresponding to the affine expressions.
1530  */
1531 __isl_give isl_set *isl_set_from_pw_aff(__isl_take isl_pw_aff *pwaff)
1532 {
1533         if (!pwaff)
1534                 return NULL;
1535         if (!isl_space_is_set(pwaff->dim))
1536                 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
1537                         "space of input is not a set",
1538                         return isl_pw_aff_free(pwaff));
1539         return map_from_pw_aff(pwaff);
1540 }
1541
1542 /* Return a set containing those elements in the domain
1543  * of pwaff where it is non-negative.
1544  */
1545 __isl_give isl_set *isl_pw_aff_nonneg_set(__isl_take isl_pw_aff *pwaff)
1546 {
1547         int i;
1548         isl_set *set;
1549
1550         if (!pwaff)
1551                 return NULL;
1552
1553         set = isl_set_empty(isl_pw_aff_get_domain_space(pwaff));
1554
1555         for (i = 0; i < pwaff->n; ++i) {
1556                 isl_basic_set *bset;
1557                 isl_set *set_i;
1558
1559                 bset = isl_aff_nonneg_basic_set(isl_aff_copy(pwaff->p[i].aff));
1560                 set_i = isl_set_from_basic_set(bset);
1561                 set_i = isl_set_intersect(set_i, isl_set_copy(pwaff->p[i].set));
1562                 set = isl_set_union_disjoint(set, set_i);
1563         }
1564
1565         isl_pw_aff_free(pwaff);
1566
1567         return set;
1568 }
1569
1570 /* Return a set containing those elements in the domain
1571  * of pwaff where it is zero (if complement is 0) or not zero
1572  * (if complement is 1).
1573  */
1574 static __isl_give isl_set *pw_aff_zero_set(__isl_take isl_pw_aff *pwaff,
1575         int complement)
1576 {
1577         int i;
1578         isl_set *set;
1579
1580         if (!pwaff)
1581                 return NULL;
1582
1583         set = isl_set_empty(isl_pw_aff_get_domain_space(pwaff));
1584
1585         for (i = 0; i < pwaff->n; ++i) {
1586                 isl_basic_set *bset;
1587                 isl_set *set_i, *zero;
1588
1589                 bset = isl_aff_zero_basic_set(isl_aff_copy(pwaff->p[i].aff));
1590                 zero = isl_set_from_basic_set(bset);
1591                 set_i = isl_set_copy(pwaff->p[i].set);
1592                 if (complement)
1593                         set_i = isl_set_subtract(set_i, zero);
1594                 else
1595                         set_i = isl_set_intersect(set_i, zero);
1596                 set = isl_set_union_disjoint(set, set_i);
1597         }
1598
1599         isl_pw_aff_free(pwaff);
1600
1601         return set;
1602 }
1603
1604 /* Return a set containing those elements in the domain
1605  * of pwaff where it is zero.
1606  */
1607 __isl_give isl_set *isl_pw_aff_zero_set(__isl_take isl_pw_aff *pwaff)
1608 {
1609         return pw_aff_zero_set(pwaff, 0);
1610 }
1611
1612 /* Return a set containing those elements in the domain
1613  * of pwaff where it is not zero.
1614  */
1615 __isl_give isl_set *isl_pw_aff_non_zero_set(__isl_take isl_pw_aff *pwaff)
1616 {
1617         return pw_aff_zero_set(pwaff, 1);
1618 }
1619
1620 /* Return a set containing those elements in the shared domain
1621  * of pwaff1 and pwaff2 where pwaff1 is greater than (or equal) to pwaff2.
1622  *
1623  * We compute the difference on the shared domain and then construct
1624  * the set of values where this difference is non-negative.
1625  * If strict is set, we first subtract 1 from the difference.
1626  * If equal is set, we only return the elements where pwaff1 and pwaff2
1627  * are equal.
1628  */
1629 static __isl_give isl_set *pw_aff_gte_set(__isl_take isl_pw_aff *pwaff1,
1630         __isl_take isl_pw_aff *pwaff2, int strict, int equal)
1631 {
1632         isl_set *set1, *set2;
1633
1634         set1 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff1));
1635         set2 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff2));
1636         set1 = isl_set_intersect(set1, set2);
1637         pwaff1 = isl_pw_aff_intersect_domain(pwaff1, isl_set_copy(set1));
1638         pwaff2 = isl_pw_aff_intersect_domain(pwaff2, isl_set_copy(set1));
1639         pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_neg(pwaff2));
1640
1641         if (strict) {
1642                 isl_space *dim = isl_set_get_space(set1);
1643                 isl_aff *aff;
1644                 aff = isl_aff_zero_on_domain(isl_local_space_from_space(dim));
1645                 aff = isl_aff_add_constant_si(aff, -1);
1646                 pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_alloc(set1, aff));
1647         } else
1648                 isl_set_free(set1);
1649
1650         if (equal)
1651                 return isl_pw_aff_zero_set(pwaff1);
1652         return isl_pw_aff_nonneg_set(pwaff1);
1653 }
1654
1655 /* Return a set containing those elements in the shared domain
1656  * of pwaff1 and pwaff2 where pwaff1 is equal to pwaff2.
1657  */
1658 static __isl_give isl_set *pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1,
1659         __isl_take isl_pw_aff *pwaff2)
1660 {
1661         return pw_aff_gte_set(pwaff1, pwaff2, 0, 1);
1662 }
1663
1664 __isl_give isl_set *isl_pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1,
1665         __isl_take isl_pw_aff *pwaff2)
1666 {
1667         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_eq_set);
1668 }
1669
1670 /* Return a set containing those elements in the shared domain
1671  * of pwaff1 and pwaff2 where pwaff1 is greater than or equal to pwaff2.
1672  */
1673 static __isl_give isl_set *pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1,
1674         __isl_take isl_pw_aff *pwaff2)
1675 {
1676         return pw_aff_gte_set(pwaff1, pwaff2, 0, 0);
1677 }
1678
1679 __isl_give isl_set *isl_pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1,
1680         __isl_take isl_pw_aff *pwaff2)
1681 {
1682         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_ge_set);
1683 }
1684
1685 /* Return a set containing those elements in the shared domain
1686  * of pwaff1 and pwaff2 where pwaff1 is strictly greater than pwaff2.
1687  */
1688 static __isl_give isl_set *pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1,
1689         __isl_take isl_pw_aff *pwaff2)
1690 {
1691         return pw_aff_gte_set(pwaff1, pwaff2, 1, 0);
1692 }
1693
1694 __isl_give isl_set *isl_pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1,
1695         __isl_take isl_pw_aff *pwaff2)
1696 {
1697         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_gt_set);
1698 }
1699
1700 __isl_give isl_set *isl_pw_aff_le_set(__isl_take isl_pw_aff *pwaff1,
1701         __isl_take isl_pw_aff *pwaff2)
1702 {
1703         return isl_pw_aff_ge_set(pwaff2, pwaff1);
1704 }
1705
1706 __isl_give isl_set *isl_pw_aff_lt_set(__isl_take isl_pw_aff *pwaff1,
1707         __isl_take isl_pw_aff *pwaff2)
1708 {
1709         return isl_pw_aff_gt_set(pwaff2, pwaff1);
1710 }
1711
1712 /* Return a set containing those elements in the shared domain
1713  * of the elements of list1 and list2 where each element in list1
1714  * has the relation specified by "fn" with each element in list2.
1715  */
1716 static __isl_give isl_set *pw_aff_list_set(__isl_take isl_pw_aff_list *list1,
1717         __isl_take isl_pw_aff_list *list2,
1718         __isl_give isl_set *(*fn)(__isl_take isl_pw_aff *pwaff1,
1719                                     __isl_take isl_pw_aff *pwaff2))
1720 {
1721         int i, j;
1722         isl_ctx *ctx;
1723         isl_set *set;
1724
1725         if (!list1 || !list2)
1726                 goto error;
1727
1728         ctx = isl_pw_aff_list_get_ctx(list1);
1729         if (list1->n < 1 || list2->n < 1)
1730                 isl_die(ctx, isl_error_invalid,
1731                         "list should contain at least one element", goto error);
1732
1733         set = isl_set_universe(isl_pw_aff_get_domain_space(list1->p[0]));
1734         for (i = 0; i < list1->n; ++i)
1735                 for (j = 0; j < list2->n; ++j) {
1736                         isl_set *set_ij;
1737
1738                         set_ij = fn(isl_pw_aff_copy(list1->p[i]),
1739                                     isl_pw_aff_copy(list2->p[j]));
1740                         set = isl_set_intersect(set, set_ij);
1741                 }
1742
1743         isl_pw_aff_list_free(list1);
1744         isl_pw_aff_list_free(list2);
1745         return set;
1746 error:
1747         isl_pw_aff_list_free(list1);
1748         isl_pw_aff_list_free(list2);
1749         return NULL;
1750 }
1751
1752 /* Return a set containing those elements in the shared domain
1753  * of the elements of list1 and list2 where each element in list1
1754  * is equal to each element in list2.
1755  */
1756 __isl_give isl_set *isl_pw_aff_list_eq_set(__isl_take isl_pw_aff_list *list1,
1757         __isl_take isl_pw_aff_list *list2)
1758 {
1759         return pw_aff_list_set(list1, list2, &isl_pw_aff_eq_set);
1760 }
1761
1762 __isl_give isl_set *isl_pw_aff_list_ne_set(__isl_take isl_pw_aff_list *list1,
1763         __isl_take isl_pw_aff_list *list2)
1764 {
1765         return pw_aff_list_set(list1, list2, &isl_pw_aff_ne_set);
1766 }
1767
1768 /* Return a set containing those elements in the shared domain
1769  * of the elements of list1 and list2 where each element in list1
1770  * is less than or equal to each element in list2.
1771  */
1772 __isl_give isl_set *isl_pw_aff_list_le_set(__isl_take isl_pw_aff_list *list1,
1773         __isl_take isl_pw_aff_list *list2)
1774 {
1775         return pw_aff_list_set(list1, list2, &isl_pw_aff_le_set);
1776 }
1777
1778 __isl_give isl_set *isl_pw_aff_list_lt_set(__isl_take isl_pw_aff_list *list1,
1779         __isl_take isl_pw_aff_list *list2)
1780 {
1781         return pw_aff_list_set(list1, list2, &isl_pw_aff_lt_set);
1782 }
1783
1784 __isl_give isl_set *isl_pw_aff_list_ge_set(__isl_take isl_pw_aff_list *list1,
1785         __isl_take isl_pw_aff_list *list2)
1786 {
1787         return pw_aff_list_set(list1, list2, &isl_pw_aff_ge_set);
1788 }
1789
1790 __isl_give isl_set *isl_pw_aff_list_gt_set(__isl_take isl_pw_aff_list *list1,
1791         __isl_take isl_pw_aff_list *list2)
1792 {
1793         return pw_aff_list_set(list1, list2, &isl_pw_aff_gt_set);
1794 }
1795
1796
1797 /* Return a set containing those elements in the shared domain
1798  * of pwaff1 and pwaff2 where pwaff1 is not equal to pwaff2.
1799  */
1800 static __isl_give isl_set *pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1,
1801         __isl_take isl_pw_aff *pwaff2)
1802 {
1803         isl_set *set_lt, *set_gt;
1804
1805         set_lt = isl_pw_aff_lt_set(isl_pw_aff_copy(pwaff1),
1806                                    isl_pw_aff_copy(pwaff2));
1807         set_gt = isl_pw_aff_gt_set(pwaff1, pwaff2);
1808         return isl_set_union_disjoint(set_lt, set_gt);
1809 }
1810
1811 __isl_give isl_set *isl_pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1,
1812         __isl_take isl_pw_aff *pwaff2)
1813 {
1814         return align_params_pw_pw_set_and(pwaff1, pwaff2, &pw_aff_ne_set);
1815 }
1816
1817 __isl_give isl_pw_aff *isl_pw_aff_scale_down(__isl_take isl_pw_aff *pwaff,
1818         isl_int v)
1819 {
1820         int i;
1821
1822         if (isl_int_is_one(v))
1823                 return pwaff;
1824         if (!isl_int_is_pos(v))
1825                 isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
1826                         "factor needs to be positive",
1827                         return isl_pw_aff_free(pwaff));
1828         pwaff = isl_pw_aff_cow(pwaff);
1829         if (!pwaff)
1830                 return NULL;
1831         if (pwaff->n == 0)
1832                 return pwaff;
1833
1834         for (i = 0; i < pwaff->n; ++i) {
1835                 pwaff->p[i].aff = isl_aff_scale_down(pwaff->p[i].aff, v);
1836                 if (!pwaff->p[i].aff)
1837                         return isl_pw_aff_free(pwaff);
1838         }
1839
1840         return pwaff;
1841 }
1842
1843 __isl_give isl_pw_aff *isl_pw_aff_floor(__isl_take isl_pw_aff *pwaff)
1844 {
1845         int i;
1846
1847         pwaff = isl_pw_aff_cow(pwaff);
1848         if (!pwaff)
1849                 return NULL;
1850         if (pwaff->n == 0)
1851                 return pwaff;
1852
1853         for (i = 0; i < pwaff->n; ++i) {
1854                 pwaff->p[i].aff = isl_aff_floor(pwaff->p[i].aff);
1855                 if (!pwaff->p[i].aff)
1856                         return isl_pw_aff_free(pwaff);
1857         }
1858
1859         return pwaff;
1860 }
1861
1862 __isl_give isl_pw_aff *isl_pw_aff_ceil(__isl_take isl_pw_aff *pwaff)
1863 {
1864         int i;
1865
1866         pwaff = isl_pw_aff_cow(pwaff);
1867         if (!pwaff)
1868                 return NULL;
1869         if (pwaff->n == 0)
1870                 return pwaff;
1871
1872         for (i = 0; i < pwaff->n; ++i) {
1873                 pwaff->p[i].aff = isl_aff_ceil(pwaff->p[i].aff);
1874                 if (!pwaff->p[i].aff)
1875                         return isl_pw_aff_free(pwaff);
1876         }
1877
1878         return pwaff;
1879 }
1880
1881 /* Return an affine expression that is equal to pwaff_true for elements
1882  * in "cond" and to pwaff_false for elements not in "cond".
1883  * That is, return cond ? pwaff_true : pwaff_false;
1884  */
1885 __isl_give isl_pw_aff *isl_pw_aff_cond(__isl_take isl_set *cond,
1886         __isl_take isl_pw_aff *pwaff_true, __isl_take isl_pw_aff *pwaff_false)
1887 {
1888         isl_set *comp;
1889
1890         comp = isl_set_complement(isl_set_copy(cond));
1891         pwaff_true = isl_pw_aff_intersect_domain(pwaff_true, cond);
1892         pwaff_false = isl_pw_aff_intersect_domain(pwaff_false, comp);
1893
1894         return isl_pw_aff_add_disjoint(pwaff_true, pwaff_false);
1895 }
1896
1897 int isl_aff_is_cst(__isl_keep isl_aff *aff)
1898 {
1899         if (!aff)
1900                 return -1;
1901
1902         return isl_seq_first_non_zero(aff->v->el + 2, aff->v->size - 2) == -1;
1903 }
1904
1905 /* Check whether pwaff is a piecewise constant.
1906  */
1907 int isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff)
1908 {
1909         int i;
1910
1911         if (!pwaff)
1912                 return -1;
1913
1914         for (i = 0; i < pwaff->n; ++i) {
1915                 int is_cst = isl_aff_is_cst(pwaff->p[i].aff);
1916                 if (is_cst < 0 || !is_cst)
1917                         return is_cst;
1918         }
1919
1920         return 1;
1921 }
1922
1923 __isl_give isl_aff *isl_aff_mul(__isl_take isl_aff *aff1,
1924         __isl_take isl_aff *aff2)
1925 {
1926         if (!isl_aff_is_cst(aff2) && isl_aff_is_cst(aff1))
1927                 return isl_aff_mul(aff2, aff1);
1928
1929         if (!isl_aff_is_cst(aff2))
1930                 isl_die(isl_aff_get_ctx(aff1), isl_error_invalid,
1931                         "at least one affine expression should be constant",
1932                         goto error);
1933
1934         aff1 = isl_aff_cow(aff1);
1935         if (!aff1 || !aff2)
1936                 goto error;
1937
1938         aff1 = isl_aff_scale(aff1, aff2->v->el[1]);
1939         aff1 = isl_aff_scale_down(aff1, aff2->v->el[0]);
1940
1941         isl_aff_free(aff2);
1942         return aff1;
1943 error:
1944         isl_aff_free(aff1);
1945         isl_aff_free(aff2);
1946         return NULL;
1947 }
1948
1949 static __isl_give isl_pw_aff *pw_aff_add(__isl_take isl_pw_aff *pwaff1,
1950         __isl_take isl_pw_aff *pwaff2)
1951 {
1952         return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_add);
1953 }
1954
1955 __isl_give isl_pw_aff *isl_pw_aff_add(__isl_take isl_pw_aff *pwaff1,
1956         __isl_take isl_pw_aff *pwaff2)
1957 {
1958         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_add);
1959 }
1960
1961 __isl_give isl_pw_aff *isl_pw_aff_union_add(__isl_take isl_pw_aff *pwaff1,
1962         __isl_take isl_pw_aff *pwaff2)
1963 {
1964         return isl_pw_aff_union_add_(pwaff1, pwaff2);
1965 }
1966
1967 static __isl_give isl_pw_aff *pw_aff_mul(__isl_take isl_pw_aff *pwaff1,
1968         __isl_take isl_pw_aff *pwaff2)
1969 {
1970         return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_mul);
1971 }
1972
1973 __isl_give isl_pw_aff *isl_pw_aff_mul(__isl_take isl_pw_aff *pwaff1,
1974         __isl_take isl_pw_aff *pwaff2)
1975 {
1976         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_mul);
1977 }
1978
1979 static __isl_give isl_pw_aff *pw_aff_min(__isl_take isl_pw_aff *pwaff1,
1980         __isl_take isl_pw_aff *pwaff2)
1981 {
1982         isl_set *le;
1983
1984         le = isl_pw_aff_le_set(isl_pw_aff_copy(pwaff1),
1985                                 isl_pw_aff_copy(pwaff2));
1986         return isl_pw_aff_cond(le, pwaff1, pwaff2);
1987 }
1988
1989 __isl_give isl_pw_aff *isl_pw_aff_min(__isl_take isl_pw_aff *pwaff1,
1990         __isl_take isl_pw_aff *pwaff2)
1991 {
1992         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_min);
1993 }
1994
1995 static __isl_give isl_pw_aff *pw_aff_max(__isl_take isl_pw_aff *pwaff1,
1996         __isl_take isl_pw_aff *pwaff2)
1997 {
1998         isl_set *le;
1999
2000         le = isl_pw_aff_ge_set(isl_pw_aff_copy(pwaff1),
2001                                 isl_pw_aff_copy(pwaff2));
2002         return isl_pw_aff_cond(le, pwaff1, pwaff2);
2003 }
2004
2005 __isl_give isl_pw_aff *isl_pw_aff_max(__isl_take isl_pw_aff *pwaff1,
2006         __isl_take isl_pw_aff *pwaff2)
2007 {
2008         return isl_pw_aff_align_params_pw_pw_and(pwaff1, pwaff2, &pw_aff_max);
2009 }
2010
2011 static __isl_give isl_pw_aff *pw_aff_list_reduce(
2012         __isl_take isl_pw_aff_list *list,
2013         __isl_give isl_pw_aff *(*fn)(__isl_take isl_pw_aff *pwaff1,
2014                                         __isl_take isl_pw_aff *pwaff2))
2015 {
2016         int i;
2017         isl_ctx *ctx;
2018         isl_pw_aff *res;
2019
2020         if (!list)
2021                 return NULL;
2022
2023         ctx = isl_pw_aff_list_get_ctx(list);
2024         if (list->n < 1)
2025                 isl_die(ctx, isl_error_invalid,
2026                         "list should contain at least one element",
2027                         return isl_pw_aff_list_free(list));
2028
2029         res = isl_pw_aff_copy(list->p[0]);
2030         for (i = 1; i < list->n; ++i)
2031                 res = fn(res, isl_pw_aff_copy(list->p[i]));
2032
2033         isl_pw_aff_list_free(list);
2034         return res;
2035 }
2036
2037 /* Return an isl_pw_aff that maps each element in the intersection of the
2038  * domains of the elements of list to the minimal corresponding affine
2039  * expression.
2040  */
2041 __isl_give isl_pw_aff *isl_pw_aff_list_min(__isl_take isl_pw_aff_list *list)
2042 {
2043         return pw_aff_list_reduce(list, &isl_pw_aff_min);
2044 }
2045
2046 /* Return an isl_pw_aff that maps each element in the intersection of the
2047  * domains of the elements of list to the maximal corresponding affine
2048  * expression.
2049  */
2050 __isl_give isl_pw_aff *isl_pw_aff_list_max(__isl_take isl_pw_aff_list *list)
2051 {
2052         return pw_aff_list_reduce(list, &isl_pw_aff_max);
2053 }
2054
2055 #undef BASE
2056 #define BASE aff
2057
2058 #include <isl_multi_templ.c>
2059
2060 __isl_give isl_multi_aff *isl_multi_aff_add(__isl_take isl_multi_aff *maff1,
2061         __isl_take isl_multi_aff *maff2)
2062 {
2063         int i;
2064         isl_ctx *ctx;
2065
2066         maff1 = isl_multi_aff_cow(maff1);
2067         if (!maff1 || !maff2)
2068                 goto error;
2069
2070         ctx = isl_multi_aff_get_ctx(maff1);
2071         if (!isl_space_is_equal(maff1->space, maff2->space))
2072                 isl_die(ctx, isl_error_invalid,
2073                         "spaces don't match", goto error);
2074
2075         for (i = 0; i < maff1->n; ++i) {
2076                 maff1->p[i] = isl_aff_add(maff1->p[i],
2077                                             isl_aff_copy(maff2->p[i]));
2078                 if (!maff1->p[i])
2079                         goto error;
2080         }
2081
2082         isl_multi_aff_free(maff2);
2083         return maff1;
2084 error:
2085         isl_multi_aff_free(maff1);
2086         isl_multi_aff_free(maff2);
2087         return NULL;
2088 }
2089
2090 /* Exploit the equalities in "eq" to simplify the affine expressions.
2091  */
2092 static __isl_give isl_multi_aff *isl_multi_aff_substitute_equalities(
2093         __isl_take isl_multi_aff *maff, __isl_take isl_basic_set *eq)
2094 {
2095         int i;
2096
2097         maff = isl_multi_aff_cow(maff);
2098         if (!maff || !eq)
2099                 goto error;
2100
2101         for (i = 0; i < maff->n; ++i) {
2102                 maff->p[i] = isl_aff_substitute_equalities(maff->p[i],
2103                                                     isl_basic_set_copy(eq));
2104                 if (!maff->p[i])
2105                         goto error;
2106         }
2107
2108         isl_basic_set_free(eq);
2109         return maff;
2110 error:
2111         isl_basic_set_free(eq);
2112         isl_multi_aff_free(maff);
2113         return NULL;
2114 }
2115
2116 __isl_give isl_multi_aff *isl_multi_aff_scale(__isl_take isl_multi_aff *maff,
2117         isl_int f)
2118 {
2119         int i;
2120
2121         maff = isl_multi_aff_cow(maff);
2122         if (!maff)
2123                 return NULL;
2124
2125         for (i = 0; i < maff->n; ++i) {
2126                 maff->p[i] = isl_aff_scale(maff->p[i], f);
2127                 if (!maff->p[i])
2128                         return isl_multi_aff_free(maff);
2129         }
2130
2131         return maff;
2132 }
2133
2134 __isl_give isl_multi_aff *isl_multi_aff_add_on_domain(__isl_keep isl_set *dom,
2135         __isl_take isl_multi_aff *maff1, __isl_take isl_multi_aff *maff2)
2136 {
2137         maff1 = isl_multi_aff_add(maff1, maff2);
2138         maff1 = isl_multi_aff_gist(maff1, isl_set_copy(dom));
2139         return maff1;
2140 }
2141
2142 int isl_multi_aff_is_empty(__isl_keep isl_multi_aff *maff)
2143 {
2144         if (!maff)
2145                 return -1;
2146
2147         return 0;
2148 }
2149
2150 int isl_multi_aff_plain_is_equal(__isl_keep isl_multi_aff *maff1,
2151         __isl_keep isl_multi_aff *maff2)
2152 {
2153         int i;
2154         int equal;
2155
2156         if (!maff1 || !maff2)
2157                 return -1;
2158         if (maff1->n != maff2->n)
2159                 return 0;
2160         equal = isl_space_is_equal(maff1->space, maff2->space);
2161         if (equal < 0 || !equal)
2162                 return equal;
2163
2164         for (i = 0; i < maff1->n; ++i) {
2165                 equal = isl_aff_plain_is_equal(maff1->p[i], maff2->p[i]);
2166                 if (equal < 0 || !equal)
2167                         return equal;
2168         }
2169
2170         return 1;
2171 }
2172
2173 __isl_give isl_multi_aff *isl_multi_aff_set_dim_name(
2174         __isl_take isl_multi_aff *maff,
2175         enum isl_dim_type type, unsigned pos, const char *s)
2176 {
2177         int i;
2178
2179         maff = isl_multi_aff_cow(maff);
2180         if (!maff)
2181                 return NULL;
2182
2183         maff->space = isl_space_set_dim_name(maff->space, type, pos, s);
2184         if (!maff->space)
2185                 return isl_multi_aff_free(maff);
2186         for (i = 0; i < maff->n; ++i) {
2187                 maff->p[i] = isl_aff_set_dim_name(maff->p[i], type, pos, s);
2188                 if (!maff->p[i])
2189                         return isl_multi_aff_free(maff);
2190         }
2191
2192         return maff;
2193 }
2194
2195 __isl_give isl_multi_aff *isl_multi_aff_drop_dims(__isl_take isl_multi_aff *maff,
2196         enum isl_dim_type type, unsigned first, unsigned n)
2197 {
2198         int i;
2199
2200         maff = isl_multi_aff_cow(maff);
2201         if (!maff)
2202                 return NULL;
2203
2204         maff->space = isl_space_drop_dims(maff->space, type, first, n);
2205         if (!maff->space)
2206                 return isl_multi_aff_free(maff);
2207
2208         if (type == isl_dim_out) {
2209                 for (i = 0; i < n; ++i)
2210                         isl_aff_free(maff->p[first + i]);
2211                 for (i = first; i + n < maff->n; ++i)
2212                         maff->p[i] = maff->p[i + n];
2213                 maff->n -= n;
2214                 return maff;
2215         }
2216
2217         for (i = 0; i < maff->n; ++i) {
2218                 maff->p[i] = isl_aff_drop_dims(maff->p[i], type, first, n);
2219                 if (!maff->p[i])
2220                         return isl_multi_aff_free(maff);
2221         }
2222
2223         return maff;
2224 }
2225
2226 #undef PW
2227 #define PW isl_pw_multi_aff
2228 #undef EL
2229 #define EL isl_multi_aff
2230 #undef EL_IS_ZERO
2231 #define EL_IS_ZERO is_empty
2232 #undef ZERO
2233 #define ZERO empty
2234 #undef IS_ZERO
2235 #define IS_ZERO is_empty
2236 #undef FIELD
2237 #define FIELD maff
2238 #undef DEFAULT_IS_ZERO
2239 #define DEFAULT_IS_ZERO 0
2240
2241 #define NO_NEG
2242 #define NO_EVAL
2243 #define NO_OPT
2244 #define NO_INVOLVES_DIMS
2245 #define NO_MOVE_DIMS
2246 #define NO_INSERT_DIMS
2247 #define NO_LIFT
2248 #define NO_MORPH
2249
2250 #include <isl_pw_templ.c>
2251
2252 static __isl_give isl_pw_multi_aff *pw_multi_aff_add(
2253         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
2254 {
2255         return isl_pw_multi_aff_on_shared_domain(pma1, pma2,
2256                                                 &isl_multi_aff_add);
2257 }
2258
2259 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_add(
2260         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
2261 {
2262         return isl_pw_multi_aff_align_params_pw_pw_and(pma1, pma2,
2263                                                 &pw_multi_aff_add);
2264 }
2265
2266 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_add(
2267         __isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
2268 {
2269         return isl_pw_multi_aff_union_add_(pma1, pma2);
2270 }
2271
2272 /* Construct a map mapping the domain the piecewise multi-affine expression
2273  * to its range, with each dimension in the range equated to the
2274  * corresponding affine expression on its cell.
2275  */
2276 __isl_give isl_map *isl_map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma)
2277 {
2278         int i;
2279         isl_map *map;
2280
2281         if (!pma)
2282                 return NULL;
2283
2284         map = isl_map_empty(isl_pw_multi_aff_get_space(pma));
2285
2286         for (i = 0; i < pma->n; ++i) {
2287                 isl_multi_aff *maff;
2288                 isl_basic_map *bmap;
2289                 isl_map *map_i;
2290
2291                 maff = isl_multi_aff_copy(pma->p[i].maff);
2292                 bmap = isl_basic_map_from_multi_aff(maff);
2293                 map_i = isl_map_from_basic_map(bmap);
2294                 map_i = isl_map_intersect_domain(map_i,
2295                                                 isl_set_copy(pma->p[i].set));
2296                 map = isl_map_union_disjoint(map, map_i);
2297         }
2298
2299         isl_pw_multi_aff_free(pma);
2300         return map;
2301 }
2302
2303 __isl_give isl_set *isl_set_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma)
2304 {
2305         if (!isl_space_is_set(pma->dim))
2306                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
2307                         "isl_pw_multi_aff cannot be converted into an isl_set",
2308                         return isl_pw_multi_aff_free(pma));
2309
2310         return isl_map_from_pw_multi_aff(pma);
2311 }
2312
2313 /* Given a basic map with a single output dimension that is defined
2314  * in terms of the parameters and input dimensions using an equality,
2315  * extract an isl_aff that expresses the output dimension in terms
2316  * of the parameters and input dimensions.
2317  *
2318  * Since some applications expect the result of isl_pw_multi_aff_from_map
2319  * to only contain integer affine expressions, we compute the floor
2320  * of the expression before returning.
2321  *
2322  * This function shares some similarities with
2323  * isl_basic_map_has_defining_equality and isl_constraint_get_bound.
2324  */
2325 static __isl_give isl_aff *extract_isl_aff_from_basic_map(
2326         __isl_take isl_basic_map *bmap)
2327 {
2328         int i;
2329         unsigned offset;
2330         unsigned total;
2331         isl_local_space *ls;
2332         isl_aff *aff;
2333
2334         if (!bmap)
2335                 return NULL;
2336         if (isl_basic_map_dim(bmap, isl_dim_out) != 1)
2337                 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
2338                         "basic map should have a single output dimension",
2339                         goto error);
2340         offset = isl_basic_map_offset(bmap, isl_dim_out);
2341         total = isl_basic_map_total_dim(bmap);
2342         for (i = 0; i < bmap->n_eq; ++i) {
2343                 if (isl_int_is_zero(bmap->eq[i][offset]))
2344                         continue;
2345                 if (isl_seq_first_non_zero(bmap->eq[i] + offset + 1,
2346                                            1 + total - (offset + 1)) != -1)
2347                         continue;
2348                 break;
2349         }
2350         if (i >= bmap->n_eq)
2351                 isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
2352                         "unable to find suitable equality", goto error);
2353         ls = isl_basic_map_get_local_space(bmap);
2354         aff = isl_aff_alloc(isl_local_space_domain(ls));
2355         if (!aff)
2356                 goto error;
2357         if (isl_int_is_neg(bmap->eq[i][offset]))
2358                 isl_seq_cpy(aff->v->el + 1, bmap->eq[i], offset);
2359         else
2360                 isl_seq_neg(aff->v->el + 1, bmap->eq[i], offset);
2361         isl_seq_clr(aff->v->el + 1 + offset, aff->v->size - (1 + offset));
2362         isl_int_abs(aff->v->el[0], bmap->eq[i][offset]);
2363         isl_basic_map_free(bmap);
2364
2365         aff = isl_aff_remove_unused_divs(aff);
2366         aff = isl_aff_floor(aff);
2367         return aff;
2368 error:
2369         isl_basic_map_free(bmap);
2370         return NULL;
2371 }
2372
2373 /* Given a basic map where each output dimension is defined
2374  * in terms of the parameters and input dimensions using an equality,
2375  * extract an isl_multi_aff that expresses the output dimensions in terms
2376  * of the parameters and input dimensions.
2377  */
2378 static __isl_give isl_multi_aff *extract_isl_multi_aff_from_basic_map(
2379         __isl_take isl_basic_map *bmap)
2380 {
2381         int i;
2382         unsigned n_out;
2383         isl_multi_aff *ma;
2384
2385         if (!bmap)
2386                 return NULL;
2387
2388         ma = isl_multi_aff_alloc(isl_basic_map_get_space(bmap));
2389         n_out = isl_basic_map_dim(bmap, isl_dim_out);
2390
2391         for (i = 0; i < n_out; ++i) {
2392                 isl_basic_map *bmap_i;
2393                 isl_aff *aff;
2394
2395                 bmap_i = isl_basic_map_copy(bmap);
2396                 bmap_i = isl_basic_map_project_out(bmap_i, isl_dim_out,
2397                                                         i + 1, n_out - (1 + i));
2398                 bmap_i = isl_basic_map_project_out(bmap_i, isl_dim_out, 0, i);
2399                 aff = extract_isl_aff_from_basic_map(bmap_i);
2400                 ma = isl_multi_aff_set_aff(ma, i, aff);
2401         }
2402
2403         isl_basic_map_free(bmap);
2404
2405         return ma;
2406 }
2407
2408 /* Create an isl_pw_multi_aff that is equivalent to
2409  * isl_map_intersect_domain(isl_map_from_basic_map(bmap), domain).
2410  * The given basic map is such that each output dimension is defined
2411  * in terms of the parameters and input dimensions using an equality.
2412  */
2413 static __isl_give isl_pw_multi_aff *plain_pw_multi_aff_from_map(
2414         __isl_take isl_set *domain, __isl_take isl_basic_map *bmap)
2415 {
2416         isl_multi_aff *ma;
2417
2418         ma = extract_isl_multi_aff_from_basic_map(bmap);
2419         return isl_pw_multi_aff_alloc(domain, ma);
2420 }
2421
2422 /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
2423  * This obivously only works if the input "map" is single-valued.
2424  * If so, we compute the lexicographic minimum of the image in the form
2425  * of an isl_pw_multi_aff.  Since the image is unique, it is equal
2426  * to its lexicographic minimum.
2427  * If the input is not single-valued, we produce an error.
2428  *
2429  * As a special case, we first check if all output dimensions are uniquely
2430  * defined in terms of the parameters and input dimensions over the entire
2431  * domain.  If so, we extract the desired isl_pw_multi_aff directly
2432  * from the affine hull of "map" and its domain.
2433  */
2434 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map)
2435 {
2436         int i;
2437         int sv;
2438         isl_pw_multi_aff *pma;
2439         isl_basic_map *hull;
2440
2441         if (!map)
2442                 return NULL;
2443
2444         hull = isl_map_affine_hull(isl_map_copy(map));
2445         sv = isl_basic_map_plain_is_single_valued(hull);
2446         if (sv >= 0 && sv)
2447                 return plain_pw_multi_aff_from_map(isl_map_domain(map), hull);
2448         isl_basic_map_free(hull);
2449         if (sv < 0)
2450                 goto error;
2451
2452         sv = isl_map_is_single_valued(map);
2453         if (sv < 0)
2454                 goto error;
2455         if (!sv)
2456                 isl_die(isl_map_get_ctx(map), isl_error_invalid,
2457                         "map is not single-valued", goto error);
2458         map = isl_map_make_disjoint(map);
2459         if (!map)
2460                 return NULL;
2461
2462         pma = isl_pw_multi_aff_empty(isl_map_get_space(map));
2463
2464         for (i = 0; i < map->n; ++i) {
2465                 isl_pw_multi_aff *pma_i;
2466                 isl_basic_map *bmap;
2467                 bmap = isl_basic_map_copy(map->p[i]);
2468                 pma_i = isl_basic_map_lexmin_pw_multi_aff(bmap);
2469                 pma = isl_pw_multi_aff_add_disjoint(pma, pma_i);
2470         }
2471
2472         isl_map_free(map);
2473         return pma;
2474 error:
2475         isl_map_free(map);
2476         return NULL;
2477 }
2478
2479 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(__isl_take isl_set *set)
2480 {
2481         return isl_pw_multi_aff_from_map(set);
2482 }
2483
2484 /* Plug in "subs" for dimension "type", "pos" of "aff".
2485  *
2486  * Let i be the dimension to replace and let "subs" be of the form
2487  *
2488  *      f/d
2489  *
2490  * and "aff" of the form
2491  *
2492  *      (a i + g)/m
2493  *
2494  * The result is
2495  *
2496  *      floor((a f + d g')/(m d))
2497  *
2498  * where g' is the result of plugging in "subs" in each of the integer
2499  * divisions in g.
2500  */
2501 __isl_give isl_aff *isl_aff_substitute(__isl_take isl_aff *aff,
2502         enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
2503 {
2504         isl_ctx *ctx;
2505         isl_int v;
2506
2507         aff = isl_aff_cow(aff);
2508         if (!aff || !subs)
2509                 return isl_aff_free(aff);
2510
2511         ctx = isl_aff_get_ctx(aff);
2512         if (!isl_space_is_equal(aff->ls->dim, subs->ls->dim))
2513                 isl_die(ctx, isl_error_invalid,
2514                         "spaces don't match", return isl_aff_free(aff));
2515         if (isl_local_space_dim(subs->ls, isl_dim_div) != 0)
2516                 isl_die(ctx, isl_error_unsupported,
2517                         "cannot handle divs yet", return isl_aff_free(aff));
2518
2519         aff->ls = isl_local_space_substitute(aff->ls, type, pos, subs);
2520         if (!aff->ls)
2521                 return isl_aff_free(aff);
2522
2523         aff->v = isl_vec_cow(aff->v);
2524         if (!aff->v)
2525                 return isl_aff_free(aff);
2526
2527         pos += isl_local_space_offset(aff->ls, type);
2528
2529         isl_int_init(v);
2530         isl_int_set(v, aff->v->el[1 + pos]);
2531         isl_int_set_si(aff->v->el[1 + pos], 0);
2532         isl_seq_combine(aff->v->el + 1, subs->v->el[0], aff->v->el + 1,
2533                         v, subs->v->el + 1, subs->v->size - 1);
2534         isl_int_mul(aff->v->el[0], aff->v->el[0], subs->v->el[0]);
2535         isl_int_clear(v);
2536
2537         return aff;
2538 }
2539
2540 /* Plug in "subs" for dimension "type", "pos" in each of the affine
2541  * expressions in "maff".
2542  */
2543 __isl_give isl_multi_aff *isl_multi_aff_substitute(
2544         __isl_take isl_multi_aff *maff, enum isl_dim_type type, unsigned pos,
2545         __isl_keep isl_aff *subs)
2546 {
2547         int i;
2548
2549         maff = isl_multi_aff_cow(maff);
2550         if (!maff || !subs)
2551                 return isl_multi_aff_free(maff);
2552
2553         if (type == isl_dim_in)
2554                 type = isl_dim_set;
2555
2556         for (i = 0; i < maff->n; ++i) {
2557                 maff->p[i] = isl_aff_substitute(maff->p[i], type, pos, subs);
2558                 if (!maff->p[i])
2559                         return isl_multi_aff_free(maff);
2560         }
2561
2562         return maff;
2563 }
2564
2565 /* Plug in "subs" for dimension "type", "pos" of "pma".
2566  *
2567  * pma is of the form
2568  *
2569  *      A_i(v) -> M_i(v)
2570  *
2571  * while subs is of the form
2572  *
2573  *      v' = B_j(v) -> S_j
2574  *
2575  * Each pair i,j such that C_ij = A_i \cap B_i is non-empty
2576  * has a contribution in the result, in particular
2577  *
2578  *      C_ij(S_j) -> M_i(S_j)
2579  *
2580  * Note that plugging in S_j in C_ij may also result in an empty set
2581  * and this contribution should simply be discarded.
2582  */
2583 __isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute(
2584         __isl_take isl_pw_multi_aff *pma, enum isl_dim_type type, unsigned pos,
2585         __isl_keep isl_pw_aff *subs)
2586 {
2587         int i, j, n;
2588         isl_pw_multi_aff *res;
2589
2590         if (!pma || !subs)
2591                 return isl_pw_multi_aff_free(pma);
2592
2593         n = pma->n * subs->n;
2594         res = isl_pw_multi_aff_alloc_size(isl_space_copy(pma->dim), n);
2595
2596         for (i = 0; i < pma->n; ++i) {
2597                 for (j = 0; j < subs->n; ++j) {
2598                         isl_set *common;
2599                         isl_multi_aff *res_ij;
2600                         common = isl_set_intersect(
2601                                         isl_set_copy(pma->p[i].set),
2602                                         isl_set_copy(subs->p[j].set));
2603                         common = isl_set_substitute(common,
2604                                         type, pos, subs->p[j].aff);
2605                         if (isl_set_plain_is_empty(common)) {
2606                                 isl_set_free(common);
2607                                 continue;
2608                         }
2609
2610                         res_ij = isl_multi_aff_substitute(
2611                                         isl_multi_aff_copy(pma->p[i].maff),
2612                                         type, pos, subs->p[j].aff);
2613
2614                         res = isl_pw_multi_aff_add_piece(res, common, res_ij);
2615                 }
2616         }
2617
2618         isl_pw_multi_aff_free(pma);
2619         return res;
2620 }
2621
2622 /* Extend the local space of "dst" to include the divs
2623  * in the local space of "src".
2624  */
2625 __isl_give isl_aff *isl_aff_align_divs(__isl_take isl_aff *dst,
2626         __isl_keep isl_aff *src)
2627 {
2628         isl_ctx *ctx;
2629         int *exp1 = NULL;
2630         int *exp2 = NULL;
2631         isl_mat *div;
2632
2633         if (!src || !dst)
2634                 return isl_aff_free(dst);
2635
2636         ctx = isl_aff_get_ctx(src);
2637         if (!isl_space_is_equal(src->ls->dim, dst->ls->dim))
2638                 isl_die(ctx, isl_error_invalid,
2639                         "spaces don't match", goto error);
2640
2641         if (src->ls->div->n_row == 0)
2642                 return dst;
2643
2644         exp1 = isl_alloc_array(ctx, int, src->ls->div->n_row);
2645         exp2 = isl_alloc_array(ctx, int, dst->ls->div->n_row);
2646         if (!exp1 || !exp2)
2647                 goto error;
2648
2649         div = isl_merge_divs(src->ls->div, dst->ls->div, exp1, exp2);
2650         dst = isl_aff_expand_divs(dst, div, exp2);
2651         free(exp1);
2652         free(exp2);
2653
2654         return dst;
2655 error:
2656         free(exp1);
2657         free(exp2);
2658         return isl_aff_free(dst);
2659 }
2660
2661 /* Adjust the local spaces of the affine expressions in "maff"
2662  * such that they all have the save divs.
2663  */
2664 __isl_give isl_multi_aff *isl_multi_aff_align_divs(
2665         __isl_take isl_multi_aff *maff)
2666 {
2667         int i;
2668
2669         if (!maff)
2670                 return NULL;
2671         if (maff->n == 0)
2672                 return maff;
2673         maff = isl_multi_aff_cow(maff);
2674         if (!maff)
2675                 return NULL;
2676
2677         for (i = 1; i < maff->n; ++i)
2678                 maff->p[0] = isl_aff_align_divs(maff->p[0], maff->p[i]);
2679         for (i = 1; i < maff->n; ++i) {
2680                 maff->p[i] = isl_aff_align_divs(maff->p[i], maff->p[0]);
2681                 if (!maff->p[i])
2682                         return isl_multi_aff_free(maff);
2683         }
2684
2685         return maff;
2686 }
2687
2688 __isl_give isl_aff *isl_aff_lift(__isl_take isl_aff *aff)
2689 {
2690         aff = isl_aff_cow(aff);
2691         if (!aff)
2692                 return NULL;
2693
2694         aff->ls = isl_local_space_lift(aff->ls);
2695         if (!aff->ls)
2696                 return isl_aff_free(aff);
2697
2698         return aff;
2699 }
2700
2701 /* Lift "maff" to a space with extra dimensions such that the result
2702  * has no more existentially quantified variables.
2703  * If "ls" is not NULL, then *ls is assigned the local space that lies
2704  * at the basis of the lifting applied to "maff".
2705  */
2706 __isl_give isl_multi_aff *isl_multi_aff_lift(__isl_take isl_multi_aff *maff,
2707         __isl_give isl_local_space **ls)
2708 {
2709         int i;
2710         isl_space *space;
2711         unsigned n_div;
2712
2713         if (ls)
2714                 *ls = NULL;
2715
2716         if (!maff)
2717                 return NULL;
2718
2719         if (maff->n == 0) {
2720                 if (ls) {
2721                         isl_space *space = isl_multi_aff_get_domain_space(maff);
2722                         *ls = isl_local_space_from_space(space);
2723                         if (!*ls)
2724                                 return isl_multi_aff_free(maff);
2725                 }
2726                 return maff;
2727         }
2728
2729         maff = isl_multi_aff_cow(maff);
2730         maff = isl_multi_aff_align_divs(maff);
2731         if (!maff)
2732                 return NULL;
2733
2734         n_div = isl_aff_dim(maff->p[0], isl_dim_div);
2735         space = isl_multi_aff_get_space(maff);
2736         space = isl_space_lift(isl_space_domain(space), n_div);
2737         space = isl_space_extend_domain_with_range(space,
2738                                                 isl_multi_aff_get_space(maff));
2739         if (!space)
2740                 return isl_multi_aff_free(maff);
2741         isl_space_free(maff->space);
2742         maff->space = space;
2743
2744         if (ls) {
2745                 *ls = isl_aff_get_domain_local_space(maff->p[0]);
2746                 if (!*ls)
2747                         return isl_multi_aff_free(maff);
2748         }
2749
2750         for (i = 0; i < maff->n; ++i) {
2751                 maff->p[i] = isl_aff_lift(maff->p[i]);
2752                 if (!maff->p[i])
2753                         goto error;
2754         }
2755
2756         return maff;
2757 error:
2758         if (ls)
2759                 isl_local_space_free(*ls);
2760         return isl_multi_aff_free(maff);
2761 }
2762
2763
2764 /* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma".
2765  */
2766 __isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff(
2767         __isl_keep isl_pw_multi_aff *pma, int pos)
2768 {
2769         int i;
2770         int n_out;
2771         isl_space *space;
2772         isl_pw_aff *pa;
2773
2774         if (!pma)
2775                 return NULL;
2776
2777         n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
2778         if (pos < 0 || pos >= n_out)
2779                 isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
2780                         "index out of bounds", return NULL);
2781
2782         space = isl_pw_multi_aff_get_space(pma);
2783         space = isl_space_drop_dims(space, isl_dim_out,
2784                                     pos + 1, n_out - pos - 1);
2785         space = isl_space_drop_dims(space, isl_dim_out, 0, pos);
2786
2787         pa = isl_pw_aff_alloc_size(space, pma->n);
2788         for (i = 0; i < pma->n; ++i) {
2789                 isl_aff *aff;
2790                 aff = isl_multi_aff_get_aff(pma->p[i].maff, pos);
2791                 pa = isl_pw_aff_add_piece(pa, isl_set_copy(pma->p[i].set), aff);
2792         }
2793
2794         return pa;
2795 }