2 #include <isl_val_private.h>
4 #define xFN(TYPE,NAME) TYPE ## _ ## NAME
5 #define FN(TYPE,NAME) xFN(TYPE,NAME)
6 #define xS(TYPE,NAME) struct TYPE ## _ ## NAME
7 #define S(TYPE,NAME) xS(TYPE,NAME)
10 __isl_give PW
*FN(PW
,alloc_size
)(__isl_take isl_space
*dim
,
11 enum isl_fold type
, int n
)
13 __isl_give PW
*FN(PW
,alloc_size
)(__isl_take isl_space
*dim
, int n
)
21 ctx
= isl_space_get_ctx(dim
);
22 isl_assert(ctx
, n
>= 0, goto error
);
23 pw
= isl_alloc(ctx
, struct PW
,
24 sizeof(struct PW
) + (n
- 1) * sizeof(S(PW
,piece
)));
42 __isl_give PW
*FN(PW
,ZERO
)(__isl_take isl_space
*dim
, enum isl_fold type
)
44 return FN(PW
,alloc_size
)(dim
, type
, 0);
47 __isl_give PW
*FN(PW
,ZERO
)(__isl_take isl_space
*dim
)
49 return FN(PW
,alloc_size
)(dim
, 0);
53 __isl_give PW
*FN(PW
,add_piece
)(__isl_take PW
*pw
,
54 __isl_take isl_set
*set
, __isl_take EL
*el
)
57 isl_space
*el_dim
= NULL
;
59 if (!pw
|| !set
|| !el
)
62 if (isl_set_plain_is_empty(set
) || FN(EL
,EL_IS_ZERO
)(el
)) {
68 ctx
= isl_set_get_ctx(set
);
70 if (pw
->type
!= el
->type
)
71 isl_die(ctx
, isl_error_invalid
, "fold types don't match",
74 el_dim
= FN(EL
,get_space(el
));
75 isl_assert(ctx
, isl_space_is_equal(pw
->dim
, el_dim
), goto error
);
76 isl_assert(ctx
, pw
->n
< pw
->size
, goto error
);
78 pw
->p
[pw
->n
].set
= set
;
79 pw
->p
[pw
->n
].FIELD
= el
;
82 isl_space_free(el_dim
);
85 isl_space_free(el_dim
);
93 __isl_give PW
*FN(PW
,alloc
)(enum isl_fold type
,
94 __isl_take isl_set
*set
, __isl_take EL
*el
)
96 __isl_give PW
*FN(PW
,alloc
)(__isl_take isl_set
*set
, __isl_take EL
*el
)
105 pw
= FN(PW
,alloc_size
)(FN(EL
,get_space
)(el
), type
, 1);
107 pw
= FN(PW
,alloc_size
)(FN(EL
,get_space
)(el
), 1);
110 return FN(PW
,add_piece
)(pw
, set
, el
);
117 __isl_give PW
*FN(PW
,dup
)(__isl_keep PW
*pw
)
126 dup
= FN(PW
,alloc_size
)(isl_space_copy(pw
->dim
), pw
->type
, pw
->n
);
128 dup
= FN(PW
,alloc_size
)(isl_space_copy(pw
->dim
), pw
->n
);
133 for (i
= 0; i
< pw
->n
; ++i
)
134 dup
= FN(PW
,add_piece
)(dup
, isl_set_copy(pw
->p
[i
].set
),
135 FN(EL
,copy
)(pw
->p
[i
].FIELD
));
140 __isl_give PW
*FN(PW
,cow
)(__isl_take PW
*pw
)
148 return FN(PW
,dup
)(pw
);
151 __isl_give PW
*FN(PW
,copy
)(__isl_keep PW
*pw
)
160 void *FN(PW
,free
)(__isl_take PW
*pw
)
169 for (i
= 0; i
< pw
->n
; ++i
) {
170 isl_set_free(pw
->p
[i
].set
);
171 FN(EL
,free
)(pw
->p
[i
].FIELD
);
173 isl_space_free(pw
->dim
);
179 const char *FN(PW
,get_dim_name
)(__isl_keep PW
*pw
, enum isl_dim_type type
,
182 return pw
? isl_space_get_dim_name(pw
->dim
, type
, pos
) : NULL
;
185 int FN(PW
,has_dim_id
)(__isl_keep PW
*pw
, enum isl_dim_type type
, unsigned pos
)
187 return pw
? isl_space_has_dim_id(pw
->dim
, type
, pos
) : -1;
190 __isl_give isl_id
*FN(PW
,get_dim_id
)(__isl_keep PW
*pw
, enum isl_dim_type type
,
193 return pw
? isl_space_get_dim_id(pw
->dim
, type
, pos
) : NULL
;
196 int FN(PW
,has_tuple_name
)(__isl_keep PW
*pw
, enum isl_dim_type type
)
198 return pw
? isl_space_has_tuple_name(pw
->dim
, type
) : -1;
201 const char *FN(PW
,get_tuple_name
)(__isl_keep PW
*pw
, enum isl_dim_type type
)
203 return pw
? isl_space_get_tuple_name(pw
->dim
, type
) : NULL
;
206 int FN(PW
,has_tuple_id
)(__isl_keep PW
*pw
, enum isl_dim_type type
)
208 return pw
? isl_space_has_tuple_id(pw
->dim
, type
) : -1;
211 __isl_give isl_id
*FN(PW
,get_tuple_id
)(__isl_keep PW
*pw
, enum isl_dim_type type
)
213 return pw
? isl_space_get_tuple_id(pw
->dim
, type
) : NULL
;
216 int FN(PW
,IS_ZERO
)(__isl_keep PW
*pw
)
225 __isl_give PW
*FN(PW
,realign_domain
)(__isl_take PW
*pw
,
226 __isl_take isl_reordering
*exp
)
234 for (i
= 0; i
< pw
->n
; ++i
) {
235 pw
->p
[i
].set
= isl_set_realign(pw
->p
[i
].set
,
236 isl_reordering_copy(exp
));
239 pw
->p
[i
].FIELD
= FN(EL
,realign_domain
)(pw
->p
[i
].FIELD
,
240 isl_reordering_copy(exp
));
245 pw
= FN(PW
,reset_domain_space
)(pw
, isl_space_copy(exp
->dim
));
247 isl_reordering_free(exp
);
250 isl_reordering_free(exp
);
255 /* Align the parameters of "pw" to those of "model".
257 __isl_give PW
*FN(PW
,align_params
)(__isl_take PW
*pw
, __isl_take isl_space
*model
)
264 ctx
= isl_space_get_ctx(model
);
265 if (!isl_space_has_named_params(model
))
266 isl_die(ctx
, isl_error_invalid
,
267 "model has unnamed parameters", goto error
);
268 if (!isl_space_has_named_params(pw
->dim
))
269 isl_die(ctx
, isl_error_invalid
,
270 "input has unnamed parameters", goto error
);
271 if (!isl_space_match(pw
->dim
, isl_dim_param
, model
, isl_dim_param
)) {
274 model
= isl_space_drop_dims(model
, isl_dim_in
,
275 0, isl_space_dim(model
, isl_dim_in
));
276 model
= isl_space_drop_dims(model
, isl_dim_out
,
277 0, isl_space_dim(model
, isl_dim_out
));
278 exp
= isl_parameter_alignment_reordering(pw
->dim
, model
);
279 exp
= isl_reordering_extend_space(exp
,
280 FN(PW
,get_domain_space
)(pw
));
281 pw
= FN(PW
,realign_domain
)(pw
, exp
);
284 isl_space_free(model
);
287 isl_space_free(model
);
292 static __isl_give PW
*FN(PW
,align_params_pw_pw_and
)(__isl_take PW
*pw1
,
294 __isl_give PW
*(*fn
)(__isl_take PW
*pw1
, __isl_take PW
*pw2
))
300 if (isl_space_match(pw1
->dim
, isl_dim_param
, pw2
->dim
, isl_dim_param
))
302 ctx
= FN(PW
,get_ctx
)(pw1
);
303 if (!isl_space_has_named_params(pw1
->dim
) ||
304 !isl_space_has_named_params(pw2
->dim
))
305 isl_die(ctx
, isl_error_invalid
,
306 "unaligned unnamed parameters", goto error
);
307 pw1
= FN(PW
,align_params
)(pw1
, FN(PW
,get_space
)(pw2
));
308 pw2
= FN(PW
,align_params
)(pw2
, FN(PW
,get_space
)(pw1
));
316 static __isl_give PW
*FN(PW
,align_params_pw_set_and
)(__isl_take PW
*pw
,
317 __isl_take isl_set
*set
,
318 __isl_give PW
*(*fn
)(__isl_take PW
*pw
, __isl_take isl_set
*set
))
324 if (isl_space_match(pw
->dim
, isl_dim_param
, set
->dim
, isl_dim_param
))
326 ctx
= FN(PW
,get_ctx
)(pw
);
327 if (!isl_space_has_named_params(pw
->dim
) ||
328 !isl_space_has_named_params(set
->dim
))
329 isl_die(ctx
, isl_error_invalid
,
330 "unaligned unnamed parameters", goto error
);
331 pw
= FN(PW
,align_params
)(pw
, isl_set_get_space(set
));
332 set
= isl_set_align_params(set
, FN(PW
,get_space
)(pw
));
341 static __isl_give PW
*FN(PW
,union_add_aligned
)(__isl_take PW
*pw1
,
352 ctx
= isl_space_get_ctx(pw1
->dim
);
354 if (pw1
->type
!= pw2
->type
)
355 isl_die(ctx
, isl_error_invalid
,
356 "fold types don't match", goto error
);
358 isl_assert(ctx
, isl_space_is_equal(pw1
->dim
, pw2
->dim
), goto error
);
360 if (FN(PW
,IS_ZERO
)(pw1
)) {
365 if (FN(PW
,IS_ZERO
)(pw2
)) {
370 n
= (pw1
->n
+ 1) * (pw2
->n
+ 1);
372 res
= FN(PW
,alloc_size
)(isl_space_copy(pw1
->dim
), pw1
->type
, n
);
374 res
= FN(PW
,alloc_size
)(isl_space_copy(pw1
->dim
), n
);
377 for (i
= 0; i
< pw1
->n
; ++i
) {
378 set
= isl_set_copy(pw1
->p
[i
].set
);
379 for (j
= 0; j
< pw2
->n
; ++j
) {
380 struct isl_set
*common
;
382 common
= isl_set_intersect(isl_set_copy(pw1
->p
[i
].set
),
383 isl_set_copy(pw2
->p
[j
].set
));
384 if (isl_set_plain_is_empty(common
)) {
385 isl_set_free(common
);
388 set
= isl_set_subtract(set
,
389 isl_set_copy(pw2
->p
[j
].set
));
391 sum
= FN(EL
,add_on_domain
)(common
,
392 FN(EL
,copy
)(pw1
->p
[i
].FIELD
),
393 FN(EL
,copy
)(pw2
->p
[j
].FIELD
));
395 res
= FN(PW
,add_piece
)(res
, common
, sum
);
397 res
= FN(PW
,add_piece
)(res
, set
, FN(EL
,copy
)(pw1
->p
[i
].FIELD
));
400 for (j
= 0; j
< pw2
->n
; ++j
) {
401 set
= isl_set_copy(pw2
->p
[j
].set
);
402 for (i
= 0; i
< pw1
->n
; ++i
)
403 set
= isl_set_subtract(set
,
404 isl_set_copy(pw1
->p
[i
].set
));
405 res
= FN(PW
,add_piece
)(res
, set
, FN(EL
,copy
)(pw2
->p
[j
].FIELD
));
418 /* Private version of "union_add". For isl_pw_qpolynomial and
419 * isl_pw_qpolynomial_fold, we prefer to simply call it "add".
421 static __isl_give PW
*FN(PW
,union_add_
)(__isl_take PW
*pw1
, __isl_take PW
*pw2
)
423 return FN(PW
,align_params_pw_pw_and
)(pw1
, pw2
,
424 &FN(PW
,union_add_aligned
));
427 /* Make sure "pw" has room for at least "n" more pieces.
429 * If there is only one reference to pw, we extend it in place.
430 * Otherwise, we create a new PW and copy the pieces.
432 static __isl_give PW
*FN(PW
,grow
)(__isl_take PW
*pw
, int n
)
440 if (pw
->n
+ n
<= pw
->size
)
442 ctx
= FN(PW
,get_ctx
)(pw
);
445 res
= isl_realloc(ctx
, pw
, struct PW
,
446 sizeof(struct PW
) + (n
- 1) * sizeof(S(PW
,piece
)));
448 return FN(PW
,free
)(pw
);
453 res
= FN(PW
,alloc_size
)(isl_space_copy(pw
->dim
), pw
->type
, n
);
455 res
= FN(PW
,alloc_size
)(isl_space_copy(pw
->dim
), n
);
458 return FN(PW
,free
)(pw
);
459 for (i
= 0; i
< pw
->n
; ++i
)
460 res
= FN(PW
,add_piece
)(res
, isl_set_copy(pw
->p
[i
].set
),
461 FN(EL
,copy
)(pw
->p
[i
].FIELD
));
466 static __isl_give PW
*FN(PW
,add_disjoint_aligned
)(__isl_take PW
*pw1
,
475 if (pw1
->size
< pw1
->n
+ pw2
->n
&& pw1
->n
< pw2
->n
)
476 return FN(PW
,add_disjoint_aligned
)(pw2
, pw1
);
478 ctx
= isl_space_get_ctx(pw1
->dim
);
480 if (pw1
->type
!= pw2
->type
)
481 isl_die(ctx
, isl_error_invalid
,
482 "fold types don't match", goto error
);
484 isl_assert(ctx
, isl_space_is_equal(pw1
->dim
, pw2
->dim
), goto error
);
486 if (FN(PW
,IS_ZERO
)(pw1
)) {
491 if (FN(PW
,IS_ZERO
)(pw2
)) {
496 pw1
= FN(PW
,grow
)(pw1
, pw2
->n
);
500 for (i
= 0; i
< pw2
->n
; ++i
)
501 pw1
= FN(PW
,add_piece
)(pw1
,
502 isl_set_copy(pw2
->p
[i
].set
),
503 FN(EL
,copy
)(pw2
->p
[i
].FIELD
));
514 __isl_give PW
*FN(PW
,add_disjoint
)(__isl_take PW
*pw1
, __isl_take PW
*pw2
)
516 return FN(PW
,align_params_pw_pw_and
)(pw1
, pw2
,
517 &FN(PW
,add_disjoint_aligned
));
520 /* This function is currently only used from isl_aff.c
522 static __isl_give PW
*FN(PW
,on_shared_domain_in
)(__isl_take PW
*pw1
,
523 __isl_take PW
*pw2
, __isl_take isl_space
*space
,
524 __isl_give EL
*(*fn
)(__isl_take EL
*el1
, __isl_take EL
*el2
))
525 __attribute__ ((unused
));
527 /* Apply "fn" to pairs of elements from pw1 and pw2 on shared domains.
528 * The result of "fn" (and therefore also of this function) lives in "space".
530 static __isl_give PW
*FN(PW
,on_shared_domain_in
)(__isl_take PW
*pw1
,
531 __isl_take PW
*pw2
, __isl_take isl_space
*space
,
532 __isl_give EL
*(*fn
)(__isl_take EL
*el1
, __isl_take EL
*el2
))
542 res
= FN(PW
,alloc_size
)(isl_space_copy(space
), pw1
->type
, n
);
544 res
= FN(PW
,alloc_size
)(isl_space_copy(space
), n
);
547 for (i
= 0; i
< pw1
->n
; ++i
) {
548 for (j
= 0; j
< pw2
->n
; ++j
) {
553 common
= isl_set_intersect(
554 isl_set_copy(pw1
->p
[i
].set
),
555 isl_set_copy(pw2
->p
[j
].set
));
556 empty
= isl_set_plain_is_empty(common
);
557 if (empty
< 0 || empty
) {
558 isl_set_free(common
);
564 res_ij
= fn(FN(EL
,copy
)(pw1
->p
[i
].FIELD
),
565 FN(EL
,copy
)(pw2
->p
[j
].FIELD
));
566 res_ij
= FN(EL
,gist
)(res_ij
, isl_set_copy(common
));
568 res
= FN(PW
,add_piece
)(res
, common
, res_ij
);
572 isl_space_free(space
);
577 isl_space_free(space
);
584 /* This function is currently only used from isl_aff.c
586 static __isl_give PW
*FN(PW
,on_shared_domain
)(__isl_take PW
*pw1
,
588 __isl_give EL
*(*fn
)(__isl_take EL
*el1
, __isl_take EL
*el2
))
589 __attribute__ ((unused
));
591 /* Apply "fn" to pairs of elements from pw1 and pw2 on shared domains.
592 * The result of "fn" is assumed to live in the same space as "pw1" and "pw2".
594 static __isl_give PW
*FN(PW
,on_shared_domain
)(__isl_take PW
*pw1
,
596 __isl_give EL
*(*fn
)(__isl_take EL
*el1
, __isl_take EL
*el2
))
603 space
= isl_space_copy(pw1
->dim
);
604 return FN(PW
,on_shared_domain_in
)(pw1
, pw2
, space
, fn
);
612 __isl_give PW
*FN(PW
,neg
)(__isl_take PW
*pw
)
619 if (FN(PW
,IS_ZERO
)(pw
))
626 for (i
= 0; i
< pw
->n
; ++i
) {
627 pw
->p
[i
].FIELD
= FN(EL
,neg
)(pw
->p
[i
].FIELD
);
629 return FN(PW
,free
)(pw
);
635 __isl_give PW
*FN(PW
,sub
)(__isl_take PW
*pw1
, __isl_take PW
*pw2
)
637 return FN(PW
,add
)(pw1
, FN(PW
,neg
)(pw2
));
642 __isl_give isl_qpolynomial
*FN(PW
,eval
)(__isl_take PW
*pw
,
643 __isl_take isl_point
*pnt
)
648 isl_space
*pnt_dim
= NULL
;
653 ctx
= isl_point_get_ctx(pnt
);
654 pnt_dim
= isl_point_get_space(pnt
);
655 isl_assert(ctx
, isl_space_is_domain_internal(pnt_dim
, pw
->dim
),
658 for (i
= 0; i
< pw
->n
; ++i
) {
659 found
= isl_set_contains_point(pw
->p
[i
].set
, pnt
);
666 qp
= FN(EL
,eval
)(FN(EL
,copy
)(pw
->p
[i
].FIELD
),
667 isl_point_copy(pnt
));
669 qp
= isl_qpolynomial_zero_on_domain(FN(PW
,get_domain_space
)(pw
));
671 isl_space_free(pnt_dim
);
676 isl_space_free(pnt_dim
);
682 __isl_give isl_set
*FN(PW
,domain
)(__isl_take PW
*pw
)
690 dom
= isl_set_empty(FN(PW
,get_domain_space
)(pw
));
691 for (i
= 0; i
< pw
->n
; ++i
)
692 dom
= isl_set_union_disjoint(dom
, isl_set_copy(pw
->p
[i
].set
));
699 /* Exploit the equalities in the domain of piece "i" of "pw"
700 * to simplify the associated function.
701 * If the domain of piece "i" is empty, then remove it entirely,
702 * replacing it with the final piece.
704 static int FN(PW
,exploit_equalities_and_remove_if_empty
)(__isl_keep PW
*pw
,
708 int empty
= isl_set_plain_is_empty(pw
->p
[i
].set
);
713 isl_set_free(pw
->p
[i
].set
);
714 FN(EL
,free
)(pw
->p
[i
].FIELD
);
716 pw
->p
[i
] = pw
->p
[pw
->n
- 1];
722 aff
= isl_set_affine_hull(isl_set_copy(pw
->p
[i
].set
));
723 pw
->p
[i
].FIELD
= FN(EL
,substitute_equalities
)(pw
->p
[i
].FIELD
, aff
);
730 /* Restrict the domain of "pw" by combining each cell
731 * with "set" through a call to "fn", where "fn" may be
732 * isl_set_intersect or isl_set_intersect_params.
734 static __isl_give PW
*FN(PW
,intersect_aligned
)(__isl_take PW
*pw
,
735 __isl_take isl_set
*set
,
736 __isl_give isl_set
*(*fn
)(__isl_take isl_set
*set1
,
737 __isl_take isl_set
*set2
))
753 for (i
= pw
->n
- 1; i
>= 0; --i
) {
754 pw
->p
[i
].set
= fn(pw
->p
[i
].set
, isl_set_copy(set
));
755 if (FN(PW
,exploit_equalities_and_remove_if_empty
)(pw
, i
) < 0)
767 static __isl_give PW
*FN(PW
,intersect_domain_aligned
)(__isl_take PW
*pw
,
768 __isl_take isl_set
*set
)
770 return FN(PW
,intersect_aligned
)(pw
, set
, &isl_set_intersect
);
773 __isl_give PW
*FN(PW
,intersect_domain
)(__isl_take PW
*pw
,
774 __isl_take isl_set
*context
)
776 return FN(PW
,align_params_pw_set_and
)(pw
, context
,
777 &FN(PW
,intersect_domain_aligned
));
780 static __isl_give PW
*FN(PW
,intersect_params_aligned
)(__isl_take PW
*pw
,
781 __isl_take isl_set
*set
)
783 return FN(PW
,intersect_aligned
)(pw
, set
, &isl_set_intersect_params
);
786 /* Intersect the domain of "pw" with the parameter domain "context".
788 __isl_give PW
*FN(PW
,intersect_params
)(__isl_take PW
*pw
,
789 __isl_take isl_set
*context
)
791 return FN(PW
,align_params_pw_set_and
)(pw
, context
,
792 &FN(PW
,intersect_params_aligned
));
795 static __isl_give PW
*FN(PW
,gist_aligned
)(__isl_take PW
*pw
,
796 __isl_take isl_set
*context
,
797 __isl_give EL
*(*fn_el
)(__isl_take EL
*el
,
798 __isl_take isl_set
*set
),
799 __isl_give isl_set
*(*fn_dom
)(__isl_take isl_set
*set
,
800 __isl_take isl_basic_set
*bset
))
803 isl_basic_set
*hull
= NULL
;
809 isl_set_free(context
);
813 if (!isl_space_match(pw
->dim
, isl_dim_param
,
814 context
->dim
, isl_dim_param
)) {
815 pw
= FN(PW
,align_params
)(pw
, isl_set_get_space(context
));
816 context
= isl_set_align_params(context
, FN(PW
,get_space
)(pw
));
819 context
= isl_set_compute_divs(context
);
820 hull
= isl_set_simple_hull(isl_set_copy(context
));
826 for (i
= pw
->n
- 1; i
>= 0; --i
) {
830 set_i
= isl_set_intersect(isl_set_copy(pw
->p
[i
].set
),
831 isl_set_copy(context
));
832 empty
= isl_set_plain_is_empty(set_i
);
833 pw
->p
[i
].FIELD
= fn_el(pw
->p
[i
].FIELD
, set_i
);
834 pw
->p
[i
].set
= fn_dom(pw
->p
[i
].set
, isl_basic_set_copy(hull
));
835 if (!pw
->p
[i
].FIELD
|| !pw
->p
[i
].set
)
838 isl_set_free(pw
->p
[i
].set
);
839 FN(EL
,free
)(pw
->p
[i
].FIELD
);
841 pw
->p
[i
] = pw
->p
[pw
->n
- 1];
846 isl_basic_set_free(hull
);
847 isl_set_free(context
);
852 isl_basic_set_free(hull
);
853 isl_set_free(context
);
857 static __isl_give PW
*FN(PW
,gist_domain_aligned
)(__isl_take PW
*pw
,
858 __isl_take isl_set
*set
)
860 return FN(PW
,gist_aligned
)(pw
, set
, &FN(EL
,gist
),
861 &isl_set_gist_basic_set
);
864 __isl_give PW
*FN(PW
,gist
)(__isl_take PW
*pw
, __isl_take isl_set
*context
)
866 return FN(PW
,align_params_pw_set_and
)(pw
, context
,
867 &FN(PW
,gist_domain_aligned
));
870 static __isl_give PW
*FN(PW
,gist_params_aligned
)(__isl_take PW
*pw
,
871 __isl_take isl_set
*set
)
873 return FN(PW
,gist_aligned
)(pw
, set
, &FN(EL
,gist_params
),
874 &isl_set_gist_params_basic_set
);
877 __isl_give PW
*FN(PW
,gist_params
)(__isl_take PW
*pw
,
878 __isl_take isl_set
*context
)
880 return FN(PW
,align_params_pw_set_and
)(pw
, context
,
881 &FN(PW
,gist_params_aligned
));
884 __isl_give PW
*FN(PW
,coalesce
)(__isl_take PW
*pw
)
893 for (i
= pw
->n
- 1; i
>= 0; --i
) {
894 for (j
= i
- 1; j
>= 0; --j
) {
895 if (!FN(EL
,plain_is_equal
)(pw
->p
[i
].FIELD
,
898 pw
->p
[j
].set
= isl_set_union(pw
->p
[j
].set
,
900 FN(EL
,free
)(pw
->p
[i
].FIELD
);
902 pw
->p
[i
] = pw
->p
[pw
->n
- 1];
908 pw
->p
[i
].set
= isl_set_coalesce(pw
->p
[i
].set
);
919 isl_ctx
*FN(PW
,get_ctx
)(__isl_keep PW
*pw
)
921 return pw
? isl_space_get_ctx(pw
->dim
) : NULL
;
924 #ifndef NO_INVOLVES_DIMS
925 int FN(PW
,involves_dims
)(__isl_keep PW
*pw
, enum isl_dim_type type
,
926 unsigned first
, unsigned n
)
929 enum isl_dim_type set_type
;
933 if (pw
->n
== 0 || n
== 0)
936 set_type
= type
== isl_dim_in
? isl_dim_set
: type
;
938 for (i
= 0; i
< pw
->n
; ++i
) {
939 int involves
= FN(EL
,involves_dims
)(pw
->p
[i
].FIELD
,
941 if (involves
< 0 || involves
)
943 involves
= isl_set_involves_dims(pw
->p
[i
].set
,
945 if (involves
< 0 || involves
)
952 __isl_give PW
*FN(PW
,set_dim_name
)(__isl_take PW
*pw
,
953 enum isl_dim_type type
, unsigned pos
, const char *s
)
956 enum isl_dim_type set_type
;
962 set_type
= type
== isl_dim_in
? isl_dim_set
: type
;
964 pw
->dim
= isl_space_set_dim_name(pw
->dim
, type
, pos
, s
);
968 for (i
= 0; i
< pw
->n
; ++i
) {
969 pw
->p
[i
].set
= isl_set_set_dim_name(pw
->p
[i
].set
,
973 pw
->p
[i
].FIELD
= FN(EL
,set_dim_name
)(pw
->p
[i
].FIELD
, type
, pos
, s
);
985 __isl_give PW
*FN(PW
,drop_dims
)(__isl_take PW
*pw
,
986 enum isl_dim_type type
, unsigned first
, unsigned n
)
989 enum isl_dim_type set_type
;
993 if (n
== 0 && !isl_space_get_tuple_name(pw
->dim
, type
))
996 set_type
= type
== isl_dim_in
? isl_dim_set
: type
;
1001 pw
->dim
= isl_space_drop_dims(pw
->dim
, type
, first
, n
);
1004 for (i
= 0; i
< pw
->n
; ++i
) {
1005 pw
->p
[i
].FIELD
= FN(EL
,drop_dims
)(pw
->p
[i
].FIELD
, type
, first
, n
);
1006 if (!pw
->p
[i
].FIELD
)
1008 if (type
== isl_dim_out
)
1010 pw
->p
[i
].set
= isl_set_drop(pw
->p
[i
].set
, set_type
, first
, n
);
1021 /* This function is very similar to drop_dims.
1022 * The only difference is that the cells may still involve
1023 * the specified dimensions. They are removed using
1024 * isl_set_project_out instead of isl_set_drop.
1026 __isl_give PW
*FN(PW
,project_out
)(__isl_take PW
*pw
,
1027 enum isl_dim_type type
, unsigned first
, unsigned n
)
1030 enum isl_dim_type set_type
;
1034 if (n
== 0 && !isl_space_get_tuple_name(pw
->dim
, type
))
1037 set_type
= type
== isl_dim_in
? isl_dim_set
: type
;
1039 pw
= FN(PW
,cow
)(pw
);
1042 pw
->dim
= isl_space_drop_dims(pw
->dim
, type
, first
, n
);
1045 for (i
= 0; i
< pw
->n
; ++i
) {
1046 pw
->p
[i
].set
= isl_set_project_out(pw
->p
[i
].set
,
1047 set_type
, first
, n
);
1050 pw
->p
[i
].FIELD
= FN(EL
,drop_dims
)(pw
->p
[i
].FIELD
, type
, first
, n
);
1051 if (!pw
->p
[i
].FIELD
)
1061 /* Project the domain of pw onto its parameter space.
1063 __isl_give PW
*FN(PW
,project_domain_on_params
)(__isl_take PW
*pw
)
1068 n
= FN(PW
,dim
)(pw
, isl_dim_in
);
1069 pw
= FN(PW
,project_out
)(pw
, isl_dim_in
, 0, n
);
1070 space
= FN(PW
,get_domain_space
)(pw
);
1071 space
= isl_space_params(space
);
1072 pw
= FN(PW
,reset_domain_space
)(pw
, space
);
1077 #ifndef NO_INSERT_DIMS
1078 __isl_give PW
*FN(PW
,insert_dims
)(__isl_take PW
*pw
, enum isl_dim_type type
,
1079 unsigned first
, unsigned n
)
1082 enum isl_dim_type set_type
;
1086 if (n
== 0 && !isl_space_is_named_or_nested(pw
->dim
, type
))
1089 set_type
= type
== isl_dim_in
? isl_dim_set
: type
;
1091 pw
= FN(PW
,cow
)(pw
);
1095 pw
->dim
= isl_space_insert_dims(pw
->dim
, type
, first
, n
);
1099 for (i
= 0; i
< pw
->n
; ++i
) {
1100 pw
->p
[i
].set
= isl_set_insert_dims(pw
->p
[i
].set
,
1101 set_type
, first
, n
);
1104 pw
->p
[i
].FIELD
= FN(EL
,insert_dims
)(pw
->p
[i
].FIELD
,
1106 if (!pw
->p
[i
].FIELD
)
1117 __isl_give PW
*FN(PW
,fix_dim
)(__isl_take PW
*pw
,
1118 enum isl_dim_type type
, unsigned pos
, isl_int v
)
1125 if (type
== isl_dim_in
)
1128 pw
= FN(PW
,cow
)(pw
);
1131 for (i
= 0; i
< pw
->n
; ++i
) {
1132 pw
->p
[i
].set
= isl_set_fix(pw
->p
[i
].set
, type
, pos
, v
);
1133 if (FN(PW
,exploit_equalities_and_remove_if_empty
)(pw
, i
) < 0)
1134 return FN(PW
,free
)(pw
);
1140 /* Fix the value of the variable at position "pos" of type "type" of "pw"
1141 * to be equal to "v".
1143 __isl_give PW
*FN(PW
,fix_val
)(__isl_take PW
*pw
,
1144 enum isl_dim_type type
, unsigned pos
, __isl_take isl_val
*v
)
1147 return FN(PW
,free
)(pw
);
1148 if (!isl_val_is_int(v
))
1149 isl_die(FN(PW
,get_ctx
)(pw
), isl_error_invalid
,
1150 "expecting integer value", goto error
);
1152 pw
= FN(PW
,fix_dim
)(pw
, type
, pos
, v
->n
);
1158 return FN(PW
,free
)(pw
);
1161 unsigned FN(PW
,dim
)(__isl_keep PW
*pw
, enum isl_dim_type type
)
1163 return pw
? isl_space_dim(pw
->dim
, type
) : 0;
1166 __isl_give PW
*FN(PW
,split_dims
)(__isl_take PW
*pw
,
1167 enum isl_dim_type type
, unsigned first
, unsigned n
)
1176 if (type
== isl_dim_in
)
1179 pw
= FN(PW
,cow
)(pw
);
1184 for (i
= 0; i
< pw
->n
; ++i
) {
1185 pw
->p
[i
].set
= isl_set_split_dims(pw
->p
[i
].set
, type
, first
, n
);
1197 /* Compute the maximal value attained by the piecewise quasipolynomial
1198 * on its domain or zero if the domain is empty.
1199 * In the worst case, the domain is scanned completely,
1200 * so the domain is assumed to be bounded.
1202 __isl_give isl_qpolynomial
*FN(PW
,opt
)(__isl_take PW
*pw
, int max
)
1205 isl_qpolynomial
*opt
;
1211 isl_space
*dim
= isl_space_copy(pw
->dim
);
1213 return isl_qpolynomial_zero_on_domain(isl_space_domain(dim
));
1216 opt
= FN(EL
,opt_on_domain
)(FN(EL
,copy
)(pw
->p
[0].FIELD
),
1217 isl_set_copy(pw
->p
[0].set
), max
);
1218 for (i
= 1; i
< pw
->n
; ++i
) {
1219 isl_qpolynomial
*opt_i
;
1220 opt_i
= FN(EL
,opt_on_domain
)(FN(EL
,copy
)(pw
->p
[i
].FIELD
),
1221 isl_set_copy(pw
->p
[i
].set
), max
);
1223 opt
= isl_qpolynomial_max_cst(opt
, opt_i
);
1225 opt
= isl_qpolynomial_min_cst(opt
, opt_i
);
1232 __isl_give isl_qpolynomial
*FN(PW
,max
)(__isl_take PW
*pw
)
1234 return FN(PW
,opt
)(pw
, 1);
1237 __isl_give isl_qpolynomial
*FN(PW
,min
)(__isl_take PW
*pw
)
1239 return FN(PW
,opt
)(pw
, 0);
1243 __isl_give isl_space
*FN(PW
,get_space
)(__isl_keep PW
*pw
)
1245 return pw
? isl_space_copy(pw
->dim
) : NULL
;
1248 __isl_give isl_space
*FN(PW
,get_domain_space
)(__isl_keep PW
*pw
)
1250 return pw
? isl_space_domain(isl_space_copy(pw
->dim
)) : NULL
;
1253 #ifndef NO_RESET_DIM
1254 /* Reset the space of "pw". Since we don't know if the elements
1255 * represent the spaces themselves or their domains, we pass along
1256 * both when we call their reset_space_and_domain.
1258 static __isl_give PW
*FN(PW
,reset_space_and_domain
)(__isl_take PW
*pw
,
1259 __isl_take isl_space
*space
, __isl_take isl_space
*domain
)
1263 pw
= FN(PW
,cow
)(pw
);
1264 if (!pw
|| !space
|| !domain
)
1267 for (i
= 0; i
< pw
->n
; ++i
) {
1268 pw
->p
[i
].set
= isl_set_reset_space(pw
->p
[i
].set
,
1269 isl_space_copy(domain
));
1272 pw
->p
[i
].FIELD
= FN(EL
,reset_space_and_domain
)(pw
->p
[i
].FIELD
,
1273 isl_space_copy(space
), isl_space_copy(domain
));
1274 if (!pw
->p
[i
].FIELD
)
1278 isl_space_free(domain
);
1280 isl_space_free(pw
->dim
);
1285 isl_space_free(domain
);
1286 isl_space_free(space
);
1291 __isl_give PW
*FN(PW
,reset_domain_space
)(__isl_take PW
*pw
,
1292 __isl_take isl_space
*domain
)
1296 space
= isl_space_extend_domain_with_range(isl_space_copy(domain
),
1297 FN(PW
,get_space
)(pw
));
1298 return FN(PW
,reset_space_and_domain
)(pw
, space
, domain
);
1301 __isl_give PW
*FN(PW
,reset_space
)(__isl_take PW
*pw
, __isl_take isl_space
*dim
)
1305 domain
= isl_space_domain(isl_space_copy(dim
));
1306 return FN(PW
,reset_space_and_domain
)(pw
, dim
, domain
);
1309 __isl_give PW
*FN(PW
,set_tuple_id
)(__isl_keep PW
*pw
, enum isl_dim_type type
,
1310 __isl_take isl_id
*id
)
1314 pw
= FN(PW
,cow
)(pw
);
1316 return isl_id_free(id
);
1318 space
= FN(PW
,get_space
)(pw
);
1319 space
= isl_space_set_tuple_id(space
, type
, id
);
1321 return FN(PW
,reset_space
)(pw
, space
);
1324 __isl_give PW
*FN(PW
,set_dim_id
)(__isl_take PW
*pw
,
1325 enum isl_dim_type type
, unsigned pos
, __isl_take isl_id
*id
)
1327 pw
= FN(PW
,cow
)(pw
);
1329 return isl_id_free(id
);
1330 pw
->dim
= isl_space_set_dim_id(pw
->dim
, type
, pos
, id
);
1331 return FN(PW
,reset_space
)(pw
, isl_space_copy(pw
->dim
));
1335 int FN(PW
,has_equal_space
)(__isl_keep PW
*pw1
, __isl_keep PW
*pw2
)
1340 return isl_space_is_equal(pw1
->dim
, pw2
->dim
);
1344 __isl_give PW
*FN(PW
,morph_domain
)(__isl_take PW
*pw
,
1345 __isl_take isl_morph
*morph
)
1353 ctx
= isl_space_get_ctx(pw
->dim
);
1354 isl_assert(ctx
, isl_space_is_domain_internal(morph
->dom
->dim
, pw
->dim
),
1357 pw
= FN(PW
,cow
)(pw
);
1360 pw
->dim
= isl_space_extend_domain_with_range(
1361 isl_space_copy(morph
->ran
->dim
), pw
->dim
);
1365 for (i
= 0; i
< pw
->n
; ++i
) {
1366 pw
->p
[i
].set
= isl_morph_set(isl_morph_copy(morph
), pw
->p
[i
].set
);
1369 pw
->p
[i
].FIELD
= FN(EL
,morph_domain
)(pw
->p
[i
].FIELD
,
1370 isl_morph_copy(morph
));
1371 if (!pw
->p
[i
].FIELD
)
1375 isl_morph_free(morph
);
1380 isl_morph_free(morph
);
1385 int FN(PW
,n_piece
)(__isl_keep PW
*pw
)
1387 return pw
? pw
->n
: 0;
1390 int FN(PW
,foreach_piece
)(__isl_keep PW
*pw
,
1391 int (*fn
)(__isl_take isl_set
*set
, __isl_take EL
*el
, void *user
),
1399 for (i
= 0; i
< pw
->n
; ++i
)
1400 if (fn(isl_set_copy(pw
->p
[i
].set
),
1401 FN(EL
,copy
)(pw
->p
[i
].FIELD
), user
) < 0)
1408 static int any_divs(__isl_keep isl_set
*set
)
1415 for (i
= 0; i
< set
->n
; ++i
)
1416 if (set
->p
[i
]->n_div
> 0)
1422 static int foreach_lifted_subset(__isl_take isl_set
*set
, __isl_take EL
*el
,
1423 int (*fn
)(__isl_take isl_set
*set
, __isl_take EL
*el
,
1424 void *user
), void *user
)
1431 for (i
= 0; i
< set
->n
; ++i
) {
1435 lift
= isl_set_from_basic_set(isl_basic_set_copy(set
->p
[i
]));
1436 lift
= isl_set_lift(lift
);
1438 copy
= FN(EL
,copy
)(el
);
1439 copy
= FN(EL
,lift
)(copy
, isl_set_get_space(lift
));
1441 if (fn(lift
, copy
, user
) < 0)
1455 int FN(PW
,foreach_lifted_piece
)(__isl_keep PW
*pw
,
1456 int (*fn
)(__isl_take isl_set
*set
, __isl_take EL
*el
,
1457 void *user
), void *user
)
1464 for (i
= 0; i
< pw
->n
; ++i
) {
1468 set
= isl_set_copy(pw
->p
[i
].set
);
1469 el
= FN(EL
,copy
)(pw
->p
[i
].FIELD
);
1470 if (!any_divs(set
)) {
1471 if (fn(set
, el
, user
) < 0)
1475 if (foreach_lifted_subset(set
, el
, fn
, user
) < 0)
1483 #ifndef NO_MOVE_DIMS
1484 __isl_give PW
*FN(PW
,move_dims
)(__isl_take PW
*pw
,
1485 enum isl_dim_type dst_type
, unsigned dst_pos
,
1486 enum isl_dim_type src_type
, unsigned src_pos
, unsigned n
)
1490 pw
= FN(PW
,cow
)(pw
);
1494 pw
->dim
= isl_space_move_dims(pw
->dim
, dst_type
, dst_pos
, src_type
, src_pos
, n
);
1498 for (i
= 0; i
< pw
->n
; ++i
) {
1499 pw
->p
[i
].FIELD
= FN(EL
,move_dims
)(pw
->p
[i
].FIELD
,
1500 dst_type
, dst_pos
, src_type
, src_pos
, n
);
1501 if (!pw
->p
[i
].FIELD
)
1505 if (dst_type
== isl_dim_in
)
1506 dst_type
= isl_dim_set
;
1507 if (src_type
== isl_dim_in
)
1508 src_type
= isl_dim_set
;
1510 for (i
= 0; i
< pw
->n
; ++i
) {
1511 pw
->p
[i
].set
= isl_set_move_dims(pw
->p
[i
].set
,
1513 src_type
, src_pos
, n
);
1525 __isl_give PW
*FN(PW
,mul_isl_int
)(__isl_take PW
*pw
, isl_int v
)
1529 if (isl_int_is_one(v
))
1531 if (pw
&& DEFAULT_IS_ZERO
&& isl_int_is_zero(v
)) {
1533 isl_space
*dim
= FN(PW
,get_space
)(pw
);
1535 zero
= FN(PW
,ZERO
)(dim
, pw
->type
);
1537 zero
= FN(PW
,ZERO
)(dim
);
1542 pw
= FN(PW
,cow
)(pw
);
1549 if (isl_int_is_neg(v
))
1550 pw
->type
= isl_fold_type_negate(pw
->type
);
1552 for (i
= 0; i
< pw
->n
; ++i
) {
1553 pw
->p
[i
].FIELD
= FN(EL
,scale
)(pw
->p
[i
].FIELD
, v
);
1554 if (!pw
->p
[i
].FIELD
)
1564 /* Multiply the pieces of "pw" by "v" and return the result.
1566 __isl_give PW
*FN(PW
,scale_val
)(__isl_take PW
*pw
, __isl_take isl_val
*v
)
1573 if (isl_val_is_one(v
)) {
1577 if (pw
&& DEFAULT_IS_ZERO
&& isl_val_is_zero(v
)) {
1579 isl_space
*space
= FN(PW
,get_space
)(pw
);
1581 zero
= FN(PW
,ZERO
)(space
, pw
->type
);
1583 zero
= FN(PW
,ZERO
)(space
);
1593 pw
= FN(PW
,cow
)(pw
);
1598 if (isl_val_is_neg(v
))
1599 pw
->type
= isl_fold_type_negate(pw
->type
);
1601 for (i
= 0; i
< pw
->n
; ++i
) {
1602 pw
->p
[i
].FIELD
= FN(EL
,scale_val
)(pw
->p
[i
].FIELD
,
1604 if (!pw
->p
[i
].FIELD
)
1616 __isl_give PW
*FN(PW
,scale
)(__isl_take PW
*pw
, isl_int v
)
1618 return FN(PW
,mul_isl_int
)(pw
, v
);
1621 static int FN(PW
,qsort_set_cmp
)(const void *p1
, const void *p2
)
1623 isl_set
*set1
= *(isl_set
* const *)p1
;
1624 isl_set
*set2
= *(isl_set
* const *)p2
;
1626 return isl_set_plain_cmp(set1
, set2
);
1629 /* We normalize in place, but if anything goes wrong we need
1630 * to return NULL, so we need to make sure we don't change the
1631 * meaning of any possible other copies of map.
1633 __isl_give PW
*FN(PW
,normalize
)(__isl_take PW
*pw
)
1640 for (i
= 0; i
< pw
->n
; ++i
) {
1641 set
= isl_set_normalize(isl_set_copy(pw
->p
[i
].set
));
1643 return FN(PW
,free
)(pw
);
1644 isl_set_free(pw
->p
[i
].set
);
1647 qsort(pw
->p
, pw
->n
, sizeof(pw
->p
[0]), &FN(PW
,qsort_set_cmp
));
1648 for (i
= pw
->n
- 1; i
>= 1; --i
) {
1649 if (!isl_set_plain_is_equal(pw
->p
[i
- 1].set
, pw
->p
[i
].set
))
1651 if (!FN(EL
,plain_is_equal
)(pw
->p
[i
- 1].FIELD
, pw
->p
[i
].FIELD
))
1653 set
= isl_set_union(isl_set_copy(pw
->p
[i
- 1].set
),
1654 isl_set_copy(pw
->p
[i
].set
));
1656 return FN(PW
,free
)(pw
);
1657 isl_set_free(pw
->p
[i
].set
);
1658 FN(EL
,free
)(pw
->p
[i
].FIELD
);
1659 isl_set_free(pw
->p
[i
- 1].set
);
1660 pw
->p
[i
- 1].set
= set
;
1661 for (j
= i
+ 1; j
< pw
->n
; ++j
)
1662 pw
->p
[j
- 1] = pw
->p
[j
];
1669 /* Is pw1 obviously equal to pw2?
1670 * That is, do they have obviously identical cells and obviously identical
1671 * elements on each cell?
1673 int FN(PW
,plain_is_equal
)(__isl_keep PW
*pw1
, __isl_keep PW
*pw2
)
1683 if (!isl_space_is_equal(pw1
->dim
, pw2
->dim
))
1686 pw1
= FN(PW
,copy
)(pw1
);
1687 pw2
= FN(PW
,copy
)(pw2
);
1688 pw1
= FN(PW
,normalize
)(pw1
);
1689 pw2
= FN(PW
,normalize
)(pw2
);
1693 equal
= pw1
->n
== pw2
->n
;
1694 for (i
= 0; equal
&& i
< pw1
->n
; ++i
) {
1695 equal
= isl_set_plain_is_equal(pw1
->p
[i
].set
, pw2
->p
[i
].set
);
1700 equal
= FN(EL
,plain_is_equal
)(pw1
->p
[i
].FIELD
, pw2
->p
[i
].FIELD
);
1715 static __isl_give PW
*FN(PW
,align_params_pw_multi_aff_and
)(__isl_take PW
*pw
,
1716 __isl_take isl_multi_aff
*ma
,
1717 __isl_give PW
*(*fn
)(__isl_take PW
*pw
, __isl_take isl_multi_aff
*ma
))
1720 isl_space
*ma_space
;
1722 ma_space
= isl_multi_aff_get_space(ma
);
1723 if (!pw
|| !ma
|| !ma_space
)
1725 if (isl_space_match(pw
->dim
, isl_dim_param
, ma_space
, isl_dim_param
)) {
1726 isl_space_free(ma_space
);
1729 ctx
= FN(PW
,get_ctx
)(pw
);
1730 if (!isl_space_has_named_params(pw
->dim
) ||
1731 !isl_space_has_named_params(ma_space
))
1732 isl_die(ctx
, isl_error_invalid
,
1733 "unaligned unnamed parameters", goto error
);
1734 pw
= FN(PW
,align_params
)(pw
, ma_space
);
1735 ma
= isl_multi_aff_align_params(ma
, FN(PW
,get_space
)(pw
));
1738 isl_space_free(ma_space
);
1740 isl_multi_aff_free(ma
);
1744 static __isl_give PW
*FN(PW
,align_params_pw_pw_multi_aff_and
)(__isl_take PW
*pw
,
1745 __isl_take isl_pw_multi_aff
*pma
,
1746 __isl_give PW
*(*fn
)(__isl_take PW
*pw
,
1747 __isl_take isl_pw_multi_aff
*ma
))
1750 isl_space
*pma_space
;
1752 pma_space
= isl_pw_multi_aff_get_space(pma
);
1753 if (!pw
|| !pma
|| !pma_space
)
1755 if (isl_space_match(pw
->dim
, isl_dim_param
, pma_space
, isl_dim_param
)) {
1756 isl_space_free(pma_space
);
1759 ctx
= FN(PW
,get_ctx
)(pw
);
1760 if (!isl_space_has_named_params(pw
->dim
) ||
1761 !isl_space_has_named_params(pma_space
))
1762 isl_die(ctx
, isl_error_invalid
,
1763 "unaligned unnamed parameters", goto error
);
1764 pw
= FN(PW
,align_params
)(pw
, pma_space
);
1765 pma
= isl_pw_multi_aff_align_params(pma
, FN(PW
,get_space
)(pw
));
1768 isl_space_free(pma_space
);
1770 isl_pw_multi_aff_free(pma
);
1774 /* Compute the pullback of "pw" by the function represented by "ma".
1775 * In other words, plug in "ma" in "pw".
1777 static __isl_give PW
*FN(PW
,pullback_multi_aff_aligned
)(__isl_take PW
*pw
,
1778 __isl_take isl_multi_aff
*ma
)
1781 isl_space
*space
= NULL
;
1783 ma
= isl_multi_aff_align_divs(ma
);
1784 pw
= FN(PW
,cow
)(pw
);
1788 space
= isl_space_join(isl_multi_aff_get_space(ma
),
1789 FN(PW
,get_space
)(pw
));
1791 for (i
= 0; i
< pw
->n
; ++i
) {
1792 pw
->p
[i
].set
= isl_set_preimage_multi_aff(pw
->p
[i
].set
,
1793 isl_multi_aff_copy(ma
));
1796 pw
->p
[i
].FIELD
= FN(EL
,pullback_multi_aff
)(pw
->p
[i
].FIELD
,
1797 isl_multi_aff_copy(ma
));
1798 if (!pw
->p
[i
].FIELD
)
1802 pw
= FN(PW
,reset_space
)(pw
, space
);
1803 isl_multi_aff_free(ma
);
1806 isl_space_free(space
);
1807 isl_multi_aff_free(ma
);
1812 __isl_give PW
*FN(PW
,pullback_multi_aff
)(__isl_take PW
*pw
,
1813 __isl_take isl_multi_aff
*ma
)
1815 return FN(PW
,align_params_pw_multi_aff_and
)(pw
, ma
,
1816 &FN(PW
,pullback_multi_aff_aligned
));
1819 /* Compute the pullback of "pw" by the function represented by "pma".
1820 * In other words, plug in "pma" in "pw".
1822 static __isl_give PW
*FN(PW
,pullback_pw_multi_aff_aligned
)(__isl_take PW
*pw
,
1823 __isl_take isl_pw_multi_aff
*pma
)
1832 isl_pw_multi_aff_free(pma
);
1833 res
= FN(PW
,empty
)(FN(PW
,get_space
)(pw
));
1838 res
= FN(PW
,pullback_multi_aff
)(FN(PW
,copy
)(pw
),
1839 isl_multi_aff_copy(pma
->p
[0].maff
));
1840 res
= FN(PW
,intersect_domain
)(res
, isl_set_copy(pma
->p
[0].set
));
1842 for (i
= 1; i
< pma
->n
; ++i
) {
1845 res_i
= FN(PW
,pullback_multi_aff
)(FN(PW
,copy
)(pw
),
1846 isl_multi_aff_copy(pma
->p
[i
].maff
));
1847 res_i
= FN(PW
,intersect_domain
)(res_i
,
1848 isl_set_copy(pma
->p
[i
].set
));
1849 res
= FN(PW
,add_disjoint
)(res
, res_i
);
1852 isl_pw_multi_aff_free(pma
);
1856 isl_pw_multi_aff_free(pma
);
1861 __isl_give PW
*FN(PW
,pullback_pw_multi_aff
)(__isl_take PW
*pw
,
1862 __isl_take isl_pw_multi_aff
*pma
)
1864 return FN(PW
,align_params_pw_pw_multi_aff_and
)(pw
, pma
,
1865 &FN(PW
,pullback_pw_multi_aff_aligned
));