2 * Copyright 2011 INRIA Saclay
4 * Use of this software is governed by the GNU LGPLv2.1 license
6 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
7 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
11 #include <isl_map_private.h>
12 #include <isl_aff_private.h>
13 #include <isl_dim_private.h>
14 #include <isl_local_space_private.h>
15 #include <isl_mat_private.h>
16 #include <isl/constraint.h>
20 __isl_give isl_aff
*isl_aff_alloc_vec(__isl_take isl_local_space
*ls
,
21 __isl_take isl_vec
*v
)
28 aff
= isl_calloc_type(v
->ctx
, struct isl_aff
);
38 isl_local_space_free(ls
);
43 __isl_give isl_aff
*isl_aff_alloc(__isl_take isl_local_space
*ls
)
52 ctx
= isl_local_space_get_ctx(ls
);
53 if (!isl_local_space_divs_known(ls
))
54 isl_die(ctx
, isl_error_invalid
, "local space has unknown divs",
57 total
= isl_local_space_dim(ls
, isl_dim_all
);
58 v
= isl_vec_alloc(ctx
, 1 + 1 + total
);
59 return isl_aff_alloc_vec(ls
, v
);
61 isl_local_space_free(ls
);
65 __isl_give isl_aff
*isl_aff_zero(__isl_take isl_local_space
*ls
)
69 aff
= isl_aff_alloc(ls
);
73 isl_int_set_si(aff
->v
->el
[0], 1);
74 isl_seq_clr(aff
->v
->el
+ 1, aff
->v
->size
- 1);
79 __isl_give isl_aff
*isl_aff_copy(__isl_keep isl_aff
*aff
)
88 __isl_give isl_aff
*isl_aff_dup(__isl_keep isl_aff
*aff
)
93 return isl_aff_alloc_vec(isl_local_space_copy(aff
->ls
),
94 isl_vec_copy(aff
->v
));
97 __isl_give isl_aff
*isl_aff_cow(__isl_take isl_aff
*aff
)
105 return isl_aff_dup(aff
);
108 void *isl_aff_free(__isl_take isl_aff
*aff
)
116 isl_local_space_free(aff
->ls
);
117 isl_vec_free(aff
->v
);
124 isl_ctx
*isl_aff_get_ctx(__isl_keep isl_aff
*aff
)
126 return aff
? isl_local_space_get_ctx(aff
->ls
) : NULL
;
129 int isl_aff_dim(__isl_keep isl_aff
*aff
, enum isl_dim_type type
)
131 return aff
? isl_local_space_dim(aff
->ls
, type
) : 0;
134 __isl_give isl_dim
*isl_aff_get_dim(__isl_keep isl_aff
*aff
)
136 return aff
? isl_local_space_get_dim(aff
->ls
) : NULL
;
139 __isl_give isl_local_space
*isl_aff_get_local_space(__isl_keep isl_aff
*aff
)
141 return aff
? isl_local_space_copy(aff
->ls
) : NULL
;
144 const char *isl_aff_get_dim_name(__isl_keep isl_aff
*aff
,
145 enum isl_dim_type type
, unsigned pos
)
147 return aff
? isl_local_space_get_dim_name(aff
->ls
, type
, pos
) : 0;
150 int isl_aff_plain_is_zero(__isl_keep isl_aff
*aff
)
155 return isl_seq_first_non_zero(aff
->v
->el
+ 1, aff
->v
->size
- 1) < 0;
158 int isl_aff_plain_is_equal(__isl_keep isl_aff
*aff1
, __isl_keep isl_aff
*aff2
)
165 equal
= isl_local_space_is_equal(aff1
->ls
, aff2
->ls
);
166 if (equal
< 0 || !equal
)
169 return isl_vec_is_equal(aff1
->v
, aff2
->v
);
172 int isl_aff_get_denominator(__isl_keep isl_aff
*aff
, isl_int
*v
)
176 isl_int_set(*v
, aff
->v
->el
[0]);
180 int isl_aff_get_constant(__isl_keep isl_aff
*aff
, isl_int
*v
)
184 isl_int_set(*v
, aff
->v
->el
[1]);
188 int isl_aff_get_coefficient(__isl_keep isl_aff
*aff
,
189 enum isl_dim_type type
, int pos
, isl_int
*v
)
194 if (pos
>= isl_local_space_dim(aff
->ls
, type
))
195 isl_die(aff
->v
->ctx
, isl_error_invalid
,
196 "position out of bounds", return -1);
198 pos
+= isl_local_space_offset(aff
->ls
, type
);
199 isl_int_set(*v
, aff
->v
->el
[1 + pos
]);
204 __isl_give isl_aff
*isl_aff_set_denominator(__isl_take isl_aff
*aff
, isl_int v
)
206 aff
= isl_aff_cow(aff
);
210 aff
->v
= isl_vec_cow(aff
->v
);
212 return isl_aff_free(aff
);
214 isl_int_set(aff
->v
->el
[0], v
);
219 __isl_give isl_aff
*isl_aff_set_constant(__isl_take isl_aff
*aff
, isl_int v
)
221 aff
= isl_aff_cow(aff
);
225 aff
->v
= isl_vec_cow(aff
->v
);
227 return isl_aff_free(aff
);
229 isl_int_set(aff
->v
->el
[1], v
);
234 __isl_give isl_aff
*isl_aff_add_constant(__isl_take isl_aff
*aff
, isl_int v
)
236 if (isl_int_is_zero(v
))
239 aff
= isl_aff_cow(aff
);
243 aff
->v
= isl_vec_cow(aff
->v
);
245 return isl_aff_free(aff
);
247 isl_int_addmul(aff
->v
->el
[1], aff
->v
->el
[0], v
);
252 __isl_give isl_aff
*isl_aff_add_constant_si(__isl_take isl_aff
*aff
, int v
)
257 isl_int_set_si(t
, v
);
258 aff
= isl_aff_add_constant(aff
, t
);
264 __isl_give isl_aff
*isl_aff_set_constant_si(__isl_take isl_aff
*aff
, int v
)
266 aff
= isl_aff_cow(aff
);
270 aff
->v
= isl_vec_cow(aff
->v
);
272 return isl_aff_free(aff
);
274 isl_int_set_si(aff
->v
->el
[1], v
);
279 __isl_give isl_aff
*isl_aff_set_coefficient(__isl_take isl_aff
*aff
,
280 enum isl_dim_type type
, int pos
, isl_int v
)
285 if (pos
>= isl_local_space_dim(aff
->ls
, type
))
286 isl_die(aff
->v
->ctx
, isl_error_invalid
,
287 "position out of bounds", return isl_aff_free(aff
));
289 aff
= isl_aff_cow(aff
);
293 aff
->v
= isl_vec_cow(aff
->v
);
295 return isl_aff_free(aff
);
297 pos
+= isl_local_space_offset(aff
->ls
, type
);
298 isl_int_set(aff
->v
->el
[1 + pos
], v
);
303 __isl_give isl_aff
*isl_aff_set_coefficient_si(__isl_take isl_aff
*aff
,
304 enum isl_dim_type type
, int pos
, int v
)
309 if (pos
>= isl_local_space_dim(aff
->ls
, type
))
310 isl_die(aff
->v
->ctx
, isl_error_invalid
,
311 "position out of bounds", return isl_aff_free(aff
));
313 aff
= isl_aff_cow(aff
);
317 aff
->v
= isl_vec_cow(aff
->v
);
319 return isl_aff_free(aff
);
321 pos
+= isl_local_space_offset(aff
->ls
, type
);
322 isl_int_set_si(aff
->v
->el
[1 + pos
], v
);
327 __isl_give isl_aff
*isl_aff_add_coefficient(__isl_take isl_aff
*aff
,
328 enum isl_dim_type type
, int pos
, isl_int v
)
333 if (pos
>= isl_local_space_dim(aff
->ls
, type
))
334 isl_die(aff
->v
->ctx
, isl_error_invalid
,
335 "position out of bounds", return isl_aff_free(aff
));
337 aff
= isl_aff_cow(aff
);
341 aff
->v
= isl_vec_cow(aff
->v
);
343 return isl_aff_free(aff
);
345 pos
+= isl_local_space_offset(aff
->ls
, type
);
346 isl_int_addmul(aff
->v
->el
[1 + pos
], aff
->v
->el
[0], v
);
351 __isl_give isl_aff
*isl_aff_add_coefficient_si(__isl_take isl_aff
*aff
,
352 enum isl_dim_type type
, int pos
, int v
)
357 isl_int_set_si(t
, v
);
358 aff
= isl_aff_add_coefficient(aff
, type
, pos
, t
);
364 __isl_give isl_div
*isl_aff_get_div(__isl_keep isl_aff
*aff
, int pos
)
369 return isl_local_space_get_div(aff
->ls
, pos
);
372 __isl_give isl_aff
*isl_aff_neg(__isl_take isl_aff
*aff
)
374 aff
= isl_aff_cow(aff
);
377 aff
->v
= isl_vec_cow(aff
->v
);
379 return isl_aff_free(aff
);
381 isl_seq_neg(aff
->v
->el
+ 1, aff
->v
->el
+ 1, aff
->v
->size
- 1);
386 /* Given f, return floor(f).
387 * If f is an integer expression, then just return f.
388 * Otherwise, create a new div d = [f] and return the expression d.
390 __isl_give isl_aff
*isl_aff_floor(__isl_take isl_aff
*aff
)
398 if (isl_int_is_one(aff
->v
->el
[0]))
401 aff
= isl_aff_cow(aff
);
405 aff
->ls
= isl_local_space_add_div(aff
->ls
, isl_vec_copy(aff
->v
));
407 return isl_aff_free(aff
);
409 ctx
= isl_aff_get_ctx(aff
);
411 isl_vec_free(aff
->v
);
412 aff
->v
= isl_vec_alloc(ctx
, size
+ 1);
413 aff
->v
= isl_vec_clr(aff
->v
);
415 return isl_aff_free(aff
);
416 isl_int_set_si(aff
->v
->el
[0], 1);
417 isl_int_set_si(aff
->v
->el
[size
], 1);
422 /* Given f, return ceil(f).
423 * If f is an integer expression, then just return f.
424 * Otherwise, create a new div d = [-f] and return the expression -d.
426 __isl_give isl_aff
*isl_aff_ceil(__isl_take isl_aff
*aff
)
431 if (isl_int_is_one(aff
->v
->el
[0]))
434 aff
= isl_aff_neg(aff
);
435 aff
= isl_aff_floor(aff
);
436 aff
= isl_aff_neg(aff
);
441 /* Apply the expansion computed by isl_merge_divs.
442 * The expansion itself is given by "exp" while the resulting
443 * list of divs is given by "div".
445 __isl_give isl_aff
*isl_aff_expand_divs( __isl_take isl_aff
*aff
,
446 __isl_take isl_mat
*div
, int *exp
)
453 aff
= isl_aff_cow(aff
);
457 old_n_div
= isl_local_space_dim(aff
->ls
, isl_dim_div
);
458 new_n_div
= isl_mat_rows(div
);
459 if (new_n_div
< old_n_div
)
460 isl_die(isl_mat_get_ctx(div
), isl_error_invalid
,
461 "not an expansion", goto error
);
463 aff
->v
= isl_vec_extend(aff
->v
, aff
->v
->size
+ new_n_div
- old_n_div
);
467 offset
= 1 + isl_local_space_offset(aff
->ls
, isl_dim_div
);
469 for (i
= new_n_div
- 1; i
>= 0; --i
) {
470 if (j
>= 0 && exp
[j
] == i
) {
472 isl_int_swap(aff
->v
->el
[offset
+ i
],
473 aff
->v
->el
[offset
+ j
]);
476 isl_int_set_si(aff
->v
->el
[offset
+ i
], 0);
479 aff
->ls
= isl_local_space_replace_divs(aff
->ls
, isl_mat_copy(div
));
490 /* Add two affine expressions that live in the same local space.
492 static __isl_give isl_aff
*add_expanded(__isl_take isl_aff
*aff1
,
493 __isl_take isl_aff
*aff2
)
497 aff1
= isl_aff_cow(aff1
);
501 aff1
->v
= isl_vec_cow(aff1
->v
);
507 isl_int_gcd(gcd
, aff1
->v
->el
[0], aff2
->v
->el
[0]);
508 isl_int_divexact(f
, aff2
->v
->el
[0], gcd
);
509 isl_seq_scale(aff1
->v
->el
+ 1, aff1
->v
->el
+ 1, f
, aff1
->v
->size
- 1);
510 isl_int_divexact(f
, aff1
->v
->el
[0], gcd
);
511 isl_seq_addmul(aff1
->v
->el
+ 1, f
, aff2
->v
->el
+ 1, aff1
->v
->size
- 1);
512 isl_int_divexact(f
, aff2
->v
->el
[0], gcd
);
513 isl_int_mul(aff1
->v
->el
[0], aff1
->v
->el
[0], f
);
525 __isl_give isl_aff
*isl_aff_add(__isl_take isl_aff
*aff1
,
526 __isl_take isl_aff
*aff2
)
536 ctx
= isl_aff_get_ctx(aff1
);
537 if (!isl_dim_equal(aff1
->ls
->dim
, aff2
->ls
->dim
))
538 isl_die(ctx
, isl_error_invalid
,
539 "spaces don't match", goto error
);
541 if (aff1
->ls
->div
->n_row
== 0 && aff2
->ls
->div
->n_row
== 0)
542 return add_expanded(aff1
, aff2
);
544 exp1
= isl_alloc_array(ctx
, int, aff1
->ls
->div
->n_row
);
545 exp2
= isl_alloc_array(ctx
, int, aff2
->ls
->div
->n_row
);
549 div
= isl_merge_divs(aff1
->ls
->div
, aff2
->ls
->div
, exp1
, exp2
);
550 aff1
= isl_aff_expand_divs(aff1
, isl_mat_copy(div
), exp1
);
551 aff2
= isl_aff_expand_divs(aff2
, div
, exp2
);
555 return add_expanded(aff1
, aff2
);
564 __isl_give isl_aff
*isl_aff_sub(__isl_take isl_aff
*aff1
,
565 __isl_take isl_aff
*aff2
)
567 return isl_aff_add(aff1
, isl_aff_neg(aff2
));
570 __isl_give isl_aff
*isl_aff_scale(__isl_take isl_aff
*aff
, isl_int f
)
574 if (isl_int_is_one(f
))
577 aff
= isl_aff_cow(aff
);
580 aff
->v
= isl_vec_cow(aff
->v
);
582 return isl_aff_free(aff
);
585 isl_int_gcd(gcd
, aff
->v
->el
[0], f
);
586 isl_int_divexact(aff
->v
->el
[0], aff
->v
->el
[0], gcd
);
587 isl_int_divexact(gcd
, f
, gcd
);
588 isl_seq_scale(aff
->v
->el
+ 1, aff
->v
->el
+ 1, gcd
, aff
->v
->size
- 1);
594 __isl_give isl_aff
*isl_aff_scale_down(__isl_take isl_aff
*aff
, isl_int f
)
598 if (isl_int_is_one(f
))
601 aff
= isl_aff_cow(aff
);
604 aff
->v
= isl_vec_cow(aff
->v
);
606 return isl_aff_free(aff
);
609 isl_seq_gcd(aff
->v
->el
+ 1, aff
->v
->size
- 1, &gcd
);
610 isl_int_gcd(gcd
, gcd
, f
);
611 isl_seq_scale_down(aff
->v
->el
+ 1, aff
->v
->el
+ 1, gcd
, aff
->v
->size
- 1);
612 isl_int_divexact(gcd
, f
, gcd
);
613 isl_int_mul(aff
->v
->el
[0], aff
->v
->el
[0], gcd
);
619 __isl_give isl_aff
*isl_aff_scale_down_ui(__isl_take isl_aff
*aff
, unsigned f
)
627 isl_int_set_ui(v
, f
);
628 aff
= isl_aff_scale_down(aff
, v
);
634 __isl_give isl_aff
*isl_aff_set_dim_name(__isl_take isl_aff
*aff
,
635 enum isl_dim_type type
, unsigned pos
, const char *s
)
637 aff
= isl_aff_cow(aff
);
640 aff
->ls
= isl_local_space_set_dim_name(aff
->ls
, type
, pos
, s
);
642 return isl_aff_free(aff
);
647 /* Exploit the equalities in "eq" to simplify the affine expression
648 * and the expressions of the integer divisions in the local space.
649 * The integer divisions in this local space are assumed to appear
650 * as regular dimensions in "eq".
652 static __isl_give isl_aff
*isl_aff_substitute_equalities(
653 __isl_take isl_aff
*aff
, __isl_take isl_basic_set
*eq
)
662 isl_basic_set_free(eq
);
666 aff
= isl_aff_cow(aff
);
670 aff
->ls
= isl_local_space_substitute_equalities(aff
->ls
,
671 isl_basic_set_copy(eq
));
675 total
= 1 + isl_dim_total(eq
->dim
);
677 for (i
= 0; i
< eq
->n_eq
; ++i
) {
678 j
= isl_seq_last_non_zero(eq
->eq
[i
], total
+ n_div
);
679 if (j
< 0 || j
== 0 || j
>= total
)
682 isl_seq_elim(aff
->v
->el
+ 1, eq
->eq
[i
], j
, total
,
686 isl_basic_set_free(eq
);
689 isl_basic_set_free(eq
);
694 /* Look for equalities among the variables shared by context and aff
695 * and the integer divisions of aff, if any.
696 * The equalities are then used to eliminate coefficients and/or integer
697 * divisions from aff.
699 __isl_give isl_aff
*isl_aff_gist(__isl_take isl_aff
*aff
,
700 __isl_take isl_set
*context
)
707 n_div
= isl_local_space_dim(aff
->ls
, isl_dim_div
);
710 context
= isl_set_add_dims(context
, isl_dim_set
, n_div
);
711 bset
= isl_basic_set_from_local_space(
712 isl_aff_get_local_space(aff
));
713 bset
= isl_basic_set_lift(bset
);
714 bset
= isl_basic_set_flatten(bset
);
715 context
= isl_set_intersect(context
,
716 isl_set_from_basic_set(bset
));
719 hull
= isl_set_affine_hull(context
);
720 return isl_aff_substitute_equalities(aff
, hull
);
723 isl_set_free(context
);
727 /* Return a basic set containing those elements in the space
728 * of aff where it is non-negative.
730 __isl_give isl_basic_set
*isl_aff_nonneg_basic_set(__isl_take isl_aff
*aff
)
732 isl_constraint
*ineq
;
734 ineq
= isl_inequality_from_aff(aff
);
736 return isl_basic_set_from_constraint(ineq
);
739 /* Return a basic set containing those elements in the shared space
740 * of aff1 and aff2 where aff1 is greater than or equal to aff2.
742 __isl_give isl_basic_set
*isl_aff_ge_basic_set(__isl_take isl_aff
*aff1
,
743 __isl_take isl_aff
*aff2
)
745 aff1
= isl_aff_sub(aff1
, aff2
);
747 return isl_aff_nonneg_basic_set(aff1
);
750 __isl_give isl_aff
*isl_aff_add_on_domain(__isl_keep isl_set
*dom
,
751 __isl_take isl_aff
*aff1
, __isl_take isl_aff
*aff2
)
753 aff1
= isl_aff_add(aff1
, aff2
);
754 aff1
= isl_aff_gist(aff1
, isl_set_copy(dom
));
758 int isl_aff_is_empty(__isl_keep isl_aff
*aff
)
766 /* Set active[i] to 1 if the dimension at position i is involved
767 * in the affine expression.
769 static int set_active(__isl_keep isl_aff
*aff
, int *active
)
778 total
= aff
->v
->size
- 2;
779 for (i
= 0; i
< total
; ++i
)
780 active
[i
] = !isl_int_is_zero(aff
->v
->el
[2 + i
]);
782 offset
= isl_local_space_offset(aff
->ls
, isl_dim_div
) - 1;
783 for (i
= aff
->ls
->div
->n_row
- 1; i
>= 0; --i
) {
784 if (!active
[offset
+ i
])
786 for (j
= 0; j
< total
; ++j
)
788 !isl_int_is_zero(aff
->ls
->div
->row
[i
][2 + j
]);
794 /* Check whether the given affine expression has non-zero coefficient
795 * for any dimension in the given range or if any of these dimensions
796 * appear with non-zero coefficients in any of the integer divisions
797 * involved in the affine expression.
799 int isl_aff_involves_dims(__isl_keep isl_aff
*aff
,
800 enum isl_dim_type type
, unsigned first
, unsigned n
)
812 ctx
= isl_aff_get_ctx(aff
);
813 if (first
+ n
> isl_aff_dim(aff
, type
))
814 isl_die(ctx
, isl_error_invalid
,
815 "range out of bounds", return -1);
817 active
= isl_calloc_array(ctx
, int,
818 isl_local_space_dim(aff
->ls
, isl_dim_all
));
819 if (set_active(aff
, active
) < 0)
822 first
+= isl_local_space_offset(aff
->ls
, type
) - 1;
823 for (i
= 0; i
< n
; ++i
)
824 if (active
[first
+ i
]) {
837 __isl_give isl_aff
*isl_aff_drop_dims(__isl_take isl_aff
*aff
,
838 enum isl_dim_type type
, unsigned first
, unsigned n
)
844 if (n
== 0 && !isl_local_space_is_named_or_nested(aff
->ls
, type
))
847 ctx
= isl_aff_get_ctx(aff
);
848 if (first
+ n
> isl_aff_dim(aff
, type
))
849 isl_die(ctx
, isl_error_invalid
, "range out of bounds",
850 return isl_aff_free(aff
));
852 aff
= isl_aff_cow(aff
);
856 aff
->ls
= isl_local_space_drop_dims(aff
->ls
, type
, first
, n
);
858 return isl_aff_free(aff
);
860 first
+= 1 + isl_local_space_offset(aff
->ls
, type
);
861 aff
->v
= isl_vec_drop_els(aff
->v
, first
, n
);
863 return isl_aff_free(aff
);
868 __isl_give isl_aff
*isl_aff_insert_dims(__isl_take isl_aff
*aff
,
869 enum isl_dim_type type
, unsigned first
, unsigned n
)
875 if (n
== 0 && !isl_local_space_is_named_or_nested(aff
->ls
, type
))
878 ctx
= isl_aff_get_ctx(aff
);
879 if (first
> isl_aff_dim(aff
, type
))
880 isl_die(ctx
, isl_error_invalid
, "position out of bounds",
881 return isl_aff_free(aff
));
883 aff
= isl_aff_cow(aff
);
887 aff
->ls
= isl_local_space_insert_dims(aff
->ls
, type
, first
, n
);
889 return isl_aff_free(aff
);
891 first
+= 1 + isl_local_space_offset(aff
->ls
, type
);
892 aff
->v
= isl_vec_insert_zero_els(aff
->v
, first
, n
);
894 return isl_aff_free(aff
);
899 __isl_give isl_aff
*isl_aff_add_dims(__isl_take isl_aff
*aff
,
900 enum isl_dim_type type
, unsigned n
)
904 pos
= isl_aff_dim(aff
, type
);
906 return isl_aff_insert_dims(aff
, type
, pos
, n
);
909 __isl_give isl_pw_aff
*isl_pw_aff_add_dims(__isl_take isl_pw_aff
*pwaff
,
910 enum isl_dim_type type
, unsigned n
)
914 pos
= isl_pw_aff_dim(pwaff
, type
);
916 return isl_pw_aff_insert_dims(pwaff
, type
, pos
, n
);
920 #define PW isl_pw_aff
924 #define EL_IS_ZERO is_empty
928 #define IS_ZERO is_empty
940 #include <isl_pw_templ.c>
942 /* Compute a piecewise quasi-affine expression with a domain that
943 * is the union of those of pwaff1 and pwaff2 and such that on each
944 * cell, the quasi-affine expression is the maximum of those of pwaff1
945 * and pwaff2. If only one of pwaff1 or pwaff2 is defined on a given
946 * cell, then the associated expression is the defined one.
948 __isl_give isl_pw_aff
*isl_pw_aff_max(__isl_take isl_pw_aff
*pwaff1
,
949 __isl_take isl_pw_aff
*pwaff2
)
956 if (!pwaff1
|| !pwaff2
)
959 ctx
= isl_dim_get_ctx(pwaff1
->dim
);
960 if (!isl_dim_equal(pwaff1
->dim
, pwaff2
->dim
))
961 isl_die(ctx
, isl_error_invalid
,
962 "arguments should live in same space", goto error
);
964 if (isl_pw_aff_is_empty(pwaff1
)) {
965 isl_pw_aff_free(pwaff1
);
969 if (isl_pw_aff_is_empty(pwaff2
)) {
970 isl_pw_aff_free(pwaff2
);
974 n
= 2 * (pwaff1
->n
+ 1) * (pwaff2
->n
+ 1);
975 res
= isl_pw_aff_alloc_(isl_dim_copy(pwaff1
->dim
), n
);
977 for (i
= 0; i
< pwaff1
->n
; ++i
) {
978 set
= isl_set_copy(pwaff1
->p
[i
].set
);
979 for (j
= 0; j
< pwaff2
->n
; ++j
) {
980 struct isl_set
*common
;
983 common
= isl_set_intersect(
984 isl_set_copy(pwaff1
->p
[i
].set
),
985 isl_set_copy(pwaff2
->p
[j
].set
));
986 ge
= isl_set_from_basic_set(isl_aff_ge_basic_set(
987 isl_aff_copy(pwaff2
->p
[j
].aff
),
988 isl_aff_copy(pwaff1
->p
[i
].aff
)));
989 ge
= isl_set_intersect(common
, ge
);
990 if (isl_set_plain_is_empty(ge
)) {
994 set
= isl_set_subtract(set
, isl_set_copy(ge
));
996 res
= isl_pw_aff_add_piece(res
, ge
,
997 isl_aff_copy(pwaff2
->p
[j
].aff
));
999 res
= isl_pw_aff_add_piece(res
, set
,
1000 isl_aff_copy(pwaff1
->p
[i
].aff
));
1003 for (j
= 0; j
< pwaff2
->n
; ++j
) {
1004 set
= isl_set_copy(pwaff2
->p
[j
].set
);
1005 for (i
= 0; i
< pwaff1
->n
; ++i
)
1006 set
= isl_set_subtract(set
,
1007 isl_set_copy(pwaff1
->p
[i
].set
));
1008 res
= isl_pw_aff_add_piece(res
, set
,
1009 isl_aff_copy(pwaff2
->p
[j
].aff
));
1012 isl_pw_aff_free(pwaff1
);
1013 isl_pw_aff_free(pwaff2
);
1017 isl_pw_aff_free(pwaff1
);
1018 isl_pw_aff_free(pwaff2
);
1022 /* Construct a map with as domain the domain of pwaff and
1023 * one-dimensional range corresponding to the affine expressions.
1025 __isl_give isl_map
*isl_map_from_pw_aff(__isl_take isl_pw_aff
*pwaff
)
1034 dim
= isl_pw_aff_get_dim(pwaff
);
1035 dim
= isl_dim_from_domain(dim
);
1036 dim
= isl_dim_add(dim
, isl_dim_out
, 1);
1037 map
= isl_map_empty(dim
);
1039 for (i
= 0; i
< pwaff
->n
; ++i
) {
1040 isl_basic_map
*bmap
;
1043 bmap
= isl_basic_map_from_aff(isl_aff_copy(pwaff
->p
[i
].aff
));
1044 map_i
= isl_map_from_basic_map(bmap
);
1045 map_i
= isl_map_intersect_domain(map_i
,
1046 isl_set_copy(pwaff
->p
[i
].set
));
1047 map
= isl_map_union_disjoint(map
, map_i
);
1050 isl_pw_aff_free(pwaff
);
1055 /* Return a set containing those elements in the domain
1056 * of pwaff where it is non-negative.
1058 __isl_give isl_set
*isl_pw_aff_nonneg_set(__isl_take isl_pw_aff
*pwaff
)
1066 set
= isl_set_empty(isl_pw_aff_get_dim(pwaff
));
1068 for (i
= 0; i
< pwaff
->n
; ++i
) {
1069 isl_basic_set
*bset
;
1072 bset
= isl_aff_nonneg_basic_set(isl_aff_copy(pwaff
->p
[i
].aff
));
1073 set_i
= isl_set_from_basic_set(bset
);
1074 set_i
= isl_set_intersect(set_i
, isl_set_copy(pwaff
->p
[i
].set
));
1075 set
= isl_set_union_disjoint(set
, set_i
);
1078 isl_pw_aff_free(pwaff
);
1083 /* Return a set containing those elements in the shared domain
1084 * of pwaff1 and pwaff2 where pwaff1 is greater than or equal to pwaff2.
1086 __isl_give isl_set
*isl_pw_aff_ge_set(__isl_take isl_pw_aff
*pwaff1
,
1087 __isl_take isl_pw_aff
*pwaff2
)
1089 isl_set
*set1
, *set2
;
1091 set1
= isl_pw_aff_domain(isl_pw_aff_copy(pwaff1
));
1092 set2
= isl_pw_aff_domain(isl_pw_aff_copy(pwaff2
));
1093 set1
= isl_set_intersect(set1
, set2
);
1094 pwaff1
= isl_pw_aff_intersect_domain(pwaff1
, isl_set_copy(set1
));
1095 pwaff2
= isl_pw_aff_intersect_domain(pwaff2
, set1
);
1096 pwaff1
= isl_pw_aff_add(pwaff1
, isl_pw_aff_neg(pwaff2
));
1098 return isl_pw_aff_nonneg_set(pwaff1
);