Bug Summary

File:tools/polly/lib/External/isl/isl_list_templ.c
Warning:line 243, column 3
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name isl_schedule_tree.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 -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-9/lib/clang/9.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/pet/include -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/ppcg/include -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/ppcg/imath -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/polly/lib/External/ppcg -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/imath -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/polly/lib/External/isl -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/polly/include -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/polly/lib/External/isl/include -I /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/include -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/include -I /build/llvm-toolchain-snapshot-9~svn362543/include -U NDEBUG -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-9/lib/clang/9.0.0/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-9~svn362543/build-llvm/tools/polly/lib/External -fdebug-prefix-map=/build/llvm-toolchain-snapshot-9~svn362543=. -ferror-limit 19 -fmessage-length 0 -stack-protector 2 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2019-06-05-060531-1271-1 -x c /build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c -faddrsig

/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c

1/*
2 * Copyright 2013-2014 Ecole Normale Superieure
3 * Copyright 2014 INRIA Rocquencourt
4 * Copyright 2016 INRIA Paris
5 *
6 * Use of this software is governed by the MIT license
7 *
8 * Written by Sven Verdoolaege,
9 * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
10 * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
11 * B.P. 105 - 78153 Le Chesnay, France
12 * and Centre de Recherche Inria de Paris, 2 rue Simone Iff - Voie DQ12,
13 * CS 42112, 75589 Paris Cedex 12, France
14 */
15
16#include <isl/id.h>
17#include <isl/val.h>
18#include <isl/space.h>
19#include <isl/map.h>
20#include <isl_schedule_band.h>
21#include <isl_schedule_private.h>
22
23#undef ELisl_schedule_tree
24#define ELisl_schedule_tree isl_schedule_tree
25
26#include <isl_list_templ.h>
27
28#undef BASEschedule_tree
29#define BASEschedule_tree schedule_tree
30
31#include <isl_list_templ.c>
32
33/* Is "tree" the leaf of a schedule tree?
34 */
35int isl_schedule_tree_is_leaf(__isl_keep isl_schedule_tree *tree)
36{
37 return isl_schedule_tree_get_type(tree) == isl_schedule_node_leaf;
38}
39
40/* Create a new schedule tree of type "type".
41 * The caller is responsible for filling in the type specific fields and
42 * the children.
43 *
44 * By default, the single node tree does not have any anchored nodes.
45 * The caller is responsible for updating the anchored field if needed.
46 */
47static __isl_give isl_schedule_tree *isl_schedule_tree_alloc(isl_ctx *ctx,
48 enum isl_schedule_node_type type)
49{
50 isl_schedule_tree *tree;
51
52 if (type == isl_schedule_node_error)
53 return NULL((void*)0);
54
55 tree = isl_calloc_type(ctx, isl_schedule_tree)((isl_schedule_tree *)isl_calloc_or_die(ctx, 1, sizeof(isl_schedule_tree
)))
;
56 if (!tree)
57 return NULL((void*)0);
58
59 tree->ref = 1;
60 tree->ctx = ctx;
61 isl_ctx_ref(ctx);
62 tree->type = type;
63 tree->anchored = 0;
64
65 return tree;
66}
67
68/* Return a fresh copy of "tree".
69 */
70__isl_take isl_schedule_tree *isl_schedule_tree_dup(
71 __isl_keep isl_schedule_tree *tree)
72{
73 isl_ctx *ctx;
74 isl_schedule_tree *dup;
75
76 if (!tree)
77 return NULL((void*)0);
78
79 ctx = isl_schedule_tree_get_ctx(tree);
80 dup = isl_schedule_tree_alloc(ctx, tree->type);
81 if (!dup)
82 return NULL((void*)0);
83
84 switch (tree->type) {
85 case isl_schedule_node_error:
86 isl_die(ctx, isl_error_internal,do { isl_handle_error(ctx, isl_error_internal, "allocation should have failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 88); return isl_schedule_tree_free(dup); } while (0)
87 "allocation should have failed",do { isl_handle_error(ctx, isl_error_internal, "allocation should have failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 88); return isl_schedule_tree_free(dup); } while (0)
88 return isl_schedule_tree_free(dup))do { isl_handle_error(ctx, isl_error_internal, "allocation should have failed"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 88); return isl_schedule_tree_free(dup); } while (0)
;
89 case isl_schedule_node_band:
90 dup->band = isl_schedule_band_copy(tree->band);
91 if (!dup->band)
92 return isl_schedule_tree_free(dup);
93 break;
94 case isl_schedule_node_context:
95 dup->context = isl_set_copy(tree->context);
96 if (!dup->context)
97 return isl_schedule_tree_free(dup);
98 break;
99 case isl_schedule_node_domain:
100 dup->domain = isl_union_set_copy(tree->domain);
101 if (!dup->domain)
102 return isl_schedule_tree_free(dup);
103 break;
104 case isl_schedule_node_expansion:
105 dup->contraction =
106 isl_union_pw_multi_aff_copy(tree->contraction);
107 dup->expansion = isl_union_map_copy(tree->expansion);
108 if (!dup->contraction || !dup->expansion)
109 return isl_schedule_tree_free(dup);
110 break;
111 case isl_schedule_node_extension:
112 dup->extension = isl_union_map_copy(tree->extension);
113 if (!dup->extension)
114 return isl_schedule_tree_free(dup);
115 break;
116 case isl_schedule_node_filter:
117 dup->filter = isl_union_set_copy(tree->filter);
118 if (!dup->filter)
119 return isl_schedule_tree_free(dup);
120 break;
121 case isl_schedule_node_guard:
122 dup->guard = isl_set_copy(tree->guard);
123 if (!dup->guard)
124 return isl_schedule_tree_free(dup);
125 break;
126 case isl_schedule_node_mark:
127 dup->mark = isl_id_copy(tree->mark);
128 if (!dup->mark)
129 return isl_schedule_tree_free(dup);
130 break;
131 case isl_schedule_node_leaf:
132 case isl_schedule_node_sequence:
133 case isl_schedule_node_set:
134 break;
135 }
136
137 if (tree->children) {
138 dup->children = isl_schedule_tree_list_copy(tree->children);
139 if (!dup->children)
140 return isl_schedule_tree_free(dup);
141 }
142 dup->anchored = tree->anchored;
143
144 return dup;
145}
146
147/* Return an isl_schedule_tree that is equal to "tree" and that has only
148 * a single reference.
149 */
150__isl_give isl_schedule_tree *isl_schedule_tree_cow(
151 __isl_take isl_schedule_tree *tree)
152{
153 if (!tree)
154 return NULL((void*)0);
155
156 if (tree->ref == 1)
157 return tree;
158 tree->ref--;
159 return isl_schedule_tree_dup(tree);
160}
161
162/* Return a new reference to "tree".
163 */
164__isl_give isl_schedule_tree *isl_schedule_tree_copy(
165 __isl_keep isl_schedule_tree *tree)
166{
167 if (!tree)
28
Assuming 'tree' is non-null
29
Taking false branch
168 return NULL((void*)0);
169
170 tree->ref++;
171 return tree;
172}
173
174/* Free "tree" and return NULL.
175 */
176__isl_null isl_schedule_tree *isl_schedule_tree_free(
177 __isl_take isl_schedule_tree *tree)
178{
179 if (!tree)
35
Taking false branch
47
Taking false branch
180 return NULL((void*)0);
181 if (--tree->ref > 0)
36
Assuming the condition is false
37
Taking false branch
48
Assuming the condition is false
49
Taking false branch
182 return NULL((void*)0);
183
184 switch (tree->type) {
38
Control jumps to 'case isl_schedule_node_band:' at line 185
50
Control jumps to 'case isl_schedule_node_band:' at line 185
185 case isl_schedule_node_band:
186 isl_schedule_band_free(tree->band);
187 break;
39
Execution continues on line 216
51
Execution continues on line 216
188 case isl_schedule_node_context:
189 isl_set_free(tree->context);
190 break;
191 case isl_schedule_node_domain:
192 isl_union_set_free(tree->domain);
193 break;
194 case isl_schedule_node_expansion:
195 isl_union_pw_multi_aff_free(tree->contraction);
196 isl_union_map_free(tree->expansion);
197 break;
198 case isl_schedule_node_extension:
199 isl_union_map_free(tree->extension);
200 break;
201 case isl_schedule_node_filter:
202 isl_union_set_free(tree->filter);
203 break;
204 case isl_schedule_node_guard:
205 isl_set_free(tree->guard);
206 break;
207 case isl_schedule_node_mark:
208 isl_id_free(tree->mark);
209 break;
210 case isl_schedule_node_sequence:
211 case isl_schedule_node_set:
212 case isl_schedule_node_error:
213 case isl_schedule_node_leaf:
214 break;
215 }
216 isl_schedule_tree_list_free(tree->children);
52
Calling 'isl_schedule_tree_list_free'
217 isl_ctx_deref(tree->ctx);
218 free(tree);
40
Memory is released
219
220 return NULL((void*)0);
221}
222
223/* Create and return a new leaf schedule tree.
224 */
225__isl_give isl_schedule_tree *isl_schedule_tree_leaf(isl_ctx *ctx)
226{
227 return isl_schedule_tree_alloc(ctx, isl_schedule_node_leaf);
228}
229
230/* Create a new band schedule tree referring to "band"
231 * with no children.
232 */
233__isl_give isl_schedule_tree *isl_schedule_tree_from_band(
234 __isl_take isl_schedule_band *band)
235{
236 isl_ctx *ctx;
237 isl_schedule_tree *tree;
238
239 if (!band)
240 return NULL((void*)0);
241
242 ctx = isl_schedule_band_get_ctx(band);
243 tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_band);
244 if (!tree)
245 goto error;
246
247 tree->band = band;
248 tree->anchored = isl_schedule_band_is_anchored(band);
249
250 return tree;
251error:
252 isl_schedule_band_free(band);
253 return NULL((void*)0);
254}
255
256/* Create a new context schedule tree with the given context and no children.
257 * Since the context references the outer schedule dimension,
258 * the tree is anchored.
259 */
260__isl_give isl_schedule_tree *isl_schedule_tree_from_context(
261 __isl_take isl_set *context)
262{
263 isl_ctx *ctx;
264 isl_schedule_tree *tree;
265
266 if (!context)
267 return NULL((void*)0);
268
269 ctx = isl_set_get_ctx(context);
270 tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_context);
271 if (!tree)
272 goto error;
273
274 tree->context = context;
275 tree->anchored = 1;
276
277 return tree;
278error:
279 isl_set_free(context);
280 return NULL((void*)0);
281}
282
283/* Create a new domain schedule tree with the given domain and no children.
284 */
285__isl_give isl_schedule_tree *isl_schedule_tree_from_domain(
286 __isl_take isl_union_set *domain)
287{
288 isl_ctx *ctx;
289 isl_schedule_tree *tree;
290
291 if (!domain)
292 return NULL((void*)0);
293
294 ctx = isl_union_set_get_ctx(domain);
295 tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_domain);
296 if (!tree)
297 goto error;
298
299 tree->domain = domain;
300
301 return tree;
302error:
303 isl_union_set_free(domain);
304 return NULL((void*)0);
305}
306
307/* Create a new expansion schedule tree with the given contraction and
308 * expansion and no children.
309 */
310__isl_give isl_schedule_tree *isl_schedule_tree_from_expansion(
311 __isl_take isl_union_pw_multi_aff *contraction,
312 __isl_take isl_union_map *expansion)
313{
314 isl_ctx *ctx;
315 isl_schedule_tree *tree;
316
317 if (!contraction || !expansion)
318 goto error;
319
320 ctx = isl_union_map_get_ctx(expansion);
321 tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_expansion);
322 if (!tree)
323 goto error;
324
325 tree->contraction = contraction;
326 tree->expansion = expansion;
327
328 return tree;
329error:
330 isl_union_pw_multi_aff_free(contraction);
331 isl_union_map_free(expansion);
332 return NULL((void*)0);
333}
334
335/* Create a new extension schedule tree with the given extension and
336 * no children.
337 * Since the domain of the extension refers to the outer schedule dimension,
338 * the tree is anchored.
339 */
340__isl_give isl_schedule_tree *isl_schedule_tree_from_extension(
341 __isl_take isl_union_map *extension)
342{
343 isl_ctx *ctx;
344 isl_schedule_tree *tree;
345
346 if (!extension)
347 return NULL((void*)0);
348
349 ctx = isl_union_map_get_ctx(extension);
350 tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_extension);
351 if (!tree)
352 goto error;
353
354 tree->extension = extension;
355 tree->anchored = 1;
356
357 return tree;
358error:
359 isl_union_map_free(extension);
360 return NULL((void*)0);
361}
362
363/* Create a new filter schedule tree with the given filter and no children.
364 */
365__isl_give isl_schedule_tree *isl_schedule_tree_from_filter(
366 __isl_take isl_union_set *filter)
367{
368 isl_ctx *ctx;
369 isl_schedule_tree *tree;
370
371 if (!filter)
372 return NULL((void*)0);
373
374 ctx = isl_union_set_get_ctx(filter);
375 tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_filter);
376 if (!tree)
377 goto error;
378
379 tree->filter = filter;
380
381 return tree;
382error:
383 isl_union_set_free(filter);
384 return NULL((void*)0);
385}
386
387/* Create a new guard schedule tree with the given guard and no children.
388 * Since the guard references the outer schedule dimension,
389 * the tree is anchored.
390 */
391__isl_give isl_schedule_tree *isl_schedule_tree_from_guard(
392 __isl_take isl_set *guard)
393{
394 isl_ctx *ctx;
395 isl_schedule_tree *tree;
396
397 if (!guard)
398 return NULL((void*)0);
399
400 ctx = isl_set_get_ctx(guard);
401 tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_guard);
402 if (!tree)
403 goto error;
404
405 tree->guard = guard;
406 tree->anchored = 1;
407
408 return tree;
409error:
410 isl_set_free(guard);
411 return NULL((void*)0);
412}
413
414/* Create a new mark schedule tree with the given mark identifier and
415 * no children.
416 */
417__isl_give isl_schedule_tree *isl_schedule_tree_from_mark(
418 __isl_take isl_id *mark)
419{
420 isl_ctx *ctx;
421 isl_schedule_tree *tree;
422
423 if (!mark)
424 return NULL((void*)0);
425
426 ctx = isl_id_get_ctx(mark);
427 tree = isl_schedule_tree_alloc(ctx, isl_schedule_node_mark);
428 if (!tree)
429 goto error;
430
431 tree->mark = mark;
432
433 return tree;
434error:
435 isl_id_free(mark);
436 return NULL((void*)0);
437}
438
439/* Does "tree" have any node that depends on its position
440 * in the complete schedule tree?
441 */
442isl_bool isl_schedule_tree_is_subtree_anchored(
443 __isl_keep isl_schedule_tree *tree)
444{
445 return tree ? tree->anchored : isl_bool_error;
446}
447
448/* Does the root node of "tree" depend on its position in the complete
449 * schedule tree?
450 * Band nodes may be anchored depending on the associated AST build options.
451 * Context, extension and guard nodes are always anchored.
452 */
453int isl_schedule_tree_is_anchored(__isl_keep isl_schedule_tree *tree)
454{
455 if (!tree)
456 return -1;
457
458 switch (isl_schedule_tree_get_type(tree)) {
459 case isl_schedule_node_error:
460 return -1;
461 case isl_schedule_node_band:
462 return isl_schedule_band_is_anchored(tree->band);
463 case isl_schedule_node_context:
464 case isl_schedule_node_extension:
465 case isl_schedule_node_guard:
466 return 1;
467 case isl_schedule_node_domain:
468 case isl_schedule_node_expansion:
469 case isl_schedule_node_filter:
470 case isl_schedule_node_leaf:
471 case isl_schedule_node_mark:
472 case isl_schedule_node_sequence:
473 case isl_schedule_node_set:
474 return 0;
475 }
476
477 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "unhandled case", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 478); return -1; } while (0)
478 "unhandled case", return -1)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "unhandled case", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 478); return -1; } while (0)
;
479}
480
481/* Update the anchored field of "tree" based on whether the root node
482 * itself in anchored and the anchored fields of the children.
483 *
484 * This function should be called whenever the children of a tree node
485 * are changed or the anchoredness of the tree root itself changes.
486 */
487__isl_give isl_schedule_tree *isl_schedule_tree_update_anchored(
488 __isl_take isl_schedule_tree *tree)
489{
490 int i, n;
491 int anchored;
492
493 if (!tree)
494 return NULL((void*)0);
495
496 anchored = isl_schedule_tree_is_anchored(tree);
497 if (anchored < 0)
498 return isl_schedule_tree_free(tree);
499
500 n = isl_schedule_tree_list_n_schedule_tree(tree->children);
501 for (i = 0; !anchored && i < n; ++i) {
502 isl_schedule_tree *child;
503
504 child = isl_schedule_tree_get_child(tree, i);
505 if (!child)
506 return isl_schedule_tree_free(tree);
507 anchored = child->anchored;
508 isl_schedule_tree_free(child);
509 }
510
511 if (anchored == tree->anchored)
512 return tree;
513 tree = isl_schedule_tree_cow(tree);
514 if (!tree)
515 return NULL((void*)0);
516 tree->anchored = anchored;
517 return tree;
518}
519
520/* Create a new tree of the given type (isl_schedule_node_sequence or
521 * isl_schedule_node_set) with the given children.
522 */
523__isl_give isl_schedule_tree *isl_schedule_tree_from_children(
524 enum isl_schedule_node_type type,
525 __isl_take isl_schedule_tree_list *list)
526{
527 isl_ctx *ctx;
528 isl_schedule_tree *tree;
529
530 if (!list)
531 return NULL((void*)0);
532
533 ctx = isl_schedule_tree_list_get_ctx(list);
534 tree = isl_schedule_tree_alloc(ctx, type);
535 if (!tree)
536 goto error;
537
538 tree->children = list;
539 tree = isl_schedule_tree_update_anchored(tree);
540
541 return tree;
542error:
543 isl_schedule_tree_list_free(list);
544 return NULL((void*)0);
545}
546
547/* Construct a tree with a root node of type "type" and as children
548 * "tree1" and "tree2".
549 * If the root of one (or both) of the input trees is itself of type "type",
550 * then the tree is replaced by its children.
551 */
552__isl_give isl_schedule_tree *isl_schedule_tree_from_pair(
553 enum isl_schedule_node_type type, __isl_take isl_schedule_tree *tree1,
554 __isl_take isl_schedule_tree *tree2)
555{
556 isl_ctx *ctx;
557 isl_schedule_tree_list *list;
558
559 if (!tree1 || !tree2)
560 goto error;
561
562 ctx = isl_schedule_tree_get_ctx(tree1);
563 if (isl_schedule_tree_get_type(tree1) == type) {
564 list = isl_schedule_tree_list_copy(tree1->children);
565 isl_schedule_tree_free(tree1);
566 } else {
567 list = isl_schedule_tree_list_alloc(ctx, 2);
568 list = isl_schedule_tree_list_add(list, tree1);
569 }
570 if (isl_schedule_tree_get_type(tree2) == type) {
571 isl_schedule_tree_list *children;
572
573 children = isl_schedule_tree_list_copy(tree2->children);
574 list = isl_schedule_tree_list_concat(list, children);
575 isl_schedule_tree_free(tree2);
576 } else {
577 list = isl_schedule_tree_list_add(list, tree2);
578 }
579
580 return isl_schedule_tree_from_children(type, list);
581error:
582 isl_schedule_tree_free(tree1);
583 isl_schedule_tree_free(tree2);
584 return NULL((void*)0);
585}
586
587/* Construct a tree with a sequence root node and as children
588 * "tree1" and "tree2".
589 * If the root of one (or both) of the input trees is itself a sequence,
590 * then the tree is replaced by its children.
591 */
592__isl_give isl_schedule_tree *isl_schedule_tree_sequence_pair(
593 __isl_take isl_schedule_tree *tree1,
594 __isl_take isl_schedule_tree *tree2)
595{
596 return isl_schedule_tree_from_pair(isl_schedule_node_sequence,
597 tree1, tree2);
598}
599
600/* Construct a tree with a set root node and as children
601 * "tree1" and "tree2".
602 * If the root of one (or both) of the input trees is itself a set,
603 * then the tree is replaced by its children.
604 */
605__isl_give isl_schedule_tree *isl_schedule_tree_set_pair(
606 __isl_take isl_schedule_tree *tree1,
607 __isl_take isl_schedule_tree *tree2)
608{
609 return isl_schedule_tree_from_pair(isl_schedule_node_set, tree1, tree2);
610}
611
612/* Return the isl_ctx to which "tree" belongs.
613 */
614isl_ctx *isl_schedule_tree_get_ctx(__isl_keep isl_schedule_tree *tree)
615{
616 return tree ? tree->ctx : NULL((void*)0);
617}
618
619/* Return the type of the root of the tree or isl_schedule_node_error
620 * on error.
621 */
622enum isl_schedule_node_type isl_schedule_tree_get_type(
623 __isl_keep isl_schedule_tree *tree)
624{
625 return tree ? tree->type : isl_schedule_node_error;
626}
627
628/* Are "tree1" and "tree2" obviously equal to each other?
629 */
630isl_bool isl_schedule_tree_plain_is_equal(__isl_keep isl_schedule_tree *tree1,
631 __isl_keep isl_schedule_tree *tree2)
632{
633 isl_bool equal;
634 int i, n;
635
636 if (!tree1 || !tree2)
637 return isl_bool_error;
638 if (tree1 == tree2)
639 return isl_bool_true;
640 if (tree1->type != tree2->type)
641 return isl_bool_false;
642
643 switch (tree1->type) {
644 case isl_schedule_node_band:
645 equal = isl_schedule_band_plain_is_equal(tree1->band,
646 tree2->band);
647 break;
648 case isl_schedule_node_context:
649 equal = isl_set_is_equal(tree1->context, tree2->context);
650 break;
651 case isl_schedule_node_domain:
652 equal = isl_union_set_is_equal(tree1->domain, tree2->domain);
653 break;
654 case isl_schedule_node_expansion:
655 equal = isl_union_map_is_equal(tree1->expansion,
656 tree2->expansion);
657 if (equal >= 0 && equal)
658 equal = isl_union_pw_multi_aff_plain_is_equal(
659 tree1->contraction, tree2->contraction);
660 break;
661 case isl_schedule_node_extension:
662 equal = isl_union_map_is_equal(tree1->extension,
663 tree2->extension);
664 break;
665 case isl_schedule_node_filter:
666 equal = isl_union_set_is_equal(tree1->filter, tree2->filter);
667 break;
668 case isl_schedule_node_guard:
669 equal = isl_set_is_equal(tree1->guard, tree2->guard);
670 break;
671 case isl_schedule_node_mark:
672 equal = tree1->mark == tree2->mark;
673 break;
674 case isl_schedule_node_leaf:
675 case isl_schedule_node_sequence:
676 case isl_schedule_node_set:
677 equal = isl_bool_true;
678 break;
679 case isl_schedule_node_error:
680 equal = isl_bool_error;
681 break;
682 }
683
684 if (equal < 0 || !equal)
685 return equal;
686
687 n = isl_schedule_tree_n_children(tree1);
688 if (n != isl_schedule_tree_n_children(tree2))
689 return isl_bool_false;
690 for (i = 0; i < n; ++i) {
691 isl_schedule_tree *child1, *child2;
692
693 child1 = isl_schedule_tree_get_child(tree1, i);
694 child2 = isl_schedule_tree_get_child(tree2, i);
695 equal = isl_schedule_tree_plain_is_equal(child1, child2);
696 isl_schedule_tree_free(child1);
697 isl_schedule_tree_free(child2);
698
699 if (equal < 0 || !equal)
700 return equal;
701 }
702
703 return isl_bool_true;
704}
705
706/* Does "tree" have any children, other than an implicit leaf.
707 */
708int isl_schedule_tree_has_children(__isl_keep isl_schedule_tree *tree)
709{
710 if (!tree)
711 return -1;
712
713 return tree->children != NULL((void*)0);
714}
715
716/* Return the number of children of "tree", excluding implicit leaves.
717 */
718int isl_schedule_tree_n_children(__isl_keep isl_schedule_tree *tree)
719{
720 if (!tree)
721 return -1;
722
723 return isl_schedule_tree_list_n_schedule_tree(tree->children);
724}
725
726/* Return a copy of the (explicit) child at position "pos" of "tree".
727 */
728__isl_give isl_schedule_tree *isl_schedule_tree_get_child(
729 __isl_keep isl_schedule_tree *tree, int pos)
730{
731 if (!tree)
23
Taking false branch
732 return NULL((void*)0);
733 if (!tree->children)
24
Taking false branch
734 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "schedule tree has no explicit children", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 735); return ((void*)0); } while (0)
735 "schedule tree has no explicit children", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "schedule tree has no explicit children", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 735); return ((void*)0); } while (0)
;
736 return isl_schedule_tree_list_get_schedule_tree(tree->children, pos);
25
Calling 'isl_schedule_tree_list_get_schedule_tree'
32
Returning from 'isl_schedule_tree_list_get_schedule_tree'
737}
738
739/* Return a copy of the (explicit) child at position "pos" of "tree" and
740 * free "tree".
741 */
742__isl_give isl_schedule_tree *isl_schedule_tree_child(
743 __isl_take isl_schedule_tree *tree, int pos)
744{
745 isl_schedule_tree *child;
746
747 child = isl_schedule_tree_get_child(tree, pos);
748 isl_schedule_tree_free(tree);
749 return child;
750}
751
752/* Remove all (explicit) children from "tree".
753 */
754__isl_give isl_schedule_tree *isl_schedule_tree_reset_children(
755 __isl_take isl_schedule_tree *tree)
756{
757 tree = isl_schedule_tree_cow(tree);
758 if (!tree)
759 return NULL((void*)0);
760 tree->children = isl_schedule_tree_list_free(tree->children);
761 return tree;
762}
763
764/* Remove the child at position "pos" from the children of "tree".
765 * If there was only one child to begin with, then remove all children.
766 */
767__isl_give isl_schedule_tree *isl_schedule_tree_drop_child(
768 __isl_take isl_schedule_tree *tree, int pos)
769{
770 int n;
771
772 tree = isl_schedule_tree_cow(tree);
773 if (!tree)
774 return NULL((void*)0);
775
776 if (!isl_schedule_tree_has_children(tree))
777 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "tree does not have any explicit children", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 779); return isl_schedule_tree_free(tree); } while (0)
778 "tree does not have any explicit children",do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "tree does not have any explicit children", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 779); return isl_schedule_tree_free(tree); } while (0)
779 return isl_schedule_tree_free(tree))do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "tree does not have any explicit children", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 779); return isl_schedule_tree_free(tree); } while (0)
;
780 n = isl_schedule_tree_list_n_schedule_tree(tree->children);
781 if (pos < 0 || pos >= n)
782 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "position out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 784); return isl_schedule_tree_free(tree); } while (0)
783 "position out of bounds",do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "position out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 784); return isl_schedule_tree_free(tree); } while (0)
784 return isl_schedule_tree_free(tree))do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "position out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 784); return isl_schedule_tree_free(tree); } while (0)
;
785 if (n == 1)
786 return isl_schedule_tree_reset_children(tree);
787
788 tree->children = isl_schedule_tree_list_drop(tree->children, pos, 1);
789 if (!tree->children)
790 return isl_schedule_tree_free(tree);
791
792 return tree;
793}
794
795/* Replace the child at position "pos" of "tree" by "child".
796 *
797 * If the new child is a leaf, then it is not explicitly
798 * recorded in the list of children. Instead, the list of children
799 * (which is assumed to have only one element) is removed.
800 * Note that the children of set and sequence nodes are always
801 * filters, so they cannot be replaced by empty trees.
802 */
803__isl_give isl_schedule_tree *isl_schedule_tree_replace_child(
804 __isl_take isl_schedule_tree *tree, int pos,
805 __isl_take isl_schedule_tree *child)
806{
807 tree = isl_schedule_tree_cow(tree);
808 if (!tree || !child)
809 goto error;
810
811 if (isl_schedule_tree_is_leaf(child)) {
812 isl_schedule_tree_free(child);
813 if (!tree->children && pos == 0)
814 return tree;
815 if (isl_schedule_tree_n_children(tree) != 1)
816 isl_die(isl_schedule_tree_get_ctx(tree),do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "can only replace single child by leaf", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 819); goto error; } while (0)
817 isl_error_internal,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "can only replace single child by leaf", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 819); goto error; } while (0)
818 "can only replace single child by leaf",do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "can only replace single child by leaf", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 819); goto error; } while (0)
819 goto error)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "can only replace single child by leaf", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 819); goto error; } while (0)
;
820 return isl_schedule_tree_reset_children(tree);
821 }
822
823 if (!tree->children && pos == 0)
824 tree->children =
825 isl_schedule_tree_list_from_schedule_tree(child);
826 else
827 tree->children = isl_schedule_tree_list_set_schedule_tree(
828 tree->children, pos, child);
829
830 if (!tree->children)
831 return isl_schedule_tree_free(tree);
832 tree = isl_schedule_tree_update_anchored(tree);
833
834 return tree;
835error:
836 isl_schedule_tree_free(tree);
837 isl_schedule_tree_free(child);
838 return NULL((void*)0);
839}
840
841/* Replace the (explicit) children of "tree" by "children"?
842 */
843__isl_give isl_schedule_tree *isl_schedule_tree_set_children(
844 __isl_take isl_schedule_tree *tree,
845 __isl_take isl_schedule_tree_list *children)
846{
847 tree = isl_schedule_tree_cow(tree);
848 if (!tree || !children)
849 goto error;
850 isl_schedule_tree_list_free(tree->children);
851 tree->children = children;
852 return tree;
853error:
854 isl_schedule_tree_free(tree);
855 isl_schedule_tree_list_free(children);
856 return NULL((void*)0);
857}
858
859/* Create a new band schedule tree referring to "band"
860 * with "tree" as single child.
861 */
862__isl_give isl_schedule_tree *isl_schedule_tree_insert_band(
863 __isl_take isl_schedule_tree *tree, __isl_take isl_schedule_band *band)
864{
865 isl_schedule_tree *res;
866
867 res = isl_schedule_tree_from_band(band);
868 return isl_schedule_tree_replace_child(res, 0, tree);
869}
870
871/* Create a new context schedule tree with the given context and
872 * with "tree" as single child.
873 */
874__isl_give isl_schedule_tree *isl_schedule_tree_insert_context(
875 __isl_take isl_schedule_tree *tree, __isl_take isl_set *context)
876{
877 isl_schedule_tree *res;
878
879 res = isl_schedule_tree_from_context(context);
880 return isl_schedule_tree_replace_child(res, 0, tree);
881}
882
883/* Create a new domain schedule tree with the given domain and
884 * with "tree" as single child.
885 */
886__isl_give isl_schedule_tree *isl_schedule_tree_insert_domain(
887 __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain)
888{
889 isl_schedule_tree *res;
890
891 res = isl_schedule_tree_from_domain(domain);
892 return isl_schedule_tree_replace_child(res, 0, tree);
893}
894
895/* Create a new expansion schedule tree with the given contraction and
896 * expansion and with "tree" as single child.
897 */
898__isl_give isl_schedule_tree *isl_schedule_tree_insert_expansion(
899 __isl_take isl_schedule_tree *tree,
900 __isl_take isl_union_pw_multi_aff *contraction,
901 __isl_take isl_union_map *expansion)
902{
903 isl_schedule_tree *res;
904
905 res = isl_schedule_tree_from_expansion(contraction, expansion);
906 return isl_schedule_tree_replace_child(res, 0, tree);
907}
908
909/* Create a new extension schedule tree with the given extension and
910 * with "tree" as single child.
911 */
912__isl_give isl_schedule_tree *isl_schedule_tree_insert_extension(
913 __isl_take isl_schedule_tree *tree, __isl_take isl_union_map *extension)
914{
915 isl_schedule_tree *res;
916
917 res = isl_schedule_tree_from_extension(extension);
918 return isl_schedule_tree_replace_child(res, 0, tree);
919}
920
921/* Create a new filter schedule tree with the given filter and single child.
922 *
923 * If the root of "tree" is itself a filter node, then the two
924 * filter nodes are merged into one node.
925 */
926__isl_give isl_schedule_tree *isl_schedule_tree_insert_filter(
927 __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter)
928{
929 isl_schedule_tree *res;
930
931 if (isl_schedule_tree_get_type(tree) == isl_schedule_node_filter) {
932 isl_union_set *tree_filter;
933
934 tree_filter = isl_schedule_tree_filter_get_filter(tree);
935 tree_filter = isl_union_set_intersect(tree_filter, filter);
936 tree = isl_schedule_tree_filter_set_filter(tree, tree_filter);
937 return tree;
938 }
939
940 res = isl_schedule_tree_from_filter(filter);
941 return isl_schedule_tree_replace_child(res, 0, tree);
942}
943
944/* Insert a filter node with filter set "filter"
945 * in each of the children of "tree".
946 */
947__isl_give isl_schedule_tree *isl_schedule_tree_children_insert_filter(
948 __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter)
949{
950 int i, n;
951
952 if (!tree || !filter)
953 goto error;
954
955 n = isl_schedule_tree_n_children(tree);
956 for (i = 0; i < n; ++i) {
957 isl_schedule_tree *child;
958
959 child = isl_schedule_tree_get_child(tree, i);
960 child = isl_schedule_tree_insert_filter(child,
961 isl_union_set_copy(filter));
962 tree = isl_schedule_tree_replace_child(tree, i, child);
963 }
964
965 isl_union_set_free(filter);
966 return tree;
967error:
968 isl_union_set_free(filter);
969 isl_schedule_tree_free(tree);
970 return NULL((void*)0);
971}
972
973/* Create a new guard schedule tree with the given guard and
974 * with "tree" as single child.
975 */
976__isl_give isl_schedule_tree *isl_schedule_tree_insert_guard(
977 __isl_take isl_schedule_tree *tree, __isl_take isl_set *guard)
978{
979 isl_schedule_tree *res;
980
981 res = isl_schedule_tree_from_guard(guard);
982 return isl_schedule_tree_replace_child(res, 0, tree);
983}
984
985/* Create a new mark schedule tree with the given mark identifier and
986 * single child.
987 */
988__isl_give isl_schedule_tree *isl_schedule_tree_insert_mark(
989 __isl_take isl_schedule_tree *tree, __isl_take isl_id *mark)
990{
991 isl_schedule_tree *res;
992
993 res = isl_schedule_tree_from_mark(mark);
994 return isl_schedule_tree_replace_child(res, 0, tree);
995}
996
997/* Return the number of members in the band tree root.
998 */
999unsigned isl_schedule_tree_band_n_member(__isl_keep isl_schedule_tree *tree)
1000{
1001 if (!tree)
1002 return 0;
1003
1004 if (tree->type != isl_schedule_node_band)
1005 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1006); return 0; } while (0)
1006 "not a band node", return 0)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1006); return 0; } while (0)
;
1007
1008 return isl_schedule_band_n_member(tree->band);
1009}
1010
1011/* Is the band member at position "pos" of the band tree root
1012 * marked coincident?
1013 */
1014isl_bool isl_schedule_tree_band_member_get_coincident(
1015 __isl_keep isl_schedule_tree *tree, int pos)
1016{
1017 if (!tree)
1018 return isl_bool_error;
1019
1020 if (tree->type != isl_schedule_node_band)
1021 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1022); return isl_bool_error; } while (0)
1022 "not a band node", return isl_bool_error)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1022); return isl_bool_error; } while (0)
;
1023
1024 return isl_schedule_band_member_get_coincident(tree->band, pos);
1025}
1026
1027/* Mark the given band member as being coincident or not
1028 * according to "coincident".
1029 */
1030__isl_give isl_schedule_tree *isl_schedule_tree_band_member_set_coincident(
1031 __isl_take isl_schedule_tree *tree, int pos, int coincident)
1032{
1033 if (!tree)
1034 return NULL((void*)0);
1035 if (tree->type != isl_schedule_node_band)
1036 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1037); return isl_schedule_tree_free(tree); } while (0)
1037 "not a band node", return isl_schedule_tree_free(tree))do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1037); return isl_schedule_tree_free(tree); } while (0)
;
1038 if (isl_schedule_tree_band_member_get_coincident(tree, pos) ==
1039 coincident)
1040 return tree;
1041 tree = isl_schedule_tree_cow(tree);
1042 if (!tree)
1043 return NULL((void*)0);
1044
1045 tree->band = isl_schedule_band_member_set_coincident(tree->band, pos,
1046 coincident);
1047 if (!tree->band)
1048 return isl_schedule_tree_free(tree);
1049 return tree;
1050}
1051
1052/* Is the band tree root marked permutable?
1053 */
1054isl_bool isl_schedule_tree_band_get_permutable(
1055 __isl_keep isl_schedule_tree *tree)
1056{
1057 if (!tree)
1058 return isl_bool_error;
1059
1060 if (tree->type != isl_schedule_node_band)
1061 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1062); return isl_bool_error; } while (0)
1062 "not a band node", return isl_bool_error)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1062); return isl_bool_error; } while (0)
;
1063
1064 return isl_schedule_band_get_permutable(tree->band);
1065}
1066
1067/* Mark the band tree root permutable or not according to "permutable"?
1068 */
1069__isl_give isl_schedule_tree *isl_schedule_tree_band_set_permutable(
1070 __isl_take isl_schedule_tree *tree, int permutable)
1071{
1072 if (!tree)
1073 return NULL((void*)0);
1074 if (tree->type != isl_schedule_node_band)
1075 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1076); return isl_schedule_tree_free(tree); } while (0)
1076 "not a band node", return isl_schedule_tree_free(tree))do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1076); return isl_schedule_tree_free(tree); } while (0)
;
1077 if (isl_schedule_tree_band_get_permutable(tree) == permutable)
1078 return tree;
1079 tree = isl_schedule_tree_cow(tree);
1080 if (!tree)
1081 return NULL((void*)0);
1082
1083 tree->band = isl_schedule_band_set_permutable(tree->band, permutable);
1084 if (!tree->band)
1085 return isl_schedule_tree_free(tree);
1086 return tree;
1087}
1088
1089/* Return the schedule space of the band tree root.
1090 */
1091__isl_give isl_space *isl_schedule_tree_band_get_space(
1092 __isl_keep isl_schedule_tree *tree)
1093{
1094 if (!tree)
1095 return NULL((void*)0);
1096
1097 if (tree->type != isl_schedule_node_band)
1098 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1099); return ((void*)0); } while (0)
1099 "not a band node", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1099); return ((void*)0); } while (0)
;
1100
1101 return isl_schedule_band_get_space(tree->band);
1102}
1103
1104/* Intersect the domain of the band schedule of the band tree root
1105 * with "domain".
1106 */
1107__isl_give isl_schedule_tree *isl_schedule_tree_band_intersect_domain(
1108 __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain)
1109{
1110 if (!tree || !domain)
1111 goto error;
1112
1113 if (tree->type != isl_schedule_node_band)
1114 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1115); goto error; } while (0)
1115 "not a band node", goto error)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1115); goto error; } while (0)
;
1116
1117 tree->band = isl_schedule_band_intersect_domain(tree->band, domain);
1118 if (!tree->band)
1119 return isl_schedule_tree_free(tree);
1120
1121 return tree;
1122error:
1123 isl_schedule_tree_free(tree);
1124 isl_union_set_free(domain);
1125 return NULL((void*)0);
1126}
1127
1128/* Return the schedule of the band tree root in isolation.
1129 */
1130__isl_give isl_multi_union_pw_aff *isl_schedule_tree_band_get_partial_schedule(
1131 __isl_keep isl_schedule_tree *tree)
1132{
1133 if (!tree)
1134 return NULL((void*)0);
1135
1136 if (tree->type != isl_schedule_node_band)
1137 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1138); return ((void*)0); } while (0)
1138 "not a band node", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1138); return ((void*)0); } while (0)
;
1139
1140 return isl_schedule_band_get_partial_schedule(tree->band);
1141}
1142
1143/* Replace the schedule of the band tree root by "schedule".
1144 */
1145__isl_give isl_schedule_tree *isl_schedule_tree_band_set_partial_schedule(
1146 __isl_take isl_schedule_tree *tree,
1147 __isl_take isl_multi_union_pw_aff *schedule)
1148{
1149 tree = isl_schedule_tree_cow(tree);
1150 if (!tree || !schedule)
1151 goto error;
1152
1153 if (tree->type != isl_schedule_node_band)
1154 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1155); return ((void*)0); } while (0)
1155 "not a band node", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1155); return ((void*)0); } while (0)
;
1156 tree->band = isl_schedule_band_set_partial_schedule(tree->band,
1157 schedule);
1158
1159 return tree;
1160error:
1161 isl_schedule_tree_free(tree);
1162 isl_multi_union_pw_aff_free(schedule);
1163 return NULL((void*)0);
1164}
1165
1166/* Return the loop AST generation type for the band member
1167 * of the band tree root at position "pos".
1168 */
1169enum isl_ast_loop_type isl_schedule_tree_band_member_get_ast_loop_type(
1170 __isl_keep isl_schedule_tree *tree, int pos)
1171{
1172 if (!tree)
1173 return isl_ast_loop_error;
1174
1175 if (tree->type != isl_schedule_node_band)
1176 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1177); return isl_ast_loop_error; } while (0)
1177 "not a band node", return isl_ast_loop_error)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1177); return isl_ast_loop_error; } while (0)
;
1178
1179 return isl_schedule_band_member_get_ast_loop_type(tree->band, pos);
1180}
1181
1182/* Set the loop AST generation type for the band member of the band tree root
1183 * at position "pos" to "type".
1184 */
1185__isl_give isl_schedule_tree *isl_schedule_tree_band_member_set_ast_loop_type(
1186 __isl_take isl_schedule_tree *tree, int pos,
1187 enum isl_ast_loop_type type)
1188{
1189 tree = isl_schedule_tree_cow(tree);
1190 if (!tree)
1191 return NULL((void*)0);
1192
1193 if (tree->type != isl_schedule_node_band)
1194 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1195); return isl_schedule_tree_free(tree); } while (0)
1195 "not a band node", return isl_schedule_tree_free(tree))do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1195); return isl_schedule_tree_free(tree); } while (0)
;
1196
1197 tree->band = isl_schedule_band_member_set_ast_loop_type(tree->band,
1198 pos, type);
1199 if (!tree->band)
1200 return isl_schedule_tree_free(tree);
1201
1202 return tree;
1203}
1204
1205/* Return the loop AST generation type for the band member
1206 * of the band tree root at position "pos" for the isolated part.
1207 */
1208enum isl_ast_loop_type isl_schedule_tree_band_member_get_isolate_ast_loop_type(
1209 __isl_keep isl_schedule_tree *tree, int pos)
1210{
1211 if (!tree)
1212 return isl_ast_loop_error;
1213
1214 if (tree->type != isl_schedule_node_band)
1215 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1216); return isl_ast_loop_error; } while (0)
1216 "not a band node", return isl_ast_loop_error)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1216); return isl_ast_loop_error; } while (0)
;
1217
1218 return isl_schedule_band_member_get_isolate_ast_loop_type(tree->band,
1219 pos);
1220}
1221
1222/* Set the loop AST generation type for the band member of the band tree root
1223 * at position "pos" for the isolated part to "type".
1224 */
1225__isl_give isl_schedule_tree *
1226isl_schedule_tree_band_member_set_isolate_ast_loop_type(
1227 __isl_take isl_schedule_tree *tree, int pos,
1228 enum isl_ast_loop_type type)
1229{
1230 tree = isl_schedule_tree_cow(tree);
1231 if (!tree)
1232 return NULL((void*)0);
1233
1234 if (tree->type != isl_schedule_node_band)
1235 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1236); return isl_schedule_tree_free(tree); } while (0)
1236 "not a band node", return isl_schedule_tree_free(tree))do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1236); return isl_schedule_tree_free(tree); } while (0)
;
1237
1238 tree->band = isl_schedule_band_member_set_isolate_ast_loop_type(
1239 tree->band, pos, type);
1240 if (!tree->band)
1241 return isl_schedule_tree_free(tree);
1242
1243 return tree;
1244}
1245
1246/* Return the AST build options associated to the band tree root.
1247 */
1248__isl_give isl_union_set *isl_schedule_tree_band_get_ast_build_options(
1249 __isl_keep isl_schedule_tree *tree)
1250{
1251 if (!tree)
1252 return NULL((void*)0);
1253
1254 if (tree->type != isl_schedule_node_band)
1255 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1256); return ((void*)0); } while (0)
1256 "not a band node", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1256); return ((void*)0); } while (0)
;
1257
1258 return isl_schedule_band_get_ast_build_options(tree->band);
1259}
1260
1261/* Replace the AST build options associated to band tree root by "options".
1262 * Updated the anchored field if the anchoredness of the root node itself
1263 * changes.
1264 */
1265__isl_give isl_schedule_tree *isl_schedule_tree_band_set_ast_build_options(
1266 __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *options)
1267{
1268 int was_anchored;
1269
1270 tree = isl_schedule_tree_cow(tree);
1271 if (!tree || !options)
1272 goto error;
1273
1274 if (tree->type != isl_schedule_node_band)
1275 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1276); goto error; } while (0)
1276 "not a band node", goto error)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1276); goto error; } while (0)
;
1277
1278 was_anchored = isl_schedule_tree_is_anchored(tree);
1279 tree->band = isl_schedule_band_set_ast_build_options(tree->band,
1280 options);
1281 if (!tree->band)
1282 return isl_schedule_tree_free(tree);
1283 if (isl_schedule_tree_is_anchored(tree) != was_anchored)
1284 tree = isl_schedule_tree_update_anchored(tree);
1285
1286 return tree;
1287error:
1288 isl_schedule_tree_free(tree);
1289 isl_union_set_free(options);
1290 return NULL((void*)0);
1291}
1292
1293/* Return the "isolate" option associated to the band tree root of "tree",
1294 * which is assumed to appear at schedule depth "depth".
1295 */
1296__isl_give isl_set *isl_schedule_tree_band_get_ast_isolate_option(
1297 __isl_keep isl_schedule_tree *tree, int depth)
1298{
1299 if (!tree)
1300 return NULL((void*)0);
1301
1302 if (tree->type != isl_schedule_node_band)
1303 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1304); return ((void*)0); } while (0)
1304 "not a band node", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1304); return ((void*)0); } while (0)
;
1305
1306 return isl_schedule_band_get_ast_isolate_option(tree->band, depth);
1307}
1308
1309/* Return the context of the context tree root.
1310 */
1311__isl_give isl_set *isl_schedule_tree_context_get_context(
1312 __isl_keep isl_schedule_tree *tree)
1313{
1314 if (!tree)
1315 return NULL((void*)0);
1316
1317 if (tree->type != isl_schedule_node_context)
1318 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a context node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1319); return ((void*)0); } while (0)
1319 "not a context node", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a context node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1319); return ((void*)0); } while (0)
;
1320
1321 return isl_set_copy(tree->context);
1322}
1323
1324/* Return the domain of the domain tree root.
1325 */
1326__isl_give isl_union_set *isl_schedule_tree_domain_get_domain(
1327 __isl_keep isl_schedule_tree *tree)
1328{
1329 if (!tree)
1330 return NULL((void*)0);
1331
1332 if (tree->type != isl_schedule_node_domain)
1333 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a domain node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1334); return ((void*)0); } while (0)
1334 "not a domain node", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a domain node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1334); return ((void*)0); } while (0)
;
1335
1336 return isl_union_set_copy(tree->domain);
1337}
1338
1339/* Replace the domain of domain tree root "tree" by "domain".
1340 */
1341__isl_give isl_schedule_tree *isl_schedule_tree_domain_set_domain(
1342 __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *domain)
1343{
1344 tree = isl_schedule_tree_cow(tree);
1345 if (!tree || !domain)
1346 goto error;
1347
1348 if (tree->type != isl_schedule_node_domain)
1349 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a domain node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1350); goto error; } while (0)
1350 "not a domain node", goto error)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a domain node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1350); goto error; } while (0)
;
1351
1352 isl_union_set_free(tree->domain);
1353 tree->domain = domain;
1354
1355 return tree;
1356error:
1357 isl_schedule_tree_free(tree);
1358 isl_union_set_free(domain);
1359 return NULL((void*)0);
1360}
1361
1362/* Return the contraction of the expansion tree root.
1363 */
1364__isl_give isl_union_pw_multi_aff *isl_schedule_tree_expansion_get_contraction(
1365 __isl_keep isl_schedule_tree *tree)
1366{
1367 if (!tree)
1368 return NULL((void*)0);
1369
1370 if (tree->type != isl_schedule_node_expansion)
1371 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not an expansion node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1372); return ((void*)0); } while (0)
1372 "not an expansion node", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not an expansion node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1372); return ((void*)0); } while (0)
;
1373
1374 return isl_union_pw_multi_aff_copy(tree->contraction);
1375}
1376
1377/* Return the expansion of the expansion tree root.
1378 */
1379__isl_give isl_union_map *isl_schedule_tree_expansion_get_expansion(
1380 __isl_keep isl_schedule_tree *tree)
1381{
1382 if (!tree)
1383 return NULL((void*)0);
1384
1385 if (tree->type != isl_schedule_node_expansion)
1386 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not an expansion node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1387); return ((void*)0); } while (0)
1387 "not an expansion node", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not an expansion node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1387); return ((void*)0); } while (0)
;
1388
1389 return isl_union_map_copy(tree->expansion);
1390}
1391
1392/* Replace the contraction and the expansion of the expansion tree root "tree"
1393 * by "contraction" and "expansion".
1394 */
1395__isl_give isl_schedule_tree *
1396isl_schedule_tree_expansion_set_contraction_and_expansion(
1397 __isl_take isl_schedule_tree *tree,
1398 __isl_take isl_union_pw_multi_aff *contraction,
1399 __isl_take isl_union_map *expansion)
1400{
1401 tree = isl_schedule_tree_cow(tree);
1402 if (!tree || !contraction || !expansion)
1403 goto error;
1404
1405 if (tree->type != isl_schedule_node_expansion)
1406 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not an expansion node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1407); return ((void*)0); } while (0)
1407 "not an expansion node", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not an expansion node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1407); return ((void*)0); } while (0)
;
1408
1409 isl_union_pw_multi_aff_free(tree->contraction);
1410 tree->contraction = contraction;
1411 isl_union_map_free(tree->expansion);
1412 tree->expansion = expansion;
1413
1414 return tree;
1415error:
1416 isl_schedule_tree_free(tree);
1417 isl_union_pw_multi_aff_free(contraction);
1418 isl_union_map_free(expansion);
1419 return NULL((void*)0);
1420}
1421
1422/* Return the extension of the extension tree root.
1423 */
1424__isl_give isl_union_map *isl_schedule_tree_extension_get_extension(
1425 __isl_take isl_schedule_tree *tree)
1426{
1427 if (!tree)
1428 return NULL((void*)0);
1429
1430 if (tree->type != isl_schedule_node_extension)
1431 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not an extension node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1432); return ((void*)0); } while (0)
1432 "not an extension node", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not an extension node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1432); return ((void*)0); } while (0)
;
1433
1434 return isl_union_map_copy(tree->extension);
1435}
1436
1437/* Replace the extension of extension tree root "tree" by "extension".
1438 */
1439__isl_give isl_schedule_tree *isl_schedule_tree_extension_set_extension(
1440 __isl_take isl_schedule_tree *tree, __isl_take isl_union_map *extension)
1441{
1442 tree = isl_schedule_tree_cow(tree);
1443 if (!tree || !extension)
1444 goto error;
1445
1446 if (tree->type != isl_schedule_node_extension)
1447 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not an extension node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1448); return ((void*)0); } while (0)
1448 "not an extension node", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not an extension node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1448); return ((void*)0); } while (0)
;
1449 isl_union_map_free(tree->extension);
1450 tree->extension = extension;
1451
1452 return tree;
1453error:
1454 isl_schedule_tree_free(tree);
1455 isl_union_map_free(extension);
1456 return NULL((void*)0);
1457}
1458
1459/* Return the filter of the filter tree root.
1460 */
1461__isl_give isl_union_set *isl_schedule_tree_filter_get_filter(
1462 __isl_keep isl_schedule_tree *tree)
1463{
1464 if (!tree)
1465 return NULL((void*)0);
1466
1467 if (tree->type != isl_schedule_node_filter)
1468 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a filter node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1469); return ((void*)0); } while (0)
1469 "not a filter node", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a filter node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1469); return ((void*)0); } while (0)
;
1470
1471 return isl_union_set_copy(tree->filter);
1472}
1473
1474/* Replace the filter of the filter tree root by "filter".
1475 */
1476__isl_give isl_schedule_tree *isl_schedule_tree_filter_set_filter(
1477 __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *filter)
1478{
1479 tree = isl_schedule_tree_cow(tree);
1480 if (!tree || !filter)
1481 goto error;
1482
1483 if (tree->type != isl_schedule_node_filter)
1484 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a filter node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1485); return ((void*)0); } while (0)
1485 "not a filter node", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a filter node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1485); return ((void*)0); } while (0)
;
1486
1487 isl_union_set_free(tree->filter);
1488 tree->filter = filter;
1489
1490 return tree;
1491error:
1492 isl_schedule_tree_free(tree);
1493 isl_union_set_free(filter);
1494 return NULL((void*)0);
1495}
1496
1497/* Return the guard of the guard tree root.
1498 */
1499__isl_give isl_set *isl_schedule_tree_guard_get_guard(
1500 __isl_take isl_schedule_tree *tree)
1501{
1502 if (!tree)
1503 return NULL((void*)0);
1504
1505 if (tree->type != isl_schedule_node_guard)
1506 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a guard node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1507); return ((void*)0); } while (0)
1507 "not a guard node", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a guard node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1507); return ((void*)0); } while (0)
;
1508
1509 return isl_set_copy(tree->guard);
1510}
1511
1512/* Return the mark identifier of the mark tree root "tree".
1513 */
1514__isl_give isl_id *isl_schedule_tree_mark_get_id(
1515 __isl_keep isl_schedule_tree *tree)
1516{
1517 if (!tree)
1518 return NULL((void*)0);
1519
1520 if (tree->type != isl_schedule_node_mark)
1521 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a mark node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1522); return ((void*)0); } while (0)
1522 "not a mark node", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a mark node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1522); return ((void*)0); } while (0)
;
1523
1524 return isl_id_copy(tree->mark);
1525}
1526
1527/* Set dim to the range dimension of "map" and abort the search.
1528 */
1529static isl_stat set_range_dim(__isl_take isl_map *map, void *user)
1530{
1531 int *dim = user;
1532
1533 *dim = isl_map_dim(map, isl_dim_out);
1534 isl_map_free(map);
1535
1536 return isl_stat_error;
1537}
1538
1539/* Return the dimension of the range of "umap".
1540 * "umap" is assumed not to be empty and
1541 * all maps inside "umap" are assumed to have the same range.
1542 *
1543 * We extract the range dimension from the first map in "umap".
1544 */
1545static int range_dim(__isl_keep isl_union_map *umap)
1546{
1547 int dim = -1;
1548
1549 if (!umap)
1550 return -1;
1551 if (isl_union_map_n_map(umap) == 0)
1552 isl_die(isl_union_map_get_ctx(umap), isl_error_internal,do { isl_handle_error(isl_union_map_get_ctx(umap), isl_error_internal
, "unexpected empty input", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1553); return -1; } while (0)
1553 "unexpected empty input", return -1)do { isl_handle_error(isl_union_map_get_ctx(umap), isl_error_internal
, "unexpected empty input", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1553); return -1; } while (0)
;
1554
1555 isl_union_map_foreach_map(umap, &set_range_dim, &dim);
1556
1557 return dim;
1558}
1559
1560/* Append an "extra" number of zeros to the range of "umap" and
1561 * return the result.
1562 */
1563static __isl_give isl_union_map *append_range(__isl_take isl_union_map *umap,
1564 int extra)
1565{
1566 isl_union_set *dom;
1567 isl_space *space;
1568 isl_multi_val *mv;
1569 isl_union_pw_multi_aff *suffix;
1570 isl_union_map *universe;
1571 isl_union_map *suffix_umap;
1572
1573 universe = isl_union_map_universe(isl_union_map_copy(umap));
1574 dom = isl_union_map_domain(universe);
1575 space = isl_union_set_get_space(dom);
1576 space = isl_space_set_from_params(space);
1577 space = isl_space_add_dims(space, isl_dim_set, extra);
1578 mv = isl_multi_val_zero(space);
1579
1580 suffix = isl_union_pw_multi_aff_multi_val_on_domain(dom, mv);
1581 suffix_umap = isl_union_map_from_union_pw_multi_aff(suffix);
1582 umap = isl_union_map_flat_range_product(umap, suffix_umap);
1583
1584 return umap;
1585}
1586
1587/* Should we skip the root of "tree" while looking for the first
1588 * descendant with schedule information?
1589 * That is, is it impossible to derive any information about
1590 * the iteration domain from this node?
1591 *
1592 * We do not want to skip leaf or error nodes because there is
1593 * no point in looking any deeper from these nodes.
1594 * We can only extract partial iteration domain information
1595 * from an extension node, but extension nodes are not supported
1596 * by the caller and it will error out on them.
1597 */
1598static int domain_less(__isl_keep isl_schedule_tree *tree)
1599{
1600 enum isl_schedule_node_type type;
1601
1602 type = isl_schedule_tree_get_type(tree);
1603 switch (type) {
1604 case isl_schedule_node_band:
1605 return isl_schedule_tree_band_n_member(tree) == 0;
1606 case isl_schedule_node_context:
1607 case isl_schedule_node_guard:
1608 case isl_schedule_node_mark:
1609 return 1;
1610 case isl_schedule_node_leaf:
1611 case isl_schedule_node_error:
1612 case isl_schedule_node_domain:
1613 case isl_schedule_node_expansion:
1614 case isl_schedule_node_extension:
1615 case isl_schedule_node_filter:
1616 case isl_schedule_node_set:
1617 case isl_schedule_node_sequence:
1618 return 0;
1619 }
1620
1621 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "unhandled case", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1622); return 0; } while (0)
1622 "unhandled case", return 0)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "unhandled case", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1622); return 0; } while (0)
;
1623}
1624
1625/* Move down to the first descendant of "tree" that contains any schedule
1626 * information or return "leaf" if there is no such descendant.
1627 */
1628__isl_give isl_schedule_tree *isl_schedule_tree_first_schedule_descendant(
1629 __isl_take isl_schedule_tree *tree, __isl_keep isl_schedule_tree *leaf)
1630{
1631 while (domain_less(tree)) {
1632 if (!isl_schedule_tree_has_children(tree)) {
1633 isl_schedule_tree_free(tree);
1634 return isl_schedule_tree_copy(leaf);
1635 }
1636 tree = isl_schedule_tree_child(tree, 0);
1637 }
1638
1639 return tree;
1640}
1641
1642static __isl_give isl_union_map *subtree_schedule_extend(
1643 __isl_keep isl_schedule_tree *tree, __isl_take isl_union_map *outer);
1644
1645/* Extend the schedule map "outer" with the subtree schedule
1646 * of the (single) child of "tree", if any.
1647 *
1648 * If "tree" does not have any descendants (apart from those that
1649 * do not carry any schedule information), then we simply return "outer".
1650 * Otherwise, we extend the schedule map "outer" with the subtree schedule
1651 * of the single child.
1652 */
1653static __isl_give isl_union_map *subtree_schedule_extend_child(
1654 __isl_keep isl_schedule_tree *tree, __isl_take isl_union_map *outer)
1655{
1656 isl_schedule_tree *child;
1657 isl_union_map *res;
1658
1659 if (!tree)
1660 return isl_union_map_free(outer);
1661 if (!isl_schedule_tree_has_children(tree))
1662 return outer;
1663 child = isl_schedule_tree_get_child(tree, 0);
1664 if (!child)
1665 return isl_union_map_free(outer);
1666 res = subtree_schedule_extend(child, outer);
1667 isl_schedule_tree_free(child);
1668 return res;
1669}
1670
1671/* Extract the parameter space from one of the children of "tree",
1672 * which are assumed to be filters.
1673 */
1674static __isl_give isl_space *extract_space_from_filter_child(
1675 __isl_keep isl_schedule_tree *tree)
1676{
1677 isl_space *space;
1678 isl_union_set *dom;
1679 isl_schedule_tree *child;
1680
1681 child = isl_schedule_tree_list_get_schedule_tree(tree->children, 0);
1682 dom = isl_schedule_tree_filter_get_filter(child);
1683 space = isl_union_set_get_space(dom);
1684 isl_union_set_free(dom);
1685 isl_schedule_tree_free(child);
1686
1687 return space;
1688}
1689
1690/* Extend the schedule map "outer" with the subtree schedule
1691 * of a set or sequence node.
1692 *
1693 * The schedule for the set or sequence node itself is composed of
1694 * pieces of the form
1695 *
1696 * filter -> []
1697 *
1698 * or
1699 *
1700 * filter -> [index]
1701 *
1702 * The first form is used if there is only a single child or
1703 * if the current node is a set node and the schedule_separate_components
1704 * option is not set.
1705 *
1706 * Each of the pieces above is extended with the subtree schedule of
1707 * the child of the corresponding filter, if any, padded with zeros
1708 * to ensure that all pieces have the same range dimension.
1709 */
1710static __isl_give isl_union_map *subtree_schedule_extend_from_children(
1711 __isl_keep isl_schedule_tree *tree, __isl_take isl_union_map *outer)
1712{
1713 int i, n;
1714 int dim;
1715 int separate;
1716 isl_ctx *ctx;
1717 isl_val *v = NULL((void*)0);
1718 isl_multi_val *mv;
1719 isl_space *space;
1720 isl_union_map *umap;
1721
1722 if (!tree)
1723 return NULL((void*)0);
1724
1725 ctx = isl_schedule_tree_get_ctx(tree);
1726 if (!tree->children)
1727 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "missing children", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1728); return ((void*)0); } while (0)
1728 "missing children", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "missing children", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1728); return ((void*)0); } while (0)
;
1729 n = isl_schedule_tree_list_n_schedule_tree(tree->children);
1730 if (n == 0)
1731 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "missing children", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1732); return ((void*)0); } while (0)
1732 "missing children", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "missing children", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1732); return ((void*)0); } while (0)
;
1733
1734 separate = n > 1 && (tree->type == isl_schedule_node_sequence ||
1735 isl_options_get_schedule_separate_components(ctx));
1736
1737 space = isl_space_params_alloc(ctx, 0);
1738
1739 umap = isl_union_map_empty(isl_space_copy(space));
1740 space = isl_space_set_from_params(space);
1741 if (separate) {
1742 space = isl_space_add_dims(space, isl_dim_set, 1);
1743 v = isl_val_zero(ctx);
1744 }
1745 mv = isl_multi_val_zero(space);
1746
1747 dim = isl_multi_val_dim(mv, isl_dim_set);
1748 for (i = 0; i < n; ++i) {
1749 isl_multi_val *mv_copy;
1750 isl_union_pw_multi_aff *upma;
1751 isl_union_map *umap_i;
1752 isl_union_set *dom;
1753 isl_schedule_tree *child;
1754 int dim_i;
1755 int empty;
1756
1757 child = isl_schedule_tree_list_get_schedule_tree(
1758 tree->children, i);
1759 dom = isl_schedule_tree_filter_get_filter(child);
1760
1761 if (separate) {
1762 mv = isl_multi_val_set_val(mv, 0, isl_val_copy(v));
1763 v = isl_val_add_ui(v, 1);
1764 }
1765 mv_copy = isl_multi_val_copy(mv);
1766 space = isl_union_set_get_space(dom);
1767 mv_copy = isl_multi_val_align_params(mv_copy, space);
1768 upma = isl_union_pw_multi_aff_multi_val_on_domain(dom, mv_copy);
1769 umap_i = isl_union_map_from_union_pw_multi_aff(upma);
1770 umap_i = isl_union_map_flat_range_product(
1771 isl_union_map_copy(outer), umap_i);
1772 umap_i = subtree_schedule_extend_child(child, umap_i);
1773 isl_schedule_tree_free(child);
1774
1775 empty = isl_union_map_is_empty(umap_i);
1776 if (empty < 0)
1777 umap_i = isl_union_map_free(umap_i);
1778 else if (empty) {
1779 isl_union_map_free(umap_i);
1780 continue;
1781 }
1782
1783 dim_i = range_dim(umap_i);
1784 if (dim_i < 0) {
1785 umap = isl_union_map_free(umap);
1786 } else if (dim < dim_i) {
1787 umap = append_range(umap, dim_i - dim);
1788 dim = dim_i;
1789 } else if (dim_i < dim) {
1790 umap_i = append_range(umap_i, dim - dim_i);
1791 }
1792 umap = isl_union_map_union(umap, umap_i);
1793 }
1794
1795 isl_val_free(v);
1796 isl_multi_val_free(mv);
1797 isl_union_map_free(outer);
1798
1799 return umap;
1800}
1801
1802/* Extend the schedule map "outer" with the subtree schedule of "tree".
1803 *
1804 * If the root of the tree is a set or a sequence, then we extend
1805 * the schedule map in subtree_schedule_extend_from_children.
1806 * Otherwise, we extend the schedule map with the partial schedule
1807 * corresponding to the root of the tree and then continue with
1808 * the single child of this root.
1809 * In the special case of an expansion, the schedule map is "extended"
1810 * by applying the expansion to the domain of the schedule map.
1811 */
1812static __isl_give isl_union_map *subtree_schedule_extend(
1813 __isl_keep isl_schedule_tree *tree, __isl_take isl_union_map *outer)
1814{
1815 isl_multi_union_pw_aff *mupa;
1816 isl_union_map *umap;
1817 isl_union_set *domain;
1818
1819 if (!tree)
1820 return NULL((void*)0);
1821
1822 switch (tree->type) {
1823 case isl_schedule_node_error:
1824 return isl_union_map_free(outer);
1825 case isl_schedule_node_extension:
1826 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "cannot construct subtree schedule of tree " "with extension nodes"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1829); return isl_union_map_free(outer); } while (0)
1827 "cannot construct subtree schedule of tree "do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "cannot construct subtree schedule of tree " "with extension nodes"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1829); return isl_union_map_free(outer); } while (0)
1828 "with extension nodes",do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "cannot construct subtree schedule of tree " "with extension nodes"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1829); return isl_union_map_free(outer); } while (0)
1829 return isl_union_map_free(outer))do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "cannot construct subtree schedule of tree " "with extension nodes"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1829); return isl_union_map_free(outer); } while (0)
;
1830 case isl_schedule_node_context:
1831 case isl_schedule_node_guard:
1832 case isl_schedule_node_mark:
1833 return subtree_schedule_extend_child(tree, outer);
1834 case isl_schedule_node_band:
1835 if (isl_schedule_tree_band_n_member(tree) == 0)
1836 return subtree_schedule_extend_child(tree, outer);
1837 mupa = isl_schedule_band_get_partial_schedule(tree->band);
1838 umap = isl_union_map_from_multi_union_pw_aff(mupa);
1839 outer = isl_union_map_flat_range_product(outer, umap);
1840 umap = subtree_schedule_extend_child(tree, outer);
1841 break;
1842 case isl_schedule_node_domain:
1843 domain = isl_schedule_tree_domain_get_domain(tree);
1844 umap = isl_union_map_from_domain(domain);
1845 outer = isl_union_map_flat_range_product(outer, umap);
1846 umap = subtree_schedule_extend_child(tree, outer);
1847 break;
1848 case isl_schedule_node_expansion:
1849 umap = isl_schedule_tree_expansion_get_expansion(tree);
1850 outer = isl_union_map_apply_domain(outer, umap);
1851 umap = subtree_schedule_extend_child(tree, outer);
1852 break;
1853 case isl_schedule_node_filter:
1854 domain = isl_schedule_tree_filter_get_filter(tree);
1855 umap = isl_union_map_from_domain(domain);
1856 outer = isl_union_map_flat_range_product(outer, umap);
1857 umap = subtree_schedule_extend_child(tree, outer);
1858 break;
1859 case isl_schedule_node_leaf:
1860 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "leaf node should be handled by caller", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1861); return ((void*)0); } while (0)
1861 "leaf node should be handled by caller", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "leaf node should be handled by caller", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1861); return ((void*)0); } while (0)
;
1862 case isl_schedule_node_set:
1863 case isl_schedule_node_sequence:
1864 umap = subtree_schedule_extend_from_children(tree, outer);
1865 break;
1866 }
1867
1868 return umap;
1869}
1870
1871static __isl_give isl_union_set *initial_domain(
1872 __isl_keep isl_schedule_tree *tree);
1873
1874/* Extract a universe domain from the children of the tree root "tree",
1875 * which is a set or sequence, meaning that its children are filters.
1876 * In particular, return the union of the universes of the filters.
1877 */
1878static __isl_give isl_union_set *initial_domain_from_children(
1879 __isl_keep isl_schedule_tree *tree)
1880{
1881 int i, n;
1882 isl_space *space;
1883 isl_union_set *domain;
1884
1885 if (!tree->children)
1886 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "missing children", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1887); return ((void*)0); } while (0)
1887 "missing children", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "missing children", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1887); return ((void*)0); } while (0)
;
1888 n = isl_schedule_tree_list_n_schedule_tree(tree->children);
1889 if (n == 0)
1890 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "missing children", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1891); return ((void*)0); } while (0)
1891 "missing children", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "missing children", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1891); return ((void*)0); } while (0)
;
1892
1893 space = extract_space_from_filter_child(tree);
1894 domain = isl_union_set_empty(space);
1895
1896 for (i = 0; i < n; ++i) {
1897 isl_schedule_tree *child;
1898 isl_union_set *domain_i;
1899
1900 child = isl_schedule_tree_get_child(tree, i);
1901 domain_i = initial_domain(child);
1902 domain = isl_union_set_union(domain, domain_i);
1903 isl_schedule_tree_free(child);
1904 }
1905
1906 return domain;
1907}
1908
1909/* Extract a universe domain from the tree root "tree".
1910 * The caller is responsible for making sure that this node
1911 * would not be skipped by isl_schedule_tree_first_schedule_descendant
1912 * and that it is not a leaf node.
1913 */
1914static __isl_give isl_union_set *initial_domain(
1915 __isl_keep isl_schedule_tree *tree)
1916{
1917 isl_multi_union_pw_aff *mupa;
1918 isl_union_set *domain;
1919 isl_union_map *exp;
1920
1921 if (!tree)
1922 return NULL((void*)0);
1923
1924 switch (tree->type) {
1925 case isl_schedule_node_error:
1926 return NULL((void*)0);
1927 case isl_schedule_node_context:
1928 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "context node should be handled by caller", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1930); return ((void*)0); } while (0)
1929 "context node should be handled by caller",do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "context node should be handled by caller", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1930); return ((void*)0); } while (0)
1930 return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "context node should be handled by caller", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1930); return ((void*)0); } while (0)
;
1931 case isl_schedule_node_guard:
1932 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "guard node should be handled by caller", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1934); return ((void*)0); } while (0)
1933 "guard node should be handled by caller",do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "guard node should be handled by caller", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1934); return ((void*)0); } while (0)
1934 return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "guard node should be handled by caller", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1934); return ((void*)0); } while (0)
;
1935 case isl_schedule_node_mark:
1936 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "mark node should be handled by caller", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1938); return ((void*)0); } while (0)
1937 "mark node should be handled by caller",do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "mark node should be handled by caller", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1938); return ((void*)0); } while (0)
1938 return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "mark node should be handled by caller", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1938); return ((void*)0); } while (0)
;
1939 case isl_schedule_node_extension:
1940 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "cannot construct subtree schedule of tree " "with extension nodes"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1942); return ((void*)0); } while (0)
1941 "cannot construct subtree schedule of tree "do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "cannot construct subtree schedule of tree " "with extension nodes"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1942); return ((void*)0); } while (0)
1942 "with extension nodes", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "cannot construct subtree schedule of tree " "with extension nodes"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1942); return ((void*)0); } while (0)
;
1943 case isl_schedule_node_band:
1944 if (isl_schedule_tree_band_n_member(tree) == 0)
1945 isl_die(isl_schedule_tree_get_ctx(tree),do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "0D band should be handled by caller", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1948); return ((void*)0); } while (0)
1946 isl_error_internal,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "0D band should be handled by caller", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1948); return ((void*)0); } while (0)
1947 "0D band should be handled by caller",do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "0D band should be handled by caller", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1948); return ((void*)0); } while (0)
1948 return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "0D band should be handled by caller", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1948); return ((void*)0); } while (0)
;
1949 mupa = isl_schedule_band_get_partial_schedule(tree->band);
1950 domain = isl_multi_union_pw_aff_domain(mupa);
1951 domain = isl_union_set_universe(domain);
1952 break;
1953 case isl_schedule_node_domain:
1954 domain = isl_schedule_tree_domain_get_domain(tree);
1955 domain = isl_union_set_universe(domain);
1956 break;
1957 case isl_schedule_node_expansion:
1958 exp = isl_schedule_tree_expansion_get_expansion(tree);
1959 exp = isl_union_map_universe(exp);
1960 domain = isl_union_map_domain(exp);
1961 break;
1962 case isl_schedule_node_filter:
1963 domain = isl_schedule_tree_filter_get_filter(tree);
1964 domain = isl_union_set_universe(domain);
1965 break;
1966 case isl_schedule_node_leaf:
1967 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "leaf node should be handled by caller", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1968); return ((void*)0); } while (0)
1968 "leaf node should be handled by caller", return NULL)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "leaf node should be handled by caller", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 1968); return ((void*)0); } while (0)
;
1969 case isl_schedule_node_set:
1970 case isl_schedule_node_sequence:
1971 domain = initial_domain_from_children(tree);
1972 break;
1973 }
1974
1975 return domain;
1976}
1977
1978/* Return the subtree schedule of a node that contains some schedule
1979 * information, i.e., a node that would not be skipped by
1980 * isl_schedule_tree_first_schedule_descendant and that is not a leaf.
1981 *
1982 * If the tree contains any expansions, then the returned subtree
1983 * schedule is formulated in terms of the expanded domains.
1984 * The tree is not allowed to contain any extension nodes.
1985 *
1986 * We start with an initial zero-dimensional subtree schedule based
1987 * on the domain information in the root node and then extend it
1988 * based on the schedule information in the root node and its descendants.
1989 */
1990__isl_give isl_union_map *isl_schedule_tree_get_subtree_schedule_union_map(
1991 __isl_keep isl_schedule_tree *tree)
1992{
1993 isl_union_set *domain;
1994 isl_union_map *umap;
1995
1996 domain = initial_domain(tree);
1997 umap = isl_union_map_from_domain(domain);
1998 return subtree_schedule_extend(tree, umap);
1999}
2000
2001/* Multiply the partial schedule of the band root node of "tree"
2002 * with the factors in "mv".
2003 */
2004__isl_give isl_schedule_tree *isl_schedule_tree_band_scale(
2005 __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv)
2006{
2007 if (!tree || !mv)
2008 goto error;
2009 if (tree->type != isl_schedule_node_band)
2010 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2011); goto error; } while (0)
2011 "not a band node", goto error)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2011); goto error; } while (0)
;
2012
2013 tree = isl_schedule_tree_cow(tree);
2014 if (!tree)
2015 goto error;
2016
2017 tree->band = isl_schedule_band_scale(tree->band, mv);
2018 if (!tree->band)
2019 return isl_schedule_tree_free(tree);
2020
2021 return tree;
2022error:
2023 isl_schedule_tree_free(tree);
2024 isl_multi_val_free(mv);
2025 return NULL((void*)0);
2026}
2027
2028/* Divide the partial schedule of the band root node of "tree"
2029 * by the factors in "mv".
2030 */
2031__isl_give isl_schedule_tree *isl_schedule_tree_band_scale_down(
2032 __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv)
2033{
2034 if (!tree || !mv)
2035 goto error;
2036 if (tree->type != isl_schedule_node_band)
2037 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2038); goto error; } while (0)
2038 "not a band node", goto error)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2038); goto error; } while (0)
;
2039
2040 tree = isl_schedule_tree_cow(tree);
2041 if (!tree)
2042 goto error;
2043
2044 tree->band = isl_schedule_band_scale_down(tree->band, mv);
2045 if (!tree->band)
2046 return isl_schedule_tree_free(tree);
2047
2048 return tree;
2049error:
2050 isl_schedule_tree_free(tree);
2051 isl_multi_val_free(mv);
2052 return NULL((void*)0);
2053}
2054
2055/* Reduce the partial schedule of the band root node of "tree"
2056 * modulo the factors in "mv".
2057 */
2058__isl_give isl_schedule_tree *isl_schedule_tree_band_mod(
2059 __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *mv)
2060{
2061 if (!tree || !mv)
2062 goto error;
2063 if (tree->type != isl_schedule_node_band)
2064 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2065); goto error; } while (0)
2065 "not a band node", goto error)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2065); goto error; } while (0)
;
2066
2067 tree = isl_schedule_tree_cow(tree);
2068 if (!tree)
2069 goto error;
2070
2071 tree->band = isl_schedule_band_mod(tree->band, mv);
2072 if (!tree->band)
2073 return isl_schedule_tree_free(tree);
2074
2075 return tree;
2076error:
2077 isl_schedule_tree_free(tree);
2078 isl_multi_val_free(mv);
2079 return NULL((void*)0);
2080}
2081
2082/* Shift the partial schedule of the band root node of "tree" by "shift".
2083 */
2084__isl_give isl_schedule_tree *isl_schedule_tree_band_shift(
2085 __isl_take isl_schedule_tree *tree,
2086 __isl_take isl_multi_union_pw_aff *shift)
2087{
2088 if (!tree || !shift)
2089 goto error;
2090 if (tree->type != isl_schedule_node_band)
2091 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2092); goto error; } while (0)
2092 "not a band node", goto error)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2092); goto error; } while (0)
;
2093
2094 tree = isl_schedule_tree_cow(tree);
2095 if (!tree)
2096 goto error;
2097
2098 tree->band = isl_schedule_band_shift(tree->band, shift);
2099 if (!tree->band)
2100 return isl_schedule_tree_free(tree);
2101
2102 return tree;
2103error:
2104 isl_schedule_tree_free(tree);
2105 isl_multi_union_pw_aff_free(shift);
2106 return NULL((void*)0);
2107}
2108
2109/* Given two trees with sequence roots, replace the child at position
2110 * "pos" of "tree" with the children of "child".
2111 */
2112__isl_give isl_schedule_tree *isl_schedule_tree_sequence_splice(
2113 __isl_take isl_schedule_tree *tree, int pos,
2114 __isl_take isl_schedule_tree *child)
2115{
2116 int n;
2117 isl_schedule_tree_list *list1, *list2;
2118
2119 tree = isl_schedule_tree_cow(tree);
2120 if (!tree || !child)
2121 goto error;
2122 if (isl_schedule_tree_get_type(tree) != isl_schedule_node_sequence)
2123 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a sequence node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2124); goto error; } while (0)
2124 "not a sequence node", goto error)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a sequence node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2124); goto error; } while (0)
;
2125 n = isl_schedule_tree_n_children(tree);
2126 if (pos < 0 || pos >= n)
2127 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "position out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2128); goto error; } while (0)
2128 "position out of bounds", goto error)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "position out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2128); goto error; } while (0)
;
2129 if (isl_schedule_tree_get_type(child) != isl_schedule_node_sequence)
2130 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a sequence node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2131); goto error; } while (0)
2131 "not a sequence node", goto error)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a sequence node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2131); goto error; } while (0)
;
2132
2133 list1 = isl_schedule_tree_list_copy(tree->children);
2134 list1 = isl_schedule_tree_list_drop(list1, pos, n - pos);
2135 list2 = isl_schedule_tree_list_copy(tree->children);
2136 list2 = isl_schedule_tree_list_drop(list2, 0, pos + 1);
2137 list1 = isl_schedule_tree_list_concat(list1,
2138 isl_schedule_tree_list_copy(child->children));
2139 list1 = isl_schedule_tree_list_concat(list1, list2);
2140
2141 isl_schedule_tree_free(tree);
2142 isl_schedule_tree_free(child);
2143 return isl_schedule_tree_from_children(isl_schedule_node_sequence,
2144 list1);
2145error:
2146 isl_schedule_tree_free(tree);
2147 isl_schedule_tree_free(child);
2148 return NULL((void*)0);
2149}
2150
2151/* Tile the band root node of "tree" with tile sizes "sizes".
2152 *
2153 * We duplicate the band node, change the schedule of one of them
2154 * to the tile schedule and the other to the point schedule and then
2155 * attach the point band as a child to the tile band.
2156 */
2157__isl_give isl_schedule_tree *isl_schedule_tree_band_tile(
2158 __isl_take isl_schedule_tree *tree, __isl_take isl_multi_val *sizes)
2159{
2160 isl_schedule_tree *child = NULL((void*)0);
2161
2162 if (!tree || !sizes)
2163 goto error;
2164 if (tree->type != isl_schedule_node_band)
2165 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2166); goto error; } while (0)
2166 "not a band node", goto error)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2166); goto error; } while (0)
;
2167
2168 child = isl_schedule_tree_copy(tree);
2169 tree = isl_schedule_tree_cow(tree);
2170 child = isl_schedule_tree_cow(child);
2171 if (!tree || !child)
2172 goto error;
2173
2174 tree->band = isl_schedule_band_tile(tree->band,
2175 isl_multi_val_copy(sizes));
2176 if (!tree->band)
2177 goto error;
2178 child->band = isl_schedule_band_point(child->band, tree->band, sizes);
2179 if (!child->band)
2180 child = isl_schedule_tree_free(child);
2181
2182 tree = isl_schedule_tree_replace_child(tree, 0, child);
2183
2184 return tree;
2185error:
2186 isl_schedule_tree_free(child);
2187 isl_schedule_tree_free(tree);
2188 isl_multi_val_free(sizes);
2189 return NULL((void*)0);
2190}
2191
2192/* Given an isolate AST generation option "isolate" for a band of size pos + n,
2193 * return the corresponding option for a band covering the first "pos"
2194 * members.
2195 *
2196 * The input isolate option is of the form
2197 *
2198 * isolate[[flattened outer bands] -> [pos; n]]
2199 *
2200 * The output isolate option is of the form
2201 *
2202 * isolate[[flattened outer bands] -> [pos]]
2203 */
2204static __isl_give isl_set *isolate_initial(__isl_keep isl_set *isolate,
2205 int pos, int n)
2206{
2207 isl_id *id;
2208 isl_map *map;
2209
2210 isolate = isl_set_copy(isolate);
2211 id = isl_set_get_tuple_id(isolate);
2212 map = isl_set_unwrap(isolate);
2213 map = isl_map_project_out(map, isl_dim_out, pos, n);
2214 isolate = isl_map_wrap(map);
2215 isolate = isl_set_set_tuple_id(isolate, id);
2216
2217 return isolate;
2218}
2219
2220/* Given an isolate AST generation option "isolate" for a band of size pos + n,
2221 * return the corresponding option for a band covering the final "n"
2222 * members within a band covering the first "pos" members.
2223 *
2224 * The input isolate option is of the form
2225 *
2226 * isolate[[flattened outer bands] -> [pos; n]]
2227 *
2228 * The output isolate option is of the form
2229 *
2230 * isolate[[flattened outer bands; pos] -> [n]]
2231 *
2232 *
2233 * The range is first split into
2234 *
2235 * isolate[[flattened outer bands] -> [[pos] -> [n]]]
2236 *
2237 * and then the first pos members are moved to the domain
2238 *
2239 * isolate[[[flattened outer bands] -> [pos]] -> [n]]
2240 *
2241 * after which the domain is flattened to obtain the desired output.
2242 */
2243static __isl_give isl_set *isolate_final(__isl_keep isl_set *isolate,
2244 int pos, int n)
2245{
2246 isl_id *id;
2247 isl_space *space;
2248 isl_multi_aff *ma1, *ma2;
2249 isl_map *map;
2250
2251 isolate = isl_set_copy(isolate);
2252 id = isl_set_get_tuple_id(isolate);
2253 map = isl_set_unwrap(isolate);
2254 space = isl_space_range(isl_map_get_space(map));
2255 ma1 = isl_multi_aff_project_out_map(isl_space_copy(space),
2256 isl_dim_set, pos, n);
2257 ma2 = isl_multi_aff_project_out_map(space, isl_dim_set, 0, pos);
2258 ma1 = isl_multi_aff_range_product(ma1, ma2);
2259 map = isl_map_apply_range(map, isl_map_from_multi_aff(ma1));
2260 map = isl_map_uncurry(map);
2261 map = isl_map_flatten_domain(map);
2262 isolate = isl_map_wrap(map);
2263 isolate = isl_set_set_tuple_id(isolate, id);
2264
2265 return isolate;
2266}
2267
2268/* Split the band root node of "tree" into two nested band nodes,
2269 * one with the first "pos" dimensions and
2270 * one with the remaining dimensions.
2271 * The tree is itself positioned at schedule depth "depth".
2272 *
2273 * The loop AST generation type options and the isolate option
2274 * are split over the two band nodes.
2275 */
2276__isl_give isl_schedule_tree *isl_schedule_tree_band_split(
2277 __isl_take isl_schedule_tree *tree, int pos, int depth)
2278{
2279 int n;
2280 isl_set *isolate, *tree_isolate, *child_isolate;
2281 isl_schedule_tree *child;
2282
2283 if (!tree)
2284 return NULL((void*)0);
2285 if (tree->type != isl_schedule_node_band)
2286 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2287); return isl_schedule_tree_free(tree); } while (0)
2287 "not a band node", return isl_schedule_tree_free(tree))do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2287); return isl_schedule_tree_free(tree); } while (0)
;
2288
2289 n = isl_schedule_tree_band_n_member(tree);
2290 if (pos < 0 || pos > n)
2291 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "position out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2293); return isl_schedule_tree_free(tree); } while (0)
2292 "position out of bounds",do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "position out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2293); return isl_schedule_tree_free(tree); } while (0)
2293 return isl_schedule_tree_free(tree))do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "position out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2293); return isl_schedule_tree_free(tree); } while (0)
;
2294
2295 child = isl_schedule_tree_copy(tree);
2296 tree = isl_schedule_tree_cow(tree);
2297 child = isl_schedule_tree_cow(child);
2298 if (!tree || !child)
2299 goto error;
2300
2301 isolate = isl_schedule_tree_band_get_ast_isolate_option(tree, depth);
2302 tree_isolate = isolate_initial(isolate, pos, n - pos);
2303 child_isolate = isolate_final(isolate, pos, n - pos);
2304 child->band = isl_schedule_band_drop(child->band, 0, pos);
2305 child->band = isl_schedule_band_replace_ast_build_option(child->band,
2306 isl_set_copy(isolate), child_isolate);
2307 tree->band = isl_schedule_band_drop(tree->band, pos, n - pos);
2308 tree->band = isl_schedule_band_replace_ast_build_option(tree->band,
2309 isl_set_copy(isolate), tree_isolate);
2310 isl_set_free(isolate);
2311 if (!child->band || !tree->band)
2312 goto error;
2313
2314 tree = isl_schedule_tree_replace_child(tree, 0, child);
2315
2316 return tree;
2317error:
2318 isl_schedule_tree_free(child);
2319 isl_schedule_tree_free(tree);
2320 return NULL((void*)0);
2321}
2322
2323/* Attach "tree2" at each of the leaves of "tree1".
2324 *
2325 * If "tree1" does not have any explicit children, then make "tree2"
2326 * its single child. Otherwise, attach "tree2" to the leaves of
2327 * each of the children of "tree1".
2328 */
2329__isl_give isl_schedule_tree *isl_schedule_tree_append_to_leaves(
2330 __isl_take isl_schedule_tree *tree1,
2331 __isl_take isl_schedule_tree *tree2)
2332{
2333 int i, n;
2334
2335 if (!tree1 || !tree2)
2336 goto error;
2337 n = isl_schedule_tree_n_children(tree1);
2338 if (n == 0) {
2339 isl_schedule_tree_list *list;
2340 list = isl_schedule_tree_list_from_schedule_tree(tree2);
2341 tree1 = isl_schedule_tree_set_children(tree1, list);
2342 return tree1;
2343 }
2344 for (i = 0; i < n; ++i) {
2345 isl_schedule_tree *child;
2346
2347 child = isl_schedule_tree_get_child(tree1, i);
2348 child = isl_schedule_tree_append_to_leaves(child,
2349 isl_schedule_tree_copy(tree2));
2350 tree1 = isl_schedule_tree_replace_child(tree1, i, child);
2351 }
2352
2353 isl_schedule_tree_free(tree2);
2354 return tree1;
2355error:
2356 isl_schedule_tree_free(tree1);
2357 isl_schedule_tree_free(tree2);
2358 return NULL((void*)0);
2359}
2360
2361/* Reset the user pointer on all identifiers of parameters and tuples
2362 * in the root of "tree".
2363 */
2364__isl_give isl_schedule_tree *isl_schedule_tree_reset_user(
2365 __isl_take isl_schedule_tree *tree)
2366{
2367 if (isl_schedule_tree_is_leaf(tree))
2368 return tree;
2369
2370 tree = isl_schedule_tree_cow(tree);
2371 if (!tree)
2372 return NULL((void*)0);
2373
2374 switch (tree->type) {
2375 case isl_schedule_node_error:
2376 return isl_schedule_tree_free(tree);
2377 case isl_schedule_node_band:
2378 tree->band = isl_schedule_band_reset_user(tree->band);
2379 if (!tree->band)
2380 return isl_schedule_tree_free(tree);
2381 break;
2382 case isl_schedule_node_context:
2383 tree->context = isl_set_reset_user(tree->context);
2384 if (!tree->context)
2385 return isl_schedule_tree_free(tree);
2386 break;
2387 case isl_schedule_node_domain:
2388 tree->domain = isl_union_set_reset_user(tree->domain);
2389 if (!tree->domain)
2390 return isl_schedule_tree_free(tree);
2391 break;
2392 case isl_schedule_node_expansion:
2393 tree->contraction =
2394 isl_union_pw_multi_aff_reset_user(tree->contraction);
2395 tree->expansion = isl_union_map_reset_user(tree->expansion);
2396 if (!tree->contraction || !tree->expansion)
2397 return isl_schedule_tree_free(tree);
2398 break;
2399 case isl_schedule_node_extension:
2400 tree->extension = isl_union_map_reset_user(tree->extension);
2401 if (!tree->extension)
2402 return isl_schedule_tree_free(tree);
2403 break;
2404 case isl_schedule_node_filter:
2405 tree->filter = isl_union_set_reset_user(tree->filter);
2406 if (!tree->filter)
2407 return isl_schedule_tree_free(tree);
2408 break;
2409 case isl_schedule_node_guard:
2410 tree->guard = isl_set_reset_user(tree->guard);
2411 if (!tree->guard)
2412 return isl_schedule_tree_free(tree);
2413 break;
2414 case isl_schedule_node_leaf:
2415 case isl_schedule_node_mark:
2416 case isl_schedule_node_sequence:
2417 case isl_schedule_node_set:
2418 break;
2419 }
2420
2421 return tree;
2422}
2423
2424/* Align the parameters of the root of "tree" to those of "space".
2425 */
2426__isl_give isl_schedule_tree *isl_schedule_tree_align_params(
2427 __isl_take isl_schedule_tree *tree, __isl_take isl_space *space)
2428{
2429 if (!space)
2430 goto error;
2431
2432 if (isl_schedule_tree_is_leaf(tree)) {
2433 isl_space_free(space);
2434 return tree;
2435 }
2436
2437 tree = isl_schedule_tree_cow(tree);
2438 if (!tree)
2439 goto error;
2440
2441 switch (tree->type) {
2442 case isl_schedule_node_error:
2443 goto error;
2444 case isl_schedule_node_band:
2445 tree->band = isl_schedule_band_align_params(tree->band, space);
2446 if (!tree->band)
2447 return isl_schedule_tree_free(tree);
2448 break;
2449 case isl_schedule_node_context:
2450 tree->context = isl_set_align_params(tree->context, space);
2451 if (!tree->context)
2452 return isl_schedule_tree_free(tree);
2453 break;
2454 case isl_schedule_node_domain:
2455 tree->domain = isl_union_set_align_params(tree->domain, space);
2456 if (!tree->domain)
2457 return isl_schedule_tree_free(tree);
2458 break;
2459 case isl_schedule_node_expansion:
2460 tree->contraction =
2461 isl_union_pw_multi_aff_align_params(tree->contraction,
2462 isl_space_copy(space));
2463 tree->expansion = isl_union_map_align_params(tree->expansion,
2464 space);
2465 if (!tree->contraction || !tree->expansion)
2466 return isl_schedule_tree_free(tree);
2467 break;
2468 case isl_schedule_node_extension:
2469 tree->extension = isl_union_map_align_params(tree->extension,
2470 space);
2471 if (!tree->extension)
2472 return isl_schedule_tree_free(tree);
2473 break;
2474 case isl_schedule_node_filter:
2475 tree->filter = isl_union_set_align_params(tree->filter, space);
2476 if (!tree->filter)
2477 return isl_schedule_tree_free(tree);
2478 break;
2479 case isl_schedule_node_guard:
2480 tree->guard = isl_set_align_params(tree->guard, space);
2481 if (!tree->guard)
2482 return isl_schedule_tree_free(tree);
2483 break;
2484 case isl_schedule_node_leaf:
2485 case isl_schedule_node_mark:
2486 case isl_schedule_node_sequence:
2487 case isl_schedule_node_set:
2488 isl_space_free(space);
2489 break;
2490 }
2491
2492 return tree;
2493error:
2494 isl_space_free(space);
2495 isl_schedule_tree_free(tree);
2496 return NULL((void*)0);
2497}
2498
2499/* Does "tree" involve the iteration domain?
2500 * That is, does it need to be modified
2501 * by isl_schedule_tree_pullback_union_pw_multi_aff?
2502 */
2503static int involves_iteration_domain(__isl_keep isl_schedule_tree *tree)
2504{
2505 if (!tree)
2506 return -1;
2507
2508 switch (tree->type) {
2509 case isl_schedule_node_error:
2510 return -1;
2511 case isl_schedule_node_band:
2512 case isl_schedule_node_domain:
2513 case isl_schedule_node_expansion:
2514 case isl_schedule_node_extension:
2515 case isl_schedule_node_filter:
2516 return 1;
2517 case isl_schedule_node_context:
2518 case isl_schedule_node_leaf:
2519 case isl_schedule_node_guard:
2520 case isl_schedule_node_mark:
2521 case isl_schedule_node_sequence:
2522 case isl_schedule_node_set:
2523 return 0;
2524 }
2525
2526 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_internal,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "unhandled case", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2527); return -1; } while (0)
2527 "unhandled case", return -1)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_internal
, "unhandled case", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2527); return -1; } while (0)
;
2528}
2529
2530/* Compute the pullback of the root node of "tree" by the function
2531 * represented by "upma".
2532 * In other words, plug in "upma" in the iteration domains of
2533 * the root node of "tree".
2534 * We currently do not handle expansion nodes.
2535 *
2536 * We first check if the root node involves any iteration domains.
2537 * If so, we handle the specific cases.
2538 */
2539__isl_give isl_schedule_tree *isl_schedule_tree_pullback_union_pw_multi_aff(
2540 __isl_take isl_schedule_tree *tree,
2541 __isl_take isl_union_pw_multi_aff *upma)
2542{
2543 int involves;
2544
2545 if (!tree || !upma)
2546 goto error;
2547
2548 involves = involves_iteration_domain(tree);
2549 if (involves < 0)
2550 goto error;
2551 if (!involves) {
2552 isl_union_pw_multi_aff_free(upma);
2553 return tree;
2554 }
2555
2556 tree = isl_schedule_tree_cow(tree);
2557 if (!tree)
2558 goto error;
2559
2560 if (tree->type == isl_schedule_node_band) {
2561 tree->band = isl_schedule_band_pullback_union_pw_multi_aff(
2562 tree->band, upma);
2563 if (!tree->band)
2564 return isl_schedule_tree_free(tree);
2565 } else if (tree->type == isl_schedule_node_domain) {
2566 tree->domain =
2567 isl_union_set_preimage_union_pw_multi_aff(tree->domain,
2568 upma);
2569 if (!tree->domain)
2570 return isl_schedule_tree_free(tree);
2571 } else if (tree->type == isl_schedule_node_expansion) {
2572 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_unsupported,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_unsupported
, "cannot pullback expansion node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2573); goto error; } while (0)
2573 "cannot pullback expansion node", goto error)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_unsupported
, "cannot pullback expansion node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2573); goto error; } while (0)
;
2574 } else if (tree->type == isl_schedule_node_extension) {
2575 tree->extension =
2576 isl_union_map_preimage_range_union_pw_multi_aff(
2577 tree->extension, upma);
2578 if (!tree->extension)
2579 return isl_schedule_tree_free(tree);
2580 } else if (tree->type == isl_schedule_node_filter) {
2581 tree->filter =
2582 isl_union_set_preimage_union_pw_multi_aff(tree->filter,
2583 upma);
2584 if (!tree->filter)
2585 return isl_schedule_tree_free(tree);
2586 }
2587
2588 return tree;
2589error:
2590 isl_union_pw_multi_aff_free(upma);
2591 isl_schedule_tree_free(tree);
2592 return NULL((void*)0);
2593}
2594
2595/* Compute the gist of the band tree root with respect to "context".
2596 */
2597__isl_give isl_schedule_tree *isl_schedule_tree_band_gist(
2598 __isl_take isl_schedule_tree *tree, __isl_take isl_union_set *context)
2599{
2600 if (!tree)
2601 return NULL((void*)0);
2602 if (tree->type != isl_schedule_node_band)
2603 isl_die(isl_schedule_tree_get_ctx(tree), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2604); goto error; } while (0)
2604 "not a band node", goto error)do { isl_handle_error(isl_schedule_tree_get_ctx(tree), isl_error_invalid
, "not a band node", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_schedule_tree.c"
, 2604); goto error; } while (0)
;
2605 tree = isl_schedule_tree_cow(tree);
2606 if (!tree)
2607 goto error;
2608
2609 tree->band = isl_schedule_band_gist(tree->band, context);
2610 if (!tree->band)
2611 return isl_schedule_tree_free(tree);
2612 return tree;
2613error:
2614 isl_union_set_free(context);
2615 isl_schedule_tree_free(tree);
2616 return NULL((void*)0);
2617}
2618
2619/* Are any members in "band" marked coincident?
2620 */
2621static int any_coincident(__isl_keep isl_schedule_band *band)
2622{
2623 int i, n;
2624
2625 n = isl_schedule_band_n_member(band);
2626 for (i = 0; i < n; ++i)
2627 if (isl_schedule_band_member_get_coincident(band, i))
2628 return 1;
2629
2630 return 0;
2631}
2632
2633/* Print the band node "band" to "p".
2634 *
2635 * The permutable and coincident properties are only printed if they
2636 * are different from the defaults.
2637 * The coincident property is always printed in YAML flow style.
2638 */
2639static __isl_give isl_printer *print_tree_band(__isl_take isl_printer *p,
2640 __isl_keep isl_schedule_band *band)
2641{
2642 isl_union_set *options;
2643 int empty;
2644
2645 p = isl_printer_print_str(p, "schedule");
2646 p = isl_printer_yaml_next(p);
2647 p = isl_printer_print_str(p, "\"");
2648 p = isl_printer_print_multi_union_pw_aff(p, band->mupa);
2649 p = isl_printer_print_str(p, "\"");
2650 if (isl_schedule_band_get_permutable(band)) {
2651 p = isl_printer_yaml_next(p);
2652 p = isl_printer_print_str(p, "permutable");
2653 p = isl_printer_yaml_next(p);
2654 p = isl_printer_print_int(p, 1);
2655 }
2656 if (any_coincident(band)) {
2657 int i, n;
2658 int style;
2659
2660 p = isl_printer_yaml_next(p);
2661 p = isl_printer_print_str(p, "coincident");
2662 p = isl_printer_yaml_next(p);
2663 style = isl_printer_get_yaml_style(p);
2664 p = isl_printer_set_yaml_style(p, ISL_YAML_STYLE_FLOW1);
2665 p = isl_printer_yaml_start_sequence(p);
2666 n = isl_schedule_band_n_member(band);
2667 for (i = 0; i < n; ++i) {
2668 p = isl_printer_print_int(p,
2669 isl_schedule_band_member_get_coincident(band, i));
2670 p = isl_printer_yaml_next(p);
2671 }
2672 p = isl_printer_yaml_end_sequence(p);
2673 p = isl_printer_set_yaml_style(p, style);
2674 }
2675 options = isl_schedule_band_get_ast_build_options(band);
2676 empty = isl_union_set_is_empty(options);
2677 if (empty < 0)
2678 p = isl_printer_free(p);
2679 if (!empty) {
2680 p = isl_printer_yaml_next(p);
2681 p = isl_printer_print_str(p, "options");
2682 p = isl_printer_yaml_next(p);
2683 p = isl_printer_print_str(p, "\"");
2684 p = isl_printer_print_union_set(p, options);
2685 p = isl_printer_print_str(p, "\"");
2686 }
2687 isl_union_set_free(options);
2688
2689 return p;
2690}
2691
2692/* Print "tree" to "p".
2693 *
2694 * If "n_ancestor" is non-negative, then "child_pos" contains the child
2695 * positions of a descendant of the current node that should be marked
2696 * (by the comment "YOU ARE HERE"). In particular, if "n_ancestor"
2697 * is zero, then the current node should be marked.
2698 * The marking is only printed in YAML block format.
2699 *
2700 * Implicit leaf nodes are not printed, except if they correspond
2701 * to the node that should be marked.
2702 */
2703__isl_give isl_printer *isl_printer_print_schedule_tree_mark(
2704 __isl_take isl_printer *p, __isl_keep isl_schedule_tree *tree,
2705 int n_ancestor, int *child_pos)
2706{
2707 int i, n;
2708 int sequence = 0;
2709 int block;
2710
2711 block = isl_printer_get_yaml_style(p) == ISL_YAML_STYLE_BLOCK0;
5
Assuming the condition is false
14
Assuming the condition is false
2712
2713 p = isl_printer_yaml_start_mapping(p);
2714 if (n_ancestor == 0 && block) {
2715 p = isl_printer_print_str(p, "# YOU ARE HERE");
2716 p = isl_printer_end_line(p);
2717 p = isl_printer_start_line(p);
2718 }
2719 switch (tree->type) {
6
Control jumps to 'case isl_schedule_node_band:' at line 2789
15
Control jumps to 'case isl_schedule_node_band:' at line 2789
2720 case isl_schedule_node_error:
2721 p = isl_printer_print_str(p, "ERROR");
2722 break;
2723 case isl_schedule_node_leaf:
2724 p = isl_printer_print_str(p, "leaf");
2725 break;
2726 case isl_schedule_node_sequence:
2727 p = isl_printer_print_str(p, "sequence");
2728 sequence = 1;
2729 break;
2730 case isl_schedule_node_set:
2731 p = isl_printer_print_str(p, "set");
2732 sequence = 1;
2733 break;
2734 case isl_schedule_node_context:
2735 p = isl_printer_print_str(p, "context");
2736 p = isl_printer_yaml_next(p);
2737 p = isl_printer_print_str(p, "\"");
2738 p = isl_printer_print_set(p, tree->context);
2739 p = isl_printer_print_str(p, "\"");
2740 break;
2741 case isl_schedule_node_domain:
2742 p = isl_printer_print_str(p, "domain");
2743 p = isl_printer_yaml_next(p);
2744 p = isl_printer_print_str(p, "\"");
2745 p = isl_printer_print_union_set(p, tree->domain);
2746 p = isl_printer_print_str(p, "\"");
2747 break;
2748 case isl_schedule_node_expansion:
2749 p = isl_printer_print_str(p, "contraction");
2750 p = isl_printer_yaml_next(p);
2751 p = isl_printer_print_str(p, "\"");
2752 p = isl_printer_print_union_pw_multi_aff(p, tree->contraction);
2753 p = isl_printer_print_str(p, "\"");
2754 p = isl_printer_yaml_next(p);
2755 p = isl_printer_print_str(p, "expansion");
2756 p = isl_printer_yaml_next(p);
2757 p = isl_printer_print_str(p, "\"");
2758 p = isl_printer_print_union_map(p, tree->expansion);
2759 p = isl_printer_print_str(p, "\"");
2760 break;
2761 case isl_schedule_node_extension:
2762 p = isl_printer_print_str(p, "extension");
2763 p = isl_printer_yaml_next(p);
2764 p = isl_printer_print_str(p, "\"");
2765 p = isl_printer_print_union_map(p, tree->extension);
2766 p = isl_printer_print_str(p, "\"");
2767 break;
2768 case isl_schedule_node_filter:
2769 p = isl_printer_print_str(p, "filter");
2770 p = isl_printer_yaml_next(p);
2771 p = isl_printer_print_str(p, "\"");
2772 p = isl_printer_print_union_set(p, tree->filter);
2773 p = isl_printer_print_str(p, "\"");
2774 break;
2775 case isl_schedule_node_guard:
2776 p = isl_printer_print_str(p, "guard");
2777 p = isl_printer_yaml_next(p);
2778 p = isl_printer_print_str(p, "\"");
2779 p = isl_printer_print_set(p, tree->guard);
2780 p = isl_printer_print_str(p, "\"");
2781 break;
2782 case isl_schedule_node_mark:
2783 p = isl_printer_print_str(p, "mark");
2784 p = isl_printer_yaml_next(p);
2785 p = isl_printer_print_str(p, "\"");
2786 p = isl_printer_print_str(p, isl_id_get_name(tree->mark));
2787 p = isl_printer_print_str(p, "\"");
2788 break;
2789 case isl_schedule_node_band:
2790 p = print_tree_band(p, tree->band);
2791 break;
7
Execution continues on line 2793
16
Execution continues on line 2793
2792 }
2793 p = isl_printer_yaml_next(p);
2794
2795 if (!tree->children) {
8
Assuming the condition is false
9
Taking false branch
17
Assuming the condition is false
18
Taking false branch
2796 if (n_ancestor > 0 && block) {
2797 isl_schedule_tree *leaf;
2798
2799 p = isl_printer_print_str(p, "child");
2800 p = isl_printer_yaml_next(p);
2801 leaf = isl_schedule_tree_leaf(isl_printer_get_ctx(p));
2802 p = isl_printer_print_schedule_tree_mark(p,
2803 leaf, 0, NULL((void*)0));
2804 isl_schedule_tree_free(leaf);
2805 p = isl_printer_yaml_next(p);
2806 }
2807 return isl_printer_yaml_end_mapping(p);
2808 }
2809
2810 if (sequence) {
10
Taking false branch
19
Taking false branch
2811 p = isl_printer_yaml_start_sequence(p);
2812 } else {
2813 p = isl_printer_print_str(p, "child");
2814 p = isl_printer_yaml_next(p);
2815 }
2816
2817 n = isl_schedule_tree_list_n_schedule_tree(tree->children);
2818 for (i = 0; i < n; ++i) {
11
Assuming 'i' is < 'n'
12
Loop condition is true. Entering loop body
20
Assuming 'i' is < 'n'
21
Loop condition is true. Entering loop body
42
Assuming 'i' is >= 'n'
43
Loop condition is false. Execution continues on line 2833
2819 isl_schedule_tree *t;
2820
2821 t = isl_schedule_tree_get_child(tree, i);
22
Calling 'isl_schedule_tree_get_child'
33
Returning from 'isl_schedule_tree_get_child'
2822 if (n_ancestor > 0 && child_pos[0] == i)
2823 p = isl_printer_print_schedule_tree_mark(p, t,
2824 n_ancestor - 1, child_pos + 1);
2825 else
2826 p = isl_printer_print_schedule_tree_mark(p, t,
13
Calling 'isl_printer_print_schedule_tree_mark'
45
Returning; memory was released
2827 -1, NULL((void*)0));
2828 isl_schedule_tree_free(t);
34
Calling 'isl_schedule_tree_free'
41
Returning; memory was released via 1st parameter
46
Calling 'isl_schedule_tree_free'
2829
2830 p = isl_printer_yaml_next(p);
2831 }
2832
2833 if (sequence)
44
Taking false branch
2834 p = isl_printer_yaml_end_sequence(p);
2835 p = isl_printer_yaml_end_mapping(p);
2836
2837 return p;
2838}
2839
2840/* Print "tree" to "p".
2841 */
2842__isl_give isl_printer *isl_printer_print_schedule_tree(
2843 __isl_take isl_printer *p, __isl_keep isl_schedule_tree *tree)
2844{
2845 return isl_printer_print_schedule_tree_mark(p, tree, -1, NULL((void*)0));
4
Calling 'isl_printer_print_schedule_tree_mark'
2846}
2847
2848void isl_schedule_tree_dump(__isl_keep isl_schedule_tree *tree)
2849{
2850 isl_ctx *ctx;
2851 isl_printer *printer;
2852
2853 if (!tree)
1
Assuming 'tree' is non-null
2
Taking false branch
2854 return;
2855
2856 ctx = isl_schedule_tree_get_ctx(tree);
2857 printer = isl_printer_to_file(ctx, stderrstderr);
2858 printer = isl_printer_set_yaml_style(printer, ISL_YAML_STYLE_BLOCK0);
2859 printer = isl_printer_print_schedule_tree(printer, tree);
3
Calling 'isl_printer_print_schedule_tree'
2860
2861 isl_printer_free(printer);
2862}

/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_list_templ.c

1/*
2 * Copyright 2008-2009 Katholieke Universiteit Leuven
3 * Copyright 2011 INRIA Saclay
4 * Copyright 2012-2013 Ecole Normale Superieure
5 * Copyright 2017 Sven Verdoolaege
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 */
15
16#include <isl_sort.h>
17#include <isl_tarjan.h>
18#include <isl/printer.h>
19
20#define xCAT(A,B)AB A ## B
21#define CAT(A,B)AB xCAT(A,B)AB
22#undef ELisl_schedule_tree
23#define ELisl_schedule_tree CAT(isl_,BASE)isl_schedule_tree
24#define xFN(TYPE,NAME)TYPE_NAME TYPE ## _ ## NAME
25#define FN(TYPE,NAME)TYPE_NAME xFN(TYPE,NAME)TYPE_NAME
26#define xLIST(EL)EL_list ELisl_schedule_tree ## _list
27#define LIST(EL)isl_schedule_tree_list xLIST(EL)EL_list
28#define xS(TYPE,NAME)struct TYPE_NAME struct TYPE ## _ ## NAME
29#define S(TYPE,NAME)struct TYPE_NAME xS(TYPE,NAME)struct TYPE_NAME
30
31isl_ctx *FN(LIST(EL),get_ctx)isl_schedule_tree_list_get_ctx(__isl_keep LIST(EL)isl_schedule_tree_list *list)
32{
33 return list ? list->ctx : NULL((void*)0);
34}
35
36__isl_give LIST(EL)isl_schedule_tree_list *FN(LIST(EL),alloc)isl_schedule_tree_list_alloc(isl_ctx *ctx, int n)
37{
38 LIST(EL)isl_schedule_tree_list *list;
39
40 if (n < 0)
41 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "cannot create list of negative length"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_list_templ.c"
, 43); return ((void*)0); } while (0)
42 "cannot create list of negative length",do { isl_handle_error(ctx, isl_error_invalid, "cannot create list of negative length"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_list_templ.c"
, 43); return ((void*)0); } while (0)
43 return NULL)do { isl_handle_error(ctx, isl_error_invalid, "cannot create list of negative length"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_list_templ.c"
, 43); return ((void*)0); } while (0)
;
44 list = isl_alloc(ctx, LIST(EL),((isl_schedule_tree_list *)isl_malloc_or_die(ctx, sizeof(isl_schedule_tree_list
) + (n - 1) * sizeof(struct isl_schedule_tree *)))
45 sizeof(LIST(EL)) + (n - 1) * sizeof(struct EL *))((isl_schedule_tree_list *)isl_malloc_or_die(ctx, sizeof(isl_schedule_tree_list
) + (n - 1) * sizeof(struct isl_schedule_tree *)))
;
46 if (!list)
47 return NULL((void*)0);
48
49 list->ctx = ctx;
50 isl_ctx_ref(ctx);
51 list->ref = 1;
52 list->size = n;
53 list->n = 0;
54 return list;
55}
56
57__isl_give LIST(EL)isl_schedule_tree_list *FN(LIST(EL),copy)isl_schedule_tree_list_copy(__isl_keep LIST(EL)isl_schedule_tree_list *list)
58{
59 if (!list)
60 return NULL((void*)0);
61
62 list->ref++;
63 return list;
64}
65
66__isl_give LIST(EL)isl_schedule_tree_list *FN(LIST(EL),dup)isl_schedule_tree_list_dup(__isl_keep LIST(EL)isl_schedule_tree_list *list)
67{
68 int i;
69 LIST(EL)isl_schedule_tree_list *dup;
70
71 if (!list)
72 return NULL((void*)0);
73
74 dup = FN(LIST(EL),alloc)isl_schedule_tree_list_alloc(FN(LIST(EL),get_ctx)isl_schedule_tree_list_get_ctx(list), list->n);
75 if (!dup)
76 return NULL((void*)0);
77 for (i = 0; i < list->n; ++i)
78 dup = FN(LIST(EL),add)isl_schedule_tree_list_add(dup, FN(EL,copy)isl_schedule_tree_copy(list->p[i]));
79 return dup;
80}
81
82__isl_give LIST(EL)isl_schedule_tree_list *FN(LIST(EL),cow)isl_schedule_tree_list_cow(__isl_take LIST(EL)isl_schedule_tree_list *list)
83{
84 if (!list)
85 return NULL((void*)0);
86
87 if (list->ref == 1)
88 return list;
89 list->ref--;
90 return FN(LIST(EL),dup)isl_schedule_tree_list_dup(list);
91}
92
93/* Make sure "list" has room for at least "n" more pieces.
94 * Always return a list with a single reference.
95 *
96 * If there is only one reference to list, we extend it in place.
97 * Otherwise, we create a new LIST(EL) and copy the elements.
98 */
99static __isl_give LIST(EL)isl_schedule_tree_list *FN(LIST(EL),grow)isl_schedule_tree_list_grow(__isl_take LIST(EL)isl_schedule_tree_list *list, int n)
100{
101 isl_ctx *ctx;
102 int i, new_size;
103 LIST(EL)isl_schedule_tree_list *res;
104
105 if (!list)
106 return NULL((void*)0);
107 if (list->ref == 1 && list->n + n <= list->size)
108 return list;
109
110 ctx = FN(LIST(EL),get_ctx)isl_schedule_tree_list_get_ctx(list);
111 new_size = ((list->n + n + 1) * 3) / 2;
112 if (list->ref == 1) {
113 res = isl_realloc(ctx, list, LIST(EL),((isl_schedule_tree_list *)isl_realloc_or_die(ctx, list, sizeof
(isl_schedule_tree_list) + (new_size - 1) * sizeof(isl_schedule_tree
*)))
114 sizeof(LIST(EL)) + (new_size - 1) * sizeof(EL *))((isl_schedule_tree_list *)isl_realloc_or_die(ctx, list, sizeof
(isl_schedule_tree_list) + (new_size - 1) * sizeof(isl_schedule_tree
*)))
;
115 if (!res)
116 return FN(LIST(EL),free)isl_schedule_tree_list_free(list);
117 res->size = new_size;
118 return res;
119 }
120
121 if (list->n + n <= list->size && list->size < new_size)
122 new_size = list->size;
123
124 res = FN(LIST(EL),alloc)isl_schedule_tree_list_alloc(ctx, new_size);
125 if (!res)
126 return FN(LIST(EL),free)isl_schedule_tree_list_free(list);
127
128 for (i = 0; i < list->n; ++i)
129 res = FN(LIST(EL),add)isl_schedule_tree_list_add(res, FN(EL,copy)isl_schedule_tree_copy(list->p[i]));
130
131 FN(LIST(EL),free)isl_schedule_tree_list_free(list);
132 return res;
133}
134
135/* Check that "index" is a valid position in "list".
136 */
137static isl_stat FN(LIST(EL),check_index)isl_schedule_tree_list_check_index(__isl_keep LIST(EL)isl_schedule_tree_list *list, int index)
138{
139 if (!list)
140 return isl_stat_error;
141 if (index < 0 || index >= list->n)
142 isl_die(FN(LIST(EL),get_ctx)(list), isl_error_invalid,do { isl_handle_error(isl_schedule_tree_list_get_ctx(list), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_list_templ.c"
, 143); return isl_stat_error; } while (0)
143 "index out of bounds", return isl_stat_error)do { isl_handle_error(isl_schedule_tree_list_get_ctx(list), isl_error_invalid
, "index out of bounds", "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_list_templ.c"
, 143); return isl_stat_error; } while (0)
;
144 return isl_stat_ok;
145}
146
147__isl_give LIST(EL)isl_schedule_tree_list *FN(LIST(EL),add)isl_schedule_tree_list_add(__isl_take LIST(EL)isl_schedule_tree_list *list,
148 __isl_take struct ELisl_schedule_tree *el)
149{
150 list = FN(LIST(EL),grow)isl_schedule_tree_list_grow(list, 1);
151 if (!list || !el)
152 goto error;
153 list->p[list->n] = el;
154 list->n++;
155 return list;
156error:
157 FN(EL,free)isl_schedule_tree_free(el);
158 FN(LIST(EL),free)isl_schedule_tree_list_free(list);
159 return NULL((void*)0);
160}
161
162/* Remove the "n" elements starting at "first" from "list".
163 */
164__isl_give LIST(EL)isl_schedule_tree_list *FN(LIST(EL),drop)isl_schedule_tree_list_drop(__isl_take LIST(EL)isl_schedule_tree_list *list,
165 unsigned first, unsigned n)
166{
167 int i;
168
169 if (!list)
170 return NULL((void*)0);
171 if (first + n > list->n || first + n < first)
172 isl_die(list->ctx, isl_error_invalid,do { isl_handle_error(list->ctx, isl_error_invalid, "index out of bounds"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_list_templ.c"
, 173); return isl_schedule_tree_list_free(list); } while (0)
173 "index out of bounds", return FN(LIST(EL),free)(list))do { isl_handle_error(list->ctx, isl_error_invalid, "index out of bounds"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_list_templ.c"
, 173); return isl_schedule_tree_list_free(list); } while (0)
;
174 if (n == 0)
175 return list;
176 list = FN(LIST(EL),cow)isl_schedule_tree_list_cow(list);
177 if (!list)
178 return NULL((void*)0);
179 for (i = 0; i < n; ++i)
180 FN(EL,free)isl_schedule_tree_free(list->p[first + i]);
181 for (i = first; i + n < list->n; ++i)
182 list->p[i] = list->p[i + n];
183 list->n -= n;
184 return list;
185}
186
187/* Insert "el" at position "pos" in "list".
188 *
189 * If there is only one reference to "list" and if it already has space
190 * for one extra element, we insert it directly into "list".
191 * Otherwise, we create a new list consisting of "el" and copied
192 * elements from "list".
193 */
194__isl_give LIST(EL)isl_schedule_tree_list *FN(LIST(EL),insert)isl_schedule_tree_list_insert(__isl_take LIST(EL)isl_schedule_tree_list *list,
195 unsigned pos, __isl_take struct ELisl_schedule_tree *el)
196{
197 int i;
198 isl_ctx *ctx;
199 LIST(EL)isl_schedule_tree_list *res;
200
201 if (!list || !el)
202 goto error;
203 ctx = FN(LIST(EL),get_ctx)isl_schedule_tree_list_get_ctx(list);
204 if (pos > list->n)
205 isl_die(ctx, isl_error_invalid,do { isl_handle_error(ctx, isl_error_invalid, "index out of bounds"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_list_templ.c"
, 206); goto error; } while (0)
206 "index out of bounds", goto error)do { isl_handle_error(ctx, isl_error_invalid, "index out of bounds"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_list_templ.c"
, 206); goto error; } while (0)
;
207
208 if (list->ref == 1 && list->size > list->n) {
209 for (i = list->n; i > pos; --i)
210 list->p[i] = list->p[i - 1];
211 list->n++;
212 list->p[pos] = el;
213 return list;
214 }
215
216 res = FN(LIST(EL),alloc)isl_schedule_tree_list_alloc(ctx, list->n + 1);
217 for (i = 0; i < pos; ++i)
218 res = FN(LIST(EL),add)isl_schedule_tree_list_add(res, FN(EL,copy)isl_schedule_tree_copy(list->p[i]));
219 res = FN(LIST(EL),add)isl_schedule_tree_list_add(res, el);
220 for (i = pos; i < list->n; ++i)
221 res = FN(LIST(EL),add)isl_schedule_tree_list_add(res, FN(EL,copy)isl_schedule_tree_copy(list->p[i]));
222 FN(LIST(EL),free)isl_schedule_tree_list_free(list);
223
224 return res;
225error:
226 FN(EL,free)isl_schedule_tree_free(el);
227 FN(LIST(EL),free)isl_schedule_tree_list_free(list);
228 return NULL((void*)0);
229}
230
231__isl_null LIST(EL)isl_schedule_tree_list *FN(LIST(EL),free)isl_schedule_tree_list_free(__isl_take LIST(EL)isl_schedule_tree_list *list)
232{
233 int i;
234
235 if (!list)
53
Taking false branch
236 return NULL((void*)0);
237
238 if (--list->ref > 0)
54
Assuming the condition is false
55
Taking false branch
239 return NULL((void*)0);
240
241 isl_ctx_deref(list->ctx);
242 for (i = 0; i < list->n; ++i)
56
Assuming the condition is true
57
Loop condition is true. Entering loop body
243 FN(EL,free)isl_schedule_tree_free(list->p[i]);
58
Use of memory after it is freed
244 free(list);
245
246 return NULL((void*)0);
247}
248
249/* Return the number of elements in "list".
250 */
251int FN(LIST(EL),size)isl_schedule_tree_list_size(__isl_keep LIST(EL)isl_schedule_tree_list *list)
252{
253 return list ? list->n : 0;
254}
255
256/* This is an alternative name for the function above.
257 */
258int FN(FN(LIST(EL),n),BASE)isl_schedule_tree_list_n_schedule_tree(__isl_keep LIST(EL)isl_schedule_tree_list *list)
259{
260 return FN(LIST(EL),size)isl_schedule_tree_list_size(list);
261}
262
263/* Return the element at position "index" in "list".
264 */
265static __isl_keep ELisl_schedule_tree *FN(LIST(EL),peek)isl_schedule_tree_list_peek(__isl_keep LIST(EL)isl_schedule_tree_list *list, int index)
266{
267 if (FN(LIST(EL),check_index)isl_schedule_tree_list_check_index(list, index) < 0)
268 return NULL((void*)0);
269 return list->p[index];
270}
271
272/* Return a copy of the element at position "index" in "list".
273 */
274__isl_give ELisl_schedule_tree *FN(LIST(EL),get_at)isl_schedule_tree_list_get_at(__isl_keep LIST(EL)isl_schedule_tree_list *list, int index)
275{
276 return FN(EL,copy)isl_schedule_tree_copy(FN(LIST(EL),peek)isl_schedule_tree_list_peek(list, index));
27
Calling 'isl_schedule_tree_copy'
30
Returning from 'isl_schedule_tree_copy'
277}
278
279/* This is an alternative name for the function above.
280 */
281__isl_give ELisl_schedule_tree *FN(FN(LIST(EL),get),BASE)isl_schedule_tree_list_get_schedule_tree(__isl_keep LIST(EL)isl_schedule_tree_list *list, int index)
282{
283 return FN(LIST(EL),get_at)isl_schedule_tree_list_get_at(list, index);
26
Calling 'isl_schedule_tree_list_get_at'
31
Returning from 'isl_schedule_tree_list_get_at'
284}
285
286/* Replace the element at position "index" in "list" by "el".
287 */
288__isl_give LIST(EL)isl_schedule_tree_list *FN(FN(LIST(EL),set),BASE)isl_schedule_tree_list_set_schedule_tree(__isl_take LIST(EL)isl_schedule_tree_list *list,
289 int index, __isl_take ELisl_schedule_tree *el)
290{
291 if (!list || !el)
292 goto error;
293 if (FN(LIST(EL),check_index)isl_schedule_tree_list_check_index(list, index) < 0)
294 goto error;
295 if (list->p[index] == el) {
296 FN(EL,free)isl_schedule_tree_free(el);
297 return list;
298 }
299 list = FN(LIST(EL),cow)isl_schedule_tree_list_cow(list);
300 if (!list)
301 goto error;
302 FN(EL,free)isl_schedule_tree_free(list->p[index]);
303 list->p[index] = el;
304 return list;
305error:
306 FN(EL,free)isl_schedule_tree_free(el);
307 FN(LIST(EL),free)isl_schedule_tree_list_free(list);
308 return NULL((void*)0);
309}
310
311/* Return the element at position "index" of "list".
312 * This may be either a copy or the element itself
313 * if there is only one reference to "list".
314 * This allows the element to be modified inplace
315 * if both the list and the element have only a single reference.
316 * The caller is not allowed to modify "list" between
317 * this call to isl_list_*_take_* and a subsequent call
318 * to isl_list_*_restore_*.
319 * The only exception is that isl_list_*_free can be called instead.
320 */
321static __isl_give ELisl_schedule_tree *FN(FN(LIST(EL),take),BASE)isl_schedule_tree_list_take_schedule_tree(__isl_keep LIST(EL)isl_schedule_tree_list *list,
322 int index)
323{
324 ELisl_schedule_tree *el;
325
326 if (FN(LIST(EL),check_index)isl_schedule_tree_list_check_index(list, index) < 0)
327 return NULL((void*)0);
328 if (list->ref != 1)
329 return FN(FN(LIST(EL),get),BASE)isl_schedule_tree_list_get_schedule_tree(list, index);
330 el = list->p[index];
331 list->p[index] = NULL((void*)0);
332 return el;
333}
334
335/* Set the element at position "index" of "list" to "el",
336 * where the position may be empty due to a previous call
337 * to isl_list_*_take_*.
338 */
339static __isl_give LIST(EL)isl_schedule_tree_list *FN(FN(LIST(EL),restore),BASE)isl_schedule_tree_list_restore_schedule_tree(
340 __isl_take LIST(EL)isl_schedule_tree_list *list, int index, __isl_take ELisl_schedule_tree *el)
341{
342 return FN(FN(LIST(EL),set),BASE)isl_schedule_tree_list_set_schedule_tree(list, index, el);
343}
344
345/* Swap the elements of "list" in positions "pos1" and "pos2".
346 */
347__isl_give LIST(EL)isl_schedule_tree_list *FN(LIST(EL),swap)isl_schedule_tree_list_swap(__isl_take LIST(EL)isl_schedule_tree_list *list,
348 unsigned pos1, unsigned pos2)
349{
350 ELisl_schedule_tree *el1, *el2;
351
352 if (pos1 == pos2)
353 return list;
354 el1 = FN(FN(LIST(EL),take),BASE)isl_schedule_tree_list_take_schedule_tree(list, pos1);
355 el2 = FN(FN(LIST(EL),take),BASE)isl_schedule_tree_list_take_schedule_tree(list, pos2);
356 list = FN(FN(LIST(EL),restore),BASE)isl_schedule_tree_list_restore_schedule_tree(list, pos1, el2);
357 list = FN(FN(LIST(EL),restore),BASE)isl_schedule_tree_list_restore_schedule_tree(list, pos2, el1);
358 return list;
359}
360
361/* Reverse the elements of "list".
362 */
363__isl_give LIST(EL)isl_schedule_tree_list *FN(LIST(EL),reverse)isl_schedule_tree_list_reverse(__isl_take LIST(EL)isl_schedule_tree_list *list)
364{
365 int i, n;
366
367 n = FN(LIST(EL),size)isl_schedule_tree_list_size(list);
368 for (i = 0; i < n - 1 - i; ++i)
369 list = FN(LIST(EL),swap)isl_schedule_tree_list_swap(list, i, n - 1 - i);
370 return list;
371}
372
373isl_stat FN(LIST(EL),foreach)isl_schedule_tree_list_foreach(__isl_keep LIST(EL)isl_schedule_tree_list *list,
374 isl_stat (*fn)(__isl_take ELisl_schedule_tree *el, void *user), void *user)
375{
376 int i;
377
378 if (!list)
379 return isl_stat_error;
380
381 for (i = 0; i < list->n; ++i) {
382 ELisl_schedule_tree *el = FN(EL,copy)isl_schedule_tree_copy(list->p[i]);
383 if (!el)
384 return isl_stat_error;
385 if (fn(el, user) < 0)
386 return isl_stat_error;
387 }
388
389 return isl_stat_ok;
390}
391
392/* Replace each element in "list" by the result of calling "fn"
393 * on the element.
394 */
395__isl_give LIST(EL)isl_schedule_tree_list *FN(LIST(EL),map)isl_schedule_tree_list_map(__isl_keep LIST(EL)isl_schedule_tree_list *list,
396 __isl_give ELisl_schedule_tree *(*fn)(__isl_take ELisl_schedule_tree *el, void *user), void *user)
397{
398 int i, n;
399
400 if (!list)
401 return NULL((void*)0);
402
403 n = list->n;
404 for (i = 0; i < n; ++i) {
405 ELisl_schedule_tree *el = FN(FN(LIST(EL),take),BASE)isl_schedule_tree_list_take_schedule_tree(list, i);
406 if (!el)
407 return FN(LIST(EL),free)isl_schedule_tree_list_free(list);
408 el = fn(el, user);
409 list = FN(FN(LIST(EL),restore),BASE)isl_schedule_tree_list_restore_schedule_tree(list, i, el);
410 }
411
412 return list;
413}
414
415/* Internal data structure for isl_*_list_sort.
416 *
417 * "cmp" is the original comparison function.
418 * "user" is a user provided pointer that should be passed to "cmp".
419 */
420S(LIST(EL),sort_data)struct isl_schedule_tree_list_sort_data {
421 int (*cmp)(__isl_keep ELisl_schedule_tree *a, __isl_keep ELisl_schedule_tree *b, void *user);
422 void *user;
423};
424
425/* Compare two entries of an isl_*_list based on the user provided
426 * comparison function on pairs of isl_* objects.
427 */
428static int FN(LIST(EL),cmp)isl_schedule_tree_list_cmp(const void *a, const void *b, void *user)
429{
430 S(LIST(EL),sort_data)struct isl_schedule_tree_list_sort_data *data = user;
431 ELisl_schedule_tree * const *el1 = a;
432 ELisl_schedule_tree * const *el2 = b;
433
434 return data->cmp(*el1, *el2, data->user);
435}
436
437/* Sort the elements of "list" in ascending order according to
438 * comparison function "cmp".
439 */
440__isl_give LIST(EL)isl_schedule_tree_list *FN(LIST(EL),sort)isl_schedule_tree_list_sort(__isl_take LIST(EL)isl_schedule_tree_list *list,
441 int (*cmp)(__isl_keep ELisl_schedule_tree *a, __isl_keep ELisl_schedule_tree *b, void *user), void *user)
442{
443 S(LIST(EL),sort_data)struct isl_schedule_tree_list_sort_data data = { cmp, user };
444
445 if (!list)
446 return NULL((void*)0);
447 if (list->n <= 1)
448 return list;
449 list = FN(LIST(EL),cow)isl_schedule_tree_list_cow(list);
450 if (!list)
451 return NULL((void*)0);
452
453 if (isl_sort(list->p, list->n, sizeof(list->p[0]),
454 &FN(LIST(EL),cmp)isl_schedule_tree_list_cmp, &data) < 0)
455 return FN(LIST(EL),free)isl_schedule_tree_list_free(list);
456
457 return list;
458}
459
460/* Internal data structure for isl_*_list_foreach_scc.
461 *
462 * "list" is the original list.
463 * "follows" is the user provided callback that defines the edges of the graph.
464 */
465S(LIST(EL),foreach_scc_data)struct isl_schedule_tree_list_foreach_scc_data {
466 LIST(EL)isl_schedule_tree_list *list;
467 isl_bool (*follows)(__isl_keep ELisl_schedule_tree *a, __isl_keep ELisl_schedule_tree *b, void *user);
468 void *follows_user;
469};
470
471/* Does element i of data->list follow element j?
472 *
473 * Use the user provided callback to find out.
474 */
475static isl_bool FN(LIST(EL),follows)isl_schedule_tree_list_follows(int i, int j, void *user)
476{
477 S(LIST(EL),foreach_scc_data)struct isl_schedule_tree_list_foreach_scc_data *data = user;
478
479 return data->follows(data->list->p[i], data->list->p[j],
480 data->follows_user);
481}
482
483/* Call "fn" on the sublist of "list" that consists of the elements
484 * with indices specified by the "n" elements of "pos".
485 */
486static isl_stat FN(LIST(EL),call_on_scc)isl_schedule_tree_list_call_on_scc(__isl_keep LIST(EL)isl_schedule_tree_list *list, int *pos,
487 int n, isl_stat (*fn)(__isl_take LIST(EL)isl_schedule_tree_list *scc, void *user), void *user)
488{
489 int i;
490 isl_ctx *ctx;
491 LIST(EL)isl_schedule_tree_list *slice;
492
493 ctx = FN(LIST(EL),get_ctx)isl_schedule_tree_list_get_ctx(list);
494 slice = FN(LIST(EL),alloc)isl_schedule_tree_list_alloc(ctx, n);
495 for (i = 0; i < n; ++i) {
496 ELisl_schedule_tree *el;
497
498 el = FN(EL,copy)isl_schedule_tree_copy(list->p[pos[i]]);
499 slice = FN(LIST(EL),add)isl_schedule_tree_list_add(slice, el);
500 }
501
502 return fn(slice, user);
503}
504
505/* Call "fn" on each of the strongly connected components (SCCs) of
506 * the graph with as vertices the elements of "list" and
507 * a directed edge from node b to node a iff follows(a, b)
508 * returns 1. follows should return -1 on error.
509 *
510 * If SCC a contains a node i that follows a node j in another SCC b
511 * (i.e., follows(i, j, user) returns 1), then fn will be called on SCC a
512 * after being called on SCC b.
513 *
514 * We simply call isl_tarjan_graph_init, extract the SCCs from the result and
515 * call fn on each of them.
516 */
517isl_stat FN(LIST(EL),foreach_scc)isl_schedule_tree_list_foreach_scc(__isl_keep LIST(EL)isl_schedule_tree_list *list,
518 isl_bool (*follows)(__isl_keep ELisl_schedule_tree *a, __isl_keep ELisl_schedule_tree *b, void *user),
519 void *follows_user,
520 isl_stat (*fn)(__isl_take LIST(EL)isl_schedule_tree_list *scc, void *user), void *fn_user)
521{
522 S(LIST(EL),foreach_scc_data)struct isl_schedule_tree_list_foreach_scc_data data = { list, follows, follows_user };
523 int i, n;
524 isl_ctx *ctx;
525 struct isl_tarjan_graph *g;
526
527 if (!list)
528 return isl_stat_error;
529 if (list->n == 0)
530 return isl_stat_ok;
531 if (list->n == 1)
532 return fn(FN(LIST(EL),copy)isl_schedule_tree_list_copy(list), fn_user);
533
534 ctx = FN(LIST(EL),get_ctx)isl_schedule_tree_list_get_ctx(list);
535 n = list->n;
536 g = isl_tarjan_graph_init(ctx, n, &FN(LIST(EL),follows)isl_schedule_tree_list_follows, &data);
537 if (!g)
538 return isl_stat_error;
539
540 i = 0;
541 do {
542 int first;
543
544 if (g->order[i] == -1)
545 isl_die(ctx, isl_error_internal, "cannot happen",do { isl_handle_error(ctx, isl_error_internal, "cannot happen"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_list_templ.c"
, 546); break; } while (0)
546 break)do { isl_handle_error(ctx, isl_error_internal, "cannot happen"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/polly/lib/External/isl/isl_list_templ.c"
, 546); break; } while (0)
;
547 first = i;
548 while (g->order[i] != -1) {
549 ++i; --n;
550 }
551 if (first == 0 && n == 0) {
552 isl_tarjan_graph_free(g);
553 return fn(FN(LIST(EL),copy)isl_schedule_tree_list_copy(list), fn_user);
554 }
555 if (FN(LIST(EL),call_on_scc)isl_schedule_tree_list_call_on_scc(list, g->order + first, i - first,
556 fn, fn_user) < 0)
557 break;
558 ++i;
559 } while (n);
560
561 isl_tarjan_graph_free(g);
562
563 return n > 0 ? isl_stat_error : isl_stat_ok;
564}
565
566__isl_give LIST(EL)isl_schedule_tree_list *FN(FN(LIST(EL),from),BASE)isl_schedule_tree_list_from_schedule_tree(__isl_take ELisl_schedule_tree *el)
567{
568 isl_ctx *ctx;
569 LIST(EL)isl_schedule_tree_list *list;
570
571 if (!el)
572 return NULL((void*)0);
573 ctx = FN(EL,get_ctx)isl_schedule_tree_get_ctx(el);
574 list = FN(LIST(EL),alloc)isl_schedule_tree_list_alloc(ctx, 1);
575 if (!list)
576 goto error;
577 list = FN(LIST(EL),add)isl_schedule_tree_list_add(list, el);
578 return list;
579error:
580 FN(EL,free)isl_schedule_tree_free(el);
581 return NULL((void*)0);
582}
583
584/* Append the elements of "list2" to "list1", where "list1" is known
585 * to have only a single reference and enough room to hold
586 * the extra elements.
587 */
588static __isl_give LIST(EL)isl_schedule_tree_list *FN(LIST(EL),concat_inplace)isl_schedule_tree_list_concat_inplace(
589 __isl_take LIST(EL)isl_schedule_tree_list *list1, __isl_take LIST(EL)isl_schedule_tree_list *list2)
590{
591 int i;
592
593 for (i = 0; i < list2->n; ++i)
594 list1 = FN(LIST(EL),add)isl_schedule_tree_list_add(list1, FN(EL,copy)isl_schedule_tree_copy(list2->p[i]));
595 FN(LIST(EL),free)isl_schedule_tree_list_free(list2);
596 return list1;
597}
598
599/* Concatenate "list1" and "list2".
600 * If "list1" has only one reference and has enough room
601 * for the elements of "list2", the add the elements to "list1" itself.
602 * Otherwise, create a new list to store the result.
603 */
604__isl_give LIST(EL)isl_schedule_tree_list *FN(LIST(EL),concat)isl_schedule_tree_list_concat(__isl_take LIST(EL)isl_schedule_tree_list *list1,
605 __isl_take LIST(EL)isl_schedule_tree_list *list2)
606{
607 int i;
608 isl_ctx *ctx;
609 LIST(EL)isl_schedule_tree_list *res;
610
611 if (!list1 || !list2)
612 goto error;
613
614 if (list1->ref == 1 && list1->n + list2->n <= list1->size)
615 return FN(LIST(EL),concat_inplace)isl_schedule_tree_list_concat_inplace(list1, list2);
616
617 ctx = FN(LIST(EL),get_ctx)isl_schedule_tree_list_get_ctx(list1);
618 res = FN(LIST(EL),alloc)isl_schedule_tree_list_alloc(ctx, list1->n + list2->n);
619 for (i = 0; i < list1->n; ++i)
620 res = FN(LIST(EL),add)isl_schedule_tree_list_add(res, FN(EL,copy)isl_schedule_tree_copy(list1->p[i]));
621 for (i = 0; i < list2->n; ++i)
622 res = FN(LIST(EL),add)isl_schedule_tree_list_add(res, FN(EL,copy)isl_schedule_tree_copy(list2->p[i]));
623
624 FN(LIST(EL),free)isl_schedule_tree_list_free(list1);
625 FN(LIST(EL),free)isl_schedule_tree_list_free(list2);
626 return res;
627error:
628 FN(LIST(EL),free)isl_schedule_tree_list_free(list1);
629 FN(LIST(EL),free)isl_schedule_tree_list_free(list2);
630 return NULL((void*)0);
631}
632
633__isl_give isl_printer *CAT(isl_printer_print_,LIST(BASE))isl_printer_print_schedule_tree_list(
634 __isl_take isl_printer *p, __isl_keep LIST(EL)isl_schedule_tree_list *list)
635{
636 int i;
637
638 if (!p || !list)
639 goto error;
640 p = isl_printer_print_str(p, "(");
641 for (i = 0; i < list->n; ++i) {
642 if (i)
643 p = isl_printer_print_str(p, ",");
644 p = CAT(isl_printer_print_,BASE)isl_printer_print_schedule_tree(p, list->p[i]);
645 }
646 p = isl_printer_print_str(p, ")");
647 return p;
648error:
649 isl_printer_free(p);
650 return NULL((void*)0);
651}
652
653void FN(LIST(EL),dump)isl_schedule_tree_list_dump(__isl_keep LIST(EL)isl_schedule_tree_list *list)
654{
655 isl_printer *printer;
656
657 if (!list)
658 return;
659
660 printer = isl_printer_to_file(FN(LIST(EL),get_ctx)isl_schedule_tree_list_get_ctx(list), stderrstderr);
661 printer = CAT(isl_printer_print_,LIST(BASE))isl_printer_print_schedule_tree_list(printer, list);
662 printer = isl_printer_end_line(printer);
663
664 isl_printer_free(printer);
665}