avoid NULL pointer exception in isl_basic_map_n_*
[isl.git] / isl_dim.c
blob19a6bf91611b48c29e9df9fd6ad0ec65bfb9c749
1 /*
2 * Copyright 2008-2009 Katholieke Universiteit Leuven
4 * Use of this software is governed by the GNU LGPLv2.1 license
6 * Written by Sven Verdoolaege, K.U.Leuven, Departement
7 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
8 */
10 #include <stdlib.h>
11 #include <isl_dim_private.h>
12 #include "isl_name.h"
14 isl_ctx *isl_dim_get_ctx(__isl_keep isl_dim *dim)
16 return dim ? dim->ctx : NULL;
19 struct isl_dim *isl_dim_alloc(struct isl_ctx *ctx,
20 unsigned nparam, unsigned n_in, unsigned n_out)
22 struct isl_dim *dim;
24 dim = isl_alloc_type(ctx, struct isl_dim);
25 if (!dim)
26 return NULL;
28 dim->ctx = ctx;
29 isl_ctx_ref(ctx);
30 dim->ref = 1;
31 dim->nparam = nparam;
32 dim->n_in = n_in;
33 dim->n_out = n_out;
35 dim->tuple_name[0] = NULL;
36 dim->tuple_name[1] = NULL;
38 dim->n_name = 0;
39 dim->names = NULL;
41 return dim;
44 struct isl_dim *isl_dim_set_alloc(struct isl_ctx *ctx,
45 unsigned nparam, unsigned dim)
47 return isl_dim_alloc(ctx, nparam, 0, dim);
50 static unsigned global_pos(struct isl_dim *dim,
51 enum isl_dim_type type, unsigned pos)
53 struct isl_ctx *ctx = dim->ctx;
55 switch (type) {
56 case isl_dim_param:
57 isl_assert(ctx, pos < dim->nparam, return isl_dim_total(dim));
58 return pos;
59 case isl_dim_in:
60 isl_assert(ctx, pos < dim->n_in, return isl_dim_total(dim));
61 return pos + dim->nparam;
62 case isl_dim_out:
63 isl_assert(ctx, pos < dim->n_out, return isl_dim_total(dim));
64 return pos + dim->nparam + dim->n_in;
65 default:
66 isl_assert(ctx, 0, return isl_dim_total(dim));
68 return isl_dim_total(dim);
71 /* Extend length of names array to the total number of dimensions.
73 static __isl_give isl_dim *extend_names(__isl_take isl_dim *dim)
75 struct isl_name **names;
76 int i;
78 if (isl_dim_total(dim) <= dim->n_name)
79 return dim;
81 if (!dim->names) {
82 dim->names = isl_calloc_array(dim->ctx,
83 struct isl_name *, isl_dim_total(dim));
84 if (!dim->names)
85 goto error;
86 } else {
87 names = isl_realloc_array(dim->ctx, dim->names,
88 struct isl_name *, isl_dim_total(dim));
89 if (!names)
90 goto error;
91 dim->names = names;
92 for (i = dim->n_name; i < isl_dim_total(dim); ++i)
93 dim->names[i] = NULL;
96 dim->n_name = isl_dim_total(dim);
98 return dim;
99 error:
100 isl_dim_free(dim);
101 return NULL;
104 static struct isl_dim *set_name(struct isl_dim *dim,
105 enum isl_dim_type type, unsigned pos,
106 struct isl_name *name)
108 struct isl_ctx *ctx = dim->ctx;
109 dim = isl_dim_cow(dim);
111 if (!dim)
112 goto error;
114 pos = global_pos(dim, type, pos);
115 isl_assert(ctx, pos != isl_dim_total(dim), goto error);
117 if (pos >= dim->n_name) {
118 if (!name)
119 return dim;
120 dim = extend_names(dim);
121 if (!dim)
122 goto error;
125 dim->names[pos] = name;
127 return dim;
128 error:
129 isl_name_free(ctx, name);
130 isl_dim_free(dim);
131 return NULL;
134 static struct isl_name *get_name(struct isl_dim *dim,
135 enum isl_dim_type type, unsigned pos)
137 if (!dim)
138 return NULL;
140 pos = global_pos(dim, type, pos);
141 if (pos == isl_dim_total(dim))
142 return NULL;
143 if (pos >= dim->n_name)
144 return NULL;
145 return dim->names[pos];
148 static unsigned offset(struct isl_dim *dim, enum isl_dim_type type)
150 switch (type) {
151 case isl_dim_param: return 0;
152 case isl_dim_in: return dim->nparam;
153 case isl_dim_out: return dim->nparam + dim->n_in;
154 default: return 0;
158 static unsigned n(struct isl_dim *dim, enum isl_dim_type type)
160 switch (type) {
161 case isl_dim_param: return dim->nparam;
162 case isl_dim_in: return dim->n_in;
163 case isl_dim_out: return dim->n_out;
164 default: return 0;
168 unsigned isl_dim_size(struct isl_dim *dim, enum isl_dim_type type)
170 if (!dim)
171 return 0;
172 return n(dim, type);
175 unsigned isl_dim_offset(__isl_keep isl_dim *dim, enum isl_dim_type type)
177 if (!dim)
178 return 0;
179 return offset(dim, type);
182 static struct isl_dim *copy_names(struct isl_dim *dst,
183 enum isl_dim_type dst_type, unsigned offset, struct isl_dim *src,
184 enum isl_dim_type src_type)
186 int i;
187 struct isl_name *name;
189 if (!dst)
190 return NULL;
192 for (i = 0; i < n(src, src_type); ++i) {
193 name = get_name(src, src_type, i);
194 if (!name)
195 continue;
196 dst = set_name(dst, dst_type, offset + i,
197 isl_name_copy(dst->ctx, name));
198 if (!dst)
199 return NULL;
201 return dst;
204 struct isl_dim *isl_dim_dup(struct isl_dim *dim)
206 struct isl_dim *dup;
207 if (!dim)
208 return NULL;
209 dup = isl_dim_alloc(dim->ctx, dim->nparam, dim->n_in, dim->n_out);
210 if (dim->tuple_name[0] &&
211 !(dup->tuple_name[0] = isl_name_copy(dim->ctx, dim->tuple_name[0])))
212 goto error;
213 if (dim->tuple_name[1] &&
214 !(dup->tuple_name[1] = isl_name_copy(dim->ctx, dim->tuple_name[1])))
215 goto error;
216 if (!dim->names)
217 return dup;
218 dup = copy_names(dup, isl_dim_param, 0, dim, isl_dim_param);
219 dup = copy_names(dup, isl_dim_in, 0, dim, isl_dim_in);
220 dup = copy_names(dup, isl_dim_out, 0, dim, isl_dim_out);
221 return dup;
222 error:
223 isl_dim_free(dup);
224 return NULL;
227 struct isl_dim *isl_dim_cow(struct isl_dim *dim)
229 if (!dim)
230 return NULL;
232 if (dim->ref == 1)
233 return dim;
234 dim->ref--;
235 return isl_dim_dup(dim);
238 struct isl_dim *isl_dim_copy(struct isl_dim *dim)
240 if (!dim)
241 return NULL;
243 dim->ref++;
244 return dim;
247 void isl_dim_free(struct isl_dim *dim)
249 int i;
251 if (!dim)
252 return;
254 if (--dim->ref > 0)
255 return;
257 isl_name_free(dim->ctx, dim->tuple_name[0]);
258 isl_name_free(dim->ctx, dim->tuple_name[1]);
260 for (i = 0; i < dim->n_name; ++i)
261 isl_name_free(dim->ctx, dim->names[i]);
262 free(dim->names);
263 isl_ctx_deref(dim->ctx);
265 free(dim);
268 static int name_ok(isl_ctx *ctx, const char *s)
270 char *p;
271 long dummy;
273 dummy = strtol(s, &p, 0);
274 if (p != s)
275 isl_die(ctx, isl_error_invalid, "name looks like a number",
276 return 0);
278 return 1;
281 __isl_give isl_dim *isl_dim_set_tuple_name(__isl_take isl_dim *dim,
282 enum isl_dim_type type, const char *s)
284 struct isl_name *name;
286 dim = isl_dim_cow(dim);
287 if (!dim)
288 return NULL;
289 if (type != isl_dim_in && type != isl_dim_out)
290 isl_die(dim->ctx, isl_error_invalid,
291 "only input, output and set tuples can have names",
292 goto error);
293 if (!s) {
294 name = NULL;
295 } else {
296 if (!name_ok(dim->ctx, s))
297 goto error;
298 name = isl_name_get(dim->ctx, s);
299 if (!name)
300 goto error;
303 isl_name_free(dim->ctx, dim->tuple_name[type - isl_dim_in]);
304 dim->tuple_name[type - isl_dim_in] = name;
306 return dim;
307 error:
308 isl_dim_free(dim);
309 return NULL;
312 const char *isl_dim_get_tuple_name(__isl_keep isl_dim *dim,
313 enum isl_dim_type type)
315 struct isl_name *name;
316 if (!dim)
317 return NULL;
318 if (type != isl_dim_in && type != isl_dim_out)
319 return NULL;
320 name = dim->tuple_name[type - isl_dim_in];
321 return name ? name->name : NULL;
324 struct isl_dim *isl_dim_set_name(struct isl_dim *dim,
325 enum isl_dim_type type, unsigned pos,
326 const char *s)
328 struct isl_name *name;
330 if (!dim)
331 return NULL;
332 if (!name_ok(dim->ctx, s))
333 goto error;
334 name = isl_name_get(dim->ctx, s);
335 if (!name)
336 goto error;
337 return set_name(dim, type, pos, name);
338 error:
339 isl_dim_free(dim);
340 return NULL;
343 const char *isl_dim_get_name(struct isl_dim *dim,
344 enum isl_dim_type type, unsigned pos)
346 struct isl_name *name = get_name(dim, type, pos);
347 return name ? name->name : NULL;
350 static struct isl_name *tuple_name(__isl_keep isl_dim *dim,
351 enum isl_dim_type type)
353 if (!dim)
354 return NULL;
355 if (type == isl_dim_in)
356 return dim->tuple_name[0];
357 if (type == isl_dim_out)
358 return dim->tuple_name[1];
359 return NULL;
362 int isl_dim_tuple_match(__isl_keep isl_dim *dim1, enum isl_dim_type dim1_type,
363 __isl_keep isl_dim *dim2, enum isl_dim_type dim2_type)
365 struct isl_name *name1, *name2;
367 if (n(dim1, dim1_type) != n(dim2, dim2_type))
368 return 0;
369 name1 = tuple_name(dim1, dim1_type);
370 name2 = tuple_name(dim2, dim2_type);
371 if (!name1 ^ !name2)
372 return 0;
373 if (name1 && name1->name != name2->name)
374 return 0;
375 return 1;
378 static int match(struct isl_dim *dim1, enum isl_dim_type dim1_type,
379 struct isl_dim *dim2, enum isl_dim_type dim2_type)
381 int i;
383 if (!isl_dim_tuple_match(dim1, dim1_type, dim2, dim2_type))
384 return 0;
386 if (!dim1->names && !dim2->names)
387 return 1;
389 for (i = 0; i < n(dim1, dim1_type); ++i) {
390 if (get_name(dim1, dim1_type, i) !=
391 get_name(dim2, dim2_type, i))
392 return 0;
394 return 1;
397 int isl_dim_match(struct isl_dim *dim1, enum isl_dim_type dim1_type,
398 struct isl_dim *dim2, enum isl_dim_type dim2_type)
400 return match(dim1, dim1_type, dim2, dim2_type);
403 static void get_names(struct isl_dim *dim, enum isl_dim_type type,
404 unsigned first, unsigned n, struct isl_name **names)
406 int i;
408 for (i = 0; i < n ; ++i)
409 names[i] = get_name(dim, type, first+i);
412 struct isl_dim *isl_dim_extend(struct isl_dim *dim,
413 unsigned nparam, unsigned n_in, unsigned n_out)
415 struct isl_name **names = NULL;
417 if (!dim)
418 return NULL;
419 if (dim->nparam == nparam && dim->n_in == n_in && dim->n_out == n_out)
420 return dim;
422 isl_assert(dim->ctx, dim->nparam <= nparam, goto error);
423 isl_assert(dim->ctx, dim->n_in <= n_in, goto error);
424 isl_assert(dim->ctx, dim->n_out <= n_out, goto error);
426 dim = isl_dim_cow(dim);
428 if (dim->names) {
429 names = isl_calloc_array(dim->ctx, struct isl_name *,
430 nparam + n_in + n_out);
431 if (!names)
432 goto error;
433 get_names(dim, isl_dim_param, 0, dim->nparam, names);
434 get_names(dim, isl_dim_in, 0, dim->n_in, names + nparam);
435 get_names(dim, isl_dim_out, 0, dim->n_out,
436 names + nparam + n_in);
437 free(dim->names);
438 dim->names = names;
439 dim->n_name = nparam + n_in + n_out;
441 dim->nparam = nparam;
442 dim->n_in = n_in;
443 dim->n_out = n_out;
445 return dim;
446 error:
447 free(names);
448 isl_dim_free(dim);
449 return NULL;
452 struct isl_dim *isl_dim_add(struct isl_dim *dim, enum isl_dim_type type,
453 unsigned n)
455 if (!dim)
456 return NULL;
457 if ((type == isl_dim_in || type == isl_dim_out) &&
458 dim->tuple_name[type - isl_dim_in]) {
459 dim = isl_dim_cow(dim);
460 if (!dim)
461 return NULL;
462 isl_name_free(dim->ctx, dim->tuple_name[type - isl_dim_in]);
463 dim->tuple_name[type - isl_dim_in] = NULL;
465 switch (type) {
466 case isl_dim_param:
467 return isl_dim_extend(dim,
468 dim->nparam + n, dim->n_in, dim->n_out);
469 case isl_dim_in:
470 return isl_dim_extend(dim,
471 dim->nparam, dim->n_in + n, dim->n_out);
472 case isl_dim_out:
473 return isl_dim_extend(dim,
474 dim->nparam, dim->n_in, dim->n_out + n);
476 return dim;
479 __isl_give isl_dim *isl_dim_insert(__isl_take isl_dim *dim,
480 enum isl_dim_type type, unsigned pos, unsigned n)
482 struct isl_name **names = NULL;
484 if (!dim)
485 return NULL;
486 if (n == 0 && !isl_dim_get_tuple_name(dim, type))
487 return dim;
489 isl_assert(dim->ctx, pos <= isl_dim_size(dim, type), goto error);
491 dim = isl_dim_cow(dim);
492 if (!dim)
493 return NULL;
495 if (dim->names) {
496 enum isl_dim_type t;
497 int off;
498 int size[3];
499 names = isl_calloc_array(dim->ctx, struct isl_name *,
500 dim->nparam + dim->n_in + dim->n_out + n);
501 if (!names)
502 goto error;
503 off = 0;
504 size[isl_dim_param] = dim->nparam;
505 size[isl_dim_in] = dim->n_in;
506 size[isl_dim_out] = dim->n_out;
507 for (t = isl_dim_param; t <= isl_dim_out; ++t) {
508 if (t != type) {
509 get_names(dim, t, 0, size[t], names + off);
510 off += size[t];
511 } else {
512 get_names(dim, t, 0, pos, names + off);
513 off += pos + n;
514 get_names(dim, t, pos, size[t]-pos, names+off);
515 off += size[t] - pos;
518 free(dim->names);
519 dim->names = names;
520 dim->n_name = dim->nparam + dim->n_in + dim->n_out + n;
522 switch (type) {
523 case isl_dim_param: dim->nparam += n; break;
524 case isl_dim_in: dim->n_in += n; break;
525 case isl_dim_out: dim->n_out += n; break;
527 if (type == isl_dim_in || type == isl_dim_out) {
528 isl_name_free(dim->ctx, dim->tuple_name[type - isl_dim_in]);
529 dim->tuple_name[type - isl_dim_in] = NULL;
532 return dim;
533 error:
534 isl_dim_free(dim);
535 return NULL;
538 __isl_give isl_dim *isl_dim_move(__isl_take isl_dim *dim,
539 enum isl_dim_type dst_type, unsigned dst_pos,
540 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
542 if (!dim)
543 return NULL;
544 if (n == 0)
545 return dim;
547 isl_assert(dim->ctx, src_pos + n <= isl_dim_size(dim, src_type),
548 goto error);
550 if (dst_type == src_type && dst_pos == src_pos)
551 return dim;
553 isl_assert(dim->ctx, dst_type != src_type, goto error);
555 dim = isl_dim_cow(dim);
556 if (!dim)
557 return NULL;
559 if (dim->names) {
560 struct isl_name **names;
561 enum isl_dim_type t;
562 int off;
563 int size[3];
564 names = isl_calloc_array(dim->ctx, struct isl_name *,
565 dim->nparam + dim->n_in + dim->n_out);
566 if (!names)
567 goto error;
568 off = 0;
569 size[isl_dim_param] = dim->nparam;
570 size[isl_dim_in] = dim->n_in;
571 size[isl_dim_out] = dim->n_out;
572 for (t = isl_dim_param; t <= isl_dim_out; ++t) {
573 if (t == dst_type) {
574 get_names(dim, t, 0, dst_pos, names + off);
575 off += dst_pos;
576 get_names(dim, src_type, src_pos, n, names+off);
577 off += n;
578 get_names(dim, t, dst_pos, size[t] - dst_pos,
579 names + off);
580 off += size[t] - dst_pos;
581 } else if (t == src_type) {
582 get_names(dim, t, 0, src_pos, names + off);
583 off += src_pos;
584 get_names(dim, t, src_pos + n,
585 size[t] - src_pos - n, names + off);
586 off += size[t] - src_pos - n;
587 } else {
588 get_names(dim, t, 0, size[t], names + off);
589 off += size[t];
592 free(dim->names);
593 dim->names = names;
594 dim->n_name = dim->nparam + dim->n_in + dim->n_out;
597 switch (dst_type) {
598 case isl_dim_param: dim->nparam += n; break;
599 case isl_dim_in: dim->n_in += n; break;
600 case isl_dim_out: dim->n_out += n; break;
603 switch (src_type) {
604 case isl_dim_param: dim->nparam -= n; break;
605 case isl_dim_in: dim->n_in -= n; break;
606 case isl_dim_out: dim->n_out -= n; break;
609 return dim;
610 error:
611 isl_dim_free(dim);
612 return NULL;
615 struct isl_dim *isl_dim_join(struct isl_dim *left, struct isl_dim *right)
617 struct isl_dim *dim;
619 if (!left || !right)
620 goto error;
622 isl_assert(left->ctx, match(left, isl_dim_param, right, isl_dim_param),
623 goto error);
624 isl_assert(left->ctx,
625 isl_dim_tuple_match(left, isl_dim_out, right, isl_dim_in),
626 goto error);
628 dim = isl_dim_alloc(left->ctx, left->nparam, left->n_in, right->n_out);
629 if (!dim)
630 goto error;
632 dim = copy_names(dim, isl_dim_param, 0, left, isl_dim_param);
633 dim = copy_names(dim, isl_dim_in, 0, left, isl_dim_in);
634 dim = copy_names(dim, isl_dim_out, 0, right, isl_dim_out);
636 if (dim && left->tuple_name[0] &&
637 !(dim->tuple_name[0] = isl_name_copy(dim->ctx, left->tuple_name[0])))
638 goto error;
639 if (dim && right->tuple_name[1] &&
640 !(dim->tuple_name[1] = isl_name_copy(dim->ctx, right->tuple_name[1])))
641 goto error;
643 isl_dim_free(left);
644 isl_dim_free(right);
646 return dim;
647 error:
648 isl_dim_free(left);
649 isl_dim_free(right);
650 return NULL;
653 struct isl_dim *isl_dim_product(struct isl_dim *left, struct isl_dim *right)
655 struct isl_dim *dim;
657 if (!left || !right)
658 goto error;
660 isl_assert(left->ctx, match(left, isl_dim_param, right, isl_dim_param),
661 goto error);
663 dim = isl_dim_alloc(left->ctx, left->nparam,
664 left->n_in + right->n_in, left->n_out + right->n_out);
665 if (!dim)
666 goto error;
668 dim = copy_names(dim, isl_dim_param, 0, left, isl_dim_param);
669 dim = copy_names(dim, isl_dim_in, 0, left, isl_dim_in);
670 dim = copy_names(dim, isl_dim_in, left->n_in, right, isl_dim_in);
671 dim = copy_names(dim, isl_dim_out, 0, left, isl_dim_out);
672 dim = copy_names(dim, isl_dim_out, left->n_out, right, isl_dim_out);
674 isl_dim_free(left);
675 isl_dim_free(right);
677 return dim;
678 error:
679 isl_dim_free(left);
680 isl_dim_free(right);
681 return NULL;
684 struct isl_dim *isl_dim_map(struct isl_dim *dim)
686 struct isl_name **names = NULL;
688 if (!dim)
689 return NULL;
690 isl_assert(dim->ctx, dim->n_in == 0, goto error);
691 if (dim->n_out == 0 && !dim->tuple_name[1])
692 return dim;
693 dim = isl_dim_cow(dim);
694 if (!dim)
695 return NULL;
696 if (dim->names) {
697 names = isl_calloc_array(dim->ctx, struct isl_name *,
698 dim->nparam + dim->n_out + dim->n_out);
699 if (!names)
700 goto error;
701 get_names(dim, isl_dim_param, 0, dim->nparam, names);
702 get_names(dim, isl_dim_out, 0, dim->n_out, names + dim->nparam);
704 dim->n_in = dim->n_out;
705 if (names) {
706 free(dim->names);
707 dim->names = names;
708 dim->n_name = dim->nparam + dim->n_out + dim->n_out;
709 dim = copy_names(dim, isl_dim_out, 0, dim, isl_dim_in);
711 isl_name_free(dim->ctx, dim->tuple_name[0]);
712 dim->tuple_name[0] = isl_name_copy(dim->ctx, dim->tuple_name[1]);
713 return dim;
714 error:
715 isl_dim_free(dim);
716 return NULL;
719 static struct isl_dim *set_names(struct isl_dim *dim, enum isl_dim_type type,
720 unsigned first, unsigned n, struct isl_name **names)
722 int i;
724 for (i = 0; i < n ; ++i)
725 dim = set_name(dim, type, first+i, names[i]);
727 return dim;
730 struct isl_dim *isl_dim_reverse(struct isl_dim *dim)
732 unsigned t;
733 struct isl_name **names = NULL;
734 struct isl_name *name;
736 if (!dim)
737 return NULL;
738 if (match(dim, isl_dim_in, dim, isl_dim_out))
739 return dim;
741 dim = isl_dim_cow(dim);
742 if (!dim)
743 return NULL;
745 name = dim->tuple_name[0];
746 dim->tuple_name[0] = dim->tuple_name[1];
747 dim->tuple_name[1] = name;
749 if (dim->names) {
750 names = isl_alloc_array(dim->ctx, struct isl_name *,
751 dim->n_in + dim->n_out);
752 if (!names)
753 goto error;
754 get_names(dim, isl_dim_in, 0, dim->n_in, names);
755 get_names(dim, isl_dim_out, 0, dim->n_out, names + dim->n_in);
758 t = dim->n_in;
759 dim->n_in = dim->n_out;
760 dim->n_out = t;
762 if (dim->names) {
763 dim = set_names(dim, isl_dim_out, 0, dim->n_out, names);
764 dim = set_names(dim, isl_dim_in, 0, dim->n_in, names + dim->n_out);
765 free(names);
768 return dim;
769 error:
770 free(names);
771 isl_dim_free(dim);
772 return NULL;
775 struct isl_dim *isl_dim_drop(struct isl_dim *dim, enum isl_dim_type type,
776 unsigned first, unsigned num)
778 int i;
780 if (!dim)
781 return NULL;
783 if (n == 0 && !isl_dim_get_tuple_name(dim, type))
784 return dim;
786 isl_assert(dim->ctx, first + num <= n(dim, type), goto error);
787 dim = isl_dim_cow(dim);
788 if (!dim)
789 goto error;
790 if (dim->names) {
791 dim = extend_names(dim);
792 if (!dim)
793 goto error;
794 for (i = 0; i < num; ++i)
795 isl_name_free(dim->ctx, get_name(dim, type, first+i));
796 for (i = first+num; i < n(dim, type); ++i)
797 set_name(dim, type, i - num, get_name(dim, type, i));
798 switch (type) {
799 case isl_dim_param:
800 get_names(dim, isl_dim_in, 0, dim->n_in,
801 dim->names + offset(dim, isl_dim_in) - num);
802 case isl_dim_in:
803 get_names(dim, isl_dim_out, 0, dim->n_out,
804 dim->names + offset(dim, isl_dim_out) - num);
805 case isl_dim_out:
808 dim->n_name -= num;
810 switch (type) {
811 case isl_dim_param: dim->nparam -= num; break;
812 case isl_dim_in: dim->n_in -= num; break;
813 case isl_dim_out: dim->n_out -= num; break;
815 if (type == isl_dim_in || type == isl_dim_out) {
816 isl_name_free(dim->ctx, dim->tuple_name[type - isl_dim_in]);
817 dim->tuple_name[type - isl_dim_in] = NULL;
819 return dim;
820 error:
821 isl_dim_free(dim);
822 return NULL;
825 struct isl_dim *isl_dim_drop_inputs(struct isl_dim *dim,
826 unsigned first, unsigned n)
828 if (!dim)
829 return NULL;
830 return isl_dim_drop(dim, isl_dim_in, first, n);
833 struct isl_dim *isl_dim_drop_outputs(struct isl_dim *dim,
834 unsigned first, unsigned n)
836 if (!dim)
837 return NULL;
838 return isl_dim_drop(dim, isl_dim_out, first, n);
841 struct isl_dim *isl_dim_domain(struct isl_dim *dim)
843 if (!dim)
844 return NULL;
845 dim = isl_dim_drop_outputs(dim, 0, dim->n_out);
846 return isl_dim_reverse(dim);
849 struct isl_dim *isl_dim_range(struct isl_dim *dim)
851 if (!dim)
852 return NULL;
853 return isl_dim_drop_inputs(dim, 0, dim->n_in);
856 __isl_give isl_dim *isl_dim_as_set_dim(__isl_take isl_dim *dim)
858 dim = isl_dim_cow(dim);
859 if (!dim)
860 return NULL;
862 dim->n_out += dim->n_in;
863 dim->n_in = 0;
864 isl_name_free(dim->ctx, dim->tuple_name[0]);
865 isl_name_free(dim->ctx, dim->tuple_name[1]);
866 dim->tuple_name[0] = NULL;
867 dim->tuple_name[1] = NULL;
869 return dim;
872 struct isl_dim *isl_dim_underlying(struct isl_dim *dim, unsigned n_div)
874 int i;
876 if (!dim)
877 return NULL;
878 if (n_div == 0 &&
879 dim->nparam == 0 && dim->n_in == 0 && dim->n_name == 0 &&
880 !dim->tuple_name[1])
881 return dim;
882 dim = isl_dim_cow(dim);
883 if (!dim)
884 return NULL;
885 dim->n_out += dim->nparam + dim->n_in + n_div;
886 dim->nparam = 0;
887 dim->n_in = 0;
889 for (i = 0; i < dim->n_name; ++i)
890 isl_name_free(dim->ctx, get_name(dim, isl_dim_out, i));
891 dim->n_name = 0;
892 isl_name_free(dim->ctx, dim->tuple_name[0]);
893 isl_name_free(dim->ctx, dim->tuple_name[1]);
894 dim->tuple_name[0] = NULL;
895 dim->tuple_name[1] = NULL;
897 return dim;
900 unsigned isl_dim_total(struct isl_dim *dim)
902 return dim->nparam + dim->n_in + dim->n_out;
905 int isl_dim_equal(struct isl_dim *dim1, struct isl_dim *dim2)
907 return match(dim1, isl_dim_param, dim2, isl_dim_param) &&
908 isl_dim_tuple_match(dim1, isl_dim_in, dim2, isl_dim_in) &&
909 isl_dim_tuple_match(dim1, isl_dim_out, dim2, isl_dim_out);
912 int isl_dim_compatible(struct isl_dim *dim1, struct isl_dim *dim2)
914 return dim1->nparam == dim2->nparam &&
915 dim1->n_in + dim1->n_out == dim2->n_in + dim2->n_out;
918 uint32_t isl_dim_get_hash(__isl_keep isl_dim *dim)
920 int i;
921 uint32_t hash;
922 struct isl_name *name;
924 if (!dim)
925 return 0;
926 hash = isl_hash_init();
928 hash = isl_hash_builtin(hash, dim->nparam);
929 hash = isl_hash_builtin(hash, dim->n_in);
930 hash = isl_hash_builtin(hash, dim->n_out);
932 for (i = 0; i < dim->nparam; ++i) {
933 name = get_name(dim, isl_dim_param, i);
934 hash = isl_hash_builtin(hash, name);
937 name = tuple_name(dim, isl_dim_in);
938 hash = isl_hash_builtin(hash, name);
939 name = tuple_name(dim, isl_dim_out);
940 hash = isl_hash_builtin(hash, name);
942 return hash;