Polly 19.0.0git
isl_box.c
Go to the documentation of this file.
1/*
2 * Copyright 2010-2011 INRIA Saclay
3 * Copyright 2012-2013 Ecole Normale Superieure
4 *
5 * Use of this software is governed by the MIT license
6 *
7 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
8 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
9 * 91893 Orsay, France
10 * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
11 */
12
13#include <isl/val.h>
14#include <isl/space.h>
15#include <isl_map_private.h>
16#include <isl_aff_private.h>
17#include <isl/constraint.h>
18#include <isl/ilp.h>
19#include <isl/fixed_box.h>
20
21/* Representation of a box of fixed size containing the elements
22 * [offset, offset + size).
23 * "size" lives in the target space of "offset".
24 *
25 * If any of the "offsets" is NaN, then the object represents
26 * the failure of finding a fixed-size box.
27 */
31};
32
33/* Free "box" and return NULL.
34 */
36{
37 if (!box)
38 return NULL;
39 isl_multi_aff_free(box->offset);
40 isl_multi_val_free(box->size);
41 free(box);
42 return NULL;
43}
44
45/* Construct an isl_fixed_box with the given offset and size.
46 */
49{
50 isl_ctx *ctx;
51 isl_fixed_box *box;
52
53 if (!offset || !size)
54 goto error;
55 ctx = isl_multi_aff_get_ctx(offset);
56 box = isl_alloc_type(ctx, struct isl_fixed_box);
57 if (!box)
58 goto error;
59 box->offset = offset;
60 box->size = size;
61
62 return box;
63error:
64 isl_multi_aff_free(offset);
65 isl_multi_val_free(size);
66 return NULL;
67}
68
69/* Construct an initial isl_fixed_box with zero offsets
70 * in the given space and zero corresponding sizes.
71 */
73 __isl_take isl_space *space)
74{
77
78 offset = isl_multi_aff_zero(isl_space_copy(space));
80 size = isl_multi_val_zero(space);
82}
83
84/* Return a copy of "box".
85 */
87{
90
94}
95
96/* Replace the offset and size in direction "pos" by "offset" and "size"
97 * (without checking whether "box" is a valid box).
98 */
102{
103 if (!box)
104 return NULL;
105 box->offset = isl_multi_aff_set_aff(box->offset, pos,
107 box->size = isl_multi_val_set_val(box->size, pos, isl_val_copy(size));
108 if (!box->offset || !box->size)
109 return isl_fixed_box_free(box);
110 return box;
111}
112
113/* Replace the offset and size in direction "pos" by "offset" and "size",
114 * if "box" is a valid box.
115 */
119{
120 isl_bool valid;
121
122 valid = isl_fixed_box_is_valid(box);
123 if (valid < 0 || !valid)
124 return box;
126}
127
128/* Replace "box" by an invalid box, by setting all offsets to NaN
129 * (and all sizes to infinity).
130 */
133{
134 int i;
135 isl_size n;
136 isl_space *space;
137 isl_val *infty;
138 isl_aff *nan;
139
140 if (!box)
141 return NULL;
142 n = isl_multi_val_dim(box->size, isl_dim_set);
143 if (n < 0)
144 return isl_fixed_box_free(box);
145
149 for (i = 0; i < n; ++i)
150 box = isl_fixed_box_set_extent(box, i, nan, infty);
151 isl_aff_free(nan);
152 isl_val_free(infty);
153
154 if (!box->offset || !box->size)
155 return isl_fixed_box_free(box);
156 return box;
157}
158
159/* Project the domain of the fixed box onto its parameter space.
160 * In particular, project out the domain of the offset.
161 */
164{
165 isl_bool valid;
166
167 valid = isl_fixed_box_is_valid(box);
168 if (valid < 0)
169 return isl_fixed_box_free(box);
170 if (!valid)
171 return box;
172
173 box->offset = isl_multi_aff_project_domain_on_params(box->offset);
174 if (!box->offset)
175 return isl_fixed_box_free(box);
176
177 return box;
178}
179
180/* Return the isl_ctx to which "box" belongs.
181 */
183{
184 if (!box)
185 return NULL;
186 return isl_multi_aff_get_ctx(box->offset);
187}
188
189/* Return the space in which "box" lives.
190 */
192{
193 if (!box)
194 return NULL;
195 return isl_multi_aff_get_space(box->offset);
196}
197
198/* Does "box" contain valid information?
199 */
201{
202 if (!box)
203 return isl_bool_error;
204 return isl_bool_not(isl_multi_aff_involves_nan(box->offset));
205}
206
207/* Return the offsets of the box "box".
208 */
211{
212 if (!box)
213 return NULL;
214 return isl_multi_aff_copy(box->offset);
215}
216
217/* Return the sizes of the box "box".
218 */
220{
221 if (!box)
222 return NULL;
223 return isl_multi_val_copy(box->size);
224}
225
226/* Data used in set_dim_extent and compute_size_in_direction.
227 *
228 * "bset" is a wrapped copy of the basic map that has the selected
229 * output dimension as range.
230 * "pos" is the position of the variable representing the output dimension,
231 * i.e., the variable for which the size should be computed. This variable
232 * is also the last variable in "bset".
233 * "size" is the best size found so far
234 * (infinity if no offset was found so far).
235 * "offset" is the offset corresponding to the best size
236 * (NULL if no offset was found so far).
237 */
243};
244
245/* Is "c" a suitable bound on dimension "pos" for use as a lower bound
246 * of a fixed-size range.
247 * In particular, it needs to be a lower bound on "pos".
248 * In order for the final offset not to be too complicated,
249 * the constraint itself should also not involve any integer divisions.
250 */
252{
253 isl_size n_div;
254 isl_bool is_bound, any_divs;
255
257 if (is_bound < 0 || !is_bound)
258 return is_bound;
259
261 if (n_div < 0)
262 return isl_bool_error;
263 any_divs = isl_constraint_involves_dims(c, isl_dim_div, 0, n_div);
264 return isl_bool_not(any_divs);
265}
266
267/* Given a constraint from the basic set describing the bounds on
268 * an array index, check if it is a lower bound, say m i >= b(x), and,
269 * if so, check whether the expression "i - ceil(b(x)/m) + 1" has a constant
270 * upper bound. If so, and if this bound is smaller than any bound
271 * derived from earlier constraints, set the size to this bound on
272 * the expression and the lower bound to ceil(b(x)/m).
273 */
275 void *user)
276{
277 struct isl_size_info *info = user;
278 isl_val *v;
279 isl_aff *aff;
280 isl_aff *lb;
281 isl_bool is_bound, better;
282
283 is_bound = is_suitable_bound(c, info->pos);
284 if (is_bound < 0 || !is_bound) {
286 return is_bound < 0 ? isl_stat_error : isl_stat_ok;
287 }
288
291
292 lb = isl_aff_copy(aff);
293
296
297 v = isl_basic_set_max_val(info->bset, aff);
299
300 v = isl_val_add_ui(v, 1);
301 better = isl_val_lt(v, info->size);
302 if (better >= 0 && better) {
303 isl_val_free(info->size);
304 info->size = isl_val_copy(v);
306 isl_aff_free(info->offset);
307 info->offset = isl_aff_copy(lb);
308 }
309 isl_val_free(v);
310 isl_aff_free(lb);
311
313
314 return better < 0 ? isl_stat_error : isl_stat_ok;
315}
316
317/* Look for a fixed-size range of values for the output dimension "pos"
318 * of "map", by looking for a lower-bound expression in the parameters
319 * and input dimensions such that the range of the output dimension
320 * is a constant shifted by this expression.
321 *
322 * In particular, look through the explicit lower bounds on the output dimension
323 * for candidate expressions and pick the one that results in the smallest size.
324 * Initialize the size with infinity and if no better size is found
325 * then invalidate the box. Otherwise, set the offset and size
326 * in the given direction by those that correspond to the smallest size.
327 *
328 * Note that while evaluating the size corresponding to a lower bound,
329 * an affine expression is constructed from the lower bound.
330 * This lower bound may therefore not have any unknown local variables.
331 * Eliminate any unknown local variables up front.
332 * No such restriction needs to be imposed on the set over which
333 * the size is computed.
334 */
337{
338 struct isl_size_info info;
339 isl_bool valid;
340 isl_ctx *ctx;
342
343 if (!box || !map)
344 return isl_fixed_box_free(box);
345
346 ctx = isl_map_get_ctx(map);
349 info.size = isl_val_infty(ctx);
350 info.offset = NULL;
351 info.pos = isl_map_dim(map, isl_dim_in);
355 if (info.pos < 0)
358 &compute_size_in_direction, &info) < 0)
359 box = isl_fixed_box_free(box);
361 valid = isl_val_is_int(info.size);
362 if (valid < 0)
363 box = isl_fixed_box_free(box);
364 else if (valid)
366 info.offset, info.size);
367 else
368 box = isl_fixed_box_invalidate(box);
369 isl_val_free(info.size);
370 isl_aff_free(info.offset);
372
373 return box;
374}
375
376/* Try and construct a fixed-size rectangular box with an offset
377 * in terms of the domain of "map" that contains the range of "map".
378 * If no such box can be constructed, then return an invalidated box,
379 * i.e., one where isl_fixed_box_is_valid returns false.
380 *
381 * Iterate over the dimensions in the range
382 * setting the corresponding offset and extent.
383 */
386{
387 int i;
388 isl_size n;
389 isl_space *space;
390 isl_fixed_box *box;
391
393 if (n < 0)
394 return NULL;
395 space = isl_map_get_space(map);
396 box = isl_fixed_box_init(space);
397
399 for (i = 0; i < n; ++i) {
400 isl_bool valid;
401
402 box = set_dim_extent(box, map, i);
403 valid = isl_fixed_box_is_valid(box);
404 if (valid < 0 || !valid)
405 break;
406 }
408
409 return box;
410}
411
412/* Compute a fixed box from "set" using "map_box" by treating it as a map
413 * with a zero-dimensional domain and
414 * project out the domain again from the result.
415 */
418{
419 isl_map *map;
420 isl_fixed_box *box;
421
423 box = map_box(map);
426
427 return box;
428}
429
430/* Try and construct a fixed-size rectangular box with an offset
431 * in terms of the parameters of "set" that contains "set".
432 * If no such box can be constructed, then return an invalidated box,
433 * i.e., one where isl_fixed_box_is_valid returns false.
434 *
435 * Compute the box using isl_map_get_range_simple_fixed_box_hull
436 * by constructing a map from the set and
437 * project out the domain again from the result.
438 */
441{
443}
444
445/* Check whether the output elements lie on a rectangular lattice,
446 * possibly depending on the parameters and the input dimensions.
447 * Return a tile in this lattice.
448 * If no stride information can be found, then return a tile of size 1
449 * (and offset 0).
450 *
451 * Obtain stride information in each output dimension separately and
452 * combine the results.
453 */
456{
457 int i;
458 isl_size n;
459 isl_space *space;
460 isl_fixed_box *box;
461
463 if (n < 0)
464 return NULL;
465 space = isl_map_get_space(map);
466 box = isl_fixed_box_init(space);
467
468 for (i = 0; i < n; ++i) {
469 isl_val *stride;
471 isl_stride_info *si;
472
474 stride = isl_stride_info_get_stride(si);
477
478 box = isl_fixed_box_set_valid_extent(box, i, offset, stride);
479
481 isl_val_free(stride);
482 }
483
484 return box;
485}
486
487/* Check whether the elements lie on a rectangular lattice,
488 * possibly depending on the parameters.
489 * Return a tile in this lattice.
490 * If no stride information can be found, then return a tile of size 1
491 * (and offset 0).
492 *
493 * Consider the set as a map with a zero-dimensional domain and
494 * obtain a lattice tile of that map.
495 */
497{
499}
500
501#undef BASE
502#define BASE multi_val
504
505#undef BASE
506#define BASE multi_aff
508
509/* Print the information contained in "box" to "p".
510 * The information is printed as a YAML document.
511 */
514{
515 if (!box)
516 return isl_printer_free(p);
517
519 p = print_yaml_field_multi_aff(p, "offset", box->offset);
520 p = print_yaml_field_multi_val(p, "size", box->size);
522
523 return p;
524}
525
526#undef BASE
527#define BASE fixed_box
528#include <print_templ_yaml.c>
__isl_null isl_aff * isl_aff_free(__isl_take isl_aff *aff)
Definition: isl_aff.c:390
__isl_give isl_aff * isl_aff_nan_on_domain(__isl_take isl_local_space *ls)
Definition: isl_aff.c:232
__isl_export __isl_give isl_aff * isl_aff_neg(__isl_take isl_aff *aff)
Definition: isl_aff.c:1378
__isl_give isl_aff * isl_aff_copy(__isl_keep isl_aff *aff)
Definition: isl_aff.c:145
__isl_give isl_aff * isl_aff_add_coefficient_si(__isl_take isl_aff *aff, enum isl_dim_type type, int pos, int v)
Definition: isl_aff.c:1353
__isl_export __isl_give isl_aff * isl_aff_ceil(__isl_take isl_aff *aff)
Definition: isl_aff.c:1793
struct isl_multi_aff isl_multi_aff
Definition: aff_type.h:29
isl_size isl_constraint_dim(__isl_keep isl_constraint *constraint, enum isl_dim_type type)
__isl_give isl_aff * isl_constraint_get_bound(__isl_keep isl_constraint *constraint, enum isl_dim_type type, int pos)
__isl_null isl_constraint * isl_constraint_free(__isl_take isl_constraint *c)
isl_bool isl_constraint_involves_dims(__isl_keep isl_constraint *constraint, enum isl_dim_type type, unsigned first, unsigned n)
isl_bool isl_constraint_is_lower_bound(__isl_keep isl_constraint *constraint, enum isl_dim_type type, unsigned pos)
isl_stat isl_basic_set_foreach_constraint(__isl_keep isl_basic_set *bset, isl_stat(*fn)(__isl_take isl_constraint *c, void *user), void *user)
#define __isl_take
Definition: ctx.h:22
isl_stat
Definition: ctx.h:84
@ isl_stat_error
Definition: ctx.h:85
@ isl_stat_ok
Definition: ctx.h:86
#define __isl_give
Definition: ctx.h:19
#define __isl_null
Definition: ctx.h:28
#define __isl_keep
Definition: ctx.h:25
int isl_size
Definition: ctx.h:96
#define isl_alloc_type(ctx, type)
Definition: ctx.h:128
isl_bool isl_bool_not(isl_bool b)
Definition: isl_ctx.c:32
isl_bool
Definition: ctx.h:89
@ isl_bool_error
Definition: ctx.h:90
isl_stat isl_stat(*) void user)
Definition: hmap.h:39
__isl_give isl_val * isl_basic_set_max_val(__isl_keep isl_basic_set *bset, __isl_keep isl_aff *obj)
Definition: isl_ilp.c:562
__isl_give isl_aff * isl_aff_domain_factor_domain(__isl_take isl_aff *aff)
__isl_give isl_fixed_box * isl_set_get_lattice_tile(__isl_keep isl_set *set)
Definition: isl_box.c:496
static __isl_give isl_fixed_box * isl_fixed_box_set_extent(__isl_take isl_fixed_box *box, int pos, __isl_keep isl_aff *offset, __isl_keep isl_val *size)
Definition: isl_box.c:99
__isl_give isl_fixed_box * isl_set_get_simple_fixed_box_hull(__isl_keep isl_set *set)
Definition: isl_box.c:439
static isl_stat compute_size_in_direction(__isl_take isl_constraint *c, void *user)
Definition: isl_box.c:274
isl_ctx * isl_fixed_box_get_ctx(__isl_keep isl_fixed_box *box)
Definition: isl_box.c:182
static isl_bool is_suitable_bound(__isl_keep isl_constraint *c, unsigned pos)
Definition: isl_box.c:251
static __isl_give isl_fixed_box * isl_fixed_box_init(__isl_take isl_space *space)
Definition: isl_box.c:72
__isl_give isl_fixed_box * isl_map_get_range_lattice_tile(__isl_keep isl_map *map)
Definition: isl_box.c:454
__isl_give isl_fixed_box * isl_fixed_box_copy(__isl_keep isl_fixed_box *box)
Definition: isl_box.c:86
__isl_give isl_fixed_box * isl_map_get_range_simple_fixed_box_hull(__isl_keep isl_map *map)
Definition: isl_box.c:384
static __isl_give isl_fixed_box * set_dim_extent(__isl_take isl_fixed_box *box, __isl_keep isl_map *map, int pos)
Definition: isl_box.c:335
__isl_give isl_multi_val * isl_fixed_box_get_size(__isl_keep isl_fixed_box *box)
Definition: isl_box.c:219
__isl_give isl_printer * isl_printer_print_fixed_box(__isl_take isl_printer *p, __isl_keep isl_fixed_box *box)
Definition: isl_box.c:512
__isl_give isl_multi_aff * isl_fixed_box_get_offset(__isl_keep isl_fixed_box *box)
Definition: isl_box.c:209
static __isl_give isl_fixed_box * isl_fixed_box_alloc(__isl_take isl_multi_aff *offset, __isl_take isl_multi_val *size)
Definition: isl_box.c:47
__isl_null isl_fixed_box * isl_fixed_box_free(__isl_take isl_fixed_box *box)
Definition: isl_box.c:35
__isl_give isl_space * isl_fixed_box_get_space(__isl_keep isl_fixed_box *box)
Definition: isl_box.c:191
static __isl_give isl_fixed_box * fixed_box_as_map(__isl_keep isl_set *set, __isl_give isl_fixed_box *(*map_box)(__isl_keep isl_map *map))
Definition: isl_box.c:416
static __isl_give isl_fixed_box * isl_fixed_box_project_domain_on_params(__isl_take isl_fixed_box *box)
Definition: isl_box.c:162
static __isl_give isl_fixed_box * isl_fixed_box_invalidate(__isl_take isl_fixed_box *box)
Definition: isl_box.c:131
isl_bool isl_fixed_box_is_valid(__isl_keep isl_fixed_box *box)
Definition: isl_box.c:200
static __isl_give isl_fixed_box * isl_fixed_box_set_valid_extent(__isl_take isl_fixed_box *box, int pos, __isl_keep isl_aff *offset, __isl_keep isl_val *size)
Definition: isl_box.c:116
static int is_bound(struct sh_data *data, __isl_keep isl_set *set, int j, isl_int *ineq, int shift)
__isl_give isl_map * isl_map_project_onto(__isl_take isl_map *map, enum isl_dim_type type, unsigned first, unsigned n)
Definition: isl_map.c:4623
static unsigned pos(__isl_keep isl_space *space, enum isl_dim_type type)
Definition: isl_map.c:70
const char * set
Definition: isl_test.c:1356
const char * map
Definition: isl_test.c:1783
const char * p
Definition: isl_test.c:8643
const char * offset
Definition: isl_test.c:1569
const char * aff
Definition: isl_test.c:7278
const char * size
Definition: isl_test.c:1570
__isl_give isl_local_space * isl_local_space_from_space(__isl_take isl_space *space)
__isl_export __isl_give isl_map * isl_map_detect_equalities(__isl_take isl_map *map)
__isl_give isl_map * isl_map_copy(__isl_keep isl_map *map)
Definition: isl_map.c:1494
__isl_export __isl_give isl_space * isl_map_get_space(__isl_keep isl_map *map)
Definition: isl_map.c:598
isl_ctx * isl_map_get_ctx(__isl_keep isl_map *map)
Definition: isl_map.c:391
isl_size isl_map_dim(__isl_keep isl_map *map, enum isl_dim_type type)
Definition: isl_map.c:110
__isl_give isl_map * isl_map_from_range(__isl_take isl_set *set)
Definition: isl_map.c:6204
__isl_give isl_basic_set * isl_basic_map_wrap(__isl_take isl_basic_map *bmap)
Definition: isl_map.c:12198
__isl_null isl_map * isl_map_free(__isl_take isl_map *map)
Definition: isl_map.c:6421
__isl_give isl_stride_info * isl_map_get_range_stride_info(__isl_keep isl_map *map, int pos)
Definition: isl_stride.c:368
__isl_give isl_basic_map * isl_map_simple_hull(__isl_take isl_map *map)
struct isl_set isl_set
Definition: map_type.h:26
struct isl_basic_set isl_basic_set
Definition: map_type.h:20
__isl_give isl_printer * isl_printer_yaml_start_mapping(__isl_take isl_printer *p)
Definition: isl_printer.c:707
__isl_null isl_printer * isl_printer_free(__isl_take isl_printer *printer)
Definition: isl_printer.c:269
__isl_give isl_printer * isl_printer_yaml_end_mapping(__isl_take isl_printer *p)
Definition: isl_printer.c:740
__isl_null isl_basic_set * isl_basic_set_free(__isl_take isl_basic_set *bset)
Definition: isl_map.c:1523
__isl_give isl_set * isl_set_copy(__isl_keep isl_set *set)
Definition: isl_map.c:1470
__isl_give isl_basic_set * isl_basic_set_copy(__isl_keep isl_basic_set *bset)
Definition: isl_map.c:1465
__isl_give isl_basic_set * isl_basic_set_remove_unknown_divs(__isl_take isl_basic_set *bset)
Definition: isl_map.c:3284
__isl_give isl_space * isl_space_copy(__isl_keep isl_space *space)
Definition: isl_space.c:436
__isl_export __isl_give isl_space * isl_space_range(__isl_take isl_space *space)
Definition: isl_space.c:2163
__isl_give isl_space * isl_space_drop_all_params(__isl_take isl_space *space)
Definition: isl_space.c:2128
__isl_export __isl_give isl_space * isl_space_domain(__isl_take isl_space *space)
Definition: isl_space.c:2138
@ isl_dim_in
Definition: space_type.h:16
@ isl_dim_set
Definition: space_type.h:18
@ isl_dim_div
Definition: space_type.h:19
@ isl_dim_out
Definition: space_type.h:17
__isl_null isl_stride_info * isl_stride_info_free(__isl_take isl_stride_info *si)
Definition: isl_stride.c:37
__isl_give isl_aff * isl_stride_info_get_offset(__isl_keep isl_stride_info *si)
Definition: isl_stride.c:92
__isl_give isl_val * isl_stride_info_get_stride(__isl_keep isl_stride_info *si)
Definition: isl_stride.c:83
isl_multi_val * size
Definition: isl_box.c:30
isl_multi_aff * offset
Definition: isl_box.c:29
isl_aff * offset
Definition: isl_box.c:242
isl_size pos
Definition: isl_box.c:240
isl_basic_set * bset
Definition: isl_box.c:239
isl_val * size
Definition: isl_box.c:241
__isl_export isl_bool isl_val_lt(__isl_keep isl_val *v1, __isl_keep isl_val *v2)
Definition: isl_val.c:1285
__isl_give isl_val * isl_val_copy(__isl_keep isl_val *v)
Definition: isl_val.c:219
__isl_give isl_val * isl_val_add_ui(__isl_take isl_val *v1, unsigned long v2)
Definition: isl_val.c:685
__isl_export __isl_give isl_val * isl_val_infty(isl_ctx *ctx)
Definition: isl_val.c:96
__isl_null isl_val * isl_val_free(__isl_take isl_val *v)
Definition: isl_val.c:263
__isl_export isl_bool isl_val_is_int(__isl_keep isl_val *v)
Definition: isl_val.c:1141
struct isl_multi_val isl_multi_val
Definition: val_type.h:16
n
Definition: youcefn.c:8