xref: /netbsd-src/external/mit/isl/dist/isl_map_lexopt_templ.c (revision 5971e316fdea024efff6be8f03536623db06833e)
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