isl_map.c: room_for_ineq: add memory management annotation
[isl.git] / isl_point.c
blobbe41c53b79d83dca0a5a97625a1a26f61bda316d
1 /*
2 * Copyright 2010 INRIA Saclay
3 * Copyright 2013 Ecole Normale Superieure
4 * Copyright 2015 Sven Verdoolaege
5 * Copyright 2019 Cerebras Systems
7 * Use of this software is governed by the MIT license
9 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
10 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
11 * 91893 Orsay, France
12 * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
13 * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA
16 #include <isl_map_private.h>
17 #include <isl_point_private.h>
18 #include <isl/set.h>
19 #include <isl/union_set.h>
20 #include <isl_sample.h>
21 #include <isl_scan.h>
22 #include <isl_seq.h>
23 #include <isl_space_private.h>
24 #include <isl_local_private.h>
25 #include <isl_val_private.h>
26 #include <isl_vec_private.h>
27 #include <isl_output_private.h>
29 #include <set_to_map.c>
31 isl_ctx *isl_point_get_ctx(__isl_keep isl_point *pnt)
33 return pnt ? isl_space_get_ctx(pnt->dim) : NULL;
36 /* Return the space of "pnt".
38 __isl_keep isl_space *isl_point_peek_space(__isl_keep isl_point *pnt)
40 return pnt ? pnt->dim : NULL;
43 __isl_give isl_space *isl_point_get_space(__isl_keep isl_point *pnt)
45 return isl_space_copy(isl_point_peek_space(pnt));
48 #undef TYPE1
49 #define TYPE1 isl_basic_map
50 #undef TYPE2
51 #define TYPE2 isl_point
52 #undef TYPE_PAIR
53 #define TYPE_PAIR isl_basic_map_point
55 static
56 #include "isl_type_has_equal_space_templ.c"
57 static
58 #include "isl_type_check_equal_space_templ.c"
60 __isl_give isl_point *isl_point_alloc(__isl_take isl_space *space,
61 __isl_take isl_vec *vec)
63 struct isl_point *pnt;
64 isl_size dim;
66 dim = isl_space_dim(space, isl_dim_all);
67 if (dim < 0 || !vec)
68 goto error;
70 if (vec->size > 1 + dim) {
71 vec = isl_vec_cow(vec);
72 if (!vec)
73 goto error;
74 vec->size = 1 + dim;
77 pnt = isl_alloc_type(space->ctx, struct isl_point);
78 if (!pnt)
79 goto error;
81 pnt->ref = 1;
82 pnt->dim = space;
83 pnt->vec = vec;
85 return pnt;
86 error:
87 isl_space_free(space);
88 isl_vec_free(vec);
89 return NULL;
92 __isl_give isl_point *isl_point_zero(__isl_take isl_space *space)
94 isl_vec *vec;
95 isl_size dim;
97 dim = isl_space_dim(space, isl_dim_all);
98 if (dim < 0)
99 goto error;
100 vec = isl_vec_alloc(space->ctx, 1 + dim);
101 if (!vec)
102 goto error;
103 isl_int_set_si(vec->el[0], 1);
104 isl_seq_clr(vec->el + 1, vec->size - 1);
105 return isl_point_alloc(space, vec);
106 error:
107 isl_space_free(space);
108 return NULL;
111 __isl_give isl_point *isl_point_dup(__isl_keep isl_point *pnt)
113 struct isl_point *pnt2;
115 if (!pnt)
116 return NULL;
117 pnt2 = isl_point_alloc(isl_space_copy(pnt->dim), isl_vec_copy(pnt->vec));
118 return pnt2;
121 __isl_give isl_point *isl_point_cow(__isl_take isl_point *pnt)
123 struct isl_point *pnt2;
124 if (!pnt)
125 return NULL;
127 if (pnt->ref == 1)
128 return pnt;
130 pnt2 = isl_point_dup(pnt);
131 isl_point_free(pnt);
132 return pnt2;
135 __isl_give isl_point *isl_point_copy(__isl_keep isl_point *pnt)
137 if (!pnt)
138 return NULL;
140 pnt->ref++;
141 return pnt;
144 __isl_null isl_point *isl_point_free(__isl_take isl_point *pnt)
146 if (!pnt)
147 return NULL;
149 if (--pnt->ref > 0)
150 return NULL;
152 isl_space_free(pnt->dim);
153 isl_vec_free(pnt->vec);
154 free(pnt);
155 return NULL;
158 __isl_give isl_point *isl_point_void(__isl_take isl_space *space)
160 if (!space)
161 return NULL;
163 return isl_point_alloc(space, isl_vec_alloc(space->ctx, 0));
166 isl_bool isl_point_is_void(__isl_keep isl_point *pnt)
168 if (!pnt)
169 return isl_bool_error;
171 return isl_bool_ok(pnt->vec->size == 0);
174 /* Return the space of "pnt".
175 * This may be either a copy or the space itself
176 * if there is only one reference to "pnt".
177 * This allows the space to be modified inplace
178 * if both the point and its space have only a single reference.
179 * The caller is not allowed to modify "pnt" between this call and
180 * a subsequent call to isl_point_restore_space.
181 * The only exception is that isl_point_free can be called instead.
183 __isl_give isl_space *isl_point_take_space(__isl_keep isl_point *pnt)
185 isl_space *space;
187 if (!pnt)
188 return NULL;
189 if (pnt->ref != 1)
190 return isl_point_get_space(pnt);
191 space = pnt->dim;
192 pnt->dim = NULL;
193 return space;
196 /* Set the space of "pnt" to "space", where the space of "pnt" may be missing
197 * due to a preceding call to isl_point_take_space.
198 * However, in this case, "pnt" only has a single reference and
199 * then the call to isl_point_cow has no effect.
201 __isl_give isl_point *isl_point_restore_space(__isl_take isl_point *pnt,
202 __isl_take isl_space *space)
204 if (!pnt || !space)
205 goto error;
207 if (pnt->dim == space) {
208 isl_space_free(space);
209 return pnt;
212 pnt = isl_point_cow(pnt);
213 if (!pnt)
214 goto error;
215 isl_space_free(pnt->dim);
216 pnt->dim = space;
218 return pnt;
219 error:
220 isl_point_free(pnt);
221 isl_space_free(space);
222 return NULL;
225 /* Return the coordinate vector of "pnt".
227 __isl_keep isl_vec *isl_point_peek_vec(__isl_keep isl_point *pnt)
229 return pnt ? pnt->vec : NULL;
232 /* Return a copy of the coordinate vector of "pnt".
234 __isl_give isl_vec *isl_point_get_vec(__isl_keep isl_point *pnt)
236 return isl_vec_copy(isl_point_peek_vec(pnt));
239 /* Return the coordinate vector of "pnt".
240 * This may be either a copy or the coordinate vector itself
241 * if there is only one reference to "pnt".
242 * This allows the coordinate vector to be modified inplace
243 * if both the point and its coordinate vector have only a single reference.
244 * The caller is not allowed to modify "pnt" between this call and
245 * a subsequent call to isl_point_restore_vec.
246 * The only exception is that isl_point_free can be called instead.
248 __isl_give isl_vec *isl_point_take_vec(__isl_keep isl_point *pnt)
250 isl_vec *vec;
252 if (!pnt)
253 return NULL;
254 if (pnt->ref != 1)
255 return isl_point_get_vec(pnt);
256 vec = pnt->vec;
257 pnt->vec = NULL;
258 return vec;
261 /* Set the coordinate vector of "pnt" to "vec",
262 * where the coordinate vector of "pnt" may be missing
263 * due to a preceding call to isl_point_take_vec.
264 * However, in this case, "pnt" only has a single reference and
265 * then the call to isl_point_cow has no effect.
267 __isl_give isl_point *isl_point_restore_vec(__isl_take isl_point *pnt,
268 __isl_take isl_vec *vec)
270 if (!pnt || !vec)
271 goto error;
273 if (pnt->vec == vec) {
274 isl_vec_free(vec);
275 return pnt;
278 pnt = isl_point_cow(pnt);
279 if (!pnt)
280 goto error;
281 isl_vec_free(pnt->vec);
282 pnt->vec = vec;
284 return pnt;
285 error:
286 isl_point_free(pnt);
287 isl_vec_free(vec);
288 return NULL;
291 /* Return the number of variables of the given type.
293 static isl_size isl_point_dim(__isl_keep isl_point *pnt, enum isl_dim_type type)
295 return isl_space_dim(isl_point_peek_space(pnt), type);
298 /* Return the position of the coordinates of the given type
299 * within the sequence of coordinates of "pnt".
301 static isl_size isl_point_var_offset(__isl_keep isl_point *pnt,
302 enum isl_dim_type type)
304 return pnt ? isl_space_offset(pnt->dim, type) : isl_size_error;
307 #undef TYPE
308 #define TYPE isl_point
309 static
310 #include "check_type_range_templ.c"
312 /* Return the value of coordinate "pos" of type "type" of "pnt".
314 __isl_give isl_val *isl_point_get_coordinate_val(__isl_keep isl_point *pnt,
315 enum isl_dim_type type, int pos)
317 isl_ctx *ctx;
318 isl_val *v;
319 isl_size off;
321 if (!pnt)
322 return NULL;
324 ctx = isl_point_get_ctx(pnt);
325 if (isl_point_is_void(pnt))
326 isl_die(ctx, isl_error_invalid,
327 "void point does not have coordinates", return NULL);
328 if (isl_point_check_range(pnt, type, pos, 1) < 0)
329 return NULL;
331 off = isl_point_var_offset(pnt, type);
332 if (off < 0)
333 return NULL;
334 pos += off;
336 v = isl_val_rat_from_isl_int(ctx, pnt->vec->el[1 + pos],
337 pnt->vec->el[0]);
338 return isl_val_normalize(v);
341 /* Set all entries of "mv" to NaN.
343 static __isl_give isl_multi_val *set_nan(__isl_take isl_multi_val *mv)
345 int i;
346 isl_size n;
347 isl_val *v;
349 n = isl_multi_val_size(mv);
350 if (n < 0)
351 return isl_multi_val_free(mv);
352 v = isl_val_nan(isl_multi_val_get_ctx(mv));
353 for (i = 0; i < n; ++i)
354 mv = isl_multi_val_set_at(mv, i, isl_val_copy(v));
355 isl_val_free(v);
357 return mv;
360 /* Return the values of the set dimensions of "pnt".
361 * Return a sequence of NaNs in case of a void point.
363 __isl_give isl_multi_val *isl_point_get_multi_val(__isl_keep isl_point *pnt)
365 int i;
366 isl_bool is_void;
367 isl_size n;
368 isl_multi_val *mv;
370 is_void = isl_point_is_void(pnt);
371 if (is_void < 0)
372 return NULL;
374 mv = isl_multi_val_alloc(isl_point_get_space(pnt));
375 if (is_void)
376 return set_nan(mv);
377 n = isl_multi_val_size(mv);
378 if (n < 0)
379 return isl_multi_val_free(mv);
380 for (i = 0; i < n; ++i) {
381 isl_val *v;
383 v = isl_point_get_coordinate_val(pnt, isl_dim_set, i);
384 mv = isl_multi_val_set_at(mv, i, v);
387 return mv;
390 /* Replace coordinate "pos" of type "type" of "pnt" by "v".
392 __isl_give isl_point *isl_point_set_coordinate_val(__isl_take isl_point *pnt,
393 enum isl_dim_type type, int pos, __isl_take isl_val *v)
395 if (!pnt || !v)
396 goto error;
397 if (isl_point_is_void(pnt))
398 isl_die(isl_point_get_ctx(pnt), isl_error_invalid,
399 "void point does not have coordinates", goto error);
400 if (isl_point_check_range(pnt, type, pos, 1) < 0)
401 goto error;
402 if (!isl_val_is_rat(v))
403 isl_die(isl_point_get_ctx(pnt), isl_error_invalid,
404 "expecting rational value", goto error);
406 pos += isl_space_offset(isl_point_peek_space(pnt), type);
407 if (isl_int_eq(pnt->vec->el[1 + pos], v->n) &&
408 isl_int_eq(pnt->vec->el[0], v->d)) {
409 isl_val_free(v);
410 return pnt;
413 pnt = isl_point_cow(pnt);
414 if (!pnt)
415 goto error;
416 pnt->vec = isl_vec_cow(pnt->vec);
417 if (!pnt->vec)
418 goto error;
420 if (isl_int_eq(pnt->vec->el[0], v->d)) {
421 isl_int_set(pnt->vec->el[1 + pos], v->n);
422 } else if (isl_int_is_one(v->d)) {
423 isl_int_mul(pnt->vec->el[1 + pos], pnt->vec->el[0], v->n);
424 } else {
425 isl_seq_scale(pnt->vec->el + 1,
426 pnt->vec->el + 1, v->d, pnt->vec->size - 1);
427 isl_int_mul(pnt->vec->el[1 + pos], pnt->vec->el[0], v->n);
428 isl_int_mul(pnt->vec->el[0], pnt->vec->el[0], v->d);
429 pnt->vec = isl_vec_normalize(pnt->vec);
430 if (!pnt->vec)
431 goto error;
434 isl_val_free(v);
435 return pnt;
436 error:
437 isl_val_free(v);
438 isl_point_free(pnt);
439 return NULL;
442 __isl_give isl_point *isl_point_add_ui(__isl_take isl_point *pnt,
443 enum isl_dim_type type, int pos, unsigned val)
445 isl_size off;
447 if (!pnt || isl_point_is_void(pnt))
448 return pnt;
450 pnt = isl_point_cow(pnt);
451 if (!pnt)
452 return NULL;
453 pnt->vec = isl_vec_cow(pnt->vec);
454 if (!pnt->vec)
455 goto error;
457 off = isl_point_var_offset(pnt, type);
458 if (off < 0)
459 goto error;
460 pos += off;
462 isl_int_add_ui(pnt->vec->el[1 + pos], pnt->vec->el[1 + pos], val);
464 return pnt;
465 error:
466 isl_point_free(pnt);
467 return NULL;
470 __isl_give isl_point *isl_point_sub_ui(__isl_take isl_point *pnt,
471 enum isl_dim_type type, int pos, unsigned val)
473 isl_size off;
475 if (!pnt || isl_point_is_void(pnt))
476 return pnt;
478 pnt = isl_point_cow(pnt);
479 if (!pnt)
480 return NULL;
481 pnt->vec = isl_vec_cow(pnt->vec);
482 if (!pnt->vec)
483 goto error;
485 off = isl_point_var_offset(pnt, type);
486 if (off < 0)
487 goto error;
488 pos += off;
490 isl_int_sub_ui(pnt->vec->el[1 + pos], pnt->vec->el[1 + pos], val);
492 return pnt;
493 error:
494 isl_point_free(pnt);
495 return NULL;
498 struct isl_foreach_point {
499 struct isl_scan_callback callback;
500 isl_stat (*fn)(__isl_take isl_point *pnt, void *user);
501 void *user;
502 isl_space *dim;
505 static isl_stat foreach_point(struct isl_scan_callback *cb,
506 __isl_take isl_vec *sample)
508 struct isl_foreach_point *fp = (struct isl_foreach_point *)cb;
509 isl_point *pnt;
511 pnt = isl_point_alloc(isl_space_copy(fp->dim), sample);
513 return fp->fn(pnt, fp->user);
516 isl_stat isl_set_foreach_point(__isl_keep isl_set *set,
517 isl_stat (*fn)(__isl_take isl_point *pnt, void *user), void *user)
519 struct isl_foreach_point fp = { { &foreach_point }, fn, user };
520 int i;
522 if (!set)
523 return isl_stat_error;
525 fp.dim = isl_set_get_space(set);
526 if (!fp.dim)
527 return isl_stat_error;
529 set = isl_set_copy(set);
530 set = isl_set_cow(set);
531 set = isl_set_make_disjoint(set);
532 set = isl_set_compute_divs(set);
533 if (!set)
534 goto error;
536 for (i = 0; i < set->n; ++i)
537 if (isl_basic_set_scan(isl_basic_set_copy(set->p[i]),
538 &fp.callback) < 0)
539 goto error;
541 isl_set_free(set);
542 isl_space_free(fp.dim);
544 return isl_stat_ok;
545 error:
546 isl_set_free(set);
547 isl_space_free(fp.dim);
548 return isl_stat_error;
551 /* Return 1 if "bmap" contains the point "point".
552 * "bmap" is assumed to have known divs.
553 * The point is first extended with the divs and then passed
554 * to basic_map_contains.
556 isl_bool isl_basic_map_contains_point(__isl_keep isl_basic_map *bmap,
557 __isl_keep isl_point *point)
559 isl_local *local;
560 isl_vec *vec;
561 isl_bool contains;
563 if (isl_basic_map_point_check_equal_space(bmap, point) < 0)
564 return isl_bool_error;
565 if (bmap->n_div == 0)
566 return isl_basic_map_contains(bmap, point->vec);
568 local = isl_local_alloc_from_mat(isl_basic_map_get_divs(bmap));
569 vec = isl_point_get_vec(point);
570 vec = isl_local_extend_point_vec(local, vec);
571 isl_local_free(local);
573 contains = isl_basic_map_contains(bmap, vec);
575 isl_vec_free(vec);
576 return contains;
579 isl_bool isl_map_contains_point(__isl_keep isl_map *map,
580 __isl_keep isl_point *point)
582 int i;
583 isl_bool found = isl_bool_false;
585 if (!map || !point)
586 return isl_bool_error;
588 map = isl_map_copy(map);
589 map = isl_map_compute_divs(map);
590 if (!map)
591 return isl_bool_error;
593 for (i = 0; i < map->n; ++i) {
594 found = isl_basic_map_contains_point(map->p[i], point);
595 if (found < 0)
596 goto error;
597 if (found)
598 break;
600 isl_map_free(map);
602 return found;
603 error:
604 isl_map_free(map);
605 return isl_bool_error;
608 isl_bool isl_set_contains_point(__isl_keep isl_set *set,
609 __isl_keep isl_point *point)
611 return isl_map_contains_point(set_to_map(set), point);
614 __isl_give isl_basic_set *isl_basic_set_from_point(__isl_take isl_point *pnt)
616 isl_basic_set *bset;
617 isl_basic_set *model;
619 if (!pnt)
620 return NULL;
622 model = isl_basic_set_empty(isl_space_copy(pnt->dim));
623 bset = isl_basic_set_from_vec(isl_vec_copy(pnt->vec));
624 bset = isl_basic_set_from_underlying_set(bset, model);
625 isl_point_free(pnt);
627 return bset;
630 __isl_give isl_set *isl_set_from_point(__isl_take isl_point *pnt)
632 isl_basic_set *bset;
633 bset = isl_basic_set_from_point(pnt);
634 return isl_set_from_basic_set(bset);
637 /* Construct a union set, containing the single element "pnt".
638 * If "pnt" is void, then return an empty union set.
640 __isl_give isl_union_set *isl_union_set_from_point(__isl_take isl_point *pnt)
642 if (!pnt)
643 return NULL;
644 if (isl_point_is_void(pnt)) {
645 isl_space *space;
647 space = isl_point_get_space(pnt);
648 isl_point_free(pnt);
649 return isl_union_set_empty(space);
652 return isl_union_set_from_set(isl_set_from_point(pnt));
655 __isl_give isl_basic_set *isl_basic_set_box_from_points(
656 __isl_take isl_point *pnt1, __isl_take isl_point *pnt2)
658 isl_basic_set *bset = NULL;
659 isl_size total;
660 int i;
661 int k;
662 isl_int t;
664 isl_int_init(t);
666 if (!pnt1 || !pnt2)
667 goto error;
669 isl_assert(pnt1->dim->ctx,
670 isl_space_is_equal(pnt1->dim, pnt2->dim), goto error);
672 if (isl_point_is_void(pnt1) && isl_point_is_void(pnt2)) {
673 isl_space *space = isl_space_copy(pnt1->dim);
674 isl_point_free(pnt1);
675 isl_point_free(pnt2);
676 isl_int_clear(t);
677 return isl_basic_set_empty(space);
679 if (isl_point_is_void(pnt1)) {
680 isl_point_free(pnt1);
681 isl_int_clear(t);
682 return isl_basic_set_from_point(pnt2);
684 if (isl_point_is_void(pnt2)) {
685 isl_point_free(pnt2);
686 isl_int_clear(t);
687 return isl_basic_set_from_point(pnt1);
690 total = isl_point_dim(pnt1, isl_dim_all);
691 if (total < 0)
692 goto error;
693 bset = isl_basic_set_alloc_space(isl_space_copy(pnt1->dim), 0, 0, 2 * total);
695 for (i = 0; i < total; ++i) {
696 isl_int_mul(t, pnt1->vec->el[1 + i], pnt2->vec->el[0]);
697 isl_int_submul(t, pnt2->vec->el[1 + i], pnt1->vec->el[0]);
699 k = isl_basic_set_alloc_inequality(bset);
700 if (k < 0)
701 goto error;
702 isl_seq_clr(bset->ineq[k] + 1, total);
703 if (isl_int_is_pos(t)) {
704 isl_int_set_si(bset->ineq[k][1 + i], -1);
705 isl_int_set(bset->ineq[k][0], pnt1->vec->el[1 + i]);
706 } else {
707 isl_int_set_si(bset->ineq[k][1 + i], 1);
708 isl_int_neg(bset->ineq[k][0], pnt1->vec->el[1 + i]);
710 isl_int_fdiv_q(bset->ineq[k][0], bset->ineq[k][0], pnt1->vec->el[0]);
712 k = isl_basic_set_alloc_inequality(bset);
713 if (k < 0)
714 goto error;
715 isl_seq_clr(bset->ineq[k] + 1, total);
716 if (isl_int_is_pos(t)) {
717 isl_int_set_si(bset->ineq[k][1 + i], 1);
718 isl_int_neg(bset->ineq[k][0], pnt2->vec->el[1 + i]);
719 } else {
720 isl_int_set_si(bset->ineq[k][1 + i], -1);
721 isl_int_set(bset->ineq[k][0], pnt2->vec->el[1 + i]);
723 isl_int_fdiv_q(bset->ineq[k][0], bset->ineq[k][0], pnt2->vec->el[0]);
726 bset = isl_basic_set_finalize(bset);
728 isl_point_free(pnt1);
729 isl_point_free(pnt2);
731 isl_int_clear(t);
733 return bset;
734 error:
735 isl_point_free(pnt1);
736 isl_point_free(pnt2);
737 isl_int_clear(t);
738 isl_basic_set_free(bset);
739 return NULL;
742 __isl_give isl_set *isl_set_box_from_points(__isl_take isl_point *pnt1,
743 __isl_take isl_point *pnt2)
745 isl_basic_set *bset;
746 bset = isl_basic_set_box_from_points(pnt1, pnt2);
747 return isl_set_from_basic_set(bset);
750 /* Print the coordinate at position "pos" of the point "pnt".
752 static __isl_give isl_printer *print_coordinate(__isl_take isl_printer *p,
753 struct isl_print_space_data *data, unsigned pos)
755 isl_point *pnt = data->user;
757 pos += isl_space_offset(data->space, data->type);
758 p = isl_printer_print_isl_int(p, pnt->vec->el[1 + pos]);
759 if (!isl_int_is_one(pnt->vec->el[0])) {
760 p = isl_printer_print_str(p, "/");
761 p = isl_printer_print_isl_int(p, pnt->vec->el[0]);
764 return p;
767 __isl_give isl_printer *isl_printer_print_point(
768 __isl_take isl_printer *p, __isl_keep isl_point *pnt)
770 struct isl_print_space_data data = { 0 };
771 int i;
772 isl_size nparam;
774 if (!pnt)
775 return p;
776 if (isl_point_is_void(pnt)) {
777 p = isl_printer_print_str(p, "void");
778 return p;
781 nparam = isl_point_dim(pnt, isl_dim_param);
782 if (nparam < 0)
783 return isl_printer_free(p);
784 if (nparam > 0) {
785 p = isl_printer_print_str(p, "[");
786 for (i = 0; i < nparam; ++i) {
787 const char *name;
788 if (i)
789 p = isl_printer_print_str(p, ", ");
790 name = isl_space_get_dim_name(pnt->dim, isl_dim_param, i);
791 if (name) {
792 p = isl_printer_print_str(p, name);
793 p = isl_printer_print_str(p, " = ");
795 p = isl_printer_print_isl_int(p, pnt->vec->el[1 + i]);
796 if (!isl_int_is_one(pnt->vec->el[0])) {
797 p = isl_printer_print_str(p, "/");
798 p = isl_printer_print_isl_int(p, pnt->vec->el[0]);
801 p = isl_printer_print_str(p, "]");
802 p = isl_printer_print_str(p, " -> ");
804 data.print_dim = &print_coordinate;
805 data.user = pnt;
806 p = isl_printer_print_str(p, "{ ");
807 p = isl_print_space(pnt->dim, p, 0, &data);
808 p = isl_printer_print_str(p, " }");
809 return p;