add isl_local_space_substitute_equalities
[isl.git] / isl_pw_templ.c
blob9b0d3c77c6322fdf7fe76e31e34fb916d363d2da
1 #define xFN(TYPE,NAME) TYPE ## _ ## NAME
2 #define FN(TYPE,NAME) xFN(TYPE,NAME)
3 #define xS(TYPE,NAME) struct TYPE ## _ ## NAME
4 #define S(TYPE,NAME) xS(TYPE,NAME)
6 #ifdef HAS_TYPE
7 static __isl_give PW *FN(PW,alloc_)(__isl_take isl_dim *dim,
8 enum isl_fold type, int n)
9 #else
10 static __isl_give PW *FN(PW,alloc_)(__isl_take isl_dim *dim, int n)
11 #endif
13 isl_ctx *ctx;
14 struct PW *pw;
16 if (!dim)
17 return NULL;
18 ctx = isl_dim_get_ctx(dim);
19 isl_assert(ctx, n >= 0, goto error);
20 pw = isl_alloc(ctx, struct PW,
21 sizeof(struct PW) + (n - 1) * sizeof(S(PW,piece)));
22 if (!pw)
23 goto error;
25 pw->ref = 1;
26 #ifdef HAS_TYPE
27 pw->type = type;
28 #endif
29 pw->size = n;
30 pw->n = 0;
31 pw->dim = dim;
32 return pw;
33 error:
34 isl_dim_free(dim);
35 return NULL;
38 #ifdef HAS_TYPE
39 __isl_give PW *FN(PW,zero)(__isl_take isl_dim *dim, enum isl_fold type)
41 return FN(PW,alloc_)(dim, type, 0);
43 #else
44 __isl_give PW *FN(PW,zero)(__isl_take isl_dim *dim)
46 return FN(PW,alloc_)(dim, 0);
48 #endif
50 __isl_give PW *FN(PW,add_piece)(__isl_take PW *pw,
51 __isl_take isl_set *set, __isl_take EL *el)
53 isl_ctx *ctx;
54 isl_dim *el_dim = NULL;
56 if (!pw || !set || !el)
57 goto error;
59 if (isl_set_plain_is_empty(set) || FN(EL,IS_ZERO)(el)) {
60 isl_set_free(set);
61 FN(EL,free)(el);
62 return pw;
65 ctx = isl_set_get_ctx(set);
66 #ifdef HAS_TYPE
67 if (pw->type != el->type)
68 isl_die(ctx, isl_error_invalid, "fold types don't match",
69 goto error);
70 #endif
71 el_dim = FN(EL,get_dim(el));
72 isl_assert(ctx, isl_dim_equal(pw->dim, el_dim), goto error);
73 isl_assert(ctx, pw->n < pw->size, goto error);
75 pw->p[pw->n].set = set;
76 pw->p[pw->n].FIELD = el;
77 pw->n++;
79 isl_dim_free(el_dim);
80 return pw;
81 error:
82 isl_dim_free(el_dim);
83 FN(PW,free)(pw);
84 isl_set_free(set);
85 FN(EL,free)(el);
86 return NULL;
89 #ifdef HAS_TYPE
90 __isl_give PW *FN(PW,alloc)(enum isl_fold type,
91 __isl_take isl_set *set, __isl_take EL *el)
92 #else
93 __isl_give PW *FN(PW,alloc)(__isl_take isl_set *set, __isl_take EL *el)
94 #endif
96 PW *pw;
98 if (!set || !el)
99 goto error;
101 #ifdef HAS_TYPE
102 pw = FN(PW,alloc_)(isl_set_get_dim(set), type, 1);
103 #else
104 pw = FN(PW,alloc_)(isl_set_get_dim(set), 1);
105 #endif
107 return FN(PW,add_piece)(pw, set, el);
108 error:
109 isl_set_free(set);
110 FN(EL,free)(el);
111 return NULL;
114 __isl_give PW *FN(PW,dup)(__isl_keep PW *pw)
116 int i;
117 PW *dup;
119 if (!pw)
120 return NULL;
122 #ifdef HAS_TYPE
123 dup = FN(PW,alloc_)(isl_dim_copy(pw->dim), pw->type, pw->n);
124 #else
125 dup = FN(PW,alloc_)(isl_dim_copy(pw->dim), pw->n);
126 #endif
127 if (!dup)
128 return NULL;
130 for (i = 0; i < pw->n; ++i)
131 dup = FN(PW,add_piece)(dup, isl_set_copy(pw->p[i].set),
132 FN(EL,copy)(pw->p[i].FIELD));
134 return dup;
137 __isl_give PW *FN(PW,cow)(__isl_take PW *pw)
139 if (!pw)
140 return NULL;
142 if (pw->ref == 1)
143 return pw;
144 pw->ref--;
145 return FN(PW,dup)(pw);
148 __isl_give PW *FN(PW,copy)(__isl_keep PW *pw)
150 if (!pw)
151 return NULL;
153 pw->ref++;
154 return pw;
157 void FN(PW,free)(__isl_take PW *pw)
159 int i;
161 if (!pw)
162 return;
163 if (--pw->ref > 0)
164 return;
166 for (i = 0; i < pw->n; ++i) {
167 isl_set_free(pw->p[i].set);
168 FN(EL,free)(pw->p[i].FIELD);
170 isl_dim_free(pw->dim);
171 free(pw);
174 int FN(PW,is_zero)(__isl_keep PW *pw)
176 if (!pw)
177 return -1;
179 return pw->n == 0;
182 __isl_give PW *FN(PW,add)(__isl_take PW *pw1, __isl_take PW *pw2)
184 int i, j, n;
185 struct PW *res;
186 isl_ctx *ctx;
187 isl_set *set;
189 if (!pw1 || !pw2)
190 goto error;
192 ctx = isl_dim_get_ctx(pw1->dim);
193 #ifdef HAS_TYPE
194 if (pw1->type != pw2->type)
195 isl_die(ctx, isl_error_invalid,
196 "fold types don't match", goto error);
197 #endif
198 isl_assert(ctx, isl_dim_equal(pw1->dim, pw2->dim), goto error);
200 if (FN(PW,is_zero)(pw1)) {
201 FN(PW,free)(pw1);
202 return pw2;
205 if (FN(PW,is_zero)(pw2)) {
206 FN(PW,free)(pw2);
207 return pw1;
210 n = (pw1->n + 1) * (pw2->n + 1);
211 #ifdef HAS_TYPE
212 res = FN(PW,alloc_)(isl_dim_copy(pw1->dim), pw1->type, n);
213 #else
214 res = FN(PW,alloc_)(isl_dim_copy(pw1->dim), n);
215 #endif
217 for (i = 0; i < pw1->n; ++i) {
218 set = isl_set_copy(pw1->p[i].set);
219 for (j = 0; j < pw2->n; ++j) {
220 struct isl_set *common;
221 EL *sum;
222 set = isl_set_subtract(set,
223 isl_set_copy(pw2->p[j].set));
224 common = isl_set_intersect(isl_set_copy(pw1->p[i].set),
225 isl_set_copy(pw2->p[j].set));
226 if (isl_set_plain_is_empty(common)) {
227 isl_set_free(common);
228 continue;
231 sum = FN(EL,add_on_domain)(common,
232 FN(EL,copy)(pw1->p[i].FIELD),
233 FN(EL,copy)(pw2->p[j].FIELD));
235 res = FN(PW,add_piece)(res, common, sum);
237 res = FN(PW,add_piece)(res, set, FN(EL,copy)(pw1->p[i].FIELD));
240 for (j = 0; j < pw2->n; ++j) {
241 set = isl_set_copy(pw2->p[j].set);
242 for (i = 0; i < pw1->n; ++i)
243 set = isl_set_subtract(set,
244 isl_set_copy(pw1->p[i].set));
245 res = FN(PW,add_piece)(res, set, FN(EL,copy)(pw2->p[j].FIELD));
248 FN(PW,free)(pw1);
249 FN(PW,free)(pw2);
251 return res;
252 error:
253 FN(PW,free)(pw1);
254 FN(PW,free)(pw2);
255 return NULL;
258 __isl_give PW *FN(PW,add_disjoint)(__isl_take PW *pw1, __isl_take PW *pw2)
260 int i;
261 isl_ctx *ctx;
262 PW *res;
264 if (!pw1 || !pw2)
265 goto error;
267 ctx = isl_dim_get_ctx(pw1->dim);
268 #ifdef HAS_TYPE
269 if (pw1->type != pw2->type)
270 isl_die(ctx, isl_error_invalid,
271 "fold types don't match", goto error);
272 #endif
273 isl_assert(ctx, isl_dim_equal(pw1->dim, pw2->dim), goto error);
275 if (FN(PW,is_zero)(pw1)) {
276 FN(PW,free)(pw1);
277 return pw2;
280 if (FN(PW,is_zero)(pw2)) {
281 FN(PW,free)(pw2);
282 return pw1;
285 #ifdef HAS_TYPE
286 res = FN(PW,alloc_)(isl_dim_copy(pw1->dim), pw1->type, pw1->n + pw2->n);
287 #else
288 res = FN(PW,alloc_)(isl_dim_copy(pw1->dim), pw1->n + pw2->n);
289 #endif
291 for (i = 0; i < pw1->n; ++i)
292 res = FN(PW,add_piece)(res,
293 isl_set_copy(pw1->p[i].set),
294 FN(EL,copy)(pw1->p[i].FIELD));
296 for (i = 0; i < pw2->n; ++i)
297 res = FN(PW,add_piece)(res,
298 isl_set_copy(pw2->p[i].set),
299 FN(EL,copy)(pw2->p[i].FIELD));
301 FN(PW,free)(pw1);
302 FN(PW,free)(pw2);
304 return res;
305 error:
306 FN(PW,free)(pw1);
307 FN(PW,free)(pw2);
308 return NULL;
311 __isl_give isl_qpolynomial *FN(PW,eval)(__isl_take PW *pw,
312 __isl_take isl_point *pnt)
314 int i;
315 int found = 0;
316 isl_ctx *ctx;
317 isl_dim *pnt_dim = NULL;
318 isl_qpolynomial *qp;
320 if (!pw || !pnt)
321 goto error;
322 ctx = isl_point_get_ctx(pnt);
323 pnt_dim = isl_point_get_dim(pnt);
324 isl_assert(ctx, isl_dim_equal(pnt_dim, pw->dim), goto error);
326 for (i = 0; i < pw->n; ++i) {
327 found = isl_set_contains_point(pw->p[i].set, pnt);
328 if (found < 0)
329 goto error;
330 if (found)
331 break;
333 if (found)
334 qp = FN(EL,eval)(FN(EL,copy)(pw->p[i].FIELD),
335 isl_point_copy(pnt));
336 else
337 qp = isl_qpolynomial_zero(isl_dim_copy(pw->dim));
338 FN(PW,free)(pw);
339 isl_dim_free(pnt_dim);
340 isl_point_free(pnt);
341 return qp;
342 error:
343 FN(PW,free)(pw);
344 isl_dim_free(pnt_dim);
345 isl_point_free(pnt);
346 return NULL;
349 __isl_give isl_set *FN(PW,domain)(__isl_take PW *pw)
351 int i;
352 isl_set *dom;
354 if (!pw)
355 return NULL;
357 dom = isl_set_empty(isl_dim_copy(pw->dim));
358 for (i = 0; i < pw->n; ++i)
359 dom = isl_set_union_disjoint(dom, isl_set_copy(pw->p[i].set));
361 FN(PW,free)(pw);
363 return dom;
366 __isl_give PW *FN(PW,intersect_domain)(__isl_take PW *pw, __isl_take isl_set *set)
368 int i;
370 if (!pw || !set)
371 goto error;
373 if (pw->n == 0) {
374 isl_set_free(set);
375 return pw;
378 pw = FN(PW,cow)(pw);
379 if (!pw)
380 goto error;
382 for (i = pw->n - 1; i >= 0; --i) {
383 isl_basic_set *aff;
384 pw->p[i].set = isl_set_intersect(pw->p[i].set, isl_set_copy(set));
385 if (!pw->p[i].set)
386 goto error;
387 aff = isl_set_affine_hull(isl_set_copy(pw->p[i].set));
388 pw->p[i].FIELD = FN(EL,substitute_equalities)(pw->p[i].FIELD,
389 aff);
390 if (isl_set_plain_is_empty(pw->p[i].set)) {
391 isl_set_free(pw->p[i].set);
392 FN(EL,free)(pw->p[i].FIELD);
393 if (i != pw->n - 1)
394 pw->p[i] = pw->p[pw->n - 1];
395 pw->n--;
399 isl_set_free(set);
400 return pw;
401 error:
402 isl_set_free(set);
403 FN(PW,free)(pw);
404 return NULL;
407 __isl_give PW *FN(PW,gist)(__isl_take PW *pw, __isl_take isl_set *context)
409 int i;
410 isl_basic_set *hull = NULL;
412 if (!pw || !context)
413 goto error;
415 if (pw->n == 0) {
416 isl_set_free(context);
417 return pw;
420 context = isl_set_compute_divs(context);
421 hull = isl_set_simple_hull(isl_set_copy(context));
423 pw = FN(PW,cow)(pw);
424 if (!pw)
425 goto error;
427 for (i = pw->n - 1; i >= 0; --i) {
428 pw->p[i].set = isl_set_intersect(pw->p[i].set,
429 isl_set_copy(context));
430 if (!pw->p[i].set)
431 goto error;
432 pw->p[i].FIELD = FN(EL,gist)(pw->p[i].FIELD,
433 isl_set_copy(pw->p[i].set));
434 pw->p[i].set = isl_set_gist_basic_set(pw->p[i].set,
435 isl_basic_set_copy(hull));
436 if (!pw->p[i].set)
437 goto error;
438 if (isl_set_plain_is_empty(pw->p[i].set)) {
439 isl_set_free(pw->p[i].set);
440 FN(EL,free)(pw->p[i].FIELD);
441 if (i != pw->n - 1)
442 pw->p[i] = pw->p[pw->n - 1];
443 pw->n--;
447 isl_basic_set_free(hull);
448 isl_set_free(context);
450 return pw;
451 error:
452 FN(PW,free)(pw);
453 isl_basic_set_free(hull);
454 isl_set_free(context);
455 return NULL;
458 __isl_give PW *FN(PW,coalesce)(__isl_take PW *pw)
460 int i, j;
462 if (!pw)
463 return NULL;
464 if (pw->n == 0)
465 return pw;
467 for (i = pw->n - 1; i >= 0; --i) {
468 for (j = i - 1; j >= 0; --j) {
469 if (!FN(EL,plain_is_equal)(pw->p[i].FIELD,
470 pw->p[j].FIELD))
471 continue;
472 pw->p[j].set = isl_set_union(pw->p[j].set,
473 pw->p[i].set);
474 FN(EL,free)(pw->p[i].FIELD);
475 if (i != pw->n - 1)
476 pw->p[i] = pw->p[pw->n - 1];
477 pw->n--;
478 break;
480 if (j >= 0)
481 continue;
482 pw->p[i].set = isl_set_coalesce(pw->p[i].set);
483 if (!pw->p[i].set)
484 goto error;
487 return pw;
488 error:
489 FN(PW,free)(pw);
490 return NULL;
493 isl_ctx *FN(PW,get_ctx)(__isl_keep PW *pw)
495 return pw ? isl_dim_get_ctx(pw->dim) : NULL;
498 int FN(PW,involves_dims)(__isl_keep PW *pw, enum isl_dim_type type,
499 unsigned first, unsigned n)
501 int i;
503 if (!pw)
504 return -1;
505 if (pw->n == 0 || n == 0)
506 return 0;
507 for (i = 0; i < pw->n; ++i) {
508 int involves = FN(EL,involves_dims)(pw->p[i].FIELD,
509 type, first, n);
510 if (involves < 0 || involves)
511 return involves;
512 involves = isl_set_involves_dims(pw->p[i].set, type, first, n);
513 if (involves < 0 || involves)
514 return involves;
516 return 0;
519 __isl_give PW *FN(PW,set_dim_name)(__isl_take PW *pw,
520 enum isl_dim_type type, unsigned pos, const char *s)
522 int i;
524 pw = FN(PW,cow)(pw);
525 if (!pw)
526 return NULL;
528 pw->dim = isl_dim_set_name(pw->dim, type, pos, s);
529 if (!pw->dim)
530 goto error;
532 for (i = 0; i < pw->n; ++i) {
533 pw->p[i].set = isl_set_set_dim_name(pw->p[i].set, type, pos, s);
534 if (!pw->p[i].set)
535 goto error;
536 pw->p[i].FIELD = FN(EL,set_dim_name)(pw->p[i].FIELD, type, pos, s);
537 if (!pw->p[i].FIELD)
538 goto error;
541 return pw;
542 error:
543 FN(PW,free)(pw);
544 return NULL;
547 __isl_give PW *FN(PW,drop_dims)(__isl_take PW *pw,
548 enum isl_dim_type type, unsigned first, unsigned n)
550 int i;
552 if (!pw)
553 return NULL;
554 if (n == 0 && !isl_dim_get_tuple_name(pw->dim, type))
555 return pw;
557 pw = FN(PW,cow)(pw);
558 if (!pw)
559 return NULL;
560 pw->dim = isl_dim_drop(pw->dim, type, first, n);
561 if (!pw->dim)
562 goto error;
563 for (i = 0; i < pw->n; ++i) {
564 pw->p[i].set = isl_set_drop(pw->p[i].set, type, first, n);
565 if (!pw->p[i].set)
566 goto error;
567 pw->p[i].FIELD = FN(EL,drop_dims)(pw->p[i].FIELD, type, first, n);
568 if (!pw->p[i].FIELD)
569 goto error;
572 return pw;
573 error:
574 FN(PW,free)(pw);
575 return NULL;
578 __isl_give PW *FN(PW,insert_dims)(__isl_take PW *pw, enum isl_dim_type type,
579 unsigned first, unsigned n)
581 int i;
583 if (!pw)
584 return NULL;
585 if (n == 0 && !isl_dim_is_named_or_nested(pw->dim, type))
586 return pw;
588 pw = FN(PW,cow)(pw);
589 if (!pw)
590 return NULL;
592 pw->dim = isl_dim_insert(pw->dim, type, first, n);
593 if (!pw->dim)
594 goto error;
596 for (i = 0; i < pw->n; ++i) {
597 pw->p[i].set = isl_set_insert(pw->p[i].set, type, first, n);
598 if (!pw->p[i].set)
599 goto error;
600 pw->p[i].FIELD = FN(EL,insert_dims)(pw->p[i].FIELD,
601 type, first, n);
602 if (!pw->p[i].FIELD)
603 goto error;
606 return pw;
607 error:
608 FN(PW,free)(pw);
609 return NULL;
612 __isl_give PW *FN(PW,fix_dim)(__isl_take PW *pw,
613 enum isl_dim_type type, unsigned pos, isl_int v)
615 int i;
617 if (!pw)
618 return NULL;
620 pw = FN(PW,cow)(pw);
621 if (!pw)
622 return NULL;
623 for (i = 0; i < pw->n; ++i) {
624 pw->p[i].set = isl_set_fix(pw->p[i].set, type, pos, v);
625 if (!pw->p[i].set)
626 goto error;
629 return pw;
630 error:
631 FN(PW,free)(pw);
632 return NULL;
635 unsigned FN(PW,dim)(__isl_keep PW *pw, enum isl_dim_type type)
637 return pw ? isl_dim_size(pw->dim, type) : 0;
640 __isl_give PW *FN(PW,split_dims)(__isl_take PW *pw,
641 enum isl_dim_type type, unsigned first, unsigned n)
643 int i;
645 if (!pw)
646 return NULL;
647 if (n == 0)
648 return pw;
650 pw = FN(PW,cow)(pw);
651 if (!pw)
652 return NULL;
653 if (!pw->dim)
654 goto error;
655 for (i = 0; i < pw->n; ++i) {
656 pw->p[i].set = isl_set_split_dims(pw->p[i].set, type, first, n);
657 if (!pw->p[i].set)
658 goto error;
661 return pw;
662 error:
663 FN(PW,free)(pw);
664 return NULL;
667 /* Compute the maximal value attained by the piecewise quasipolynomial
668 * on its domain or zero if the domain is empty.
669 * In the worst case, the domain is scanned completely,
670 * so the domain is assumed to be bounded.
672 __isl_give isl_qpolynomial *FN(PW,opt)(__isl_take PW *pw, int max)
674 int i;
675 isl_qpolynomial *opt;
677 if (!pw)
678 return NULL;
680 if (pw->n == 0) {
681 isl_dim *dim = isl_dim_copy(pw->dim);
682 FN(PW,free)(pw);
683 return isl_qpolynomial_zero(dim);
686 opt = FN(EL,opt_on_domain)(FN(EL,copy)(pw->p[0].FIELD),
687 isl_set_copy(pw->p[0].set), max);
688 for (i = 1; i < pw->n; ++i) {
689 isl_qpolynomial *opt_i;
690 opt_i = FN(EL,opt_on_domain)(FN(EL,copy)(pw->p[i].FIELD),
691 isl_set_copy(pw->p[i].set), max);
692 if (max)
693 opt = isl_qpolynomial_max_cst(opt, opt_i);
694 else
695 opt = isl_qpolynomial_min_cst(opt, opt_i);
698 FN(PW,free)(pw);
699 return opt;
702 __isl_give isl_qpolynomial *FN(PW,max)(__isl_take PW *pw)
704 return FN(PW,opt)(pw, 1);
707 __isl_give isl_qpolynomial *FN(PW,min)(__isl_take PW *pw)
709 return FN(PW,opt)(pw, 0);
712 __isl_give isl_dim *FN(PW,get_dim)(__isl_keep PW *pw)
714 return pw ? isl_dim_copy(pw->dim) : NULL;
717 __isl_give PW *FN(PW,reset_dim)(__isl_take PW *pw, __isl_take isl_dim *dim)
719 int i;
721 pw = FN(PW,cow)(pw);
722 if (!pw || !dim)
723 goto error;
725 for (i = 0; i < pw->n; ++i) {
726 pw->p[i].set = isl_set_reset_dim(pw->p[i].set,
727 isl_dim_copy(dim));
728 if (!pw->p[i].set)
729 goto error;
730 pw->p[i].FIELD = FN(EL,reset_dim)(pw->p[i].FIELD,
731 isl_dim_copy(dim));
732 if (!pw->p[i].FIELD)
733 goto error;
735 isl_dim_free(pw->dim);
736 pw->dim = dim;
738 return pw;
739 error:
740 isl_dim_free(dim);
741 FN(PW,free)(pw);
742 return NULL;
745 int FN(PW,has_equal_dim)(__isl_keep PW *pw1, __isl_keep PW *pw2)
747 if (!pw1 || !pw2)
748 return -1;
750 return isl_dim_equal(pw1->dim, pw2->dim);
753 __isl_give PW *FN(PW,morph)(__isl_take PW *pw, __isl_take isl_morph *morph)
755 int i;
756 isl_ctx *ctx;
758 if (!pw || !morph)
759 goto error;
761 ctx = isl_dim_get_ctx(pw->dim);
762 isl_assert(ctx, isl_dim_equal(pw->dim, morph->dom->dim),
763 goto error);
765 pw = FN(PW,cow)(pw);
766 if (!pw)
767 goto error;
768 isl_dim_free(pw->dim);
769 pw->dim = isl_dim_copy(morph->ran->dim);
770 if (!pw->dim)
771 goto error;
773 for (i = 0; i < pw->n; ++i) {
774 pw->p[i].set = isl_morph_set(isl_morph_copy(morph), pw->p[i].set);
775 if (!pw->p[i].set)
776 goto error;
777 pw->p[i].FIELD = FN(EL,morph)(pw->p[i].FIELD,
778 isl_morph_copy(morph));
779 if (!pw->p[i].FIELD)
780 goto error;
783 isl_morph_free(morph);
785 return pw;
786 error:
787 FN(PW,free)(pw);
788 isl_morph_free(morph);
789 return NULL;
792 int FN(PW,foreach_piece)(__isl_keep PW *pw,
793 int (*fn)(__isl_take isl_set *set, __isl_take EL *el, void *user),
794 void *user)
796 int i;
798 if (!pw)
799 return -1;
801 for (i = 0; i < pw->n; ++i)
802 if (fn(isl_set_copy(pw->p[i].set),
803 FN(EL,copy)(pw->p[i].FIELD), user) < 0)
804 return -1;
806 return 0;
809 static int any_divs(__isl_keep isl_set *set)
811 int i;
813 if (!set)
814 return -1;
816 for (i = 0; i < set->n; ++i)
817 if (set->p[i]->n_div > 0)
818 return 1;
820 return 0;
823 static int foreach_lifted_subset(__isl_take isl_set *set, __isl_take EL *el,
824 int (*fn)(__isl_take isl_set *set, __isl_take EL *el,
825 void *user), void *user)
827 int i;
829 if (!set || !el)
830 goto error;
832 for (i = 0; i < set->n; ++i) {
833 isl_set *lift;
834 EL *copy;
836 lift = isl_set_from_basic_set(isl_basic_set_copy(set->p[i]));
837 lift = isl_set_lift(lift);
839 copy = FN(EL,copy)(el);
840 copy = FN(EL,lift)(copy, isl_set_get_dim(lift));
842 if (fn(lift, copy, user) < 0)
843 goto error;
846 isl_set_free(set);
847 FN(EL,free)(el);
849 return 0;
850 error:
851 isl_set_free(set);
852 FN(EL,free)(el);
853 return -1;
856 int FN(PW,foreach_lifted_piece)(__isl_keep PW *pw,
857 int (*fn)(__isl_take isl_set *set, __isl_take EL *el,
858 void *user), void *user)
860 int i;
862 if (!pw)
863 return -1;
865 for (i = 0; i < pw->n; ++i) {
866 isl_set *set;
867 EL *el;
869 set = isl_set_copy(pw->p[i].set);
870 el = FN(EL,copy)(pw->p[i].FIELD);
871 if (!any_divs(set)) {
872 if (fn(set, el, user) < 0)
873 return -1;
874 continue;
876 if (foreach_lifted_subset(set, el, fn, user) < 0)
877 return -1;
880 return 0;
883 __isl_give PW *FN(PW,move_dims)(__isl_take PW *pw,
884 enum isl_dim_type dst_type, unsigned dst_pos,
885 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
887 int i;
889 pw = FN(PW,cow)(pw);
890 if (!pw)
891 return NULL;
893 pw->dim = isl_dim_move(pw->dim, dst_type, dst_pos, src_type, src_pos, n);
894 if (!pw->dim)
895 goto error;
897 for (i = 0; i < pw->n; ++i) {
898 pw->p[i].set = isl_set_move_dims(pw->p[i].set,
899 dst_type, dst_pos,
900 src_type, src_pos, n);
901 if (!pw->p[i].set)
902 goto error;
903 pw->p[i].FIELD = FN(EL,move_dims)(pw->p[i].FIELD,
904 dst_type, dst_pos, src_type, src_pos, n);
905 if (!pw->p[i].FIELD)
906 goto error;
909 return pw;
910 error:
911 FN(PW,free)(pw);
912 return NULL;
915 __isl_give PW *FN(PW,realign)(__isl_take PW *pw, __isl_take isl_reordering *exp)
917 int i;
919 pw = FN(PW,cow)(pw);
920 if (!pw || !exp)
921 return NULL;
923 for (i = 0; i < pw->n; ++i) {
924 pw->p[i].set = isl_set_realign(pw->p[i].set,
925 isl_reordering_copy(exp));
926 if (!pw->p[i].set)
927 goto error;
928 pw->p[i].FIELD = FN(EL,realign)(pw->p[i].FIELD,
929 isl_reordering_copy(exp));
930 if (!pw->p[i].FIELD)
931 goto error;
934 pw = FN(PW,reset_dim)(pw, isl_dim_copy(exp->dim));
936 isl_reordering_free(exp);
937 return pw;
938 error:
939 isl_reordering_free(exp);
940 FN(PW,free)(pw);
941 return NULL;
944 __isl_give PW *FN(PW,mul_isl_int)(__isl_take PW *pw, isl_int v)
946 int i;
948 if (isl_int_is_one(v))
949 return pw;
950 if (pw && isl_int_is_zero(v)) {
951 PW *zero;
952 isl_dim *dim = FN(PW,get_dim)(pw);
953 #ifdef HAS_TYPE
954 zero = FN(PW,zero)(dim, pw->type);
955 #else
956 zero = FN(PW,zero)(dim);
957 #endif
958 FN(PW,free)(pw);
959 return zero;
961 pw = FN(PW,cow)(pw);
962 if (!pw)
963 return NULL;
964 if (pw->n == 0)
965 return pw;
967 #ifdef HAS_TYPE
968 if (isl_int_is_neg(v))
969 pw->type = isl_fold_type_negate(pw->type);
970 #endif
971 for (i = 0; i < pw->n; ++i) {
972 pw->p[i].FIELD = FN(EL,mul_isl_int)(pw->p[i].FIELD, v);
973 if (!pw->p[i].FIELD)
974 goto error;
977 return pw;
978 error:
979 FN(PW,free)(pw);
980 return NULL;