Bug Summary

File:polly/lib/External/isl/isl_space.c
Warning:line 481, column 2
Value stored to 'dummy' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name isl_space.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/polly/lib/External -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/imath -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/polly/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/pet/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/include -D NDEBUG -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=gnu99 -fconst-strings -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/polly/lib/External -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e=. -ferror-limit 19 -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2021-09-04-040900-46481-1 -x c /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c
1/*
2 * Copyright 2008-2009 Katholieke Universiteit Leuven
3 * Copyright 2010 INRIA Saclay
4 * Copyright 2013-2014 Ecole Normale Superieure
5 * Copyright 2018-2019 Cerebras Systems
6 *
7 * Use of this software is governed by the MIT license
8 *
9 * Written by Sven Verdoolaege, K.U.Leuven, Departement
10 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
11 * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
12 * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
13 * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
14 * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA
15 */
16
17#include <stdlib.h>
18#include <string.h>
19#include <isl_space_private.h>
20#include <isl_id_private.h>
21#include <isl_reordering.h>
22
23isl_ctx *isl_space_get_ctx(__isl_keep isl_space *space)
24{
25 return space ? space->ctx : NULL((void*)0);
26}
27
28__isl_give isl_space *isl_space_alloc(isl_ctx *ctx,
29 unsigned nparam, unsigned n_in, unsigned n_out)
30{
31 isl_space *space;
32
33 space = isl_alloc_type(ctx, struct isl_space)((struct isl_space *)isl_malloc_or_die(ctx, sizeof(struct isl_space
)))
;
34 if (!space)
35 return NULL((void*)0);
36
37 space->ctx = ctx;
38 isl_ctx_ref(ctx);
39 space->ref = 1;
40 space->nparam = nparam;
41 space->n_in = n_in;
42 space->n_out = n_out;
43
44 space->tuple_id[0] = NULL((void*)0);
45 space->tuple_id[1] = NULL((void*)0);
46
47 space->nested[0] = NULL((void*)0);
48 space->nested[1] = NULL((void*)0);
49
50 space->n_id = 0;
51 space->ids = NULL((void*)0);
52
53 return space;
54}
55
56/* Mark the space as being that of a set, by setting the domain tuple
57 * to isl_id_none.
58 */
59static __isl_give isl_space *mark_as_set(__isl_take isl_space *space)
60{
61 space = isl_space_cow(space);
62 if (!space)
63 return NULL((void*)0);
64 space = isl_space_set_tuple_id(space, isl_dim_in, &isl_id_none);
65 return space;
66}
67
68/* Is the space that of a set?
69 */
70isl_bool isl_space_is_set(__isl_keep isl_space *space)
71{
72 if (!space)
73 return isl_bool_error;
74 if (space->n_in != 0 || space->nested[0])
75 return isl_bool_false;
76 if (space->tuple_id[0] != &isl_id_none)
77 return isl_bool_false;
78 return isl_bool_true;
79}
80
81/* Check that "space" is a set space.
82 */
83isl_stat isl_space_check_is_set(__isl_keep isl_space *space)
84{
85 isl_bool is_set;
86
87 is_set = isl_space_is_set(space);
88 if (is_set < 0)
89 return isl_stat_error;
90 if (!is_set)
91 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "space is not a set", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 92); return isl_stat_error; } while (0)
92 "space is not a set", return isl_stat_error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "space is not a set", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 92); return isl_stat_error; } while (0)
;
93 return isl_stat_ok;
94}
95
96/* Is the given space that of a map?
97 */
98isl_bool isl_space_is_map(__isl_keep isl_space *space)
99{
100 int r;
101
102 if (!space)
103 return isl_bool_error;
104 r = space->tuple_id[0] != &isl_id_none &&
105 space->tuple_id[1] != &isl_id_none;
106 return isl_bool_ok(r);
107}
108
109/* Check that "space" is the space of a map.
110 */
111static isl_stat isl_space_check_is_map(__isl_keep isl_space *space)
112{
113 isl_bool is_space;
114
115 is_space = isl_space_is_map(space);
116 if (is_space < 0)
117 return isl_stat_error;
118 if (!is_space)
119 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "expecting map space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 120); return isl_stat_error; } while (0)
120 "expecting map space", return isl_stat_error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "expecting map space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 120); return isl_stat_error; } while (0)
;
121 return isl_stat_ok;
122}
123
124/* Check that "space" is the space of a map
125 * where the domain is a wrapped map space.
126 */
127isl_stat isl_space_check_domain_is_wrapping(__isl_keep isl_space *space)
128{
129 isl_bool wrapping;
130
131 wrapping = isl_space_domain_is_wrapping(space);
132 if (wrapping < 0)
133 return isl_stat_error;
134 if (!wrapping)
135 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "domain not a product", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 136); return isl_stat_error; } while (0)
136 "domain not a product", return isl_stat_error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "domain not a product", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 136); return isl_stat_error; } while (0)
;
137 return isl_stat_ok;
138}
139
140/* Check that "space" is the space of a map
141 * where the range is a wrapped map space.
142 */
143isl_stat isl_space_check_range_is_wrapping(__isl_keep isl_space *space)
144{
145 isl_bool wrapping;
146
147 wrapping = isl_space_range_is_wrapping(space);
148 if (wrapping < 0)
149 return isl_stat_error;
150 if (!wrapping)
151 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "range not a product", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 152); return isl_stat_error; } while (0)
152 "range not a product", return isl_stat_error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "range not a product", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 152); return isl_stat_error; } while (0)
;
153 return isl_stat_ok;
154}
155
156__isl_give isl_space *isl_space_set_alloc(isl_ctx *ctx,
157 unsigned nparam, unsigned dim)
158{
159 isl_space *space;
160 space = isl_space_alloc(ctx, nparam, 0, dim);
161 space = mark_as_set(space);
162 return space;
163}
164
165/* Mark the space as being that of a parameter domain, by setting
166 * both tuples to isl_id_none.
167 */
168static __isl_give isl_space *mark_as_params(isl_space *space)
169{
170 if (!space)
171 return NULL((void*)0);
172 space = isl_space_set_tuple_id(space, isl_dim_in, &isl_id_none);
173 space = isl_space_set_tuple_id(space, isl_dim_out, &isl_id_none);
174 return space;
175}
176
177/* Is the space that of a parameter domain?
178 */
179isl_bool isl_space_is_params(__isl_keep isl_space *space)
180{
181 if (!space)
182 return isl_bool_error;
183 if (space->n_in != 0 || space->nested[0] ||
184 space->n_out != 0 || space->nested[1])
185 return isl_bool_false;
186 if (space->tuple_id[0] != &isl_id_none)
187 return isl_bool_false;
188 if (space->tuple_id[1] != &isl_id_none)
189 return isl_bool_false;
190 return isl_bool_true;
191}
192
193/* Create a space for a parameter domain.
194 */
195__isl_give isl_space *isl_space_params_alloc(isl_ctx *ctx, unsigned nparam)
196{
197 isl_space *space;
198 space = isl_space_alloc(ctx, nparam, 0, 0);
199 space = mark_as_params(space);
200 return space;
201}
202
203/* Create a space for a parameter domain, without any parameters.
204 */
205__isl_give isl_space *isl_space_unit(isl_ctx *ctx)
206{
207 return isl_space_params_alloc(ctx, 0);
208}
209
210static isl_size global_pos(__isl_keep isl_space *space,
211 enum isl_dim_type type, unsigned pos)
212{
213 if (isl_space_check_range(space, type, pos, 1) < 0)
214 return isl_size_error((int) -1);
215
216 switch (type) {
217 case isl_dim_param:
218 return pos;
219 case isl_dim_in:
220 return pos + space->nparam;
221 case isl_dim_out:
222 return pos + space->nparam + space->n_in;
223 default:
224 isl_assert(isl_space_get_ctx(space), 0, return isl_size_error)do { if (0) break; do { isl_handle_error(isl_space_get_ctx(space
), isl_error_unknown, "Assertion \"" "0" "\" failed", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 224); return ((int) -1); } while (0); } while (0)
;
225 }
226 return isl_size_error((int) -1);
227}
228
229/* Extend length of ids array to the total number of dimensions.
230 */
231static __isl_give isl_space *extend_ids(__isl_take isl_space *space)
232{
233 isl_id **ids;
234 int i;
235 isl_size dim;
236
237 dim = isl_space_dim(space, isl_dim_all);
238 if (dim < 0)
239 return isl_space_free(space);
240 if (dim <= space->n_id)
241 return space;
242
243 if (!space->ids) {
244 space->ids = isl_calloc_array(space->ctx, isl_id *, dim)((isl_id * *)isl_calloc_or_die(space->ctx, dim, sizeof(isl_id
*)))
;
245 if (!space->ids)
246 goto error;
247 } else {
248 ids = isl_realloc_array(space->ctx, space->ids, isl_id *, dim)((isl_id * *)isl_realloc_or_die(space->ctx, space->ids,
(dim)*sizeof(isl_id *)))
;
249 if (!ids)
250 goto error;
251 space->ids = ids;
252 for (i = space->n_id; i < dim; ++i)
253 space->ids[i] = NULL((void*)0);
254 }
255
256 space->n_id = dim;
257
258 return space;
259error:
260 isl_space_free(space);
261 return NULL((void*)0);
262}
263
264static __isl_give isl_space *set_id(__isl_take isl_space *space,
265 enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
266{
267 isl_size gpos;
268
269 space = isl_space_cow(space);
270
271 gpos = global_pos(space, type, pos);
272 if (gpos < 0)
273 goto error;
274
275 if (gpos >= space->n_id) {
276 if (!id)
277 return space;
278 space = extend_ids(space);
279 if (!space)
280 goto error;
281 }
282
283 space->ids[gpos] = id;
284
285 return space;
286error:
287 isl_id_free(id);
288 isl_space_free(space);
289 return NULL((void*)0);
290}
291
292static __isl_keep isl_id *get_id(__isl_keep isl_space *space,
293 enum isl_dim_type type, unsigned pos)
294{
295 isl_size gpos;
296
297 gpos = global_pos(space, type, pos);
298 if (gpos < 0)
299 return NULL((void*)0);
300 if (gpos >= space->n_id)
301 return NULL((void*)0);
302 return space->ids[gpos];
303}
304
305/* Return the nested space at the given position.
306 */
307static __isl_keep isl_space *isl_space_peek_nested(__isl_keep isl_space *space,
308 int pos)
309{
310 if (!space)
311 return NULL((void*)0);
312 if (!space->nested[pos])
313 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "no nested space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 314); return ((void*)0); } while (0)
314 "no nested space", return NULL)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "no nested space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 314); return ((void*)0); } while (0)
;
315 return space->nested[pos];
316}
317
318static unsigned offset(__isl_keep isl_space *space, enum isl_dim_type type)
319{
320 switch (type) {
321 case isl_dim_param: return 0;
322 case isl_dim_in: return space->nparam;
323 case isl_dim_out: return space->nparam + space->n_in;
324 default: return 0;
325 }
326}
327
328static unsigned n(__isl_keep isl_space *space, enum isl_dim_type type)
329{
330 switch (type) {
331 case isl_dim_param: return space->nparam;
332 case isl_dim_in: return space->n_in;
333 case isl_dim_out: return space->n_out;
334 case isl_dim_all:
335 return space->nparam + space->n_in + space->n_out;
336 default: return 0;
337 }
338}
339
340isl_size isl_space_dim(__isl_keep isl_space *space, enum isl_dim_type type)
341{
342 if (!space)
343 return isl_size_error((int) -1);
344 return n(space, type);
345}
346
347/* Return the dimensionality of tuple "inner" within the wrapped relation
348 * inside tuple "outer".
349 */
350isl_size isl_space_wrapped_dim(__isl_keep isl_space *space,
351 enum isl_dim_type outer, enum isl_dim_type inner)
352{
353 int pos;
354
355 if (!space)
356 return isl_size_error((int) -1);
357 if (outer != isl_dim_in && outer != isl_dim_out)
358 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "only input, output and set tuples " "can have nested relations"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 360); return ((int) -1); } while (0)
359 "only input, output and set tuples "do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "only input, output and set tuples " "can have nested relations"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 360); return ((int) -1); } while (0)
360 "can have nested relations", return isl_size_error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "only input, output and set tuples " "can have nested relations"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 360); return ((int) -1); } while (0)
;
361 pos = outer - isl_dim_in;
362 return isl_space_dim(isl_space_peek_nested(space, pos), inner);
363}
364
365unsigned isl_space_offset(__isl_keep isl_space *space, enum isl_dim_type type)
366{
367 if (!space)
368 return 0;
369 return offset(space, type);
370}
371
372static __isl_give isl_space *copy_ids(__isl_take isl_space *dst,
373 enum isl_dim_type dst_type, unsigned offset, __isl_keep isl_space *src,
374 enum isl_dim_type src_type)
375{
376 int i;
377 isl_id *id;
378
379 if (!dst)
380 return NULL((void*)0);
381
382 for (i = 0; i < n(src, src_type); ++i) {
383 id = get_id(src, src_type, i);
384 if (!id)
385 continue;
386 dst = set_id(dst, dst_type, offset + i, isl_id_copy(id));
387 if (!dst)
388 return NULL((void*)0);
389 }
390 return dst;
391}
392
393__isl_take isl_space *isl_space_dup(__isl_keep isl_space *space)
394{
395 isl_space *dup;
396 if (!space)
397 return NULL((void*)0);
398 dup = isl_space_alloc(space->ctx,
399 space->nparam, space->n_in, space->n_out);
400 if (!dup)
401 return NULL((void*)0);
402 if (space->tuple_id[0] &&
403 !(dup->tuple_id[0] = isl_id_copy(space->tuple_id[0])))
404 goto error;
405 if (space->tuple_id[1] &&
406 !(dup->tuple_id[1] = isl_id_copy(space->tuple_id[1])))
407 goto error;
408 if (space->nested[0] &&
409 !(dup->nested[0] = isl_space_copy(space->nested[0])))
410 goto error;
411 if (space->nested[1] &&
412 !(dup->nested[1] = isl_space_copy(space->nested[1])))
413 goto error;
414 if (!space->ids)
415 return dup;
416 dup = copy_ids(dup, isl_dim_param, 0, space, isl_dim_param);
417 dup = copy_ids(dup, isl_dim_in, 0, space, isl_dim_in);
418 dup = copy_ids(dup, isl_dim_out, 0, space, isl_dim_out);
419 return dup;
420error:
421 isl_space_free(dup);
422 return NULL((void*)0);
423}
424
425__isl_give isl_space *isl_space_cow(__isl_take isl_space *space)
426{
427 if (!space)
428 return NULL((void*)0);
429
430 if (space->ref == 1)
431 return space;
432 space->ref--;
433 return isl_space_dup(space);
434}
435
436__isl_give isl_space *isl_space_copy(__isl_keep isl_space *space)
437{
438 if (!space)
439 return NULL((void*)0);
440
441 space->ref++;
442 return space;
443}
444
445__isl_null isl_space *isl_space_free(__isl_take isl_space *space)
446{
447 int i;
448
449 if (!space)
450 return NULL((void*)0);
451
452 if (--space->ref > 0)
453 return NULL((void*)0);
454
455 isl_id_free(space->tuple_id[0]);
456 isl_id_free(space->tuple_id[1]);
457
458 isl_space_free(space->nested[0]);
459 isl_space_free(space->nested[1]);
460
461 for (i = 0; i < space->n_id; ++i)
462 isl_id_free(space->ids[i]);
463 free(space->ids);
464 isl_ctx_deref(space->ctx);
465
466 free(space);
467
468 return NULL((void*)0);
469}
470
471/* Check if "s" is a valid dimension or tuple name.
472 * We currently only forbid names that look like a number.
473 *
474 * s is assumed to be non-NULL.
475 */
476static int name_ok(isl_ctx *ctx, const char *s)
477{
478 char *p;
479 long dummy;
480
481 dummy = strtol(s, &p, 0);
Value stored to 'dummy' is never read
482 if (p != s)
483 isl_die(ctx, isl_error_invalid, "name looks like a number",do { isl_handle_error(ctx, isl_error_invalid, "name looks like a number"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 484); return 0; } while (0)
484 return 0)do { isl_handle_error(ctx, isl_error_invalid, "name looks like a number"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 484); return 0; } while (0)
;
485
486 return 1;
487}
488
489/* Return a copy of the nested space at the given position.
490 */
491static __isl_keep isl_space *isl_space_get_nested(__isl_keep isl_space *space,
492 int pos)
493{
494 return isl_space_copy(isl_space_peek_nested(space, pos));
495}
496
497/* Return the nested space at the given position.
498 * This may be either a copy or the nested space itself
499 * if there is only one reference to "space".
500 * This allows the nested space to be modified inplace
501 * if both "space" and the nested space have only a single reference.
502 * The caller is not allowed to modify "space" between this call and
503 * a subsequent call to isl_space_restore_nested.
504 * The only exception is that isl_space_free can be called instead.
505 */
506static __isl_give isl_space *isl_space_take_nested(__isl_keep isl_space *space,
507 int pos)
508{
509 isl_space *nested;
510
511 if (!space)
512 return NULL((void*)0);
513 if (space->ref != 1)
514 return isl_space_get_nested(space, pos);
515 nested = space->nested[pos];
516 space->nested[pos] = NULL((void*)0);
517 return nested;
518}
519
520/* Replace the nested space at the given position by "nested",
521 * where this nested space of "space" may be missing
522 * due to a preceding call to isl_space_take_nested.
523 * However, in this case, "space" only has a single reference and
524 * then the call to isl_space_cow has no effect.
525 */
526static __isl_give isl_space *isl_space_restore_nested(
527 __isl_take isl_space *space, int pos, __isl_take isl_space *nested)
528{
529 if (!space || !nested)
530 goto error;
531
532 if (space->nested[pos] == nested) {
533 isl_space_free(nested);
534 return space;
535 }
536
537 space = isl_space_cow(space);
538 if (!space)
539 goto error;
540 isl_space_free(space->nested[pos]);
541 space->nested[pos] = nested;
542
543 return space;
544error:
545 isl_space_free(space);
546 isl_space_free(nested);
547 return NULL((void*)0);
548}
549
550/* Is it possible for the given dimension type to have a tuple id?
551 */
552static int space_can_have_id(__isl_keep isl_space *space,
553 enum isl_dim_type type)
554{
555 if (!space)
556 return 0;
557 if (isl_space_is_params(space))
558 isl_die(space->ctx, isl_error_invalid,do { isl_handle_error(space->ctx, isl_error_invalid, "parameter spaces don't have tuple ids"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 559); return 0; } while (0)
559 "parameter spaces don't have tuple ids", return 0)do { isl_handle_error(space->ctx, isl_error_invalid, "parameter spaces don't have tuple ids"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 559); return 0; } while (0)
;
560 if (isl_space_is_set(space) && type != isl_dim_set)
561 isl_die(space->ctx, isl_error_invalid,do { isl_handle_error(space->ctx, isl_error_invalid, "set spaces can only have a set id"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 562); return 0; } while (0)
562 "set spaces can only have a set id", return 0)do { isl_handle_error(space->ctx, isl_error_invalid, "set spaces can only have a set id"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 562); return 0; } while (0)
;
563 if (type != isl_dim_in && type != isl_dim_out)
564 isl_die(space->ctx, isl_error_invalid,do { isl_handle_error(space->ctx, isl_error_invalid, "only input, output and set tuples can have ids"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 566); return 0; } while (0)
565 "only input, output and set tuples can have ids",do { isl_handle_error(space->ctx, isl_error_invalid, "only input, output and set tuples can have ids"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 566); return 0; } while (0)
566 return 0)do { isl_handle_error(space->ctx, isl_error_invalid, "only input, output and set tuples can have ids"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 566); return 0; } while (0)
;
567
568 return 1;
569}
570
571/* Does the tuple have an id?
572 */
573isl_bool isl_space_has_tuple_id(__isl_keep isl_space *space,
574 enum isl_dim_type type)
575{
576 if (!space_can_have_id(space, type))
577 return isl_bool_error;
578 return isl_bool_ok(space->tuple_id[type - isl_dim_in] != NULL((void*)0));
579}
580
581/* Does the domain tuple of the map space "space" have an identifier?
582 */
583isl_bool isl_space_has_domain_tuple_id(__isl_keep isl_space *space)
584{
585 if (isl_space_check_is_map(space) < 0)
586 return isl_bool_error;
587 return isl_space_has_tuple_id(space, isl_dim_in);
588}
589
590/* Does the range tuple of the map space "space" have an identifier?
591 */
592isl_bool isl_space_has_range_tuple_id(__isl_keep isl_space *space)
593{
594 if (isl_space_check_is_map(space) < 0)
595 return isl_bool_error;
596 return isl_space_has_tuple_id(space, isl_dim_out);
597}
598
599__isl_give isl_id *isl_space_get_tuple_id(__isl_keep isl_space *space,
600 enum isl_dim_type type)
601{
602 int has_id;
603
604 if (!space)
605 return NULL((void*)0);
606 has_id = isl_space_has_tuple_id(space, type);
607 if (has_id < 0)
608 return NULL((void*)0);
609 if (!has_id)
610 isl_die(space->ctx, isl_error_invalid,do { isl_handle_error(space->ctx, isl_error_invalid, "tuple has no id"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 611); return ((void*)0); } while (0)
611 "tuple has no id", return NULL)do { isl_handle_error(space->ctx, isl_error_invalid, "tuple has no id"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 611); return ((void*)0); } while (0)
;
612 return isl_id_copy(space->tuple_id[type - isl_dim_in]);
613}
614
615/* Return the identifier of the domain tuple of the map space "space",
616 * assuming it has one.
617 */
618__isl_give isl_id *isl_space_get_domain_tuple_id(
619 __isl_keep isl_space *space)
620{
621 if (isl_space_check_is_map(space) < 0)
622 return NULL((void*)0);
623 return isl_space_get_tuple_id(space, isl_dim_in);
624}
625
626/* Return the identifier of the range tuple of the map space "space",
627 * assuming it has one.
628 */
629__isl_give isl_id *isl_space_get_range_tuple_id(
630 __isl_keep isl_space *space)
631{
632 if (isl_space_check_is_map(space) < 0)
633 return NULL((void*)0);
634 return isl_space_get_tuple_id(space, isl_dim_out);
635}
636
637__isl_give isl_space *isl_space_set_tuple_id(__isl_take isl_space *space,
638 enum isl_dim_type type, __isl_take isl_id *id)
639{
640 space = isl_space_cow(space);
641 if (!space || !id)
642 goto error;
643 if (type != isl_dim_in && type != isl_dim_out)
644 isl_die(space->ctx, isl_error_invalid,do { isl_handle_error(space->ctx, isl_error_invalid, "only input, output and set tuples can have names"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 646); goto error; } while (0)
645 "only input, output and set tuples can have names",do { isl_handle_error(space->ctx, isl_error_invalid, "only input, output and set tuples can have names"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 646); goto error; } while (0)
646 goto error)do { isl_handle_error(space->ctx, isl_error_invalid, "only input, output and set tuples can have names"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 646); goto error; } while (0)
;
647
648 isl_id_free(space->tuple_id[type - isl_dim_in]);
649 space->tuple_id[type - isl_dim_in] = id;
650
651 return space;
652error:
653 isl_id_free(id);
654 isl_space_free(space);
655 return NULL((void*)0);
656}
657
658/* Replace the identifier of the domain tuple of the map space "space"
659 * by "id".
660 */
661__isl_give isl_space *isl_space_set_domain_tuple_id(
662 __isl_take isl_space *space, __isl_take isl_id *id)
663{
664 if (isl_space_check_is_map(space) < 0)
665 space = isl_space_free(space);
666 return isl_space_set_tuple_id(space, isl_dim_in, id);
667}
668
669/* Replace the identifier of the range tuple of the map space "space"
670 * by "id".
671 */
672__isl_give isl_space *isl_space_set_range_tuple_id(
673 __isl_take isl_space *space, __isl_take isl_id *id)
674{
675 if (isl_space_check_is_map(space) < 0)
676 space = isl_space_free(space);
677 return isl_space_set_tuple_id(space, isl_dim_out, id);
678}
679
680__isl_give isl_space *isl_space_reset_tuple_id(__isl_take isl_space *space,
681 enum isl_dim_type type)
682{
683 space = isl_space_cow(space);
684 if (!space)
685 return NULL((void*)0);
686 if (type != isl_dim_in && type != isl_dim_out)
687 isl_die(space->ctx, isl_error_invalid,do { isl_handle_error(space->ctx, isl_error_invalid, "only input, output and set tuples can have names"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 689); goto error; } while (0)
688 "only input, output and set tuples can have names",do { isl_handle_error(space->ctx, isl_error_invalid, "only input, output and set tuples can have names"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 689); goto error; } while (0)
689 goto error)do { isl_handle_error(space->ctx, isl_error_invalid, "only input, output and set tuples can have names"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 689); goto error; } while (0)
;
690
691 isl_id_free(space->tuple_id[type - isl_dim_in]);
692 space->tuple_id[type - isl_dim_in] = NULL((void*)0);
693
694 return space;
695error:
696 isl_space_free(space);
697 return NULL((void*)0);
698}
699
700/* Set the id of the given dimension of "space" to "id".
701 * If the dimension already has an id, then it is replaced.
702 * If the dimension is a parameter, then we need to change it
703 * in the nested spaces (if any) as well.
704 */
705__isl_give isl_space *isl_space_set_dim_id(__isl_take isl_space *space,
706 enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
707{
708 space = isl_space_cow(space);
709 if (!space || !id)
710 goto error;
711
712 if (type == isl_dim_param) {
713 int i;
714
715 for (i = 0; i < 2; ++i) {
716 if (!space->nested[i])
717 continue;
718 space->nested[i] =
719 isl_space_set_dim_id(space->nested[i],
720 type, pos, isl_id_copy(id));
721 if (!space->nested[i])
722 goto error;
723 }
724 }
725
726 isl_id_free(get_id(space, type, pos));
727 return set_id(space, type, pos, id);
728error:
729 isl_id_free(id);
730 isl_space_free(space);
731 return NULL((void*)0);
732}
733
734/* Reset the id of the given dimension of "space".
735 * If the dimension already has an id, then it is removed.
736 * If the dimension is a parameter, then we need to reset it
737 * in the nested spaces (if any) as well.
738 */
739__isl_give isl_space *isl_space_reset_dim_id(__isl_take isl_space *space,
740 enum isl_dim_type type, unsigned pos)
741{
742 space = isl_space_cow(space);
743 if (!space)
744 goto error;
745
746 if (type == isl_dim_param) {
747 int i;
748
749 for (i = 0; i < 2; ++i) {
750 if (!space->nested[i])
751 continue;
752 space->nested[i] =
753 isl_space_reset_dim_id(space->nested[i],
754 type, pos);
755 if (!space->nested[i])
756 goto error;
757 }
758 }
759
760 isl_id_free(get_id(space, type, pos));
761 return set_id(space, type, pos, NULL((void*)0));
762error:
763 isl_space_free(space);
764 return NULL((void*)0);
765}
766
767isl_bool isl_space_has_dim_id(__isl_keep isl_space *space,
768 enum isl_dim_type type, unsigned pos)
769{
770 if (!space)
771 return isl_bool_error;
772 return isl_bool_ok(get_id(space, type, pos) != NULL((void*)0));
773}
774
775__isl_give isl_id *isl_space_get_dim_id(__isl_keep isl_space *space,
776 enum isl_dim_type type, unsigned pos)
777{
778 if (!space)
779 return NULL((void*)0);
780 if (!get_id(space, type, pos))
781 isl_die(space->ctx, isl_error_invalid,do { isl_handle_error(space->ctx, isl_error_invalid, "dim has no id"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 782); return ((void*)0); } while (0)
782 "dim has no id", return NULL)do { isl_handle_error(space->ctx, isl_error_invalid, "dim has no id"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 782); return ((void*)0); } while (0)
;
783 return isl_id_copy(get_id(space, type, pos));
784}
785
786__isl_give isl_space *isl_space_set_tuple_name(__isl_take isl_space *space,
787 enum isl_dim_type type, const char *s)
788{
789 isl_id *id;
790
791 if (!space)
792 return NULL((void*)0);
793
794 if (!s)
795 return isl_space_reset_tuple_id(space, type);
796
797 if (!name_ok(space->ctx, s))
798 goto error;
799
800 id = isl_id_alloc(space->ctx, s, NULL((void*)0));
801 return isl_space_set_tuple_id(space, type, id);
802error:
803 isl_space_free(space);
804 return NULL((void*)0);
805}
806
807/* Does the tuple have a name?
808 */
809isl_bool isl_space_has_tuple_name(__isl_keep isl_space *space,
810 enum isl_dim_type type)
811{
812 isl_id *id;
813
814 if (!space_can_have_id(space, type))
815 return isl_bool_error;
816 id = space->tuple_id[type - isl_dim_in];
817 return isl_bool_ok(id && id->name);
818}
819
820__isl_keep const char *isl_space_get_tuple_name(__isl_keep isl_space *space,
821 enum isl_dim_type type)
822{
823 isl_id *id;
824 if (!space)
825 return NULL((void*)0);
826 if (type != isl_dim_in && type != isl_dim_out)
827 return NULL((void*)0);
828 id = space->tuple_id[type - isl_dim_in];
829 return id ? id->name : NULL((void*)0);
830}
831
832__isl_give isl_space *isl_space_set_dim_name(__isl_take isl_space *space,
833 enum isl_dim_type type, unsigned pos,
834 const char *s)
835{
836 isl_id *id;
837
838 if (!space)
839 return NULL((void*)0);
840 if (!s)
841 return isl_space_reset_dim_id(space, type, pos);
842 if (!name_ok(space->ctx, s))
843 goto error;
844 id = isl_id_alloc(space->ctx, s, NULL((void*)0));
845 return isl_space_set_dim_id(space, type, pos, id);
846error:
847 isl_space_free(space);
848 return NULL((void*)0);
849}
850
851/* Does the given dimension have a name?
852 */
853isl_bool isl_space_has_dim_name(__isl_keep isl_space *space,
854 enum isl_dim_type type, unsigned pos)
855{
856 isl_id *id;
857
858 if (!space)
859 return isl_bool_error;
860 id = get_id(space, type, pos);
861 return isl_bool_ok(id && id->name);
862}
863
864__isl_keep const char *isl_space_get_dim_name(__isl_keep isl_space *space,
865 enum isl_dim_type type, unsigned pos)
866{
867 isl_id *id = get_id(space, type, pos);
868 return id ? id->name : NULL((void*)0);
869}
870
871int isl_space_find_dim_by_id(__isl_keep isl_space *space,
872 enum isl_dim_type type, __isl_keep isl_id *id)
873{
874 int i;
875 int offset;
876 isl_size n;
877
878 n = isl_space_dim(space, type);
879 if (n < 0 || !id)
880 return -1;
881
882 offset = isl_space_offset(space, type);
883 for (i = 0; i < n && offset + i < space->n_id; ++i)
884 if (space->ids[offset + i] == id)
885 return i;
886
887 return -1;
888}
889
890int isl_space_find_dim_by_name(__isl_keep isl_space *space,
891 enum isl_dim_type type, const char *name)
892{
893 int i;
894 int offset;
895 isl_size n;
896
897 n = isl_space_dim(space, type);
898 if (n < 0 || !name)
899 return -1;
900
901 offset = isl_space_offset(space, type);
902 for (i = 0; i < n && offset + i < space->n_id; ++i) {
903 isl_id *id = get_id(space, type, i);
904 if (id && id->name && !strcmp(id->name, name))
905 return i;
906 }
907
908 return -1;
909}
910
911/* Reset the user pointer on all identifiers of parameters and tuples
912 * of "space".
913 */
914__isl_give isl_space *isl_space_reset_user(__isl_take isl_space *space)
915{
916 int i;
917 isl_ctx *ctx;
918 isl_id *id;
919 const char *name;
920
921 if (!space)
922 return NULL((void*)0);
923
924 ctx = isl_space_get_ctx(space);
925
926 for (i = 0; i < space->nparam && i < space->n_id; ++i) {
927 if (!isl_id_get_user(space->ids[i]))
928 continue;
929 space = isl_space_cow(space);
930 if (!space)
931 return NULL((void*)0);
932 name = isl_id_get_name(space->ids[i]);
933 id = isl_id_alloc(ctx, name, NULL((void*)0));
934 isl_id_free(space->ids[i]);
935 space->ids[i] = id;
936 if (!id)
937 return isl_space_free(space);
938 }
939
940 for (i = 0; i < 2; ++i) {
941 if (!space->tuple_id[i])
942 continue;
943 if (!isl_id_get_user(space->tuple_id[i]))
944 continue;
945 space = isl_space_cow(space);
946 if (!space)
947 return NULL((void*)0);
948 name = isl_id_get_name(space->tuple_id[i]);
949 id = isl_id_alloc(ctx, name, NULL((void*)0));
950 isl_id_free(space->tuple_id[i]);
951 space->tuple_id[i] = id;
952 if (!id)
953 return isl_space_free(space);
954 }
955
956 for (i = 0; i < 2; ++i) {
957 isl_space *nested;
958
959 if (!space->nested[i])
960 continue;
961 nested = isl_space_take_nested(space, i);
962 nested = isl_space_reset_user(nested);
963 space = isl_space_restore_nested(space, i, nested);
964 if (!space)
965 return NULL((void*)0);
966 }
967
968 return space;
969}
970
971static __isl_keep isl_id *tuple_id(__isl_keep isl_space *space,
972 enum isl_dim_type type)
973{
974 if (!space)
975 return NULL((void*)0);
976 if (type == isl_dim_in)
977 return space->tuple_id[0];
978 if (type == isl_dim_out)
979 return space->tuple_id[1];
980 return NULL((void*)0);
981}
982
983static __isl_keep isl_space *nested(__isl_keep isl_space *space,
984 enum isl_dim_type type)
985{
986 if (!space)
987 return NULL((void*)0);
988 if (type == isl_dim_in)
989 return space->nested[0];
990 if (type == isl_dim_out)
991 return space->nested[1];
992 return NULL((void*)0);
993}
994
995/* Are the two spaces the same, apart from positions and names of parameters?
996 */
997isl_bool isl_space_has_equal_tuples(__isl_keep isl_space *space1,
998 __isl_keep isl_space *space2)
999{
1000 if (!space1 || !space2)
1001 return isl_bool_error;
1002 if (space1 == space2)
1003 return isl_bool_true;
1004 return isl_space_tuple_is_equal(space1, isl_dim_in,
1005 space2, isl_dim_in) &&
1006 isl_space_tuple_is_equal(space1, isl_dim_out,
1007 space2, isl_dim_out);
1008}
1009
1010/* Check that a match involving "space" was successful.
1011 * That is, check that "match" is equal to isl_bool_true.
1012 */
1013static isl_stat check_match(__isl_keep isl_space *space, isl_bool match)
1014{
1015 if (match < 0)
1016 return isl_stat_error;
1017 if (!match)
1018 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "incompatible spaces", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1019); return isl_stat_error; } while (0)
1019 "incompatible spaces", return isl_stat_error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "incompatible spaces", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1019); return isl_stat_error; } while (0)
;
1020
1021 return isl_stat_ok;
1022}
1023
1024/* Check that the two spaces are the same,
1025 * apart from positions and names of parameters.
1026 */
1027isl_stat isl_space_check_equal_tuples(__isl_keep isl_space *space1,
1028 __isl_keep isl_space *space2)
1029{
1030 isl_bool is_equal;
1031
1032 is_equal = isl_space_has_equal_tuples(space1, space2);
1033 return check_match(space1, is_equal);
1034}
1035
1036/* Check if the tuple of type "type1" of "space1" is the same as
1037 * the tuple of type "type2" of "space2".
1038 *
1039 * That is, check if the tuples have the same identifier, the same dimension
1040 * and the same internal structure.
1041 * The identifiers of the dimensions inside the tuples do not affect the result.
1042 *
1043 * Note that this function only checks the tuples themselves.
1044 * If nested tuples are involved, then we need to be careful not
1045 * to have result affected by possibly differing parameters
1046 * in those nested tuples.
1047 */
1048isl_bool isl_space_tuple_is_equal(__isl_keep isl_space *space1,
1049 enum isl_dim_type type1, __isl_keep isl_space *space2,
1050 enum isl_dim_type type2)
1051{
1052 isl_id *id1, *id2;
1053 isl_space *nested1, *nested2;
1054
1055 if (!space1 || !space2)
1056 return isl_bool_error;
1057
1058 if (space1 == space2 && type1 == type2)
1059 return isl_bool_true;
1060
1061 if (n(space1, type1) != n(space2, type2))
1062 return isl_bool_false;
1063 id1 = tuple_id(space1, type1);
1064 id2 = tuple_id(space2, type2);
1065 if (!id1 ^ !id2)
1066 return isl_bool_false;
1067 if (id1 && id1 != id2)
1068 return isl_bool_false;
1069 nested1 = nested(space1, type1);
1070 nested2 = nested(space2, type2);
1071 if (!nested1 ^ !nested2)
1072 return isl_bool_false;
1073 if (nested1 && !isl_space_has_equal_tuples(nested1, nested2))
1074 return isl_bool_false;
1075 return isl_bool_true;
1076}
1077
1078/* Is the tuple "inner" within the wrapped relation inside tuple "outer"
1079 * of "space1" equal to tuple "type2" of "space2"?
1080 */
1081isl_bool isl_space_wrapped_tuple_is_equal(__isl_keep isl_space *space1,
1082 enum isl_dim_type outer, enum isl_dim_type inner,
1083 __isl_keep isl_space *space2, enum isl_dim_type type2)
1084{
1085 int pos;
1086 isl_space *nested;
1087
1088 if (!space1)
1089 return isl_bool_error;
1090 if (outer != isl_dim_in && outer != isl_dim_out)
1091 isl_die(isl_space_get_ctx(space1), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space1), isl_error_invalid
, "only input, output and set tuples " "can have nested relations"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1093); return isl_bool_error; } while (0)
1092 "only input, output and set tuples "do { isl_handle_error(isl_space_get_ctx(space1), isl_error_invalid
, "only input, output and set tuples " "can have nested relations"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1093); return isl_bool_error; } while (0)
1093 "can have nested relations", return isl_bool_error)do { isl_handle_error(isl_space_get_ctx(space1), isl_error_invalid
, "only input, output and set tuples " "can have nested relations"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1093); return isl_bool_error; } while (0)
;
1094 pos = outer - isl_dim_in;
1095 nested = isl_space_peek_nested(space1, pos);
1096 return isl_space_tuple_is_equal(nested, inner, space2, type2);
1097}
1098
1099/* Check that the tuple "inner" within the wrapped relation inside tuple "outer"
1100 * of "space1" is equal to tuple "type2" of "space2".
1101 */
1102isl_stat isl_space_check_wrapped_tuple_is_equal(__isl_keep isl_space *space1,
1103 enum isl_dim_type outer, enum isl_dim_type inner,
1104 __isl_keep isl_space *space2, enum isl_dim_type type2)
1105{
1106 isl_bool is_equal;
1107
1108 is_equal = isl_space_wrapped_tuple_is_equal(space1, outer, inner,
1109 space2, type2);
1110 return check_match(space1, is_equal);
1111}
1112
1113static isl_bool match(__isl_keep isl_space *space1, enum isl_dim_type type1,
1114 __isl_keep isl_space *space2, enum isl_dim_type type2)
1115{
1116 int i;
1117 isl_bool equal;
1118
1119 if (!space1 || !space2)
1120 return isl_bool_error;
1121
1122 if (space1 == space2 && type1 == type2)
1123 return isl_bool_true;
1124
1125 equal = isl_space_tuple_is_equal(space1, type1, space2, type2);
1126 if (equal < 0 || !equal)
1127 return equal;
1128
1129 if (!space1->ids && !space2->ids)
1130 return isl_bool_true;
1131
1132 for (i = 0; i < n(space1, type1); ++i) {
1133 if (get_id(space1, type1, i) != get_id(space2, type2, i))
1134 return isl_bool_false;
1135 }
1136 return isl_bool_true;
1137}
1138
1139/* Do "space1" and "space2" have the same parameters?
1140 */
1141isl_bool isl_space_has_equal_params(__isl_keep isl_space *space1,
1142 __isl_keep isl_space *space2)
1143{
1144 return match(space1, isl_dim_param, space2, isl_dim_param);
1145}
1146
1147/* Do "space1" and "space2" have the same identifiers for all
1148 * the tuple variables?
1149 */
1150isl_bool isl_space_has_equal_ids(__isl_keep isl_space *space1,
1151 __isl_keep isl_space *space2)
1152{
1153 isl_bool equal;
1154
1155 equal = match(space1, isl_dim_in, space2, isl_dim_in);
1156 if (equal < 0 || !equal)
1157 return equal;
1158 return match(space1, isl_dim_out, space2, isl_dim_out);
1159}
1160
1161isl_bool isl_space_match(__isl_keep isl_space *space1, enum isl_dim_type type1,
1162 __isl_keep isl_space *space2, enum isl_dim_type type2)
1163{
1164 return match(space1, type1, space2, type2);
1165}
1166
1167static void get_ids(__isl_keep isl_space *space, enum isl_dim_type type,
1168 unsigned first, unsigned n, __isl_keep isl_id **ids)
1169{
1170 int i;
1171
1172 for (i = 0; i < n ; ++i)
1173 ids[i] = get_id(space, type, first + i);
1174}
1175
1176static __isl_give isl_space *space_extend(__isl_take isl_space *space,
1177 unsigned nparam, unsigned n_in, unsigned n_out)
1178{
1179 isl_id **ids = NULL((void*)0);
1180
1181 if (!space)
1182 return NULL((void*)0);
1183 if (space->nparam == nparam &&
1184 space->n_in == n_in && space->n_out == n_out)
1185 return space;
1186
1187 isl_assert(space->ctx, space->nparam <= nparam, goto error)do { if (space->nparam <= nparam) break; do { isl_handle_error
(space->ctx, isl_error_unknown, "Assertion \"" "space->nparam <= nparam"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1187); goto error; } while (0); } while (0)
;
1188 isl_assert(space->ctx, space->n_in <= n_in, goto error)do { if (space->n_in <= n_in) break; do { isl_handle_error
(space->ctx, isl_error_unknown, "Assertion \"" "space->n_in <= n_in"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1188); goto error; } while (0); } while (0)
;
1189 isl_assert(space->ctx, space->n_out <= n_out, goto error)do { if (space->n_out <= n_out) break; do { isl_handle_error
(space->ctx, isl_error_unknown, "Assertion \"" "space->n_out <= n_out"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1189); goto error; } while (0); } while (0)
;
1190
1191 space = isl_space_cow(space);
1192 if (!space)
1193 goto error;
1194
1195 if (space->ids) {
1196 unsigned n;
1197 n = nparam + n_in + n_out;
1198 if (n < nparam || n < n_in || n < n_out)
1199 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "overflow in total number of dimensions", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1201); goto error; } while (0)
1200 "overflow in total number of dimensions",do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "overflow in total number of dimensions", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1201); goto error; } while (0)
1201 goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "overflow in total number of dimensions", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1201); goto error; } while (0)
;
1202 ids = isl_calloc_array(space->ctx, isl_id *, n)((isl_id * *)isl_calloc_or_die(space->ctx, n, sizeof(isl_id
*)))
;
1203 if (!ids)
1204 goto error;
1205 get_ids(space, isl_dim_param, 0, space->nparam, ids);
1206 get_ids(space, isl_dim_in, 0, space->n_in, ids + nparam);
1207 get_ids(space, isl_dim_out, 0, space->n_out,
1208 ids + nparam + n_in);
1209 free(space->ids);
1210 space->ids = ids;
1211 space->n_id = nparam + n_in + n_out;
1212 }
1213 space->nparam = nparam;
1214 space->n_in = n_in;
1215 space->n_out = n_out;
1216
1217 return space;
1218error:
1219 free(ids);
1220 isl_space_free(space);
1221 return NULL((void*)0);
1222}
1223
1224__isl_give isl_space *isl_space_extend(__isl_take isl_space *space,
1225 unsigned nparam, unsigned n_in, unsigned n_out)
1226{
1227 return space_extend(space, nparam, n_in, n_out);
1228}
1229
1230__isl_give isl_space *isl_space_add_dims(__isl_take isl_space *space,
1231 enum isl_dim_type type, unsigned n)
1232{
1233 space = isl_space_reset(space, type);
1234 if (!space)
1235 return NULL((void*)0);
1236 switch (type) {
1237 case isl_dim_param:
1238 space = space_extend(space,
1239 space->nparam + n, space->n_in, space->n_out);
1240 if (space && space->nested[0] &&
1241 !(space->nested[0] = isl_space_add_dims(space->nested[0],
1242 isl_dim_param, n)))
1243 goto error;
1244 if (space && space->nested[1] &&
1245 !(space->nested[1] = isl_space_add_dims(space->nested[1],
1246 isl_dim_param, n)))
1247 goto error;
1248 return space;
1249 case isl_dim_in:
1250 return space_extend(space,
1251 space->nparam, space->n_in + n, space->n_out);
1252 case isl_dim_out:
1253 return space_extend(space,
1254 space->nparam, space->n_in, space->n_out + n);
1255 default:
1256 isl_die(space->ctx, isl_error_invalid,do { isl_handle_error(space->ctx, isl_error_invalid, "cannot add dimensions of specified type"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1257); goto error; } while (0)
1257 "cannot add dimensions of specified type", goto error)do { isl_handle_error(space->ctx, isl_error_invalid, "cannot add dimensions of specified type"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1257); goto error; } while (0)
;
1258 }
1259error:
1260 isl_space_free(space);
1261 return NULL((void*)0);
1262}
1263
1264/* Add a parameter with identifier "id" to "space", provided
1265 * it does not already appear in "space".
1266 */
1267__isl_give isl_space *isl_space_add_param_id(__isl_take isl_space *space,
1268 __isl_take isl_id *id)
1269{
1270 isl_size pos;
1271
1272 if (!space || !id)
1273 goto error;
1274
1275 if (isl_space_find_dim_by_id(space, isl_dim_param, id) >= 0) {
1276 isl_id_free(id);
1277 return space;
1278 }
1279
1280 pos = isl_space_dim(space, isl_dim_param);
1281 if (pos < 0)
1282 goto error;
1283 space = isl_space_add_dims(space, isl_dim_param, 1);
1284 space = isl_space_set_dim_id(space, isl_dim_param, pos, id);
1285
1286 return space;
1287error:
1288 isl_space_free(space);
1289 isl_id_free(id);
1290 return NULL((void*)0);
1291}
1292
1293static int valid_dim_type(enum isl_dim_type type)
1294{
1295 switch (type) {
1296 case isl_dim_param:
1297 case isl_dim_in:
1298 case isl_dim_out:
1299 return 1;
1300 default:
1301 return 0;
1302 }
1303}
1304
1305#undef TYPEisl_space
1306#define TYPEisl_space isl_space
1307#include "check_type_range_templ.c"
1308
1309/* Insert "n" dimensions of type "type" at position "pos".
1310 * If we are inserting parameters, then they are also inserted in
1311 * any nested spaces.
1312 */
1313__isl_give isl_space *isl_space_insert_dims(__isl_take isl_space *space,
1314 enum isl_dim_type type, unsigned pos, unsigned n)
1315{
1316 isl_ctx *ctx;
1317 isl_id **ids = NULL((void*)0);
1318
1319 if (!space)
1320 return NULL((void*)0);
1321 if (n == 0)
1322 return isl_space_reset(space, type);
1323
1324 ctx = isl_space_get_ctx(space);
1325 if (!valid_dim_type(type))
1326 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "cannot insert dimensions of specified type"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1328); goto error; } while (0)
1327 "cannot insert dimensions of specified type",do { isl_handle_error(ctx, isl_error_invalid, "cannot insert dimensions of specified type"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1328); goto error; } while (0)
1328 goto error)do { isl_handle_error(ctx, isl_error_invalid, "cannot insert dimensions of specified type"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1328); goto error; } while (0)
;
1329
1330 if (isl_space_check_range(space, type, pos, 0) < 0)
1331 return isl_space_free(space);
1332
1333 space = isl_space_cow(space);
1334 if (!space)
1335 return NULL((void*)0);
1336
1337 if (space->ids) {
1338 enum isl_dim_type t, o = isl_dim_param;
1339 int off;
1340 int s[3];
1341 ids = isl_calloc_array(ctx, isl_id *,((isl_id * *)isl_calloc_or_die(ctx, space->nparam + space->
n_in + space->n_out + n, sizeof(isl_id *)))
1342 space->nparam + space->n_in + space->n_out + n)((isl_id * *)isl_calloc_or_die(ctx, space->nparam + space->
n_in + space->n_out + n, sizeof(isl_id *)))
;
1343 if (!ids)
1344 goto error;
1345 off = 0;
1346 s[isl_dim_param - o] = space->nparam;
1347 s[isl_dim_in - o] = space->n_in;
1348 s[isl_dim_out - o] = space->n_out;
1349 for (t = isl_dim_param; t <= isl_dim_out; ++t) {
1350 if (t != type) {
1351 get_ids(space, t, 0, s[t - o], ids + off);
1352 off += s[t - o];
1353 } else {
1354 get_ids(space, t, 0, pos, ids + off);
1355 off += pos + n;
1356 get_ids(space, t, pos, s[t - o] - pos,
1357 ids + off);
1358 off += s[t - o] - pos;
1359 }
1360 }
1361 free(space->ids);
1362 space->ids = ids;
1363 space->n_id = space->nparam + space->n_in + space->n_out + n;
1364 }
1365 switch (type) {
1366 case isl_dim_param: space->nparam += n; break;
1367 case isl_dim_in: space->n_in += n; break;
1368 case isl_dim_out: space->n_out += n; break;
1369 default: ;
1370 }
1371 space = isl_space_reset(space, type);
1372
1373 if (type == isl_dim_param) {
1374 if (space && space->nested[0] &&
1375 !(space->nested[0] = isl_space_insert_dims(space->nested[0],
1376 isl_dim_param, pos, n)))
1377 goto error;
1378 if (space && space->nested[1] &&
1379 !(space->nested[1] = isl_space_insert_dims(space->nested[1],
1380 isl_dim_param, pos, n)))
1381 goto error;
1382 }
1383
1384 return space;
1385error:
1386 isl_space_free(space);
1387 return NULL((void*)0);
1388}
1389
1390__isl_give isl_space *isl_space_move_dims(__isl_take isl_space *space,
1391 enum isl_dim_type dst_type, unsigned dst_pos,
1392 enum isl_dim_type src_type, unsigned src_pos, unsigned n)
1393{
1394 int i;
1395
1396 space = isl_space_reset(space, src_type);
1397 space = isl_space_reset(space, dst_type);
1398 if (!space)
1399 return NULL((void*)0);
1400 if (n == 0)
1401 return space;
1402
1403 if (isl_space_check_range(space, src_type, src_pos, n) < 0)
1404 return isl_space_free(space);
1405
1406 if (dst_type == src_type && dst_pos == src_pos)
1407 return space;
1408
1409 isl_assert(space->ctx, dst_type != src_type, goto error)do { if (dst_type != src_type) break; do { isl_handle_error(space
->ctx, isl_error_unknown, "Assertion \"" "dst_type != src_type"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1409); goto error; } while (0); } while (0)
;
1410
1411 space = isl_space_cow(space);
1412 if (!space)
1413 return NULL((void*)0);
1414
1415 if (space->ids) {
1416 isl_id **ids;
1417 enum isl_dim_type t, o = isl_dim_param;
1418 int off;
1419 int s[3];
1420 ids = isl_calloc_array(space->ctx, isl_id *,((isl_id * *)isl_calloc_or_die(space->ctx, space->nparam
+ space->n_in + space->n_out, sizeof(isl_id *)))
1421 space->nparam + space->n_in + space->n_out)((isl_id * *)isl_calloc_or_die(space->ctx, space->nparam
+ space->n_in + space->n_out, sizeof(isl_id *)))
;
1422 if (!ids)
1423 goto error;
1424 off = 0;
1425 s[isl_dim_param - o] = space->nparam;
1426 s[isl_dim_in - o] = space->n_in;
1427 s[isl_dim_out - o] = space->n_out;
1428 for (t = isl_dim_param; t <= isl_dim_out; ++t) {
1429 if (t == dst_type) {
1430 get_ids(space, t, 0, dst_pos, ids + off);
1431 off += dst_pos;
1432 get_ids(space, src_type, src_pos, n, ids + off);
1433 off += n;
1434 get_ids(space, t, dst_pos, s[t - o] - dst_pos,
1435 ids + off);
1436 off += s[t - o] - dst_pos;
1437 } else if (t == src_type) {
1438 get_ids(space, t, 0, src_pos, ids + off);
1439 off += src_pos;
1440 get_ids(space, t, src_pos + n,
1441 s[t - o] - src_pos - n, ids + off);
1442 off += s[t - o] - src_pos - n;
1443 } else {
1444 get_ids(space, t, 0, s[t - o], ids + off);
1445 off += s[t - o];
1446 }
1447 }
1448 free(space->ids);
1449 space->ids = ids;
1450 space->n_id = space->nparam + space->n_in + space->n_out;
1451 }
1452
1453 switch (dst_type) {
1454 case isl_dim_param: space->nparam += n; break;
1455 case isl_dim_in: space->n_in += n; break;
1456 case isl_dim_out: space->n_out += n; break;
1457 default: ;
1458 }
1459
1460 switch (src_type) {
1461 case isl_dim_param: space->nparam -= n; break;
1462 case isl_dim_in: space->n_in -= n; break;
1463 case isl_dim_out: space->n_out -= n; break;
1464 default: ;
1465 }
1466
1467 if (dst_type != isl_dim_param && src_type != isl_dim_param)
1468 return space;
1469
1470 for (i = 0; i < 2; ++i) {
1471 isl_space *nested;
1472
1473 if (!space->nested[i])
1474 continue;
1475 nested = isl_space_take_nested(space, i);
1476 nested = isl_space_replace_params(nested, space);
1477 space = isl_space_restore_nested(space, i, nested);
1478 if (!space)
1479 return NULL((void*)0);
1480 }
1481
1482 return space;
1483error:
1484 isl_space_free(space);
1485 return NULL((void*)0);
1486}
1487
1488/* Check that "space1" and "space2" have the same parameters,
1489 * reporting an error if they do not.
1490 */
1491isl_stat isl_space_check_equal_params(__isl_keep isl_space *space1,
1492 __isl_keep isl_space *space2)
1493{
1494 isl_bool equal;
1495
1496 equal = isl_space_has_equal_params(space1, space2);
1497 if (equal < 0)
1498 return isl_stat_error;
1499 if (!equal)
1500 isl_die(isl_space_get_ctx(space1), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space1), isl_error_invalid
, "parameters need to match", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1501); return isl_stat_error; } while (0)
1501 "parameters need to match", return isl_stat_error)do { isl_handle_error(isl_space_get_ctx(space1), isl_error_invalid
, "parameters need to match", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1501); return isl_stat_error; } while (0)
;
1502 return isl_stat_ok;
1503}
1504
1505__isl_give isl_space *isl_space_join(__isl_take isl_space *left,
1506 __isl_take isl_space *right)
1507{
1508 isl_space *space;
1509
1510 if (isl_space_check_equal_params(left, right) < 0)
1511 goto error;
1512
1513 isl_assert(left->ctx,do { if (isl_space_tuple_is_equal(left, isl_dim_out, right, isl_dim_in
)) break; do { isl_handle_error(left->ctx, isl_error_unknown
, "Assertion \"" "isl_space_tuple_is_equal(left, isl_dim_out, right, isl_dim_in)"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1515); goto error; } while (0); } while (0)
1514 isl_space_tuple_is_equal(left, isl_dim_out, right, isl_dim_in),do { if (isl_space_tuple_is_equal(left, isl_dim_out, right, isl_dim_in
)) break; do { isl_handle_error(left->ctx, isl_error_unknown
, "Assertion \"" "isl_space_tuple_is_equal(left, isl_dim_out, right, isl_dim_in)"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1515); goto error; } while (0); } while (0)
1515 goto error)do { if (isl_space_tuple_is_equal(left, isl_dim_out, right, isl_dim_in
)) break; do { isl_handle_error(left->ctx, isl_error_unknown
, "Assertion \"" "isl_space_tuple_is_equal(left, isl_dim_out, right, isl_dim_in)"
"\" failed", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1515); goto error; } while (0); } while (0)
;
1516
1517 space = isl_space_alloc(left->ctx,
1518 left->nparam, left->n_in, right->n_out);
1519 if (!space)
1520 goto error;
1521
1522 space = copy_ids(space, isl_dim_param, 0, left, isl_dim_param);
1523 space = copy_ids(space, isl_dim_in, 0, left, isl_dim_in);
1524 space = copy_ids(space, isl_dim_out, 0, right, isl_dim_out);
1525
1526 if (space && left->tuple_id[0] &&
1527 !(space->tuple_id[0] = isl_id_copy(left->tuple_id[0])))
1528 goto error;
1529 if (space && right->tuple_id[1] &&
1530 !(space->tuple_id[1] = isl_id_copy(right->tuple_id[1])))
1531 goto error;
1532 if (space && left->nested[0] &&
1533 !(space->nested[0] = isl_space_copy(left->nested[0])))
1534 goto error;
1535 if (space && right->nested[1] &&
1536 !(space->nested[1] = isl_space_copy(right->nested[1])))
1537 goto error;
1538
1539 isl_space_free(left);
1540 isl_space_free(right);
1541
1542 return space;
1543error:
1544 isl_space_free(left);
1545 isl_space_free(right);
1546 return NULL((void*)0);
1547}
1548
1549/* Given two map spaces { A -> C } and { B -> D }, construct the space
1550 * { [A -> B] -> [C -> D] }.
1551 * Given two set spaces { A } and { B }, construct the space { [A -> B] }.
1552 */
1553__isl_give isl_space *isl_space_product(__isl_take isl_space *left,
1554 __isl_take isl_space *right)
1555{
1556 isl_space *dom1, *dom2, *nest1, *nest2;
1557 int is_set;
1558
1559 if (!left || !right)
1560 goto error;
1561
1562 is_set = isl_space_is_set(left);
1563 if (is_set != isl_space_is_set(right))
1564 isl_die(isl_space_get_ctx(left), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(left), isl_error_invalid
, "expecting either two set spaces or two map spaces", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1566); goto error; } while (0)
1565 "expecting either two set spaces or two map spaces",do { isl_handle_error(isl_space_get_ctx(left), isl_error_invalid
, "expecting either two set spaces or two map spaces", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1566); goto error; } while (0)
1566 goto error)do { isl_handle_error(isl_space_get_ctx(left), isl_error_invalid
, "expecting either two set spaces or two map spaces", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1566); goto error; } while (0)
;
1567 if (is_set)
1568 return isl_space_range_product(left, right);
1569
1570 if (isl_space_check_equal_params(left, right) < 0)
1571 goto error;
1572
1573 dom1 = isl_space_domain(isl_space_copy(left));
1574 dom2 = isl_space_domain(isl_space_copy(right));
1575 nest1 = isl_space_wrap(isl_space_join(isl_space_reverse(dom1), dom2));
1576
1577 dom1 = isl_space_range(left);
1578 dom2 = isl_space_range(right);
1579 nest2 = isl_space_wrap(isl_space_join(isl_space_reverse(dom1), dom2));
1580
1581 return isl_space_join(isl_space_reverse(nest1), nest2);
1582error:
1583 isl_space_free(left);
1584 isl_space_free(right);
1585 return NULL((void*)0);
1586}
1587
1588/* Given two spaces { A -> C } and { B -> C }, construct the space
1589 * { [A -> B] -> C }
1590 */
1591__isl_give isl_space *isl_space_domain_product(__isl_take isl_space *left,
1592 __isl_take isl_space *right)
1593{
1594 isl_space *ran, *dom1, *dom2, *nest;
1595
1596 if (isl_space_check_equal_params(left, right) < 0)
1597 goto error;
1598
1599 if (!isl_space_tuple_is_equal(left, isl_dim_out, right, isl_dim_out))
1600 isl_die(left->ctx, isl_error_invalid,do { isl_handle_error(left->ctx, isl_error_invalid, "ranges need to match"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1601); goto error; } while (0)
1601 "ranges need to match", goto error)do { isl_handle_error(left->ctx, isl_error_invalid, "ranges need to match"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1601); goto error; } while (0)
;
1602
1603 ran = isl_space_range(isl_space_copy(left));
1604
1605 dom1 = isl_space_domain(left);
1606 dom2 = isl_space_domain(right);
1607 nest = isl_space_wrap(isl_space_join(isl_space_reverse(dom1), dom2));
1608
1609 return isl_space_join(isl_space_reverse(nest), ran);
1610error:
1611 isl_space_free(left);
1612 isl_space_free(right);
1613 return NULL((void*)0);
1614}
1615
1616__isl_give isl_space *isl_space_range_product(__isl_take isl_space *left,
1617 __isl_take isl_space *right)
1618{
1619 isl_space *dom, *ran1, *ran2, *nest;
1620
1621 if (isl_space_check_equal_params(left, right) < 0)
1622 goto error;
1623
1624 if (!isl_space_tuple_is_equal(left, isl_dim_in, right, isl_dim_in))
1625 isl_die(left->ctx, isl_error_invalid,do { isl_handle_error(left->ctx, isl_error_invalid, "domains need to match"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1626); goto error; } while (0)
1626 "domains need to match", goto error)do { isl_handle_error(left->ctx, isl_error_invalid, "domains need to match"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1626); goto error; } while (0)
;
1627
1628 dom = isl_space_domain(isl_space_copy(left));
1629
1630 ran1 = isl_space_range(left);
1631 ran2 = isl_space_range(right);
1632 nest = isl_space_wrap(isl_space_join(isl_space_reverse(ran1), ran2));
1633
1634 return isl_space_join(isl_space_reverse(dom), nest);
1635error:
1636 isl_space_free(left);
1637 isl_space_free(right);
1638 return NULL((void*)0);
1639}
1640
1641/* Given a space of the form [A -> B] -> C, return the space A -> C.
1642 */
1643__isl_give isl_space *isl_space_domain_factor_domain(
1644 __isl_take isl_space *space)
1645{
1646 isl_space *nested;
1647 isl_space *domain;
1648
1649 if (isl_space_check_domain_is_wrapping(space) < 0)
1650 return isl_space_free(space);
1651
1652 nested = space->nested[0];
1653 domain = isl_space_copy(space);
1654 domain = isl_space_drop_dims(domain, isl_dim_in,
1655 nested->n_in, nested->n_out);
1656 if (!domain)
1657 return isl_space_free(space);
1658 if (nested->tuple_id[0]) {
1659 domain->tuple_id[0] = isl_id_copy(nested->tuple_id[0]);
1660 if (!domain->tuple_id[0])
1661 goto error;
1662 }
1663 if (nested->nested[0]) {
1664 domain->nested[0] = isl_space_copy(nested->nested[0]);
1665 if (!domain->nested[0])
1666 goto error;
1667 }
1668
1669 isl_space_free(space);
1670 return domain;
1671error:
1672 isl_space_free(space);
1673 isl_space_free(domain);
1674 return NULL((void*)0);
1675}
1676
1677/* Given a space of the form [A -> B] -> C, return the space B -> C.
1678 */
1679__isl_give isl_space *isl_space_domain_factor_range(
1680 __isl_take isl_space *space)
1681{
1682 isl_space *nested;
1683 isl_space *range;
1684
1685 if (isl_space_check_domain_is_wrapping(space) < 0)
1686 return isl_space_free(space);
1687
1688 nested = space->nested[0];
1689 range = isl_space_copy(space);
1690 range = isl_space_drop_dims(range, isl_dim_in, 0, nested->n_in);
1691 if (!range)
1692 return isl_space_free(space);
1693 if (nested->tuple_id[1]) {
1694 range->tuple_id[0] = isl_id_copy(nested->tuple_id[1]);
1695 if (!range->tuple_id[0])
1696 goto error;
1697 }
1698 if (nested->nested[1]) {
1699 range->nested[0] = isl_space_copy(nested->nested[1]);
1700 if (!range->nested[0])
1701 goto error;
1702 }
1703
1704 isl_space_free(space);
1705 return range;
1706error:
1707 isl_space_free(space);
1708 isl_space_free(range);
1709 return NULL((void*)0);
1710}
1711
1712/* Internal function that selects the domain of the map that is
1713 * embedded in either a set space or the range of a map space.
1714 * In particular, given a space of the form [A -> B], return the space A.
1715 * Given a space of the form A -> [B -> C], return the space A -> B.
1716 */
1717static __isl_give isl_space *range_factor_domain(__isl_take isl_space *space)
1718{
1719 isl_space *nested;
1720 isl_space *domain;
1721
1722 if (!space)
1723 return NULL((void*)0);
1724
1725 nested = space->nested[1];
1726 domain = isl_space_copy(space);
1727 domain = isl_space_drop_dims(domain, isl_dim_out,
1728 nested->n_in, nested->n_out);
1729 if (!domain)
1730 return isl_space_free(space);
1731 if (nested->tuple_id[0]) {
1732 domain->tuple_id[1] = isl_id_copy(nested->tuple_id[0]);
1733 if (!domain->tuple_id[1])
1734 goto error;
1735 }
1736 if (nested->nested[0]) {
1737 domain->nested[1] = isl_space_copy(nested->nested[0]);
1738 if (!domain->nested[1])
1739 goto error;
1740 }
1741
1742 isl_space_free(space);
1743 return domain;
1744error:
1745 isl_space_free(space);
1746 isl_space_free(domain);
1747 return NULL((void*)0);
1748}
1749
1750/* Given a space of the form A -> [B -> C], return the space A -> B.
1751 */
1752__isl_give isl_space *isl_space_range_factor_domain(
1753 __isl_take isl_space *space)
1754{
1755 if (isl_space_check_range_is_wrapping(space) < 0)
1756 return isl_space_free(space);
1757
1758 return range_factor_domain(space);
1759}
1760
1761/* Given a space of the form [A -> B], return the space A.
1762 */
1763static __isl_give isl_space *set_factor_domain(__isl_take isl_space *space)
1764{
1765 if (!space)
1766 return NULL((void*)0);
1767 if (!isl_space_is_wrapping(space))
1768 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "not a product", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1769); return isl_space_free(space); } while (0)
1769 "not a product", return isl_space_free(space))do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "not a product", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1769); return isl_space_free(space); } while (0)
;
1770
1771 return range_factor_domain(space);
1772}
1773
1774/* Given a space of the form [A -> B] -> [C -> D], return the space A -> C.
1775 * Given a space of the form [A -> B], return the space A.
1776 */
1777__isl_give isl_space *isl_space_factor_domain(__isl_take isl_space *space)
1778{
1779 if (!space)
1780 return NULL((void*)0);
1781 if (isl_space_is_set(space))
1782 return set_factor_domain(space);
1783 space = isl_space_domain_factor_domain(space);
1784 space = isl_space_range_factor_domain(space);
1785 return space;
1786}
1787
1788/* Internal function that selects the range of the map that is
1789 * embedded in either a set space or the range of a map space.
1790 * In particular, given a space of the form [A -> B], return the space B.
1791 * Given a space of the form A -> [B -> C], return the space A -> C.
1792 */
1793static __isl_give isl_space *range_factor_range(__isl_take isl_space *space)
1794{
1795 isl_space *nested;
1796 isl_space *range;
1797
1798 if (!space)
1799 return NULL((void*)0);
1800
1801 nested = space->nested[1];
1802 range = isl_space_copy(space);
1803 range = isl_space_drop_dims(range, isl_dim_out, 0, nested->n_in);
1804 if (!range)
1805 return isl_space_free(space);
1806 if (nested->tuple_id[1]) {
1807 range->tuple_id[1] = isl_id_copy(nested->tuple_id[1]);
1808 if (!range->tuple_id[1])
1809 goto error;
1810 }
1811 if (nested->nested[1]) {
1812 range->nested[1] = isl_space_copy(nested->nested[1]);
1813 if (!range->nested[1])
1814 goto error;
1815 }
1816
1817 isl_space_free(space);
1818 return range;
1819error:
1820 isl_space_free(space);
1821 isl_space_free(range);
1822 return NULL((void*)0);
1823}
1824
1825/* Given a space of the form A -> [B -> C], return the space A -> C.
1826 */
1827__isl_give isl_space *isl_space_range_factor_range(
1828 __isl_take isl_space *space)
1829{
1830 if (isl_space_check_range_is_wrapping(space) < 0)
1831 return isl_space_free(space);
1832
1833 return range_factor_range(space);
1834}
1835
1836/* Given a space of the form [A -> B], return the space B.
1837 */
1838static __isl_give isl_space *set_factor_range(__isl_take isl_space *space)
1839{
1840 if (!space)
1841 return NULL((void*)0);
1842 if (!isl_space_is_wrapping(space))
1843 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "not a product", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1844); return isl_space_free(space); } while (0)
1844 "not a product", return isl_space_free(space))do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "not a product", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1844); return isl_space_free(space); } while (0)
;
1845
1846 return range_factor_range(space);
1847}
1848
1849/* Given a space of the form [A -> B] -> [C -> D], return the space B -> D.
1850 * Given a space of the form [A -> B], return the space B.
1851 */
1852__isl_give isl_space *isl_space_factor_range(__isl_take isl_space *space)
1853{
1854 if (!space)
1855 return NULL((void*)0);
1856 if (isl_space_is_set(space))
1857 return set_factor_range(space);
1858 space = isl_space_domain_factor_range(space);
1859 space = isl_space_range_factor_range(space);
1860 return space;
1861}
1862
1863__isl_give isl_space *isl_space_map_from_set(__isl_take isl_space *space)
1864{
1865 isl_ctx *ctx;
1866 isl_id **ids = NULL((void*)0);
1867 int n_id;
1868
1869 if (!space)
1870 return NULL((void*)0);
1871 ctx = isl_space_get_ctx(space);
1872 if (!isl_space_is_set(space))
1873 isl_die(ctx, isl_error_invalid, "not a set space", goto error)do { isl_handle_error(ctx, isl_error_invalid, "not a set space"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1873); goto error; } while (0)
;
1874 space = isl_space_cow(space);
1875 if (!space)
1876 return NULL((void*)0);
1877 n_id = space->nparam + space->n_out + space->n_out;
1878 if (n_id > 0 && space->ids) {
1879 ids = isl_calloc_array(space->ctx, isl_id *, n_id)((isl_id * *)isl_calloc_or_die(space->ctx, n_id, sizeof(isl_id
*)))
;
1880 if (!ids)
1881 goto error;
1882 get_ids(space, isl_dim_param, 0, space->nparam, ids);
1883 get_ids(space, isl_dim_out, 0, space->n_out,
1884 ids + space->nparam);
1885 }
1886 space->n_in = space->n_out;
1887 if (ids) {
1888 free(space->ids);
1889 space->ids = ids;
1890 space->n_id = n_id;
1891 space = copy_ids(space, isl_dim_out, 0, space, isl_dim_in);
1892 }
1893 isl_id_free(space->tuple_id[0]);
1894 space->tuple_id[0] = isl_id_copy(space->tuple_id[1]);
1895 isl_space_free(space->nested[0]);
1896 space->nested[0] = isl_space_copy(space->nested[1]);
1897 return space;
1898error:
1899 isl_space_free(space);
1900 return NULL((void*)0);
1901}
1902
1903__isl_give isl_space *isl_space_map_from_domain_and_range(
1904 __isl_take isl_space *domain, __isl_take isl_space *range)
1905{
1906 if (!domain || !range)
1907 goto error;
1908 if (!isl_space_is_set(domain))
1909 isl_die(isl_space_get_ctx(domain), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(domain), isl_error_invalid
, "domain is not a set space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1910); goto error; } while (0)
1910 "domain is not a set space", goto error)do { isl_handle_error(isl_space_get_ctx(domain), isl_error_invalid
, "domain is not a set space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1910); goto error; } while (0)
;
1911 if (!isl_space_is_set(range))
1912 isl_die(isl_space_get_ctx(range), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(range), isl_error_invalid
, "range is not a set space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1913); goto error; } while (0)
1913 "range is not a set space", goto error)do { isl_handle_error(isl_space_get_ctx(range), isl_error_invalid
, "range is not a set space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 1913); goto error; } while (0)
;
1914 return isl_space_join(isl_space_reverse(domain), range);
1915error:
1916 isl_space_free(domain);
1917 isl_space_free(range);
1918 return NULL((void*)0);
1919}
1920
1921static __isl_give isl_space *set_ids(__isl_take isl_space *space,
1922 enum isl_dim_type type,
1923 unsigned first, unsigned n, __isl_take isl_id **ids)
1924{
1925 int i;
1926
1927 for (i = 0; i < n ; ++i)
1928 space = set_id(space, type, first + i, ids[i]);
1929
1930 return space;
1931}
1932
1933__isl_give isl_space *isl_space_reverse(__isl_take isl_space *space)
1934{
1935 unsigned t;
1936 isl_bool equal;
1937 isl_space *nested;
1938 isl_id **ids = NULL((void*)0);
1939 isl_id *id;
1940
1941 equal = match(space, isl_dim_in, space, isl_dim_out);
1942 if (equal < 0)
1943 return isl_space_free(space);
1944 if (equal)
1945 return space;
1946
1947 space = isl_space_cow(space);
1948 if (!space)
1949 return NULL((void*)0);
1950
1951 id = space->tuple_id[0];
1952 space->tuple_id[0] = space->tuple_id[1];
1953 space->tuple_id[1] = id;
1954
1955 nested = space->nested[0];
1956 space->nested[0] = space->nested[1];
1957 space->nested[1] = nested;
1958
1959 if (space->ids) {
1960 int n_id = space->n_in + space->n_out;
1961 ids = isl_alloc_array(space->ctx, isl_id *, n_id)((isl_id * *)isl_malloc_or_die(space->ctx, (n_id)*sizeof(isl_id
*)))
;
1962 if (n_id && !ids)
1963 goto error;
1964 get_ids(space, isl_dim_in, 0, space->n_in, ids);
1965 get_ids(space, isl_dim_out, 0, space->n_out, ids + space->n_in);
1966 }
1967
1968 t = space->n_in;
1969 space->n_in = space->n_out;
1970 space->n_out = t;
1971
1972 if (space->ids) {
1973 space = set_ids(space, isl_dim_out, 0, space->n_out, ids);
1974 space = set_ids(space, isl_dim_in, 0, space->n_in,
1975 ids + space->n_out);
1976 free(ids);
1977 }
1978
1979 return space;
1980error:
1981 free(ids);
1982 isl_space_free(space);
1983 return NULL((void*)0);
1984}
1985
1986/* Given a space A -> (B -> C), return the corresponding space
1987 * A -> (C -> B).
1988 *
1989 * If the range tuple is named, then the name is only preserved
1990 * if B and C are equal tuples, in which case the output
1991 * of this function is identical to the input.
1992 */
1993__isl_give isl_space *isl_space_range_reverse(__isl_take isl_space *space)
1994{
1995 isl_space *nested;
1996 isl_bool equal;
1997
1998 if (isl_space_check_range_is_wrapping(space) < 0)
1999 return isl_space_free(space);
2000
2001 nested = isl_space_peek_nested(space, 1);
2002 equal = isl_space_tuple_is_equal(nested, isl_dim_in,
2003 nested, isl_dim_out);
2004 if (equal < 0)
2005 return isl_space_free(space);
2006
2007 nested = isl_space_take_nested(space, 1);
2008 nested = isl_space_reverse(nested);
2009 space = isl_space_restore_nested(space, 1, nested);
2010 if (!equal)
2011 space = isl_space_reset_tuple_id(space, isl_dim_out);
2012
2013 return space;
2014}
2015
2016__isl_give isl_space *isl_space_drop_dims(__isl_take isl_space *space,
2017 enum isl_dim_type type, unsigned first, unsigned num)
2018{
2019 int i;
2020
2021 if (!space)
2022 return NULL((void*)0);
2023
2024 if (num == 0)
2025 return isl_space_reset(space, type);
2026
2027 if (!valid_dim_type(type))
2028 isl_die(space->ctx, isl_error_invalid,do { isl_handle_error(space->ctx, isl_error_invalid, "cannot drop dimensions of specified type"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 2029); goto error; } while (0)
2029 "cannot drop dimensions of specified type", goto error)do { isl_handle_error(space->ctx, isl_error_invalid, "cannot drop dimensions of specified type"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 2029); goto error; } while (0)
;
2030
2031 if (isl_space_check_range(space, type, first, num) < 0)
2032 return isl_space_free(space);
2033 space = isl_space_cow(space);
2034 if (!space)
2035 goto error;
2036 if (space->ids) {
2037 space = extend_ids(space);
2038 if (!space)
2039 goto error;
2040 for (i = 0; i < num; ++i)
2041 isl_id_free(get_id(space, type, first + i));
2042 for (i = first+num; i < n(space, type); ++i)
2043 set_id(space, type, i - num, get_id(space, type, i));
2044 switch (type) {
2045 case isl_dim_param:
2046 get_ids(space, isl_dim_in, 0, space->n_in,
2047 space->ids + offset(space, isl_dim_in) - num);
2048 case isl_dim_in:
2049 get_ids(space, isl_dim_out, 0, space->n_out,
2050 space->ids + offset(space, isl_dim_out) - num);
2051 default:
2052 ;
2053 }
2054 space->n_id -= num;
2055 }
2056 switch (type) {
2057 case isl_dim_param: space->nparam -= num; break;
2058 case isl_dim_in: space->n_in -= num; break;
2059 case isl_dim_out: space->n_out -= num; break;
2060 default: ;
2061 }
2062 space = isl_space_reset(space, type);
2063 if (type == isl_dim_param) {
2064 if (space && space->nested[0] &&
2065 !(space->nested[0] = isl_space_drop_dims(space->nested[0],
2066 isl_dim_param, first, num)))
2067 goto error;
2068 if (space && space->nested[1] &&
2069 !(space->nested[1] = isl_space_drop_dims(space->nested[1],
2070 isl_dim_param, first, num)))
2071 goto error;
2072 }
2073 return space;
2074error:
2075 isl_space_free(space);
2076 return NULL((void*)0);
2077}
2078
2079__isl_give isl_space *isl_space_drop_inputs(__isl_take isl_space *space,
2080 unsigned first, unsigned n)
2081{
2082 if (!space)
2083 return NULL((void*)0);
2084 return isl_space_drop_dims(space, isl_dim_in, first, n);
2085}
2086
2087__isl_give isl_space *isl_space_drop_outputs(__isl_take isl_space *space,
2088 unsigned first, unsigned n)
2089{
2090 if (!space)
2091 return NULL((void*)0);
2092 return isl_space_drop_dims(space, isl_dim_out, first, n);
2093}
2094
2095/* Remove all parameters from "space".
2096 */
2097__isl_give isl_space *isl_space_drop_all_params(__isl_take isl_space *space)
2098{
2099 isl_size nparam;
2100
2101 nparam = isl_space_dim(space, isl_dim_param);
2102 if (nparam < 0)
2103 return isl_space_free(space);
2104 return isl_space_drop_dims(space, isl_dim_param, 0, nparam);
2105}
2106
2107__isl_give isl_space *isl_space_domain(__isl_take isl_space *space)
2108{
2109 if (!space)
2110 return NULL((void*)0);
2111 space = isl_space_drop_dims(space, isl_dim_out, 0, space->n_out);
2112 space = isl_space_reverse(space);
2113 space = mark_as_set(space);
2114 return space;
2115}
2116
2117__isl_give isl_space *isl_space_from_domain(__isl_take isl_space *space)
2118{
2119 if (!space)
2120 return NULL((void*)0);
2121 if (!isl_space_is_set(space))
2122 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "not a set space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 2123); goto error; } while (0)
2123 "not a set space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "not a set space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 2123); goto error; } while (0)
;
2124 space = isl_space_reverse(space);
2125 space = isl_space_reset(space, isl_dim_out);
2126 return space;
2127error:
2128 isl_space_free(space);
2129 return NULL((void*)0);
2130}
2131
2132__isl_give isl_space *isl_space_range(__isl_take isl_space *space)
2133{
2134 if (!space)
2135 return NULL((void*)0);
2136 space = isl_space_drop_dims(space, isl_dim_in, 0, space->n_in);
2137 space = mark_as_set(space);
2138 return space;
2139}
2140
2141__isl_give isl_space *isl_space_from_range(__isl_take isl_space *space)
2142{
2143 if (!space)
2144 return NULL((void*)0);
2145 if (!isl_space_is_set(space))
2146 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "not a set space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 2147); goto error; } while (0)
2147 "not a set space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "not a set space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 2147); goto error; } while (0)
;
2148 return isl_space_reset(space, isl_dim_in);
2149error:
2150 isl_space_free(space);
2151 return NULL((void*)0);
2152}
2153
2154/* Given a map space A -> B, return the map space [A -> B] -> A.
2155 */
2156__isl_give isl_space *isl_space_domain_map(__isl_take isl_space *space)
2157{
2158 isl_space *domain;
2159
2160 domain = isl_space_from_range(isl_space_domain(isl_space_copy(space)));
2161 space = isl_space_from_domain(isl_space_wrap(space));
2162 space = isl_space_join(space, domain);
2163
2164 return space;
2165}
2166
2167/* Given a map space A -> B, return the map space [A -> B] -> B.
2168 */
2169__isl_give isl_space *isl_space_range_map(__isl_take isl_space *space)
2170{
2171 isl_space *range;
2172
2173 range = isl_space_from_range(isl_space_range(isl_space_copy(space)));
2174 space = isl_space_from_domain(isl_space_wrap(space));
2175 space = isl_space_join(space, range);
2176
2177 return space;
2178}
2179
2180__isl_give isl_space *isl_space_params(__isl_take isl_space *space)
2181{
2182 isl_size n_in, n_out;
2183
2184 if (isl_space_is_params(space))
2185 return space;
2186 n_in = isl_space_dim(space, isl_dim_in);
2187 n_out = isl_space_dim(space, isl_dim_out);
2188 if (n_in < 0 || n_out < 0)
2189 return isl_space_free(space);
2190 space = isl_space_drop_dims(space, isl_dim_in, 0, n_in);
2191 space = isl_space_drop_dims(space, isl_dim_out, 0, n_out);
2192 space = mark_as_params(space);
2193 return space;
2194}
2195
2196__isl_give isl_space *isl_space_set_from_params(__isl_take isl_space *space)
2197{
2198 if (!space)
2199 return NULL((void*)0);
2200 if (!isl_space_is_params(space))
2201 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "not a parameter space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 2202); goto error; } while (0)
2202 "not a parameter space", goto error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "not a parameter space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 2202); goto error; } while (0)
;
2203 return isl_space_reset(space, isl_dim_set);
2204error:
2205 isl_space_free(space);
2206 return NULL((void*)0);
2207}
2208
2209/* Add an unnamed tuple of dimension "dim" to "space".
2210 * This requires "space" to be a parameter or set space.
2211 *
2212 * In particular, if "space" is a parameter space, then return
2213 * a set space with the given dimension.
2214 * If "space" is a set space, then return a map space
2215 * with "space" as domain and a range of the given dimension.
2216 */
2217__isl_give isl_space *isl_space_add_unnamed_tuple_ui(
2218 __isl_take isl_space *space, unsigned dim)
2219{
2220 isl_bool is_params, is_set;
2221
2222 is_params = isl_space_is_params(space);
2223 is_set = isl_space_is_set(space);
2224 if (is_params < 0 || is_set < 0)
2225 return isl_space_free(space);
2226 if (!is_params && !is_set)
2227 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "cannot add tuple to map space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 2229); return isl_space_free(space); } while (0)
2228 "cannot add tuple to map space",do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "cannot add tuple to map space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 2229); return isl_space_free(space); } while (0)
2229 return isl_space_free(space))do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "cannot add tuple to map space", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 2229); return isl_space_free(space); } while (0)
;
2230 if (is_params)
2231 space = isl_space_set_from_params(space);
2232 else
2233 space = isl_space_from_domain(space);
2234 space = isl_space_add_dims(space, isl_dim_out, dim);
2235 return space;
2236}
2237
2238/* Add a tuple of dimension "dim" and with tuple identifier "tuple_id"
2239 * to "space".
2240 * This requires "space" to be a parameter or set space.
2241 */
2242__isl_give isl_space *isl_space_add_named_tuple_id_ui(
2243 __isl_take isl_space *space, __isl_take isl_id *tuple_id, unsigned dim)
2244{
2245 space = isl_space_add_unnamed_tuple_ui(space, dim);
2246 space = isl_space_set_tuple_id(space, isl_dim_out, tuple_id);
2247 return space;
2248}
2249
2250/* Check that the identifiers in "tuple" do not appear as parameters
2251 * in "space".
2252 */
2253static isl_stat check_fresh_params(__isl_keep isl_space *space,
2254 __isl_keep isl_multi_id *tuple)
2255{
2256 int i;
2257 isl_size n;
2258
2259 n = isl_multi_id_size(tuple);
2260 if (n < 0)
2261 return isl_stat_error;
2262 for (i = 0; i < n; ++i) {
2263 isl_id *id;
2264 int pos;
2265
2266 id = isl_multi_id_get_at(tuple, i);
2267 if (!id)
2268 return isl_stat_error;
2269 pos = isl_space_find_dim_by_id(space, isl_dim_param, id);
2270 isl_id_free(id);
2271 if (pos >= 0)
2272 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "parameters not unique", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 2273); return isl_stat_error; } while (0)
2273 "parameters not unique", return isl_stat_error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "parameters not unique", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 2273); return isl_stat_error; } while (0)
;
2274 }
2275
2276 return isl_stat_ok;
2277}
2278
2279/* Add the identifiers in "tuple" as parameters of "space"
2280 * that are known to be fresh.
2281 */
2282static __isl_give isl_space *add_bind_params(__isl_take isl_space *space,
2283 __isl_keep isl_multi_id *tuple)
2284{
2285 int i;
2286 isl_size first, n;
2287
2288 first = isl_space_dim(space, isl_dim_param);
2289 n = isl_multi_id_size(tuple);
2290 if (first < 0 || n < 0)
2291 return isl_space_free(space);
2292 space = isl_space_add_dims(space, isl_dim_param, n);
2293 for (i = 0; i < n; ++i) {
2294 isl_id *id;
2295
2296 id = isl_multi_id_get_at(tuple, i);
2297 space = isl_space_set_dim_id(space,
2298 isl_dim_param, first + i, id);
2299 }
2300
2301 return space;
2302}
2303
2304/* Internal function that removes the set tuple of "space",
2305 * which is assumed to correspond to the range space of "tuple", and
2306 * adds the identifiers in "tuple" as fresh parameters.
2307 * In other words, the set dimensions of "space" are reinterpreted
2308 * as parameters, but stay in the same global positions.
2309 */
2310__isl_give isl_space *isl_space_bind_set(__isl_take isl_space *space,
2311 __isl_keep isl_multi_id *tuple)
2312{
2313 isl_space *tuple_space;
2314
2315 if (isl_space_check_is_set(space) < 0)
2316 return isl_space_free(space);
2317 tuple_space = isl_multi_id_peek_space(tuple);
2318 if (isl_space_check_equal_tuples(tuple_space, space) < 0)
2319 return isl_space_free(space);
2320 if (check_fresh_params(space, tuple) < 0)
2321 return isl_space_free(space);
2322 space = isl_space_params(space);
2323 space = add_bind_params(space, tuple);
2324 return space;
2325}
2326
2327/* Internal function that removes the domain tuple of the map space "space",
2328 * which is assumed to correspond to the range space of "tuple", and
2329 * adds the identifiers in "tuple" as fresh parameters.
2330 * In other words, the domain dimensions of "space" are reinterpreted
2331 * as parameters, but stay in the same global positions.
2332 */
2333__isl_give isl_space *isl_space_bind_map_domain(__isl_take isl_space *space,
2334 __isl_keep isl_multi_id *tuple)
2335{
2336 isl_space *tuple_space;
2337
2338 if (isl_space_check_is_map(space) < 0)
2339 return isl_space_free(space);
2340 tuple_space = isl_multi_id_peek_space(tuple);
2341 if (isl_space_check_domain_tuples(tuple_space, space) < 0)
2342 return isl_space_free(space);
2343 if (check_fresh_params(space, tuple) < 0)
2344 return isl_space_free(space);
2345 space = isl_space_range(space);
2346 space = add_bind_params(space, tuple);
2347 return space;
2348}
2349
2350/* Internal function that, given a space of the form [A -> B] -> C and
2351 * a tuple of identifiers in A, returns a space B -> C with
2352 * the identifiers in "tuple" added as fresh parameters.
2353 * In other words, the domain dimensions of the wrapped relation
2354 * in the domain of "space" are reinterpreted
2355 * as parameters, but stay in the same global positions.
2356 */
2357__isl_give isl_space *isl_space_bind_domain_wrapped_domain(
2358 __isl_take isl_space *space, __isl_keep isl_multi_id *tuple)
2359{
2360 isl_space *tuple_space;
2361
2362 if (isl_space_check_is_map(space) < 0)
2363 return isl_space_free(space);
2364 tuple_space = isl_multi_id_peek_space(tuple);
2365 if (isl_space_check_domain_wrapped_domain_tuples(tuple_space,
2366 space) < 0)
2367 return isl_space_free(space);
2368 if (check_fresh_params(space, tuple) < 0)
2369 return isl_space_free(space);
2370 space = isl_space_domain_factor_range(space);
2371 space = add_bind_params(space, tuple);
2372 return space;
2373}
2374
2375/* Insert a domain tuple in "space" corresponding to the set space "domain".
2376 * In particular, if "space" is a parameter space, then the result
2377 * is the set space "domain" combined with the parameters of "space".
2378 * If "space" is a set space, then the result
2379 * is a map space with "domain" as domain and the original space as range.
2380 */
2381static __isl_give isl_space *isl_space_insert_domain(
2382 __isl_take isl_space *space, __isl_take isl_space *domain)
2383{
2384 isl_bool is_params;
2385
2386 domain = isl_space_replace_params(domain, space);
2387
2388 is_params = isl_space_is_params(space);
2389 if (is_params < 0) {
2390 isl_space_free(domain);
2391 space = isl_space_free(space);
2392 } else if (is_params) {
2393 isl_space_free(space);
2394 space = domain;
2395 } else {
2396 space = isl_space_map_from_domain_and_range(domain, space);
2397 }
2398 return space;
2399}
2400
2401/* Internal function that introduces a domain in "space"
2402 * corresponding to the range space of "tuple".
2403 * In particular, if "space" is a parameter space, then the result
2404 * is a set space. If "space" is a set space, then the result
2405 * is a map space with the original space as range.
2406 * Parameters that correspond to the identifiers in "tuple" are removed.
2407 *
2408 * The parameters are removed in reverse order (under the assumption
2409 * that they appear in the same order in "multi") because
2410 * it is slightly more efficient to remove parameters at the end.
2411 *
2412 * For pretty-printing purposes, the identifiers of the set dimensions
2413 * of the introduced domain are set to the identifiers in "tuple".
2414 */
2415__isl_give isl_space *isl_space_unbind_params_insert_domain(
2416 __isl_take isl_space *space, __isl_keep isl_multi_id *tuple)
2417{
2418 int i;
2419 isl_size n;
2420 isl_space *tuple_space;
2421
2422 n = isl_multi_id_size(tuple);
2423 if (!space || n < 0)
2424 return isl_space_free(space);
2425 for (i = n - 1; i >= 0; --i) {
2426 isl_id *id;
2427 int pos;
2428
2429 id = isl_multi_id_get_id(tuple, i);
2430 if (!id)
2431 return isl_space_free(space);
2432 pos = isl_space_find_dim_by_id(space, isl_dim_param, id);
2433 isl_id_free(id);
2434 if (pos < 0)
2435 continue;
2436 space = isl_space_drop_dims(space, isl_dim_param, pos, 1);
2437 }
2438 tuple_space = isl_multi_id_get_space(tuple);
2439 for (i = 0; i < n; ++i) {
2440 isl_id *id;
2441
2442 id = isl_multi_id_get_id(tuple, i);
2443 tuple_space = isl_space_set_dim_id(tuple_space,
2444 isl_dim_set, i, id);
2445 }
2446 return isl_space_insert_domain(space, tuple_space);
2447}
2448
2449__isl_give isl_space *isl_space_underlying(__isl_take isl_space *space,
2450 unsigned n_div)
2451{
2452 int i;
2453 isl_bool is_set;
2454
2455 is_set = isl_space_is_set(space);
2456 if (is_set < 0)
2457 return isl_space_free(space);
2458 if (n_div == 0 && is_set &&
2459 space->nparam == 0 && space->n_in == 0 && space->n_id == 0)
2460 return isl_space_reset(space, isl_dim_out);
2461 space = isl_space_cow(space);
2462 if (!space)
2463 return NULL((void*)0);
2464 space->n_out += space->nparam + space->n_in + n_div;
2465 space->nparam = 0;
2466 space->n_in = 0;
2467
2468 for (i = 0; i < space->n_id; ++i)
2469 isl_id_free(get_id(space, isl_dim_out, i));
2470 space->n_id = 0;
2471 space = isl_space_reset(space, isl_dim_in);
2472 space = isl_space_reset(space, isl_dim_out);
2473 space = mark_as_set(space);
2474
2475 return space;
2476}
2477
2478/* Are the two spaces the same, including positions and names of parameters?
2479 */
2480isl_bool isl_space_is_equal(__isl_keep isl_space *space1,
2481 __isl_keep isl_space *space2)
2482{
2483 isl_bool equal;
2484
2485 if (!space1 || !space2)
2486 return isl_bool_error;
2487 if (space1 == space2)
2488 return isl_bool_true;
2489 equal = isl_space_has_equal_params(space1, space2);
2490 if (equal < 0 || !equal)
2491 return equal;
2492 return isl_space_has_equal_tuples(space1, space2);
2493}
2494
2495/* Do the tuples of "space1" correspond to those of the domain of "space2"?
2496 * That is, is "space1" equal to the domain of "space2", ignoring parameters.
2497 *
2498 * "space2" is allowed to be a set space, in which case "space1"
2499 * should be a parameter space.
2500 */
2501isl_bool isl_space_has_domain_tuples(__isl_keep isl_space *space1,
2502 __isl_keep isl_space *space2)
2503{
2504 isl_bool is_set;
2505
2506 is_set = isl_space_is_set(space1);
2507 if (is_set < 0 || !is_set)
2508 return is_set;
2509 return isl_space_tuple_is_equal(space1, isl_dim_set,
2510 space2, isl_dim_in);
2511}
2512
2513/* Do the tuples of "space1" correspond to those of the range of "space2"?
2514 * That is, is "space1" equal to the range of "space2", ignoring parameters.
2515 *
2516 * "space2" is allowed to be the space of a set,
2517 * in which case it should be equal to "space1", ignoring parameters.
2518 */
2519isl_bool isl_space_has_range_tuples(__isl_keep isl_space *space1,
2520 __isl_keep isl_space *space2)
2521{
2522 isl_bool is_set;
2523
2524 is_set = isl_space_is_set(space1);
2525 if (is_set < 0 || !is_set)
2526 return is_set;
2527 return isl_space_tuple_is_equal(space1, isl_dim_set,
2528 space2, isl_dim_out);
2529}
2530
2531/* Check that the tuples of "space1" correspond to those
2532 * of the domain of "space2".
2533 * That is, check that "space1" is equal to the domain of "space2",
2534 * ignoring parameters.
2535 */
2536isl_stat isl_space_check_domain_tuples(__isl_keep isl_space *space1,
2537 __isl_keep isl_space *space2)
2538{
2539 isl_bool is_equal;
2540
2541 is_equal = isl_space_has_domain_tuples(space1, space2);
2542 return check_match(space1, is_equal);
2543}
2544
2545/* Check that the tuples of "space1" correspond to those
2546 * of the domain of the wrapped relation in the domain of "space2".
2547 * That is, check that "space1" is equal to this domain,
2548 * ignoring parameters.
2549 */
2550isl_stat isl_space_check_domain_wrapped_domain_tuples(
2551 __isl_keep isl_space *space1, __isl_keep isl_space *space2)
2552{
2553 isl_space *domain;
2554 isl_stat r;
2555
2556 domain = isl_space_unwrap(isl_space_domain(isl_space_copy(space2)));
2557 r = isl_space_check_domain_tuples(space1, domain);
2558 isl_space_free(domain);
2559
2560 return r;
2561}
2562
2563/* Is space1 equal to the domain of space2?
2564 *
2565 * In the internal version we also allow space2 to be the space of a set,
2566 * provided space1 is a parameter space.
2567 */
2568isl_bool isl_space_is_domain_internal(__isl_keep isl_space *space1,
2569 __isl_keep isl_space *space2)
2570{
2571 isl_bool equal_params;
2572
2573 if (!space1 || !space2)
2574 return isl_bool_error;
2575 equal_params = isl_space_has_equal_params(space1, space2);
2576 if (equal_params < 0 || !equal_params)
2577 return equal_params;
2578 return isl_space_has_domain_tuples(space1, space2);
2579}
2580
2581/* Is space1 equal to the domain of space2?
2582 */
2583isl_bool isl_space_is_domain(__isl_keep isl_space *space1,
2584 __isl_keep isl_space *space2)
2585{
2586 if (!space2)
2587 return isl_bool_error;
2588 if (!isl_space_is_map(space2))
2589 return isl_bool_false;
2590 return isl_space_is_domain_internal(space1, space2);
2591}
2592
2593/* Is space1 equal to the range of space2?
2594 *
2595 * In the internal version, space2 is allowed to be the space of a set,
2596 * in which case it should be equal to space1.
2597 */
2598isl_bool isl_space_is_range_internal(__isl_keep isl_space *space1,
2599 __isl_keep isl_space *space2)
2600{
2601 isl_bool equal_params;
2602
2603 if (!space1 || !space2)
2604 return isl_bool_error;
2605 equal_params = isl_space_has_equal_params(space1, space2);
2606 if (equal_params < 0 || !equal_params)
2607 return equal_params;
2608 return isl_space_has_range_tuples(space1, space2);
2609}
2610
2611/* Is space1 equal to the range of space2?
2612 */
2613isl_bool isl_space_is_range(__isl_keep isl_space *space1,
2614 __isl_keep isl_space *space2)
2615{
2616 if (!space2)
2617 return isl_bool_error;
2618 if (!isl_space_is_map(space2))
2619 return isl_bool_false;
2620 return isl_space_is_range_internal(space1, space2);
2621}
2622
2623/* Update "hash" by hashing in the parameters of "space".
2624 */
2625static uint32_t isl_hash_params(uint32_t hash, __isl_keep isl_space *space)
2626{
2627 int i;
2628 isl_id *id;
2629
2630 if (!space)
2631 return hash;
2632
2633 isl_hash_byte(hash, space->nparam % 256)do { hash *= 16777619; hash ^= space->nparam % 256; } while
(0)
;
2634
2635 for (i = 0; i < space->nparam; ++i) {
2636 id = get_id(space, isl_dim_param, i);
2637 hash = isl_hash_id(hash, id);
2638 }
2639
2640 return hash;
2641}
2642
2643/* Update "hash" by hashing in the tuples of "space".
2644 * Changes in this function should be reflected in isl_hash_tuples_domain.
2645 */
2646static uint32_t isl_hash_tuples(uint32_t hash, __isl_keep isl_space *space)
2647{
2648 isl_id *id;
2649
2650 if (!space)
2651 return hash;
2652
2653 isl_hash_byte(hash, space->n_in % 256)do { hash *= 16777619; hash ^= space->n_in % 256; } while(
0)
;
2654 isl_hash_byte(hash, space->n_out % 256)do { hash *= 16777619; hash ^= space->n_out % 256; } while
(0)
;
2655
2656 id = tuple_id(space, isl_dim_in);
2657 hash = isl_hash_id(hash, id);
2658 id = tuple_id(space, isl_dim_out);
2659 hash = isl_hash_id(hash, id);
2660
2661 hash = isl_hash_tuples(hash, space->nested[0]);
2662 hash = isl_hash_tuples(hash, space->nested[1]);
2663
2664 return hash;
2665}
2666
2667/* Update "hash" by hashing in the domain tuple of "space".
2668 * The result of this function is equal to the result of applying
2669 * isl_hash_tuples to the domain of "space".
2670 */
2671static uint32_t isl_hash_tuples_domain(uint32_t hash,
2672 __isl_keep isl_space *space)
2673{
2674 isl_id *id;
2675
2676 if (!space)
2677 return hash;
2678
2679 isl_hash_byte(hash, 0)do { hash *= 16777619; hash ^= 0; } while(0);
2680 isl_hash_byte(hash, space->n_in % 256)do { hash *= 16777619; hash ^= space->n_in % 256; } while(
0)
;
2681
2682 hash = isl_hash_id(hash, &isl_id_none);
2683 id = tuple_id(space, isl_dim_in);
2684 hash = isl_hash_id(hash, id);
2685
2686 hash = isl_hash_tuples(hash, space->nested[0]);
2687
2688 return hash;
2689}
2690
2691/* Return a hash value that digests the tuples of "space",
2692 * i.e., that ignores the parameters.
2693 * Changes in this function should be reflected
2694 * in isl_space_get_tuple_domain_hash.
2695 */
2696uint32_t isl_space_get_tuple_hash(__isl_keep isl_space *space)
2697{
2698 uint32_t hash;
2699
2700 if (!space)
2701 return 0;
2702
2703 hash = isl_hash_init()(2166136261u);
2704 hash = isl_hash_tuples(hash, space);
2705
2706 return hash;
2707}
2708
2709/* Return the hash value of "space".
2710 */
2711uint32_t isl_space_get_full_hash(__isl_keep isl_space *space)
2712{
2713 uint32_t hash;
2714
2715 if (!space)
2716 return 0;
2717
2718 hash = isl_hash_init()(2166136261u);
2719 hash = isl_hash_params(hash, space);
2720 hash = isl_hash_tuples(hash, space);
2721
2722 return hash;
2723}
2724
2725/* Return the hash value of the domain tuple of "space".
2726 * That is, isl_space_get_tuple_domain_hash(space) is equal to
2727 * isl_space_get_tuple_hash(isl_space_domain(space)).
2728 */
2729uint32_t isl_space_get_tuple_domain_hash(__isl_keep isl_space *space)
2730{
2731 uint32_t hash;
2732
2733 if (!space)
2734 return 0;
2735
2736 hash = isl_hash_init()(2166136261u);
2737 hash = isl_hash_tuples_domain(hash, space);
2738
2739 return hash;
2740}
2741
2742/* Is "space" the space of a set wrapping a map space?
2743 */
2744isl_bool isl_space_is_wrapping(__isl_keep isl_space *space)
2745{
2746 if (!space)
2747 return isl_bool_error;
2748
2749 if (!isl_space_is_set(space))
2750 return isl_bool_false;
2751
2752 return isl_bool_ok(space->nested[1] != NULL((void*)0));
2753}
2754
2755/* Is "space" the space of a map where the domain is a wrapped map space?
2756 */
2757isl_bool isl_space_domain_is_wrapping(__isl_keep isl_space *space)
2758{
2759 if (!space)
2760 return isl_bool_error;
2761
2762 if (isl_space_is_set(space))
2763 return isl_bool_false;
2764
2765 return isl_bool_ok(space->nested[0] != NULL((void*)0));
2766}
2767
2768/* Is "space" the space of a map where the range is a wrapped map space?
2769 */
2770isl_bool isl_space_range_is_wrapping(__isl_keep isl_space *space)
2771{
2772 if (!space)
2773 return isl_bool_error;
2774
2775 if (isl_space_is_set(space))
2776 return isl_bool_false;
2777
2778 return isl_bool_ok(space->nested[1] != NULL((void*)0));
2779}
2780
2781/* Is "space" a product of two spaces?
2782 * That is, is it a wrapping set space or a map space
2783 * with wrapping domain and range?
2784 */
2785isl_bool isl_space_is_product(__isl_keep isl_space *space)
2786{
2787 isl_bool is_set;
2788 isl_bool is_product;
2789
2790 is_set = isl_space_is_set(space);
2791 if (is_set < 0)
2792 return isl_bool_error;
2793 if (is_set)
2794 return isl_space_is_wrapping(space);
2795 is_product = isl_space_domain_is_wrapping(space);
2796 if (is_product < 0 || !is_product)
2797 return is_product;
2798 return isl_space_range_is_wrapping(space);
2799}
2800
2801__isl_give isl_space *isl_space_wrap(__isl_take isl_space *space)
2802{
2803 isl_space *wrap;
2804
2805 if (!space)
2806 return NULL((void*)0);
2807
2808 wrap = isl_space_set_alloc(space->ctx,
2809 space->nparam, space->n_in + space->n_out);
2810
2811 wrap = copy_ids(wrap, isl_dim_param, 0, space, isl_dim_param);
2812 wrap = copy_ids(wrap, isl_dim_set, 0, space, isl_dim_in);
2813 wrap = copy_ids(wrap, isl_dim_set, space->n_in, space, isl_dim_out);
2814
2815 if (!wrap)
2816 goto error;
2817
2818 wrap->nested[1] = space;
2819
2820 return wrap;
2821error:
2822 isl_space_free(space);
2823 return NULL((void*)0);
2824}
2825
2826__isl_give isl_space *isl_space_unwrap(__isl_take isl_space *space)
2827{
2828 isl_space *unwrap;
2829
2830 if (!space)
2831 return NULL((void*)0);
2832
2833 if (!isl_space_is_wrapping(space))
2834 isl_die(space->ctx, isl_error_invalid, "not a wrapping space",do { isl_handle_error(space->ctx, isl_error_invalid, "not a wrapping space"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 2835); goto error; } while (0)
2835 goto error)do { isl_handle_error(space->ctx, isl_error_invalid, "not a wrapping space"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 2835); goto error; } while (0)
;
2836
2837 unwrap = isl_space_copy(space->nested[1]);
2838 isl_space_free(space);
2839
2840 return unwrap;
2841error:
2842 isl_space_free(space);
2843 return NULL((void*)0);
2844}
2845
2846isl_bool isl_space_is_named_or_nested(__isl_keep isl_space *space,
2847 enum isl_dim_type type)
2848{
2849 if (type != isl_dim_in && type != isl_dim_out)
2850 return isl_bool_false;
2851 if (!space)
2852 return isl_bool_error;
2853 if (space->tuple_id[type - isl_dim_in])
2854 return isl_bool_true;
2855 if (space->nested[type - isl_dim_in])
2856 return isl_bool_true;
2857 return isl_bool_false;
2858}
2859
2860isl_bool isl_space_may_be_set(__isl_keep isl_space *space)
2861{
2862 isl_bool nested;
2863 isl_size n_in;
2864
2865 if (!space)
2866 return isl_bool_error;
2867 if (isl_space_is_set(space))
2868 return isl_bool_true;
2869 n_in = isl_space_dim(space, isl_dim_in);
2870 if (n_in < 0)
2871 return isl_bool_error;
2872 if (n_in != 0)
2873 return isl_bool_false;
2874 nested = isl_space_is_named_or_nested(space, isl_dim_in);
2875 if (nested < 0 || nested)
2876 return isl_bool_not(nested);
2877 return isl_bool_true;
2878}
2879
2880__isl_give isl_space *isl_space_reset(__isl_take isl_space *space,
2881 enum isl_dim_type type)
2882{
2883 if (!isl_space_is_named_or_nested(space, type))
2884 return space;
2885
2886 space = isl_space_cow(space);
2887 if (!space)
2888 return NULL((void*)0);
2889
2890 isl_id_free(space->tuple_id[type - isl_dim_in]);
2891 space->tuple_id[type - isl_dim_in] = NULL((void*)0);
2892 isl_space_free(space->nested[type - isl_dim_in]);
2893 space->nested[type - isl_dim_in] = NULL((void*)0);
2894
2895 return space;
2896}
2897
2898__isl_give isl_space *isl_space_flatten(__isl_take isl_space *space)
2899{
2900 if (!space)
2901 return NULL((void*)0);
2902 if (!space->nested[0] && !space->nested[1])
2903 return space;
2904
2905 if (space->nested[0])
2906 space = isl_space_reset(space, isl_dim_in);
2907 if (space && space->nested[1])
2908 space = isl_space_reset(space, isl_dim_out);
2909
2910 return space;
2911}
2912
2913__isl_give isl_space *isl_space_flatten_domain(__isl_take isl_space *space)
2914{
2915 if (!space)
2916 return NULL((void*)0);
2917 if (!space->nested[0])
2918 return space;
2919
2920 return isl_space_reset(space, isl_dim_in);
2921}
2922
2923__isl_give isl_space *isl_space_flatten_range(__isl_take isl_space *space)
2924{
2925 if (!space)
2926 return NULL((void*)0);
2927 if (!space->nested[1])
2928 return space;
2929
2930 return isl_space_reset(space, isl_dim_out);
2931}
2932
2933/* Replace the parameters of dst by those of src.
2934 */
2935__isl_give isl_space *isl_space_replace_params(__isl_take isl_space *dst,
2936 __isl_keep isl_space *src)
2937{
2938 isl_size dst_dim, src_dim;
2939 isl_bool equal_params;
2940 enum isl_dim_type type = isl_dim_param;
2941
2942 equal_params = isl_space_has_equal_params(dst, src);
2943 if (equal_params < 0)
2944 return isl_space_free(dst);
2945 if (equal_params)
2946 return dst;
2947
2948 dst = isl_space_cow(dst);
2949
2950 dst_dim = isl_space_dim(dst, type);
2951 src_dim = isl_space_dim(src, type);
2952 if (dst_dim < 0 || src_dim < 0)
2953 goto error;
2954
2955 dst = isl_space_drop_dims(dst, type, 0, dst_dim);
2956 dst = isl_space_add_dims(dst, type, src_dim);
2957 dst = copy_ids(dst, type, 0, src, type);
2958
2959 if (dst) {
2960 int i;
2961 for (i = 0; i <= 1; ++i) {
2962 isl_space *nested;
2963
2964 if (!dst->nested[i])
2965 continue;
2966 nested = isl_space_take_nested(dst, i);
2967 nested = isl_space_replace_params(nested, src);
2968 dst = isl_space_restore_nested(dst, i, nested);
2969 if (!dst)
2970 return NULL((void*)0);
2971 }
2972 }
2973
2974 return dst;
2975error:
2976 isl_space_free(dst);
2977 return NULL((void*)0);
2978}
2979
2980/* Given two tuples ("dst_type" in "dst" and "src_type" in "src")
2981 * of the same size, check if any of the dimensions in the "dst" tuple
2982 * have no identifier, while the corresponding dimensions in "src"
2983 * does have an identifier,
2984 * If so, copy the identifier over to "dst".
2985 */
2986__isl_give isl_space *isl_space_copy_ids_if_unset(__isl_take isl_space *dst,
2987 enum isl_dim_type dst_type, __isl_keep isl_space *src,
2988 enum isl_dim_type src_type)
2989{
2990 int i;
2991 isl_size n;
2992
2993 n = isl_space_dim(dst, dst_type);
2994 if (n < 0)
2995 return isl_space_free(dst);
2996 for (i = 0; i < n; ++i) {
2997 isl_bool set;
2998 isl_id *id;
2999
3000 set = isl_space_has_dim_id(dst, dst_type, i);
3001 if (set < 0)
3002 return isl_space_free(dst);
3003 if (set)
3004 continue;
3005
3006 set = isl_space_has_dim_id(src, src_type, i);
3007 if (set < 0)
3008 return isl_space_free(dst);
3009 if (!set)
3010 continue;
3011
3012 id = isl_space_get_dim_id(src, src_type, i);
3013 dst = isl_space_set_dim_id(dst, dst_type, i, id);
3014 }
3015
3016 return dst;
3017}
3018
3019/* Given a space "space" of a set, create a space
3020 * for the lift of the set. In particular, the result
3021 * is of the form lifted[space -> local[..]], with n_local variables in the
3022 * range of the wrapped map.
3023 */
3024__isl_give isl_space *isl_space_lift(__isl_take isl_space *space,
3025 unsigned n_local)
3026{
3027 isl_space *local_space;
3028
3029 if (!space)
3030 return NULL((void*)0);
3031
3032 local_space = isl_space_dup(space);
3033 local_space = isl_space_drop_dims(local_space, isl_dim_set, 0,
3034 space->n_out);
3035 local_space = isl_space_add_dims(local_space, isl_dim_set, n_local);
3036 local_space = isl_space_set_tuple_name(local_space,
3037 isl_dim_set, "local");
3038 space = isl_space_join(isl_space_from_domain(space),
3039 isl_space_from_range(local_space));
3040 space = isl_space_wrap(space);
3041 space = isl_space_set_tuple_name(space, isl_dim_set, "lifted");
3042
3043 return space;
3044}
3045
3046isl_bool isl_space_can_zip(__isl_keep isl_space *space)
3047{
3048 isl_bool is_set;
3049
3050 is_set = isl_space_is_set(space);
3051 if (is_set < 0)
3052 return isl_bool_error;
3053 if (is_set)
3054 return isl_bool_false;
3055 return isl_space_is_product(space);
3056}
3057
3058__isl_give isl_space *isl_space_zip(__isl_take isl_space *space)
3059{
3060 isl_space *dom, *ran;
3061 isl_space *dom_dom, *dom_ran, *ran_dom, *ran_ran;
3062
3063 if (!isl_space_can_zip(space))
3064 isl_die(space->ctx, isl_error_invalid, "space cannot be zipped",do { isl_handle_error(space->ctx, isl_error_invalid, "space cannot be zipped"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 3065); goto error; } while (0)
3065 goto error)do { isl_handle_error(space->ctx, isl_error_invalid, "space cannot be zipped"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 3065); goto error; } while (0)
;
3066
3067 if (!space)
3068 return NULL((void*)0);
3069 dom = isl_space_unwrap(isl_space_domain(isl_space_copy(space)));
3070 ran = isl_space_unwrap(isl_space_range(space));
3071 dom_dom = isl_space_domain(isl_space_copy(dom));
3072 dom_ran = isl_space_range(dom);
3073 ran_dom = isl_space_domain(isl_space_copy(ran));
3074 ran_ran = isl_space_range(ran);
3075 dom = isl_space_join(isl_space_from_domain(dom_dom),
3076 isl_space_from_range(ran_dom));
3077 ran = isl_space_join(isl_space_from_domain(dom_ran),
3078 isl_space_from_range(ran_ran));
3079 return isl_space_join(isl_space_from_domain(isl_space_wrap(dom)),
3080 isl_space_from_range(isl_space_wrap(ran)));
3081error:
3082 isl_space_free(space);
3083 return NULL((void*)0);
3084}
3085
3086/* Can we apply isl_space_curry to "space"?
3087 * That is, does is it have a map space with a nested relation in its domain?
3088 */
3089isl_bool isl_space_can_curry(__isl_keep isl_space *space)
3090{
3091 return isl_space_domain_is_wrapping(space);
3092}
3093
3094/* Given a space (A -> B) -> C, return the corresponding space
3095 * A -> (B -> C).
3096 */
3097__isl_give isl_space *isl_space_curry(__isl_take isl_space *space)
3098{
3099 isl_space *dom, *ran;
3100 isl_space *dom_dom, *dom_ran;
3101
3102 if (!space)
3103 return NULL((void*)0);
3104
3105 if (!isl_space_can_curry(space))
3106 isl_die(space->ctx, isl_error_invalid,do { isl_handle_error(space->ctx, isl_error_invalid, "space cannot be curried"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 3107); goto error; } while (0)
3107 "space cannot be curried", goto error)do { isl_handle_error(space->ctx, isl_error_invalid, "space cannot be curried"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 3107); goto error; } while (0)
;
3108
3109 dom = isl_space_unwrap(isl_space_domain(isl_space_copy(space)));
3110 ran = isl_space_range(space);
3111 dom_dom = isl_space_domain(isl_space_copy(dom));
3112 dom_ran = isl_space_range(dom);
3113 ran = isl_space_join(isl_space_from_domain(dom_ran),
3114 isl_space_from_range(ran));
3115 return isl_space_join(isl_space_from_domain(dom_dom),
3116 isl_space_from_range(isl_space_wrap(ran)));
3117error:
3118 isl_space_free(space);
3119 return NULL((void*)0);
3120}
3121
3122/* Can isl_space_range_curry be applied to "space"?
3123 * That is, does it have a nested relation in its range,
3124 * the domain of which is itself a nested relation?
3125 */
3126isl_bool isl_space_can_range_curry(__isl_keep isl_space *space)
3127{
3128 isl_bool can;
3129
3130 if (!space)
3131 return isl_bool_error;
3132 can = isl_space_range_is_wrapping(space);
3133 if (can < 0 || !can)
3134 return can;
3135 return isl_space_can_curry(space->nested[1]);
3136}
3137
3138/* Given a space A -> ((B -> C) -> D), return the corresponding space
3139 * A -> (B -> (C -> D)).
3140 */
3141__isl_give isl_space *isl_space_range_curry(__isl_take isl_space *space)
3142{
3143 isl_space *nested;
3144
3145 if (!space)
3146 return NULL((void*)0);
3147
3148 if (!isl_space_can_range_curry(space))
3149 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "space range cannot be curried", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 3151); return isl_space_free(space); } while (0)
3150 "space range cannot be curried",do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "space range cannot be curried", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 3151); return isl_space_free(space); } while (0)
3151 return isl_space_free(space))do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "space range cannot be curried", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 3151); return isl_space_free(space); } while (0)
;
3152
3153 nested = isl_space_take_nested(space, 1);
3154 nested = isl_space_curry(nested);
3155 space = isl_space_restore_nested(space, 1, nested);
3156
3157 return space;
3158}
3159
3160/* Can we apply isl_space_uncurry to "space"?
3161 * That is, does it have a map space with a nested relation in its range?
3162 */
3163isl_bool isl_space_can_uncurry(__isl_keep isl_space *space)
3164{
3165 return isl_space_range_is_wrapping(space);
3166}
3167
3168/* Given a space A -> (B -> C), return the corresponding space
3169 * (A -> B) -> C.
3170 */
3171__isl_give isl_space *isl_space_uncurry(__isl_take isl_space *space)
3172{
3173 isl_space *dom, *ran;
3174 isl_space *ran_dom, *ran_ran;
3175
3176 if (!space)
3177 return NULL((void*)0);
3178
3179 if (!isl_space_can_uncurry(space))
3180 isl_die(space->ctx, isl_error_invalid,do { isl_handle_error(space->ctx, isl_error_invalid, "space cannot be uncurried"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 3182); return isl_space_free(space); } while (0)
3181 "space cannot be uncurried",do { isl_handle_error(space->ctx, isl_error_invalid, "space cannot be uncurried"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 3182); return isl_space_free(space); } while (0)
3182 return isl_space_free(space))do { isl_handle_error(space->ctx, isl_error_invalid, "space cannot be uncurried"
, "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 3182); return isl_space_free(space); } while (0)
;
3183
3184 dom = isl_space_domain(isl_space_copy(space));
3185 ran = isl_space_unwrap(isl_space_range(space));
3186 ran_dom = isl_space_domain(isl_space_copy(ran));
3187 ran_ran = isl_space_range(ran);
3188 dom = isl_space_join(isl_space_from_domain(dom),
3189 isl_space_from_range(ran_dom));
3190 return isl_space_join(isl_space_from_domain(isl_space_wrap(dom)),
3191 isl_space_from_range(ran_ran));
3192}
3193
3194isl_bool isl_space_has_named_params(__isl_keep isl_space *space)
3195{
3196 int i;
3197 unsigned off;
3198
3199 if (!space)
3200 return isl_bool_error;
3201 if (space->nparam == 0)
3202 return isl_bool_true;
3203 off = isl_space_offset(space, isl_dim_param);
3204 if (off + space->nparam > space->n_id)
3205 return isl_bool_false;
3206 for (i = 0; i < space->nparam; ++i)
3207 if (!space->ids[off + i])
3208 return isl_bool_false;
3209 return isl_bool_true;
3210}
3211
3212/* Check that "space" has only named parameters, reporting an error
3213 * if it does not.
3214 */
3215isl_stat isl_space_check_named_params(__isl_keep isl_space *space)
3216{
3217 isl_bool named;
3218
3219 named = isl_space_has_named_params(space);
3220 if (named < 0)
3221 return isl_stat_error;
3222 if (!named)
3223 isl_die(isl_space_get_ctx(space), isl_error_invalid,do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "unexpected unnamed parameters", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 3224); return isl_stat_error; } while (0)
3224 "unexpected unnamed parameters", return isl_stat_error)do { isl_handle_error(isl_space_get_ctx(space), isl_error_invalid
, "unexpected unnamed parameters", "/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/polly/lib/External/isl/isl_space.c"
, 3224); return isl_stat_error; } while (0)
;
3225
3226 return isl_stat_ok;
3227}
3228
3229/* Align the initial parameters of space1 to match the order in space2.
3230 */
3231__isl_give isl_space *isl_space_align_params(__isl_take isl_space *space1,
3232 __isl_take isl_space *space2)
3233{
3234 isl_reordering *exp;
3235
3236 if (isl_space_check_named_params(space1) < 0 ||
3237 isl_space_check_named_params(space2) < 0)
3238 goto error;
3239
3240 exp = isl_parameter_alignment_reordering(space1, space2);
3241 exp = isl_reordering_extend_space(exp, space1);
3242 isl_space_free(space2);
3243 space1 = isl_reordering_get_space(exp);
3244 isl_reordering_free(exp);
3245 return space1;
3246error:
3247 isl_space_free(space1);
3248 isl_space_free(space2);
3249 return NULL((void*)0);
3250}
3251
3252/* Given the space of set (domain), construct a space for a map
3253 * with as domain the given space and as range the range of "model".
3254 */
3255__isl_give isl_space *isl_space_extend_domain_with_range(
3256 __isl_take isl_space *space, __isl_take isl_space *model)
3257{
3258 isl_size n_out;
3259
3260 if (!model)
3261 goto error;
3262
3263 space = isl_space_from_domain(space);
3264 n_out = isl_space_dim(model, isl_dim_out);
3265 if (n_out < 0)
3266 goto error;
3267 space = isl_space_add_dims(space, isl_dim_out, n_out);
3268 if (isl_space_has_tuple_id(model, isl_dim_out))
3269 space = isl_space_set_tuple_id(space, isl_dim_out,
3270 isl_space_get_tuple_id(model, isl_dim_out));
3271 if (!space)
3272 goto error;
3273 if (model->nested[1]) {
3274 isl_space *nested = isl_space_copy(model->nested[1]);
3275 isl_size n_nested, n_space;
3276 nested = isl_space_align_params(nested, isl_space_copy(space));
3277 n_nested = isl_space_dim(nested, isl_dim_param);
3278 n_space = isl_space_dim(space, isl_dim_param);
3279 if (n_nested < 0 || n_space < 0)
3280 goto error;
3281 if (n_nested > n_space)
3282 nested = isl_space_drop_dims(nested, isl_dim_param,
3283 n_space, n_nested - n_space);
3284 if (!nested)
3285 goto error;
3286 space->nested[1] = nested;
3287 }
3288 isl_space_free(model);
3289 return space;
3290error:
3291 isl_space_free(model);
3292 isl_space_free(space);
3293 return NULL((void*)0);
3294}
3295
3296/* Compare the "type" dimensions of two isl_spaces.
3297 *
3298 * The order is fairly arbitrary.
3299 */
3300static int isl_space_cmp_type(__isl_keep isl_space *space1,
3301 __isl_keep isl_space *space2, enum isl_dim_type type)
3302{
3303 int cmp;
3304 isl_size dim1, dim2;
3305 isl_space *nested1, *nested2;
3306
3307 dim1 = isl_space_dim(space1, type);
3308 dim2 = isl_space_dim(space2, type);
3309 if (dim1 < 0 || dim2 < 0)
3310 return 0;
3311 if (dim1 != dim2)
3312 return dim1 - dim2;
3313
3314 cmp = isl_id_cmp(tuple_id(space1, type), tuple_id(space2, type));
3315 if (cmp != 0)
3316 return cmp;
3317
3318 nested1 = nested(space1, type);
3319 nested2 = nested(space2, type);
3320 if (!nested1 != !nested2)
3321 return !nested1 - !nested2;
3322
3323 if (nested1)
3324 return isl_space_cmp(nested1, nested2);
3325
3326 return 0;
3327}
3328
3329/* Compare two isl_spaces.
3330 *
3331 * The order is fairly arbitrary.
3332 */
3333int isl_space_cmp(__isl_keep isl_space *space1, __isl_keep isl_space *space2)
3334{
3335 int i;
3336 int cmp;
3337
3338 if (space1 == space2)
3339 return 0;
3340 if (!space1)
3341 return -1;
3342 if (!space2)
3343 return 1;
3344
3345 cmp = isl_space_cmp_type(space1, space2, isl_dim_param);
3346 if (cmp != 0)
3347 return cmp;
3348 cmp = isl_space_cmp_type(space1, space2, isl_dim_in);
3349 if (cmp != 0)
3350 return cmp;
3351 cmp = isl_space_cmp_type(space1, space2, isl_dim_out);
3352 if (cmp != 0)
3353 return cmp;
3354
3355 if (!space1->ids && !space2->ids)
3356 return 0;
3357
3358 for (i = 0; i < n(space1, isl_dim_param); ++i) {
3359 cmp = isl_id_cmp(get_id(space1, isl_dim_param, i),
3360 get_id(space2, isl_dim_param, i));
3361 if (cmp != 0)
3362 return cmp;
3363 }
3364
3365 return 0;
3366}