/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/polly/lib/External/isl/isl_point.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include <isl_map_private.h> |
2 | | #include <isl_point_private.h> |
3 | | #include <isl/set.h> |
4 | | #include <isl/union_set.h> |
5 | | #include <isl_sample.h> |
6 | | #include <isl_scan.h> |
7 | | #include <isl_seq.h> |
8 | | #include <isl_space_private.h> |
9 | | #include <isl_val_private.h> |
10 | | #include <isl_vec_private.h> |
11 | | #include <isl_output_private.h> |
12 | | |
13 | | #include <set_to_map.c> |
14 | | |
15 | | isl_ctx *isl_point_get_ctx(__isl_keep isl_point *pnt) |
16 | 27 | { |
17 | 27 | return pnt ? isl_space_get_ctx(pnt->dim) : NULL; |
18 | 27 | } |
19 | | |
20 | | /* Return the space of "pnt". |
21 | | */ |
22 | | __isl_keep isl_space *isl_point_peek_space(__isl_keep isl_point *pnt) |
23 | 81 | { |
24 | 81 | return pnt ? pnt->dim : NULL; |
25 | 81 | } |
26 | | |
27 | | __isl_give isl_space *isl_point_get_space(__isl_keep isl_point *pnt) |
28 | 19 | { |
29 | 19 | return isl_space_copy(isl_point_peek_space(pnt)); |
30 | 19 | } |
31 | | |
32 | | __isl_give isl_point *isl_point_alloc(__isl_take isl_space *dim, |
33 | | __isl_take isl_vec *vec) |
34 | 449 | { |
35 | 449 | struct isl_point *pnt; |
36 | 449 | |
37 | 449 | if (!dim || !vec) |
38 | 0 | goto error; |
39 | 449 | |
40 | 449 | if (vec->size > 1 + isl_space_dim(dim, isl_dim_all)) { |
41 | 0 | vec = isl_vec_cow(vec); |
42 | 0 | if (!vec) |
43 | 0 | goto error; |
44 | 0 | vec->size = 1 + isl_space_dim(dim, isl_dim_all); |
45 | 0 | } |
46 | 449 | |
47 | 449 | pnt = isl_alloc_type(dim->ctx, struct isl_point); |
48 | 449 | if (!pnt) |
49 | 0 | goto error; |
50 | 449 | |
51 | 449 | pnt->ref = 1; |
52 | 449 | pnt->dim = dim; |
53 | 449 | pnt->vec = vec; |
54 | 449 | |
55 | 449 | return pnt; |
56 | 0 | error: |
57 | 0 | isl_space_free(dim); |
58 | 0 | isl_vec_free(vec); |
59 | 0 | return NULL; |
60 | 449 | } |
61 | | |
62 | | __isl_give isl_point *isl_point_zero(__isl_take isl_space *dim) |
63 | 1 | { |
64 | 1 | isl_vec *vec; |
65 | 1 | |
66 | 1 | if (!dim) |
67 | 0 | return NULL; |
68 | 1 | vec = isl_vec_alloc(dim->ctx, 1 + isl_space_dim(dim, isl_dim_all)); |
69 | 1 | if (!vec) |
70 | 0 | goto error; |
71 | 1 | isl_int_set_si(vec->el[0], 1); |
72 | 1 | isl_seq_clr(vec->el + 1, vec->size - 1); |
73 | 1 | return isl_point_alloc(dim, vec); |
74 | 0 | error: |
75 | 0 | isl_space_free(dim); |
76 | 0 | return NULL; |
77 | 1 | } |
78 | | |
79 | | __isl_give isl_point *isl_point_dup(__isl_keep isl_point *pnt) |
80 | 19 | { |
81 | 19 | struct isl_point *pnt2; |
82 | 19 | |
83 | 19 | if (!pnt) |
84 | 0 | return NULL; |
85 | 19 | pnt2 = isl_point_alloc(isl_space_copy(pnt->dim), isl_vec_copy(pnt->vec)); |
86 | 19 | return pnt2; |
87 | 19 | } |
88 | | |
89 | | __isl_give isl_point *isl_point_cow(__isl_take isl_point *pnt) |
90 | 31 | { |
91 | 31 | struct isl_point *pnt2; |
92 | 31 | if (!pnt) |
93 | 0 | return NULL; |
94 | 31 | |
95 | 31 | if (pnt->ref == 1) |
96 | 12 | return pnt; |
97 | 19 | |
98 | 19 | pnt2 = isl_point_dup(pnt); |
99 | 19 | isl_point_free(pnt); |
100 | 19 | return pnt2; |
101 | 19 | } |
102 | | |
103 | | __isl_give isl_point *isl_point_copy(__isl_keep isl_point *pnt) |
104 | 20 | { |
105 | 20 | if (!pnt) |
106 | 0 | return NULL; |
107 | 20 | |
108 | 20 | pnt->ref++; |
109 | 20 | return pnt; |
110 | 20 | } |
111 | | |
112 | | __isl_null isl_point *isl_point_free(__isl_take isl_point *pnt) |
113 | 469 | { |
114 | 469 | if (!pnt) |
115 | 0 | return NULL; |
116 | 469 | |
117 | 469 | if (--pnt->ref > 0) |
118 | 20 | return NULL; |
119 | 449 | |
120 | 449 | isl_space_free(pnt->dim); |
121 | 449 | isl_vec_free(pnt->vec); |
122 | 449 | free(pnt); |
123 | 449 | return NULL; |
124 | 449 | } |
125 | | |
126 | | __isl_give isl_point *isl_point_void(__isl_take isl_space *dim) |
127 | 3 | { |
128 | 3 | if (!dim) |
129 | 0 | return NULL; |
130 | 3 | |
131 | 3 | return isl_point_alloc(dim, isl_vec_alloc(dim->ctx, 0)); |
132 | 3 | } |
133 | | |
134 | | isl_bool isl_point_is_void(__isl_keep isl_point *pnt) |
135 | 68 | { |
136 | 68 | if (!pnt) |
137 | 0 | return isl_bool_error; |
138 | 68 | |
139 | 68 | return pnt->vec->size == 0; |
140 | 68 | } |
141 | | |
142 | | /* Return the space of "pnt". |
143 | | * This may be either a copy or the space itself |
144 | | * if there is only one reference to "pnt". |
145 | | * This allows the space to be modified inplace |
146 | | * if both the point and its space have only a single reference. |
147 | | * The caller is not allowed to modify "pnt" between this call and |
148 | | * a subsequent call to isl_point_restore_space. |
149 | | * The only exception is that isl_point_free can be called instead. |
150 | | */ |
151 | | __isl_give isl_space *isl_point_take_space(__isl_keep isl_point *pnt) |
152 | 19 | { |
153 | 19 | isl_space *space; |
154 | 19 | |
155 | 19 | if (!pnt) |
156 | 0 | return NULL; |
157 | 19 | if (pnt->ref != 1) |
158 | 19 | return isl_point_get_space(pnt); |
159 | 0 | space = pnt->dim; |
160 | 0 | pnt->dim = NULL; |
161 | 0 | return space; |
162 | 0 | } |
163 | | |
164 | | /* Set the space of "pnt" to "space", where the space of "pnt" may be missing |
165 | | * due to a preceding call to isl_point_take_space. |
166 | | * However, in this case, "pnt" only has a single reference and |
167 | | * then the call to isl_point_cow has no effect. |
168 | | */ |
169 | | __isl_give isl_point *isl_point_restore_space(__isl_take isl_point *pnt, |
170 | | __isl_take isl_space *space) |
171 | 19 | { |
172 | 19 | if (!pnt || !space) |
173 | 0 | goto error; |
174 | 19 | |
175 | 19 | if (pnt->dim == space) { |
176 | 0 | isl_space_free(space); |
177 | 0 | return pnt; |
178 | 0 | } |
179 | 19 | |
180 | 19 | pnt = isl_point_cow(pnt); |
181 | 19 | if (!pnt) |
182 | 0 | goto error; |
183 | 19 | isl_space_free(pnt->dim); |
184 | 19 | pnt->dim = space; |
185 | 19 | |
186 | 19 | return pnt; |
187 | 0 | error: |
188 | 0 | isl_point_free(pnt); |
189 | 0 | isl_space_free(space); |
190 | 0 | return NULL; |
191 | 19 | } |
192 | | |
193 | | /* Return the coordinate vector of "pnt". |
194 | | */ |
195 | | __isl_keep isl_vec *isl_point_peek_vec(__isl_keep isl_point *pnt) |
196 | 38 | { |
197 | 38 | return pnt ? pnt->vec : NULL; |
198 | 38 | } |
199 | | |
200 | | /* Return a copy of the coordinate vector of "pnt". |
201 | | */ |
202 | | __isl_give isl_vec *isl_point_get_vec(__isl_keep isl_point *pnt) |
203 | 19 | { |
204 | 19 | return isl_vec_copy(isl_point_peek_vec(pnt)); |
205 | 19 | } |
206 | | |
207 | | /* Return the coordinate vector of "pnt". |
208 | | * This may be either a copy or the coordinate vector itself |
209 | | * if there is only one reference to "pnt". |
210 | | * This allows the coordinate vector to be modified inplace |
211 | | * if both the point and its coordinate vector have only a single reference. |
212 | | * The caller is not allowed to modify "pnt" between this call and |
213 | | * a subsequent call to isl_point_restore_vec. |
214 | | * The only exception is that isl_point_free can be called instead. |
215 | | */ |
216 | | __isl_give isl_vec *isl_point_take_vec(__isl_keep isl_point *pnt) |
217 | 19 | { |
218 | 19 | isl_vec *vec; |
219 | 19 | |
220 | 19 | if (!pnt) |
221 | 0 | return NULL; |
222 | 19 | if (pnt->ref != 1) |
223 | 19 | return isl_point_get_vec(pnt); |
224 | 0 | vec = pnt->vec; |
225 | 0 | pnt->vec = NULL; |
226 | 0 | return vec; |
227 | 0 | } |
228 | | |
229 | | /* Set the coordinate vector of "pnt" to "vec", |
230 | | * where the coordinate vector of "pnt" may be missing |
231 | | * due to a preceding call to isl_point_take_vec. |
232 | | * However, in this case, "pnt" only has a single reference and |
233 | | * then the call to isl_point_cow has no effect. |
234 | | */ |
235 | | __isl_give isl_point *isl_point_restore_vec(__isl_take isl_point *pnt, |
236 | | __isl_take isl_vec *vec) |
237 | 19 | { |
238 | 19 | if (!pnt || !vec) |
239 | 0 | goto error; |
240 | 19 | |
241 | 19 | if (pnt->vec == vec) { |
242 | 7 | isl_vec_free(vec); |
243 | 7 | return pnt; |
244 | 7 | } |
245 | 12 | |
246 | 12 | pnt = isl_point_cow(pnt); |
247 | 12 | if (!pnt) |
248 | 0 | goto error; |
249 | 12 | isl_vec_free(pnt->vec); |
250 | 12 | pnt->vec = vec; |
251 | 12 | |
252 | 12 | return pnt; |
253 | 0 | error: |
254 | 0 | isl_point_free(pnt); |
255 | 0 | isl_vec_free(vec); |
256 | 0 | return NULL; |
257 | 12 | } |
258 | | |
259 | | /* Return the value of coordinate "pos" of type "type" of "pnt". |
260 | | */ |
261 | | __isl_give isl_val *isl_point_get_coordinate_val(__isl_keep isl_point *pnt, |
262 | | enum isl_dim_type type, int pos) |
263 | 0 | { |
264 | 0 | isl_ctx *ctx; |
265 | 0 | isl_val *v; |
266 | 0 |
|
267 | 0 | if (!pnt) |
268 | 0 | return NULL; |
269 | 0 | |
270 | 0 | ctx = isl_point_get_ctx(pnt); |
271 | 0 | if (isl_point_is_void(pnt)) |
272 | 0 | isl_die(ctx, isl_error_invalid, |
273 | 0 | "void point does not have coordinates", return NULL); |
274 | 0 | if (pos < 0 || pos >= isl_space_dim(pnt->dim, type)) |
275 | 0 | isl_die(ctx, isl_error_invalid, |
276 | 0 | "position out of bounds", return NULL); |
277 | 0 |
|
278 | 0 | if (type == isl_dim_set) |
279 | 0 | pos += isl_space_dim(pnt->dim, isl_dim_param); |
280 | 0 |
|
281 | 0 | v = isl_val_rat_from_isl_int(ctx, pnt->vec->el[1 + pos], |
282 | 0 | pnt->vec->el[0]); |
283 | 0 | return isl_val_normalize(v); |
284 | 0 | } |
285 | | |
286 | | /* Replace coordinate "pos" of type "type" of "pnt" by "v". |
287 | | */ |
288 | | __isl_give isl_point *isl_point_set_coordinate_val(__isl_take isl_point *pnt, |
289 | | enum isl_dim_type type, int pos, __isl_take isl_val *v) |
290 | 0 | { |
291 | 0 | if (!pnt || !v) |
292 | 0 | goto error; |
293 | 0 | if (isl_point_is_void(pnt)) |
294 | 0 | isl_die(isl_point_get_ctx(pnt), isl_error_invalid, |
295 | 0 | "void point does not have coordinates", goto error); |
296 | 0 | if (pos < 0 || pos >= isl_space_dim(pnt->dim, type)) |
297 | 0 | isl_die(isl_point_get_ctx(pnt), isl_error_invalid, |
298 | 0 | "position out of bounds", goto error); |
299 | 0 | if (!isl_val_is_rat(v)) |
300 | 0 | isl_die(isl_point_get_ctx(pnt), isl_error_invalid, |
301 | 0 | "expecting rational value", goto error); |
302 | 0 |
|
303 | 0 | if (isl_int_eq(pnt->vec->el[1 + pos], v->n) && |
304 | 0 | isl_int_eq(pnt->vec->el[0], v->d)) { |
305 | 0 | isl_val_free(v); |
306 | 0 | return pnt; |
307 | 0 | } |
308 | 0 | |
309 | 0 | pnt = isl_point_cow(pnt); |
310 | 0 | if (!pnt) |
311 | 0 | goto error; |
312 | 0 | pnt->vec = isl_vec_cow(pnt->vec); |
313 | 0 | if (!pnt->vec) |
314 | 0 | goto error; |
315 | 0 | |
316 | 0 | if (isl_int_eq(pnt->vec->el[0], v->d)) { |
317 | 0 | isl_int_set(pnt->vec->el[1 + pos], v->n); |
318 | 0 | } else if (isl_int_is_one(v->d)) { |
319 | 0 | isl_int_mul(pnt->vec->el[1 + pos], pnt->vec->el[0], v->n); |
320 | 0 | } else { |
321 | 0 | isl_seq_scale(pnt->vec->el + 1, |
322 | 0 | pnt->vec->el + 1, v->d, pnt->vec->size - 1); |
323 | 0 | isl_int_mul(pnt->vec->el[1 + pos], pnt->vec->el[0], v->n); |
324 | 0 | isl_int_mul(pnt->vec->el[0], pnt->vec->el[0], v->d); |
325 | 0 | pnt->vec = isl_vec_normalize(pnt->vec); |
326 | 0 | if (!pnt->vec) |
327 | 0 | goto error; |
328 | 0 | } |
329 | 0 | |
330 | 0 | isl_val_free(v); |
331 | 0 | return pnt; |
332 | 0 | error: |
333 | 0 | isl_val_free(v); |
334 | 0 | isl_point_free(pnt); |
335 | 0 | return NULL; |
336 | 0 | } |
337 | | |
338 | | __isl_give isl_point *isl_point_add_ui(__isl_take isl_point *pnt, |
339 | | enum isl_dim_type type, int pos, unsigned val) |
340 | 0 | { |
341 | 0 | if (!pnt || isl_point_is_void(pnt)) |
342 | 0 | return pnt; |
343 | 0 | |
344 | 0 | pnt = isl_point_cow(pnt); |
345 | 0 | if (!pnt) |
346 | 0 | return NULL; |
347 | 0 | pnt->vec = isl_vec_cow(pnt->vec); |
348 | 0 | if (!pnt->vec) |
349 | 0 | goto error; |
350 | 0 | |
351 | 0 | if (type == isl_dim_set) |
352 | 0 | pos += isl_space_dim(pnt->dim, isl_dim_param); |
353 | 0 |
|
354 | 0 | isl_int_add_ui(pnt->vec->el[1 + pos], pnt->vec->el[1 + pos], val); |
355 | 0 |
|
356 | 0 | return pnt; |
357 | 0 | error: |
358 | 0 | isl_point_free(pnt); |
359 | 0 | return NULL; |
360 | 0 | } |
361 | | |
362 | | __isl_give isl_point *isl_point_sub_ui(__isl_take isl_point *pnt, |
363 | | enum isl_dim_type type, int pos, unsigned val) |
364 | 0 | { |
365 | 0 | if (!pnt || isl_point_is_void(pnt)) |
366 | 0 | return pnt; |
367 | 0 | |
368 | 0 | pnt = isl_point_cow(pnt); |
369 | 0 | if (!pnt) |
370 | 0 | return NULL; |
371 | 0 | pnt->vec = isl_vec_cow(pnt->vec); |
372 | 0 | if (!pnt->vec) |
373 | 0 | goto error; |
374 | 0 | |
375 | 0 | if (type == isl_dim_set) |
376 | 0 | pos += isl_space_dim(pnt->dim, isl_dim_param); |
377 | 0 |
|
378 | 0 | isl_int_sub_ui(pnt->vec->el[1 + pos], pnt->vec->el[1 + pos], val); |
379 | 0 |
|
380 | 0 | return pnt; |
381 | 0 | error: |
382 | 0 | isl_point_free(pnt); |
383 | 0 | return NULL; |
384 | 0 | } |
385 | | |
386 | | struct isl_foreach_point { |
387 | | struct isl_scan_callback callback; |
388 | | isl_stat (*fn)(__isl_take isl_point *pnt, void *user); |
389 | | void *user; |
390 | | isl_space *dim; |
391 | | }; |
392 | | |
393 | | static isl_stat foreach_point(struct isl_scan_callback *cb, |
394 | | __isl_take isl_vec *sample) |
395 | 0 | { |
396 | 0 | struct isl_foreach_point *fp = (struct isl_foreach_point *)cb; |
397 | 0 | isl_point *pnt; |
398 | 0 |
|
399 | 0 | pnt = isl_point_alloc(isl_space_copy(fp->dim), sample); |
400 | 0 |
|
401 | 0 | return fp->fn(pnt, fp->user); |
402 | 0 | } |
403 | | |
404 | | isl_stat isl_set_foreach_point(__isl_keep isl_set *set, |
405 | | isl_stat (*fn)(__isl_take isl_point *pnt, void *user), void *user) |
406 | 84 | { |
407 | 84 | struct isl_foreach_point fp = { { &foreach_point }, fn, user }; |
408 | 84 | int i; |
409 | 84 | |
410 | 84 | if (!set) |
411 | 0 | return isl_stat_error; |
412 | 84 | |
413 | 84 | fp.dim = isl_set_get_space(set); |
414 | 84 | if (!fp.dim) |
415 | 0 | return isl_stat_error; |
416 | 84 | |
417 | 84 | set = isl_set_copy(set); |
418 | 84 | set = isl_set_cow(set); |
419 | 84 | set = isl_set_make_disjoint(set); |
420 | 84 | set = isl_set_compute_divs(set); |
421 | 84 | if (!set) |
422 | 0 | goto error; |
423 | 84 | |
424 | 84 | for (i = 0; i < set->n; ++i0 ) |
425 | 0 | if (isl_basic_set_scan(isl_basic_set_copy(set->p[i]), |
426 | 0 | &fp.callback) < 0) |
427 | 0 | goto error; |
428 | 84 | |
429 | 84 | isl_set_free(set); |
430 | 84 | isl_space_free(fp.dim); |
431 | 84 | |
432 | 84 | return isl_stat_ok; |
433 | 0 | error: |
434 | 0 | isl_set_free(set); |
435 | 0 | isl_space_free(fp.dim); |
436 | 0 | return isl_stat_error; |
437 | 84 | } |
438 | | |
439 | | /* Return 1 if "bmap" contains the point "point". |
440 | | * "bmap" is assumed to have known divs. |
441 | | * The point is first extended with the divs and then passed |
442 | | * to basic_map_contains. |
443 | | */ |
444 | | isl_bool isl_basic_map_contains_point(__isl_keep isl_basic_map *bmap, |
445 | | __isl_keep isl_point *point) |
446 | 450 | { |
447 | 450 | int i; |
448 | 450 | struct isl_vec *vec; |
449 | 450 | unsigned dim; |
450 | 450 | isl_bool contains; |
451 | 450 | |
452 | 450 | if (!bmap || !point) |
453 | 0 | return isl_bool_error; |
454 | 450 | isl_assert(bmap->ctx, isl_space_is_equal(bmap->dim, point->dim), |
455 | 450 | return isl_bool_error); |
456 | 450 | if (bmap->n_div == 0) |
457 | 444 | return isl_basic_map_contains(bmap, point->vec); |
458 | 6 | |
459 | 6 | dim = isl_basic_map_total_dim(bmap) - bmap->n_div; |
460 | 6 | vec = isl_vec_alloc(bmap->ctx, 1 + dim + bmap->n_div); |
461 | 6 | if (!vec) |
462 | 0 | return isl_bool_error; |
463 | 6 | |
464 | 6 | isl_seq_cpy(vec->el, point->vec->el, point->vec->size); |
465 | 15 | for (i = 0; i < bmap->n_div; ++i9 ) { |
466 | 9 | isl_seq_inner_product(bmap->div[i] + 1, vec->el, |
467 | 9 | 1 + dim + i, &vec->el[1+dim+i]); |
468 | 9 | isl_int_fdiv_q(vec->el[1+dim+i], vec->el[1+dim+i], |
469 | 9 | bmap->div[i][0]); |
470 | 9 | } |
471 | 6 | |
472 | 6 | contains = isl_basic_map_contains(bmap, vec); |
473 | 6 | |
474 | 6 | isl_vec_free(vec); |
475 | 6 | return contains; |
476 | 6 | } |
477 | | |
478 | | isl_bool isl_map_contains_point(__isl_keep isl_map *map, |
479 | | __isl_keep isl_point *point) |
480 | 24 | { |
481 | 24 | int i; |
482 | 24 | isl_bool found = isl_bool_false; |
483 | 24 | |
484 | 24 | if (!map || !point) |
485 | 0 | return isl_bool_error; |
486 | 24 | |
487 | 24 | map = isl_map_copy(map); |
488 | 24 | map = isl_map_compute_divs(map); |
489 | 24 | if (!map) |
490 | 0 | return isl_bool_error; |
491 | 24 | |
492 | 28 | for (i = 0; 24 i < map->n; ++i4 ) { |
493 | 24 | found = isl_basic_map_contains_point(map->p[i], point); |
494 | 24 | if (found < 0) |
495 | 0 | goto error; |
496 | 24 | if (found) |
497 | 20 | break; |
498 | 24 | } |
499 | 24 | isl_map_free(map); |
500 | 24 | |
501 | 24 | return found; |
502 | 0 | error: |
503 | 0 | isl_map_free(map); |
504 | 0 | return isl_bool_error; |
505 | 24 | } |
506 | | |
507 | | isl_bool isl_set_contains_point(__isl_keep isl_set *set, |
508 | | __isl_keep isl_point *point) |
509 | 24 | { |
510 | 24 | return isl_map_contains_point(set_to_map(set), point); |
511 | 24 | } |
512 | | |
513 | | __isl_give isl_basic_set *isl_basic_set_from_point(__isl_take isl_point *pnt) |
514 | 1 | { |
515 | 1 | isl_basic_set *bset; |
516 | 1 | isl_basic_set *model; |
517 | 1 | |
518 | 1 | if (!pnt) |
519 | 0 | return NULL; |
520 | 1 | |
521 | 1 | model = isl_basic_set_empty(isl_space_copy(pnt->dim)); |
522 | 1 | bset = isl_basic_set_from_vec(isl_vec_copy(pnt->vec)); |
523 | 1 | bset = isl_basic_set_from_underlying_set(bset, model); |
524 | 1 | isl_point_free(pnt); |
525 | 1 | |
526 | 1 | return bset; |
527 | 1 | } |
528 | | |
529 | | __isl_give isl_set *isl_set_from_point(__isl_take isl_point *pnt) |
530 | 0 | { |
531 | 0 | isl_basic_set *bset; |
532 | 0 | bset = isl_basic_set_from_point(pnt); |
533 | 0 | return isl_set_from_basic_set(bset); |
534 | 0 | } |
535 | | |
536 | | /* Construct a union set, containing the single element "pnt". |
537 | | * If "pnt" is void, then return an empty union set. |
538 | | */ |
539 | | __isl_give isl_union_set *isl_union_set_from_point(__isl_take isl_point *pnt) |
540 | 0 | { |
541 | 0 | if (!pnt) |
542 | 0 | return NULL; |
543 | 0 | if (isl_point_is_void(pnt)) { |
544 | 0 | isl_space *space; |
545 | 0 |
|
546 | 0 | space = isl_point_get_space(pnt); |
547 | 0 | isl_point_free(pnt); |
548 | 0 | return isl_union_set_empty(space); |
549 | 0 | } |
550 | 0 | |
551 | 0 | return isl_union_set_from_set(isl_set_from_point(pnt)); |
552 | 0 | } |
553 | | |
554 | | __isl_give isl_basic_set *isl_basic_set_box_from_points( |
555 | | __isl_take isl_point *pnt1, __isl_take isl_point *pnt2) |
556 | 0 | { |
557 | 0 | isl_basic_set *bset = NULL; |
558 | 0 | unsigned total; |
559 | 0 | int i; |
560 | 0 | int k; |
561 | 0 | isl_int t; |
562 | 0 |
|
563 | 0 | isl_int_init(t); |
564 | 0 |
|
565 | 0 | if (!pnt1 || !pnt2) |
566 | 0 | goto error; |
567 | 0 | |
568 | 0 | isl_assert(pnt1->dim->ctx, |
569 | 0 | isl_space_is_equal(pnt1->dim, pnt2->dim), goto error); |
570 | 0 |
|
571 | 0 | if (isl_point_is_void(pnt1) && isl_point_is_void(pnt2)) { |
572 | 0 | isl_space *dim = isl_space_copy(pnt1->dim); |
573 | 0 | isl_point_free(pnt1); |
574 | 0 | isl_point_free(pnt2); |
575 | 0 | isl_int_clear(t); |
576 | 0 | return isl_basic_set_empty(dim); |
577 | 0 | } |
578 | 0 | if (isl_point_is_void(pnt1)) { |
579 | 0 | isl_point_free(pnt1); |
580 | 0 | isl_int_clear(t); |
581 | 0 | return isl_basic_set_from_point(pnt2); |
582 | 0 | } |
583 | 0 | if (isl_point_is_void(pnt2)) { |
584 | 0 | isl_point_free(pnt2); |
585 | 0 | isl_int_clear(t); |
586 | 0 | return isl_basic_set_from_point(pnt1); |
587 | 0 | } |
588 | 0 |
|
589 | 0 | total = isl_space_dim(pnt1->dim, isl_dim_all); |
590 | 0 | bset = isl_basic_set_alloc_space(isl_space_copy(pnt1->dim), 0, 0, 2 * total); |
591 | 0 |
|
592 | 0 | for (i = 0; i < total; ++i) { |
593 | 0 | isl_int_mul(t, pnt1->vec->el[1 + i], pnt2->vec->el[0]); |
594 | 0 | isl_int_submul(t, pnt2->vec->el[1 + i], pnt1->vec->el[0]); |
595 | 0 |
|
596 | 0 | k = isl_basic_set_alloc_inequality(bset); |
597 | 0 | if (k < 0) |
598 | 0 | goto error; |
599 | 0 | isl_seq_clr(bset->ineq[k] + 1, total); |
600 | 0 | if (isl_int_is_pos(t)) { |
601 | 0 | isl_int_set_si(bset->ineq[k][1 + i], -1); |
602 | 0 | isl_int_set(bset->ineq[k][0], pnt1->vec->el[1 + i]); |
603 | 0 | } else { |
604 | 0 | isl_int_set_si(bset->ineq[k][1 + i], 1); |
605 | 0 | isl_int_neg(bset->ineq[k][0], pnt1->vec->el[1 + i]); |
606 | 0 | } |
607 | 0 | isl_int_fdiv_q(bset->ineq[k][0], bset->ineq[k][0], pnt1->vec->el[0]); |
608 | 0 |
|
609 | 0 | k = isl_basic_set_alloc_inequality(bset); |
610 | 0 | if (k < 0) |
611 | 0 | goto error; |
612 | 0 | isl_seq_clr(bset->ineq[k] + 1, total); |
613 | 0 | if (isl_int_is_pos(t)) { |
614 | 0 | isl_int_set_si(bset->ineq[k][1 + i], 1); |
615 | 0 | isl_int_neg(bset->ineq[k][0], pnt2->vec->el[1 + i]); |
616 | 0 | } else { |
617 | 0 | isl_int_set_si(bset->ineq[k][1 + i], -1); |
618 | 0 | isl_int_set(bset->ineq[k][0], pnt2->vec->el[1 + i]); |
619 | 0 | } |
620 | 0 | isl_int_fdiv_q(bset->ineq[k][0], bset->ineq[k][0], pnt2->vec->el[0]); |
621 | 0 | } |
622 | 0 |
|
623 | 0 | bset = isl_basic_set_finalize(bset); |
624 | 0 |
|
625 | 0 | isl_point_free(pnt1); |
626 | 0 | isl_point_free(pnt2); |
627 | 0 |
|
628 | 0 | isl_int_clear(t); |
629 | 0 |
|
630 | 0 | return bset; |
631 | 0 | error: |
632 | 0 | isl_point_free(pnt1); |
633 | 0 | isl_point_free(pnt2); |
634 | 0 | isl_int_clear(t); |
635 | 0 | isl_basic_set_free(bset); |
636 | 0 | return NULL; |
637 | 0 | } |
638 | | |
639 | | __isl_give isl_set *isl_set_box_from_points(__isl_take isl_point *pnt1, |
640 | | __isl_take isl_point *pnt2) |
641 | 0 | { |
642 | 0 | isl_basic_set *bset; |
643 | 0 | bset = isl_basic_set_box_from_points(pnt1, pnt2); |
644 | 0 | return isl_set_from_basic_set(bset); |
645 | 0 | } |
646 | | |
647 | | /* Print the coordinate at position "pos" of the point "pnt". |
648 | | */ |
649 | | static __isl_give isl_printer *print_coordinate(__isl_take isl_printer *p, |
650 | | struct isl_print_space_data *data, unsigned pos) |
651 | 0 | { |
652 | 0 | isl_point *pnt = data->user; |
653 | 0 |
|
654 | 0 | p = isl_printer_print_isl_int(p, pnt->vec->el[1 + pos]); |
655 | 0 | if (!isl_int_is_one(pnt->vec->el[0])) { |
656 | 0 | p = isl_printer_print_str(p, "/"); |
657 | 0 | p = isl_printer_print_isl_int(p, pnt->vec->el[0]); |
658 | 0 | } |
659 | 0 |
|
660 | 0 | return p; |
661 | 0 | } |
662 | | |
663 | | __isl_give isl_printer *isl_printer_print_point( |
664 | | __isl_take isl_printer *p, __isl_keep isl_point *pnt) |
665 | 0 | { |
666 | 0 | struct isl_print_space_data data = { 0 }; |
667 | 0 | int i; |
668 | 0 | unsigned nparam; |
669 | 0 |
|
670 | 0 | if (!pnt) |
671 | 0 | return p; |
672 | 0 | if (isl_point_is_void(pnt)) { |
673 | 0 | p = isl_printer_print_str(p, "void"); |
674 | 0 | return p; |
675 | 0 | } |
676 | 0 | |
677 | 0 | nparam = isl_space_dim(pnt->dim, isl_dim_param); |
678 | 0 | if (nparam > 0) { |
679 | 0 | p = isl_printer_print_str(p, "["); |
680 | 0 | for (i = 0; i < nparam; ++i) { |
681 | 0 | const char *name; |
682 | 0 | if (i) |
683 | 0 | p = isl_printer_print_str(p, ", "); |
684 | 0 | name = isl_space_get_dim_name(pnt->dim, isl_dim_param, i); |
685 | 0 | if (name) { |
686 | 0 | p = isl_printer_print_str(p, name); |
687 | 0 | p = isl_printer_print_str(p, " = "); |
688 | 0 | } |
689 | 0 | p = isl_printer_print_isl_int(p, pnt->vec->el[1 + i]); |
690 | 0 | if (!isl_int_is_one(pnt->vec->el[0])) { |
691 | 0 | p = isl_printer_print_str(p, "/"); |
692 | 0 | p = isl_printer_print_isl_int(p, pnt->vec->el[0]); |
693 | 0 | } |
694 | 0 | } |
695 | 0 | p = isl_printer_print_str(p, "]"); |
696 | 0 | p = isl_printer_print_str(p, " -> "); |
697 | 0 | } |
698 | 0 | data.print_dim = &print_coordinate; |
699 | 0 | data.user = pnt; |
700 | 0 | p = isl_printer_print_str(p, "{ "); |
701 | 0 | p = isl_print_space(pnt->dim, p, 0, &data); |
702 | 0 | p = isl_printer_print_str(p, " }"); |
703 | 0 | return p; |
704 | 0 | } |