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