1 | #include <isl/id.h> |
2 | #include <isl/val.h> |
3 | #include <isl/schedule.h> |
4 | #include <isl/stream.h> |
5 | #include <isl_schedule_private.h> |
6 | #include <isl_schedule_tree.h> |
7 | |
8 | /* An enumeration of the various keys that may appear in a YAML mapping |
9 | * of a schedule. |
10 | */ |
11 | enum isl_schedule_key { |
12 | isl_schedule_key_error = -1, |
13 | isl_schedule_key_child, |
14 | isl_schedule_key_coincident, |
15 | isl_schedule_key_context, |
16 | isl_schedule_key_contraction, |
17 | isl_schedule_key_domain, |
18 | isl_schedule_key_expansion, |
19 | isl_schedule_key_extension, |
20 | isl_schedule_key_filter, |
21 | isl_schedule_key_guard, |
22 | isl_schedule_key_leaf, |
23 | isl_schedule_key_mark, |
24 | isl_schedule_key_options, |
25 | isl_schedule_key_permutable, |
26 | isl_schedule_key_schedule, |
27 | isl_schedule_key_sequence, |
28 | isl_schedule_key_set, |
29 | isl_schedule_key_end |
30 | }; |
31 | |
32 | /* Textual representations of the YAML keys for an isl_schedule object. |
33 | */ |
34 | static char *key_str[] = { |
35 | [isl_schedule_key_child] = "child" , |
36 | [isl_schedule_key_coincident] = "coincident" , |
37 | [isl_schedule_key_context] = "context" , |
38 | [isl_schedule_key_contraction] = "contraction" , |
39 | [isl_schedule_key_domain] = "domain" , |
40 | [isl_schedule_key_expansion] = "expansion" , |
41 | [isl_schedule_key_extension] = "extension" , |
42 | [isl_schedule_key_filter] = "filter" , |
43 | [isl_schedule_key_guard] = "guard" , |
44 | [isl_schedule_key_leaf] = "leaf" , |
45 | [isl_schedule_key_mark] = "mark" , |
46 | [isl_schedule_key_options] = "options" , |
47 | [isl_schedule_key_permutable] = "permutable" , |
48 | [isl_schedule_key_schedule] = "schedule" , |
49 | [isl_schedule_key_sequence] = "sequence" , |
50 | [isl_schedule_key_set] = "set" , |
51 | }; |
52 | |
53 | #undef KEY |
54 | #define KEY enum isl_schedule_key |
55 | #undef KEY_ERROR |
56 | #define KEY_ERROR isl_schedule_key_error |
57 | #undef KEY_END |
58 | #define KEY_END isl_schedule_key_end |
59 | #undef KEY_STR |
60 | #define KEY_STR key_str |
61 | #undef KEY_EXTRACT |
62 | #define extract_key |
63 | #undef KEY_GET |
64 | #define KEY_GET get_key |
65 | #include "extract_key.c" |
66 | |
67 | static __isl_give isl_schedule_tree *isl_stream_read_schedule_tree( |
68 | __isl_keep isl_stream *s); |
69 | |
70 | /* Read a subtree with context root node from "s". |
71 | */ |
72 | static __isl_give isl_schedule_tree *read_context(__isl_keep isl_stream *s) |
73 | { |
74 | isl_set *context = NULL; |
75 | isl_schedule_tree *tree; |
76 | isl_ctx *ctx; |
77 | struct isl_token *tok; |
78 | enum isl_schedule_key key; |
79 | char *str; |
80 | isl_bool more; |
81 | |
82 | ctx = isl_stream_get_ctx(s); |
83 | |
84 | key = get_key(s); |
85 | |
86 | if (isl_stream_yaml_next(s) < 0) |
87 | return NULL; |
88 | |
89 | tok = isl_stream_next_token(s); |
90 | if (!tok) { |
91 | isl_stream_error(s, NULL, msg: "unexpected EOF" ); |
92 | return NULL; |
93 | } |
94 | str = isl_token_get_str(ctx, tok); |
95 | context = isl_set_read_from_str(ctx, str); |
96 | free(ptr: str); |
97 | isl_token_free(tok); |
98 | |
99 | more = isl_stream_yaml_next(s); |
100 | if (more < 0) |
101 | goto error; |
102 | if (!more) { |
103 | tree = isl_schedule_tree_from_context(context); |
104 | } else { |
105 | key = get_key(s); |
106 | if (key != isl_schedule_key_child) |
107 | isl_die(ctx, isl_error_invalid, "expecting child" , |
108 | goto error); |
109 | if (isl_stream_yaml_next(s) < 0) |
110 | goto error; |
111 | tree = isl_stream_read_schedule_tree(s); |
112 | tree = isl_schedule_tree_insert_context(tree, context); |
113 | } |
114 | |
115 | return tree; |
116 | error: |
117 | isl_set_free(set: context); |
118 | return NULL; |
119 | } |
120 | |
121 | /* Read a subtree with domain root node from "s". |
122 | */ |
123 | static __isl_give isl_schedule_tree *read_domain(__isl_keep isl_stream *s) |
124 | { |
125 | isl_union_set *domain = NULL; |
126 | isl_schedule_tree *tree; |
127 | isl_ctx *ctx; |
128 | struct isl_token *tok; |
129 | enum isl_schedule_key key; |
130 | char *str; |
131 | isl_bool more; |
132 | |
133 | ctx = isl_stream_get_ctx(s); |
134 | |
135 | key = get_key(s); |
136 | |
137 | if (isl_stream_yaml_next(s) < 0) |
138 | return NULL; |
139 | |
140 | tok = isl_stream_next_token(s); |
141 | if (!tok) { |
142 | isl_stream_error(s, NULL, msg: "unexpected EOF" ); |
143 | return NULL; |
144 | } |
145 | str = isl_token_get_str(ctx, tok); |
146 | domain = isl_union_set_read_from_str(ctx, str); |
147 | free(ptr: str); |
148 | isl_token_free(tok); |
149 | |
150 | more = isl_stream_yaml_next(s); |
151 | if (more < 0) |
152 | goto error; |
153 | if (!more) { |
154 | tree = isl_schedule_tree_from_domain(domain); |
155 | } else { |
156 | key = get_key(s); |
157 | if (key != isl_schedule_key_child) |
158 | isl_die(ctx, isl_error_invalid, "expecting child" , |
159 | goto error); |
160 | if (isl_stream_yaml_next(s) < 0) |
161 | goto error; |
162 | tree = isl_stream_read_schedule_tree(s); |
163 | tree = isl_schedule_tree_insert_domain(tree, domain); |
164 | } |
165 | |
166 | return tree; |
167 | error: |
168 | isl_union_set_free(uset: domain); |
169 | return NULL; |
170 | } |
171 | |
172 | /* Read a subtree with expansion root node from "s". |
173 | */ |
174 | static __isl_give isl_schedule_tree *read_expansion(isl_stream *s) |
175 | { |
176 | isl_ctx *ctx; |
177 | isl_union_pw_multi_aff *contraction = NULL; |
178 | isl_union_map *expansion = NULL; |
179 | isl_schedule_tree *tree = NULL; |
180 | isl_bool more; |
181 | |
182 | ctx = isl_stream_get_ctx(s); |
183 | |
184 | do { |
185 | struct isl_token *tok; |
186 | enum isl_schedule_key key; |
187 | char *str; |
188 | |
189 | key = get_key(s); |
190 | if (isl_stream_yaml_next(s) < 0) |
191 | goto error; |
192 | |
193 | switch (key) { |
194 | case isl_schedule_key_contraction: |
195 | isl_union_pw_multi_aff_free(upma: contraction); |
196 | tok = isl_stream_next_token(s); |
197 | str = isl_token_get_str(ctx, tok); |
198 | contraction = isl_union_pw_multi_aff_read_from_str(ctx, |
199 | str); |
200 | free(ptr: str); |
201 | isl_token_free(tok); |
202 | if (!contraction) |
203 | goto error; |
204 | break; |
205 | case isl_schedule_key_expansion: |
206 | isl_union_map_free(umap: expansion); |
207 | tok = isl_stream_next_token(s); |
208 | str = isl_token_get_str(ctx, tok); |
209 | expansion = isl_union_map_read_from_str(ctx, str); |
210 | free(ptr: str); |
211 | isl_token_free(tok); |
212 | if (!expansion) |
213 | goto error; |
214 | break; |
215 | case isl_schedule_key_child: |
216 | isl_schedule_tree_free(tree); |
217 | tree = isl_stream_read_schedule_tree(s); |
218 | if (!tree) |
219 | goto error; |
220 | break; |
221 | default: |
222 | isl_die(ctx, isl_error_invalid, "unexpected key" , |
223 | goto error); |
224 | } |
225 | } while ((more = isl_stream_yaml_next(s)) == isl_bool_true); |
226 | |
227 | if (more < 0) |
228 | goto error; |
229 | |
230 | if (!contraction) |
231 | isl_die(ctx, isl_error_invalid, "missing contraction" , |
232 | goto error); |
233 | if (!expansion) |
234 | isl_die(ctx, isl_error_invalid, "missing expansion" , |
235 | goto error); |
236 | |
237 | if (!tree) |
238 | return isl_schedule_tree_from_expansion(contraction, expansion); |
239 | return isl_schedule_tree_insert_expansion(tree, contraction, expansion); |
240 | error: |
241 | isl_schedule_tree_free(tree); |
242 | isl_union_pw_multi_aff_free(upma: contraction); |
243 | isl_union_map_free(umap: expansion); |
244 | return NULL; |
245 | } |
246 | |
247 | /* Read a subtree with extension root node from "s". |
248 | */ |
249 | static __isl_give isl_schedule_tree *read_extension(isl_stream *s) |
250 | { |
251 | isl_union_map *extension = NULL; |
252 | isl_schedule_tree *tree; |
253 | isl_ctx *ctx; |
254 | struct isl_token *tok; |
255 | enum isl_schedule_key key; |
256 | char *str; |
257 | isl_bool more; |
258 | |
259 | ctx = isl_stream_get_ctx(s); |
260 | |
261 | key = get_key(s); |
262 | |
263 | if (isl_stream_yaml_next(s) < 0) |
264 | return NULL; |
265 | |
266 | tok = isl_stream_next_token(s); |
267 | if (!tok) { |
268 | isl_stream_error(s, NULL, msg: "unexpected EOF" ); |
269 | return NULL; |
270 | } |
271 | str = isl_token_get_str(ctx, tok); |
272 | extension = isl_union_map_read_from_str(ctx, str); |
273 | free(ptr: str); |
274 | isl_token_free(tok); |
275 | |
276 | more = isl_stream_yaml_next(s); |
277 | if (more < 0) |
278 | goto error; |
279 | if (!more) { |
280 | tree = isl_schedule_tree_from_extension(extension); |
281 | } else { |
282 | key = get_key(s); |
283 | if (key != isl_schedule_key_child) |
284 | isl_die(ctx, isl_error_invalid, "expecting child" , |
285 | goto error); |
286 | if (isl_stream_yaml_next(s) < 0) |
287 | goto error; |
288 | tree = isl_stream_read_schedule_tree(s); |
289 | tree = isl_schedule_tree_insert_extension(tree, extension); |
290 | } |
291 | |
292 | return tree; |
293 | error: |
294 | isl_union_map_free(umap: extension); |
295 | return NULL; |
296 | } |
297 | |
298 | /* Read a subtree with filter root node from "s". |
299 | */ |
300 | static __isl_give isl_schedule_tree *read_filter(__isl_keep isl_stream *s) |
301 | { |
302 | isl_union_set *filter = NULL; |
303 | isl_schedule_tree *tree; |
304 | isl_ctx *ctx; |
305 | struct isl_token *tok; |
306 | enum isl_schedule_key key; |
307 | char *str; |
308 | isl_bool more; |
309 | |
310 | ctx = isl_stream_get_ctx(s); |
311 | |
312 | key = get_key(s); |
313 | |
314 | if (isl_stream_yaml_next(s) < 0) |
315 | return NULL; |
316 | |
317 | tok = isl_stream_next_token(s); |
318 | if (!tok) { |
319 | isl_stream_error(s, NULL, msg: "unexpected EOF" ); |
320 | return NULL; |
321 | } |
322 | str = isl_token_get_str(ctx, tok); |
323 | filter = isl_union_set_read_from_str(ctx, str); |
324 | free(ptr: str); |
325 | isl_token_free(tok); |
326 | |
327 | more = isl_stream_yaml_next(s); |
328 | if (more < 0) |
329 | goto error; |
330 | if (!more) { |
331 | tree = isl_schedule_tree_from_filter(filter); |
332 | } else { |
333 | key = get_key(s); |
334 | if (key != isl_schedule_key_child) |
335 | isl_die(ctx, isl_error_invalid, "expecting child" , |
336 | goto error); |
337 | if (isl_stream_yaml_next(s) < 0) |
338 | goto error; |
339 | tree = isl_stream_read_schedule_tree(s); |
340 | tree = isl_schedule_tree_insert_filter(tree, filter); |
341 | } |
342 | |
343 | return tree; |
344 | error: |
345 | isl_union_set_free(uset: filter); |
346 | return NULL; |
347 | } |
348 | |
349 | /* Read a subtree with guard root node from "s". |
350 | */ |
351 | static __isl_give isl_schedule_tree *read_guard(isl_stream *s) |
352 | { |
353 | isl_set *guard = NULL; |
354 | isl_schedule_tree *tree; |
355 | isl_ctx *ctx; |
356 | struct isl_token *tok; |
357 | enum isl_schedule_key key; |
358 | char *str; |
359 | isl_bool more; |
360 | |
361 | ctx = isl_stream_get_ctx(s); |
362 | |
363 | key = get_key(s); |
364 | |
365 | if (isl_stream_yaml_next(s) < 0) |
366 | return NULL; |
367 | |
368 | tok = isl_stream_next_token(s); |
369 | if (!tok) { |
370 | isl_stream_error(s, NULL, msg: "unexpected EOF" ); |
371 | return NULL; |
372 | } |
373 | str = isl_token_get_str(ctx, tok); |
374 | guard = isl_set_read_from_str(ctx, str); |
375 | free(ptr: str); |
376 | isl_token_free(tok); |
377 | |
378 | more = isl_stream_yaml_next(s); |
379 | if (more < 0) |
380 | goto error; |
381 | if (!more) { |
382 | tree = isl_schedule_tree_from_guard(guard); |
383 | } else { |
384 | key = get_key(s); |
385 | if (key != isl_schedule_key_child) |
386 | isl_die(ctx, isl_error_invalid, "expecting child" , |
387 | goto error); |
388 | if (isl_stream_yaml_next(s) < 0) |
389 | goto error; |
390 | tree = isl_stream_read_schedule_tree(s); |
391 | tree = isl_schedule_tree_insert_guard(tree, guard); |
392 | } |
393 | |
394 | return tree; |
395 | error: |
396 | isl_set_free(set: guard); |
397 | return NULL; |
398 | } |
399 | |
400 | /* Read a subtree with mark root node from "s". |
401 | */ |
402 | static __isl_give isl_schedule_tree *read_mark(isl_stream *s) |
403 | { |
404 | isl_id *mark; |
405 | isl_schedule_tree *tree; |
406 | isl_ctx *ctx; |
407 | struct isl_token *tok; |
408 | enum isl_schedule_key key; |
409 | char *str; |
410 | isl_bool more; |
411 | |
412 | ctx = isl_stream_get_ctx(s); |
413 | |
414 | key = get_key(s); |
415 | |
416 | if (isl_stream_yaml_next(s) < 0) |
417 | return NULL; |
418 | |
419 | tok = isl_stream_next_token(s); |
420 | if (!tok) { |
421 | isl_stream_error(s, NULL, msg: "unexpected EOF" ); |
422 | return NULL; |
423 | } |
424 | str = isl_token_get_str(ctx, tok); |
425 | mark = isl_id_alloc(ctx, name: str, NULL); |
426 | free(ptr: str); |
427 | isl_token_free(tok); |
428 | |
429 | more = isl_stream_yaml_next(s); |
430 | if (more < 0) |
431 | goto error; |
432 | if (!more) { |
433 | isl_die(ctx, isl_error_invalid, "expecting child" , |
434 | goto error); |
435 | } else { |
436 | key = get_key(s); |
437 | if (key != isl_schedule_key_child) |
438 | isl_die(ctx, isl_error_invalid, "expecting child" , |
439 | goto error); |
440 | if (isl_stream_yaml_next(s) < 0) |
441 | goto error; |
442 | tree = isl_stream_read_schedule_tree(s); |
443 | tree = isl_schedule_tree_insert_mark(tree, mark); |
444 | } |
445 | |
446 | return tree; |
447 | error: |
448 | isl_id_free(id: mark); |
449 | return NULL; |
450 | } |
451 | |
452 | #undef EL_BASE |
453 | #define EL_BASE val |
454 | |
455 | #include <isl_list_read_yaml_templ.c> |
456 | |
457 | /* Read a sequence of integers from "s" (representing the coincident |
458 | * property of a band node). |
459 | */ |
460 | static __isl_give isl_val_list *read_coincident(__isl_keep isl_stream *s) |
461 | { |
462 | return isl_stream_yaml_read_val_list(s); |
463 | } |
464 | |
465 | /* Set the (initial) coincident properties of "band" according to |
466 | * the (initial) elements of "coincident". |
467 | */ |
468 | static __isl_give isl_schedule_band *set_coincident( |
469 | __isl_take isl_schedule_band *band, __isl_take isl_val_list *coincident) |
470 | { |
471 | int i; |
472 | isl_size n, m; |
473 | |
474 | n = isl_schedule_band_n_member(band); |
475 | m = isl_val_list_n_val(list: coincident); |
476 | if (n < 0 || m < 0) |
477 | band = isl_schedule_band_free(band); |
478 | |
479 | for (i = 0; i < n && i < m; ++i) { |
480 | isl_val *v; |
481 | |
482 | v = isl_val_list_get_val(list: coincident, index: i); |
483 | if (!v) |
484 | band = isl_schedule_band_free(band); |
485 | band = isl_schedule_band_member_set_coincident(band, pos: i, |
486 | coincident: !isl_val_is_zero(v)); |
487 | isl_val_free(v); |
488 | } |
489 | isl_val_list_free(list: coincident); |
490 | return band; |
491 | } |
492 | |
493 | /* Read a subtree with band root node from "s". |
494 | */ |
495 | static __isl_give isl_schedule_tree *read_band(isl_stream *s) |
496 | { |
497 | isl_multi_union_pw_aff *schedule = NULL; |
498 | isl_schedule_tree *tree = NULL; |
499 | isl_val_list *coincident = NULL; |
500 | isl_union_set *options = NULL; |
501 | isl_ctx *ctx; |
502 | isl_schedule_band *band; |
503 | int permutable = 0; |
504 | isl_bool more; |
505 | |
506 | ctx = isl_stream_get_ctx(s); |
507 | |
508 | do { |
509 | struct isl_token *tok; |
510 | enum isl_schedule_key key; |
511 | char *str; |
512 | isl_val *v; |
513 | |
514 | key = get_key(s); |
515 | if (isl_stream_yaml_next(s) < 0) |
516 | goto error; |
517 | |
518 | switch (key) { |
519 | case isl_schedule_key_schedule: |
520 | schedule = isl_multi_union_pw_aff_free(multi: schedule); |
521 | tok = isl_stream_next_token(s); |
522 | if (!tok) { |
523 | isl_stream_error(s, NULL, msg: "unexpected EOF" ); |
524 | goto error; |
525 | } |
526 | str = isl_token_get_str(ctx, tok); |
527 | schedule = isl_multi_union_pw_aff_read_from_str(ctx, |
528 | str); |
529 | free(ptr: str); |
530 | isl_token_free(tok); |
531 | if (!schedule) |
532 | goto error; |
533 | break; |
534 | case isl_schedule_key_coincident: |
535 | coincident = read_coincident(s); |
536 | if (!coincident) |
537 | goto error; |
538 | break; |
539 | case isl_schedule_key_permutable: |
540 | v = isl_stream_read_val(s); |
541 | permutable = !isl_val_is_zero(v); |
542 | isl_val_free(v); |
543 | break; |
544 | case isl_schedule_key_options: |
545 | isl_union_set_free(uset: options); |
546 | tok = isl_stream_next_token(s); |
547 | str = isl_token_get_str(ctx, tok); |
548 | options = isl_union_set_read_from_str(ctx, str); |
549 | free(ptr: str); |
550 | isl_token_free(tok); |
551 | if (!options) |
552 | goto error; |
553 | break; |
554 | case isl_schedule_key_child: |
555 | isl_schedule_tree_free(tree); |
556 | tree = isl_stream_read_schedule_tree(s); |
557 | if (!tree) |
558 | goto error; |
559 | break; |
560 | default: |
561 | isl_die(ctx, isl_error_invalid, "unexpected key" , |
562 | goto error); |
563 | } |
564 | } while ((more = isl_stream_yaml_next(s)) == isl_bool_true); |
565 | |
566 | if (more < 0) |
567 | goto error; |
568 | |
569 | if (!schedule) |
570 | isl_die(ctx, isl_error_invalid, "missing schedule" , goto error); |
571 | |
572 | band = isl_schedule_band_from_multi_union_pw_aff(mupa: schedule); |
573 | band = isl_schedule_band_set_permutable(band, permutable); |
574 | if (coincident) |
575 | band = set_coincident(band, coincident); |
576 | if (options) |
577 | band = isl_schedule_band_set_ast_build_options(band, options); |
578 | if (tree) |
579 | tree = isl_schedule_tree_insert_band(tree, band); |
580 | else |
581 | tree = isl_schedule_tree_from_band(band); |
582 | |
583 | return tree; |
584 | error: |
585 | isl_val_list_free(list: coincident); |
586 | isl_union_set_free(uset: options); |
587 | isl_schedule_tree_free(tree); |
588 | isl_multi_union_pw_aff_free(multi: schedule); |
589 | return NULL; |
590 | } |
591 | |
592 | #undef EL_BASE |
593 | #define EL_BASE schedule_tree |
594 | |
595 | #include <isl_list_read_yaml_templ.c> |
596 | |
597 | /* Read a subtree with root node of type "type" from "s". |
598 | * The node is represented by a sequence of children. |
599 | */ |
600 | static __isl_give isl_schedule_tree *read_children(isl_stream *s, |
601 | enum isl_schedule_node_type type) |
602 | { |
603 | isl_schedule_tree_list *list; |
604 | |
605 | isl_token_free(tok: isl_stream_next_token(s)); |
606 | |
607 | if (isl_stream_yaml_next(s) < 0) |
608 | return NULL; |
609 | |
610 | list = isl_stream_yaml_read_schedule_tree_list(s); |
611 | |
612 | return isl_schedule_tree_from_children(type, list); |
613 | } |
614 | |
615 | /* Read a subtree with sequence root node from "s". |
616 | */ |
617 | static __isl_give isl_schedule_tree *read_sequence(isl_stream *s) |
618 | { |
619 | return read_children(s, type: isl_schedule_node_sequence); |
620 | } |
621 | |
622 | /* Read a subtree with set root node from "s". |
623 | */ |
624 | static __isl_give isl_schedule_tree *read_set(isl_stream *s) |
625 | { |
626 | return read_children(s, type: isl_schedule_node_set); |
627 | } |
628 | |
629 | /* Read a schedule (sub)tree from "s". |
630 | * |
631 | * We first determine the type of the root node based on the first |
632 | * mapping key and then hand over to a function tailored to reading |
633 | * nodes of this type. |
634 | */ |
635 | static __isl_give isl_schedule_tree *isl_stream_read_schedule_tree( |
636 | struct isl_stream *s) |
637 | { |
638 | enum isl_schedule_key key; |
639 | struct isl_token *tok; |
640 | isl_schedule_tree *tree = NULL; |
641 | isl_bool more; |
642 | |
643 | if (isl_stream_yaml_read_start_mapping(s) < 0) |
644 | return NULL; |
645 | more = isl_stream_yaml_next(s); |
646 | if (more < 0) |
647 | return NULL; |
648 | if (!more) { |
649 | isl_stream_error(s, NULL, msg: "missing key" ); |
650 | return NULL; |
651 | } |
652 | |
653 | tok = isl_stream_next_token(s); |
654 | key = extract_key(s, tok); |
655 | isl_stream_push_token(s, tok); |
656 | if (key < 0) |
657 | return NULL; |
658 | switch (key) { |
659 | case isl_schedule_key_context: |
660 | tree = read_context(s); |
661 | break; |
662 | case isl_schedule_key_domain: |
663 | tree = read_domain(s); |
664 | break; |
665 | case isl_schedule_key_contraction: |
666 | case isl_schedule_key_expansion: |
667 | tree = read_expansion(s); |
668 | break; |
669 | case isl_schedule_key_extension: |
670 | tree = read_extension(s); |
671 | break; |
672 | case isl_schedule_key_filter: |
673 | tree = read_filter(s); |
674 | break; |
675 | case isl_schedule_key_guard: |
676 | tree = read_guard(s); |
677 | break; |
678 | case isl_schedule_key_leaf: |
679 | isl_token_free(tok: isl_stream_next_token(s)); |
680 | tree = isl_schedule_tree_leaf(ctx: isl_stream_get_ctx(s)); |
681 | break; |
682 | case isl_schedule_key_mark: |
683 | tree = read_mark(s); |
684 | break; |
685 | case isl_schedule_key_sequence: |
686 | tree = read_sequence(s); |
687 | break; |
688 | case isl_schedule_key_set: |
689 | tree = read_set(s); |
690 | break; |
691 | case isl_schedule_key_schedule: |
692 | case isl_schedule_key_coincident: |
693 | case isl_schedule_key_options: |
694 | case isl_schedule_key_permutable: |
695 | tree = read_band(s); |
696 | break; |
697 | case isl_schedule_key_child: |
698 | isl_die(isl_stream_get_ctx(s), isl_error_unsupported, |
699 | "cannot identify node type" , return NULL); |
700 | case isl_schedule_key_end: |
701 | case isl_schedule_key_error: |
702 | return NULL; |
703 | } |
704 | |
705 | if (isl_stream_yaml_read_end_mapping(s) < 0) |
706 | return isl_schedule_tree_free(tree); |
707 | |
708 | return tree; |
709 | } |
710 | |
711 | /* Read an isl_schedule from "s". |
712 | */ |
713 | __isl_give isl_schedule *isl_stream_read_schedule(isl_stream *s) |
714 | { |
715 | isl_ctx *ctx; |
716 | isl_schedule_tree *tree; |
717 | |
718 | if (!s) |
719 | return NULL; |
720 | |
721 | ctx = isl_stream_get_ctx(s); |
722 | tree = isl_stream_read_schedule_tree(s); |
723 | return isl_schedule_from_schedule_tree(ctx, tree); |
724 | } |
725 | |
726 | /* Read an isl_schedule from "input". |
727 | */ |
728 | __isl_give isl_schedule *isl_schedule_read_from_file(isl_ctx *ctx, FILE *input) |
729 | { |
730 | struct isl_stream *s; |
731 | isl_schedule *schedule; |
732 | |
733 | s = isl_stream_new_file(ctx, file: input); |
734 | if (!s) |
735 | return NULL; |
736 | schedule = isl_stream_read_schedule(s); |
737 | isl_stream_free(s); |
738 | |
739 | return schedule; |
740 | } |
741 | |
742 | #undef TYPE_BASE |
743 | #define TYPE_BASE schedule |
744 | #include "isl_read_from_str_templ.c" |
745 | |