1*5971e316Smrg /*
2*5971e316Smrg * Copyright 2010 INRIA Saclay
3*5971e316Smrg * Copyright 2012 Ecole Normale Superieure
4*5971e316Smrg *
5*5971e316Smrg * Use of this software is governed by the MIT license
6*5971e316Smrg *
7*5971e316Smrg * Written by Sven Verdoolaege,
8*5971e316Smrg * INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
9*5971e316Smrg * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
10*5971e316Smrg * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
11*5971e316Smrg */
12*5971e316Smrg
13*5971e316Smrg /* Function for computing the lexicographic optimum of a map
14*5971e316Smrg * in the form of either an isl_map or an isl_pw_multi_aff.
15*5971e316Smrg */
16*5971e316Smrg
17*5971e316Smrg #define xSF(TYPE,SUFFIX) TYPE ## SUFFIX
18*5971e316Smrg #define SF(TYPE,SUFFIX) xSF(TYPE,SUFFIX)
19*5971e316Smrg
20*5971e316Smrg /* Compute the lexicographic minimum (or maximum if "flags" includes
21*5971e316Smrg * ISL_OPT_MAX) of "bmap" over the domain "dom" and return the result.
22*5971e316Smrg * If "empty" is not NULL, then *empty is assigned a set that
23*5971e316Smrg * contains those parts of the domain where there is no solution.
24*5971e316Smrg * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
25*5971e316Smrg * should be computed over the domain of "bmap". "empty" is also NULL
26*5971e316Smrg * in this case.
27*5971e316Smrg * If "bmap" is marked as rational (ISL_BASIC_MAP_RATIONAL),
28*5971e316Smrg * then the rational optimum is computed. Otherwise, the integral optimum
29*5971e316Smrg * is computed.
30*5971e316Smrg */
SF(isl_basic_map_partial_lexopt,SUFFIX)31*5971e316Smrg static __isl_give TYPE *SF(isl_basic_map_partial_lexopt,SUFFIX)(
32*5971e316Smrg __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom,
33*5971e316Smrg __isl_give isl_set **empty, unsigned flags)
34*5971e316Smrg {
35*5971e316Smrg return SF(isl_tab_basic_map_partial_lexopt,SUFFIX)(bmap, dom, empty,
36*5971e316Smrg flags);
37*5971e316Smrg }
38*5971e316Smrg
SF(isl_basic_map_partial_lexmax,SUFFIX)39*5971e316Smrg __isl_give TYPE *SF(isl_basic_map_partial_lexmax,SUFFIX)(
40*5971e316Smrg __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom,
41*5971e316Smrg __isl_give isl_set **empty)
42*5971e316Smrg {
43*5971e316Smrg unsigned flags = ISL_OPT_MAX;
44*5971e316Smrg return SF(isl_basic_map_partial_lexopt,SUFFIX)(bmap, dom, empty, flags);
45*5971e316Smrg }
46*5971e316Smrg
SF(isl_basic_map_partial_lexmin,SUFFIX)47*5971e316Smrg __isl_give TYPE *SF(isl_basic_map_partial_lexmin,SUFFIX)(
48*5971e316Smrg __isl_take isl_basic_map *bmap, __isl_take isl_basic_set *dom,
49*5971e316Smrg __isl_give isl_set **empty)
50*5971e316Smrg {
51*5971e316Smrg unsigned flags = 0;
52*5971e316Smrg return SF(isl_basic_map_partial_lexopt,SUFFIX)(bmap, dom, empty, flags);
53*5971e316Smrg }
54*5971e316Smrg
SF(isl_basic_set_partial_lexmin,SUFFIX)55*5971e316Smrg __isl_give TYPE *SF(isl_basic_set_partial_lexmin,SUFFIX)(
56*5971e316Smrg __isl_take isl_basic_set *bset, __isl_take isl_basic_set *dom,
57*5971e316Smrg __isl_give isl_set **empty)
58*5971e316Smrg {
59*5971e316Smrg return SF(isl_basic_map_partial_lexmin,SUFFIX)(bset, dom, empty);
60*5971e316Smrg }
61*5971e316Smrg
SF(isl_basic_set_partial_lexmax,SUFFIX)62*5971e316Smrg __isl_give TYPE *SF(isl_basic_set_partial_lexmax,SUFFIX)(
63*5971e316Smrg __isl_take isl_basic_set *bset, __isl_take isl_basic_set *dom,
64*5971e316Smrg __isl_give isl_set **empty)
65*5971e316Smrg {
66*5971e316Smrg return SF(isl_basic_map_partial_lexmax,SUFFIX)(bset, dom, empty);
67*5971e316Smrg }
68*5971e316Smrg
69*5971e316Smrg /* Given a basic map "bmap", compute the lexicographically minimal
70*5971e316Smrg * (or maximal) image element for each domain element in dom.
71*5971e316Smrg * If empty is not NULL, then set *empty to those elements in dom
72*5971e316Smrg * that do not have an image element.
73*5971e316Smrg * If "flags" includes ISL_OPT_FULL, then "dom" is NULL and the optimum
74*5971e316Smrg * should be computed over the domain of "bmap". "empty" is also NULL
75*5971e316Smrg * in this case.
76*5971e316Smrg *
77*5971e316Smrg * We first make sure the basic sets in dom are disjoint and then
78*5971e316Smrg * simply collect the results over each of the basic sets separately.
79*5971e316Smrg * We could probably improve the efficiency a bit by moving the union
80*5971e316Smrg * domain down into the parametric integer programming.
81*5971e316Smrg *
82*5971e316Smrg * If a full optimum is being computed (i.e., "flags" includes ISL_OPT_FULL),
83*5971e316Smrg * then no domain is given and there is then also no need to consider
84*5971e316Smrg * the disjuncts of the domain.
85*5971e316Smrg */
SF(basic_map_partial_lexopt,SUFFIX)86*5971e316Smrg static __isl_give TYPE *SF(basic_map_partial_lexopt,SUFFIX)(
87*5971e316Smrg __isl_take isl_basic_map *bmap, __isl_take isl_set *dom,
88*5971e316Smrg __isl_give isl_set **empty, unsigned flags)
89*5971e316Smrg {
90*5971e316Smrg int i;
91*5971e316Smrg TYPE *res;
92*5971e316Smrg isl_set *all_empty;
93*5971e316Smrg
94*5971e316Smrg if (ISL_FL_ISSET(flags, ISL_OPT_FULL))
95*5971e316Smrg return SF(isl_basic_map_partial_lexopt,SUFFIX)(bmap, NULL,
96*5971e316Smrg empty, flags);
97*5971e316Smrg
98*5971e316Smrg dom = isl_set_make_disjoint(dom);
99*5971e316Smrg if (!dom)
100*5971e316Smrg goto error;
101*5971e316Smrg
102*5971e316Smrg if (isl_set_plain_is_empty(dom)) {
103*5971e316Smrg isl_space *space = isl_basic_map_get_space(bmap);
104*5971e316Smrg if (empty)
105*5971e316Smrg *empty = dom;
106*5971e316Smrg else
107*5971e316Smrg isl_set_free(dom);
108*5971e316Smrg isl_basic_map_free(bmap);
109*5971e316Smrg return EMPTY(space);
110*5971e316Smrg }
111*5971e316Smrg
112*5971e316Smrg res = SF(isl_basic_map_partial_lexopt,SUFFIX)(isl_basic_map_copy(bmap),
113*5971e316Smrg isl_basic_set_copy(dom->p[0]), empty, flags);
114*5971e316Smrg
115*5971e316Smrg if (empty)
116*5971e316Smrg all_empty = *empty;
117*5971e316Smrg for (i = 1; i < dom->n; ++i) {
118*5971e316Smrg TYPE *res_i;
119*5971e316Smrg
120*5971e316Smrg res_i = SF(isl_basic_map_partial_lexopt,SUFFIX)(
121*5971e316Smrg isl_basic_map_copy(bmap),
122*5971e316Smrg isl_basic_set_copy(dom->p[i]), empty, flags);
123*5971e316Smrg
124*5971e316Smrg res = ADD(res, res_i);
125*5971e316Smrg if (empty)
126*5971e316Smrg all_empty = isl_set_union_disjoint(all_empty, *empty);
127*5971e316Smrg }
128*5971e316Smrg
129*5971e316Smrg if (empty)
130*5971e316Smrg *empty = all_empty;
131*5971e316Smrg isl_set_free(dom);
132*5971e316Smrg isl_basic_map_free(bmap);
133*5971e316Smrg return res;
134*5971e316Smrg error:
135*5971e316Smrg if (empty)
136*5971e316Smrg *empty = NULL;
137*5971e316Smrg isl_set_free(dom);
138*5971e316Smrg isl_basic_map_free(bmap);
139*5971e316Smrg return NULL;
140*5971e316Smrg }
141*5971e316Smrg
142*5971e316Smrg /* Compute the lexicographic minimum (or maximum if "flags" includes
143*5971e316Smrg * ISL_OPT_MAX) of "bmap" over its domain.
144*5971e316Smrg */
SF(isl_basic_map_lexopt,SUFFIX)145*5971e316Smrg __isl_give TYPE *SF(isl_basic_map_lexopt,SUFFIX)(
146*5971e316Smrg __isl_take isl_basic_map *bmap, unsigned flags)
147*5971e316Smrg {
148*5971e316Smrg ISL_FL_SET(flags, ISL_OPT_FULL);
149*5971e316Smrg return SF(isl_basic_map_partial_lexopt,SUFFIX)(bmap, NULL, NULL, flags);
150*5971e316Smrg }
151*5971e316Smrg
SF(isl_basic_map_lexmin,SUFFIX)152*5971e316Smrg __isl_give TYPE *SF(isl_basic_map_lexmin,SUFFIX)(__isl_take isl_basic_map *bmap)
153*5971e316Smrg {
154*5971e316Smrg return SF(isl_basic_map_lexopt,SUFFIX)(bmap, 0);
155*5971e316Smrg }
156*5971e316Smrg
157*5971e316Smrg static __isl_give TYPE *SF(isl_map_partial_lexopt_aligned,SUFFIX)(
158*5971e316Smrg __isl_take isl_map *map, __isl_take isl_set *dom,
159*5971e316Smrg __isl_give isl_set **empty, unsigned flags);
160*5971e316Smrg /* This function is currently only used when TYPE is defined as isl_map. */
161*5971e316Smrg static __isl_give TYPE *SF(isl_map_partial_lexopt,SUFFIX)(
162*5971e316Smrg __isl_take isl_map *map, __isl_take isl_set *dom,
163*5971e316Smrg __isl_give isl_set **empty, unsigned flags)
164*5971e316Smrg __attribute__ ((unused));
165*5971e316Smrg
166*5971e316Smrg /* Given a map "map", compute the lexicographically minimal
167*5971e316Smrg * (or maximal) image element for each domain element in dom.
168*5971e316Smrg * Set *empty to those elements in dom that do not have an image element.
169*5971e316Smrg *
170*5971e316Smrg * Align parameters if needed and then call isl_map_partial_lexopt_aligned.
171*5971e316Smrg */
SF(isl_map_partial_lexopt,SUFFIX)172*5971e316Smrg static __isl_give TYPE *SF(isl_map_partial_lexopt,SUFFIX)(
173*5971e316Smrg __isl_take isl_map *map, __isl_take isl_set *dom,
174*5971e316Smrg __isl_give isl_set **empty, unsigned flags)
175*5971e316Smrg {
176*5971e316Smrg isl_bool aligned;
177*5971e316Smrg
178*5971e316Smrg aligned = isl_map_set_has_equal_params(map, dom);
179*5971e316Smrg if (aligned < 0)
180*5971e316Smrg goto error;
181*5971e316Smrg if (aligned)
182*5971e316Smrg return SF(isl_map_partial_lexopt_aligned,SUFFIX)(map, dom,
183*5971e316Smrg empty, flags);
184*5971e316Smrg if (!isl_space_has_named_params(map->dim) ||
185*5971e316Smrg !isl_space_has_named_params(dom->dim))
186*5971e316Smrg isl_die(map->ctx, isl_error_invalid,
187*5971e316Smrg "unaligned unnamed parameters", goto error);
188*5971e316Smrg map = isl_map_align_params(map, isl_map_get_space(dom));
189*5971e316Smrg dom = isl_map_align_params(dom, isl_map_get_space(map));
190*5971e316Smrg return SF(isl_map_partial_lexopt_aligned,SUFFIX)(map, dom, empty,
191*5971e316Smrg flags);
192*5971e316Smrg error:
193*5971e316Smrg if (empty)
194*5971e316Smrg *empty = NULL;
195*5971e316Smrg isl_set_free(dom);
196*5971e316Smrg isl_map_free(map);
197*5971e316Smrg return NULL;
198*5971e316Smrg }
199*5971e316Smrg
200*5971e316Smrg /* Compute the lexicographic minimum (or maximum if "flags" includes
201*5971e316Smrg * ISL_OPT_MAX) of "map" over its domain.
202*5971e316Smrg */
SF(isl_map_lexopt,SUFFIX)203*5971e316Smrg __isl_give TYPE *SF(isl_map_lexopt,SUFFIX)(__isl_take isl_map *map,
204*5971e316Smrg unsigned flags)
205*5971e316Smrg {
206*5971e316Smrg ISL_FL_SET(flags, ISL_OPT_FULL);
207*5971e316Smrg return SF(isl_map_partial_lexopt_aligned,SUFFIX)(map, NULL, NULL,
208*5971e316Smrg flags);
209*5971e316Smrg }
210*5971e316Smrg
SF(isl_map_lexmin,SUFFIX)211*5971e316Smrg __isl_give TYPE *SF(isl_map_lexmin,SUFFIX)(__isl_take isl_map *map)
212*5971e316Smrg {
213*5971e316Smrg return SF(isl_map_lexopt,SUFFIX)(map, 0);
214*5971e316Smrg }
215*5971e316Smrg
SF(isl_map_lexmax,SUFFIX)216*5971e316Smrg __isl_give TYPE *SF(isl_map_lexmax,SUFFIX)(__isl_take isl_map *map)
217*5971e316Smrg {
218*5971e316Smrg return SF(isl_map_lexopt,SUFFIX)(map, ISL_OPT_MAX);
219*5971e316Smrg }
220*5971e316Smrg
SF(isl_set_lexmin,SUFFIX)221*5971e316Smrg __isl_give TYPE *SF(isl_set_lexmin,SUFFIX)(__isl_take isl_set *set)
222*5971e316Smrg {
223*5971e316Smrg return SF(isl_map_lexmin,SUFFIX)(set);
224*5971e316Smrg }
225*5971e316Smrg
SF(isl_set_lexmax,SUFFIX)226*5971e316Smrg __isl_give TYPE *SF(isl_set_lexmax,SUFFIX)(__isl_take isl_set *set)
227*5971e316Smrg {
228*5971e316Smrg return SF(isl_map_lexmax,SUFFIX)(set);
229*5971e316Smrg }
230