3 #include <isl/schedule.h>
4 #include <isl/stream.h>
5 #include <isl_schedule_private.h>
6 #include <isl_schedule_tree.h>
8 /* An enumeration of the various keys that may appear in a YAML mapping
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
,
32 /* Textual representations of the YAML keys for an isl_schedule object.
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",
54 #define KEY enum isl_schedule_key
56 #define KEY_ERROR isl_schedule_key_error
58 #define KEY_END isl_schedule_key_end
60 #define KEY_STR key_str
62 #define KEY_EXTRACT extract_key
64 #define KEY_GET get_key
65 #include "extract_key.c"
67 static __isl_give isl_schedule_tree
*isl_stream_read_schedule_tree(
68 __isl_keep isl_stream
*s
);
70 /* Read a subtree with context root node from "s".
72 static __isl_give isl_schedule_tree
*read_context(__isl_keep isl_stream
*s
)
74 isl_set
*context
= NULL
;
75 isl_schedule_tree
*tree
;
77 struct isl_token
*tok
;
78 enum isl_schedule_key key
;
82 ctx
= isl_stream_get_ctx(s
);
86 if (isl_stream_yaml_next(s
) < 0)
89 tok
= isl_stream_next_token(s
);
91 isl_stream_error(s
, NULL
, "unexpected EOF");
94 str
= isl_token_get_str(ctx
, tok
);
95 context
= isl_set_read_from_str(ctx
, str
);
99 more
= isl_stream_yaml_next(s
);
103 tree
= isl_schedule_tree_from_context(context
);
106 if (key
!= isl_schedule_key_child
)
107 isl_die(ctx
, isl_error_invalid
, "expecting child",
109 if (isl_stream_yaml_next(s
) < 0)
111 tree
= isl_stream_read_schedule_tree(s
);
112 tree
= isl_schedule_tree_insert_context(tree
, context
);
117 isl_set_free(context
);
121 /* Read a subtree with domain root node from "s".
123 static __isl_give isl_schedule_tree
*read_domain(__isl_keep isl_stream
*s
)
125 isl_union_set
*domain
= NULL
;
126 isl_schedule_tree
*tree
;
128 struct isl_token
*tok
;
129 enum isl_schedule_key key
;
133 ctx
= isl_stream_get_ctx(s
);
137 if (isl_stream_yaml_next(s
) < 0)
140 tok
= isl_stream_next_token(s
);
142 isl_stream_error(s
, NULL
, "unexpected EOF");
145 str
= isl_token_get_str(ctx
, tok
);
146 domain
= isl_union_set_read_from_str(ctx
, str
);
150 more
= isl_stream_yaml_next(s
);
154 tree
= isl_schedule_tree_from_domain(domain
);
157 if (key
!= isl_schedule_key_child
)
158 isl_die(ctx
, isl_error_invalid
, "expecting child",
160 if (isl_stream_yaml_next(s
) < 0)
162 tree
= isl_stream_read_schedule_tree(s
);
163 tree
= isl_schedule_tree_insert_domain(tree
, domain
);
168 isl_union_set_free(domain
);
172 /* Read a subtree with expansion root node from "s".
174 static __isl_give isl_schedule_tree
*read_expansion(isl_stream
*s
)
177 isl_union_pw_multi_aff
*contraction
= NULL
;
178 isl_union_map
*expansion
= NULL
;
179 isl_schedule_tree
*tree
= NULL
;
182 ctx
= isl_stream_get_ctx(s
);
185 struct isl_token
*tok
;
186 enum isl_schedule_key key
;
190 if (isl_stream_yaml_next(s
) < 0)
194 case isl_schedule_key_contraction
:
195 isl_union_pw_multi_aff_free(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
,
205 case isl_schedule_key_expansion
:
206 isl_union_map_free(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
);
215 case isl_schedule_key_child
:
216 isl_schedule_tree_free(tree
);
217 tree
= isl_stream_read_schedule_tree(s
);
222 isl_die(ctx
, isl_error_invalid
, "unexpected key",
225 } while ((more
= isl_stream_yaml_next(s
)) == isl_bool_true
);
231 isl_die(ctx
, isl_error_invalid
, "missing contraction",
234 isl_die(ctx
, isl_error_invalid
, "missing expansion",
238 return isl_schedule_tree_from_expansion(contraction
, expansion
);
239 return isl_schedule_tree_insert_expansion(tree
, contraction
, expansion
);
241 isl_schedule_tree_free(tree
);
242 isl_union_pw_multi_aff_free(contraction
);
243 isl_union_map_free(expansion
);
247 /* Read a subtree with extension root node from "s".
249 static __isl_give isl_schedule_tree
*read_extension(isl_stream
*s
)
251 isl_union_map
*extension
= NULL
;
252 isl_schedule_tree
*tree
;
254 struct isl_token
*tok
;
255 enum isl_schedule_key key
;
259 ctx
= isl_stream_get_ctx(s
);
263 if (isl_stream_yaml_next(s
) < 0)
266 tok
= isl_stream_next_token(s
);
268 isl_stream_error(s
, NULL
, "unexpected EOF");
271 str
= isl_token_get_str(ctx
, tok
);
272 extension
= isl_union_map_read_from_str(ctx
, str
);
276 more
= isl_stream_yaml_next(s
);
280 tree
= isl_schedule_tree_from_extension(extension
);
283 if (key
!= isl_schedule_key_child
)
284 isl_die(ctx
, isl_error_invalid
, "expecting child",
286 if (isl_stream_yaml_next(s
) < 0)
288 tree
= isl_stream_read_schedule_tree(s
);
289 tree
= isl_schedule_tree_insert_extension(tree
, extension
);
294 isl_union_map_free(extension
);
298 /* Read a subtree with filter root node from "s".
300 static __isl_give isl_schedule_tree
*read_filter(__isl_keep isl_stream
*s
)
302 isl_union_set
*filter
= NULL
;
303 isl_schedule_tree
*tree
;
305 struct isl_token
*tok
;
306 enum isl_schedule_key key
;
310 ctx
= isl_stream_get_ctx(s
);
314 if (isl_stream_yaml_next(s
) < 0)
317 tok
= isl_stream_next_token(s
);
319 isl_stream_error(s
, NULL
, "unexpected EOF");
322 str
= isl_token_get_str(ctx
, tok
);
323 filter
= isl_union_set_read_from_str(ctx
, str
);
327 more
= isl_stream_yaml_next(s
);
331 tree
= isl_schedule_tree_from_filter(filter
);
334 if (key
!= isl_schedule_key_child
)
335 isl_die(ctx
, isl_error_invalid
, "expecting child",
337 if (isl_stream_yaml_next(s
) < 0)
339 tree
= isl_stream_read_schedule_tree(s
);
340 tree
= isl_schedule_tree_insert_filter(tree
, filter
);
345 isl_union_set_free(filter
);
349 /* Read a subtree with guard root node from "s".
351 static __isl_give isl_schedule_tree
*read_guard(isl_stream
*s
)
353 isl_set
*guard
= NULL
;
354 isl_schedule_tree
*tree
;
356 struct isl_token
*tok
;
357 enum isl_schedule_key key
;
361 ctx
= isl_stream_get_ctx(s
);
365 if (isl_stream_yaml_next(s
) < 0)
368 tok
= isl_stream_next_token(s
);
370 isl_stream_error(s
, NULL
, "unexpected EOF");
373 str
= isl_token_get_str(ctx
, tok
);
374 guard
= isl_set_read_from_str(ctx
, str
);
378 more
= isl_stream_yaml_next(s
);
382 tree
= isl_schedule_tree_from_guard(guard
);
385 if (key
!= isl_schedule_key_child
)
386 isl_die(ctx
, isl_error_invalid
, "expecting child",
388 if (isl_stream_yaml_next(s
) < 0)
390 tree
= isl_stream_read_schedule_tree(s
);
391 tree
= isl_schedule_tree_insert_guard(tree
, guard
);
400 /* Read a subtree with mark root node from "s".
402 static __isl_give isl_schedule_tree
*read_mark(isl_stream
*s
)
405 isl_schedule_tree
*tree
;
407 struct isl_token
*tok
;
408 enum isl_schedule_key key
;
412 ctx
= isl_stream_get_ctx(s
);
416 if (isl_stream_yaml_next(s
) < 0)
419 tok
= isl_stream_next_token(s
);
421 isl_stream_error(s
, NULL
, "unexpected EOF");
424 str
= isl_token_get_str(ctx
, tok
);
425 mark
= isl_id_alloc(ctx
, str
, NULL
);
429 more
= isl_stream_yaml_next(s
);
433 isl_die(ctx
, isl_error_invalid
, "expecting child",
437 if (key
!= isl_schedule_key_child
)
438 isl_die(ctx
, isl_error_invalid
, "expecting child",
440 if (isl_stream_yaml_next(s
) < 0)
442 tree
= isl_stream_read_schedule_tree(s
);
443 tree
= isl_schedule_tree_insert_mark(tree
, mark
);
455 #include <isl_list_read_yaml_templ.c>
457 /* Read a sequence of integers from "s" (representing the coincident
458 * property of a band node).
460 static __isl_give isl_val_list
*read_coincident(__isl_keep isl_stream
*s
)
462 return isl_stream_yaml_read_val_list(s
);
465 /* Set the (initial) coincident properties of "band" according to
466 * the (initial) elements of "coincident".
468 static __isl_give isl_schedule_band
*set_coincident(
469 __isl_take isl_schedule_band
*band
, __isl_take isl_val_list
*coincident
)
474 n
= isl_schedule_band_n_member(band
);
475 m
= isl_val_list_n_val(coincident
);
477 band
= isl_schedule_band_free(band
);
479 for (i
= 0; i
< n
&& i
< m
; ++i
) {
482 v
= isl_val_list_get_val(coincident
, i
);
484 band
= isl_schedule_band_free(band
);
485 band
= isl_schedule_band_member_set_coincident(band
, i
,
486 !isl_val_is_zero(v
));
489 isl_val_list_free(coincident
);
493 /* Read a subtree with band root node from "s".
495 static __isl_give isl_schedule_tree
*read_band(isl_stream
*s
)
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
;
502 isl_schedule_band
*band
;
506 ctx
= isl_stream_get_ctx(s
);
509 struct isl_token
*tok
;
510 enum isl_schedule_key key
;
515 if (isl_stream_yaml_next(s
) < 0)
519 case isl_schedule_key_schedule
:
520 schedule
= isl_multi_union_pw_aff_free(schedule
);
521 tok
= isl_stream_next_token(s
);
523 isl_stream_error(s
, NULL
, "unexpected EOF");
526 str
= isl_token_get_str(ctx
, tok
);
527 schedule
= isl_multi_union_pw_aff_read_from_str(ctx
,
534 case isl_schedule_key_coincident
:
535 coincident
= read_coincident(s
);
539 case isl_schedule_key_permutable
:
540 v
= isl_stream_read_val(s
);
541 permutable
= !isl_val_is_zero(v
);
544 case isl_schedule_key_options
:
545 isl_union_set_free(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
);
554 case isl_schedule_key_child
:
555 isl_schedule_tree_free(tree
);
556 tree
= isl_stream_read_schedule_tree(s
);
561 isl_die(ctx
, isl_error_invalid
, "unexpected key",
564 } while ((more
= isl_stream_yaml_next(s
)) == isl_bool_true
);
570 isl_die(ctx
, isl_error_invalid
, "missing schedule", goto error
);
572 band
= isl_schedule_band_from_multi_union_pw_aff(schedule
);
573 band
= isl_schedule_band_set_permutable(band
, permutable
);
575 band
= set_coincident(band
, coincident
);
577 band
= isl_schedule_band_set_ast_build_options(band
, options
);
579 tree
= isl_schedule_tree_insert_band(tree
, band
);
581 tree
= isl_schedule_tree_from_band(band
);
585 isl_val_list_free(coincident
);
586 isl_union_set_free(options
);
587 isl_schedule_tree_free(tree
);
588 isl_multi_union_pw_aff_free(schedule
);
593 #define EL_BASE schedule_tree
595 #include <isl_list_read_yaml_templ.c>
597 /* Read a subtree with root node of type "type" from "s".
598 * The node is represented by a sequence of children.
600 static __isl_give isl_schedule_tree
*read_children(isl_stream
*s
,
601 enum isl_schedule_node_type type
)
603 isl_schedule_tree_list
*list
;
605 isl_token_free(isl_stream_next_token(s
));
607 if (isl_stream_yaml_next(s
) < 0)
610 list
= isl_stream_yaml_read_schedule_tree_list(s
);
612 return isl_schedule_tree_from_children(type
, list
);
615 /* Read a subtree with sequence root node from "s".
617 static __isl_give isl_schedule_tree
*read_sequence(isl_stream
*s
)
619 return read_children(s
, isl_schedule_node_sequence
);
622 /* Read a subtree with set root node from "s".
624 static __isl_give isl_schedule_tree
*read_set(isl_stream
*s
)
626 return read_children(s
, isl_schedule_node_set
);
629 /* Read a schedule (sub)tree from "s".
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.
635 static __isl_give isl_schedule_tree
*isl_stream_read_schedule_tree(
636 struct isl_stream
*s
)
638 enum isl_schedule_key key
;
639 struct isl_token
*tok
;
640 isl_schedule_tree
*tree
= NULL
;
643 if (isl_stream_yaml_read_start_mapping(s
) < 0)
645 more
= isl_stream_yaml_next(s
);
649 isl_stream_error(s
, NULL
, "missing key");
653 tok
= isl_stream_next_token(s
);
654 key
= extract_key(s
, tok
);
655 isl_stream_push_token(s
, tok
);
659 case isl_schedule_key_context
:
660 tree
= read_context(s
);
662 case isl_schedule_key_domain
:
663 tree
= read_domain(s
);
665 case isl_schedule_key_contraction
:
666 case isl_schedule_key_expansion
:
667 tree
= read_expansion(s
);
669 case isl_schedule_key_extension
:
670 tree
= read_extension(s
);
672 case isl_schedule_key_filter
:
673 tree
= read_filter(s
);
675 case isl_schedule_key_guard
:
676 tree
= read_guard(s
);
678 case isl_schedule_key_leaf
:
679 isl_token_free(isl_stream_next_token(s
));
680 tree
= isl_schedule_tree_leaf(isl_stream_get_ctx(s
));
682 case isl_schedule_key_mark
:
685 case isl_schedule_key_sequence
:
686 tree
= read_sequence(s
);
688 case isl_schedule_key_set
:
691 case isl_schedule_key_schedule
:
692 case isl_schedule_key_coincident
:
693 case isl_schedule_key_options
:
694 case isl_schedule_key_permutable
:
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
:
705 if (isl_stream_yaml_read_end_mapping(s
) < 0)
706 return isl_schedule_tree_free(tree
);
711 /* Read an isl_schedule from "s".
713 __isl_give isl_schedule
*isl_stream_read_schedule(isl_stream
*s
)
716 isl_schedule_tree
*tree
;
721 ctx
= isl_stream_get_ctx(s
);
722 tree
= isl_stream_read_schedule_tree(s
);
723 return isl_schedule_from_schedule_tree(ctx
, tree
);
726 /* Read an isl_schedule from "input".
728 __isl_give isl_schedule
*isl_schedule_read_from_file(isl_ctx
*ctx
, FILE *input
)
730 struct isl_stream
*s
;
731 isl_schedule
*schedule
;
733 s
= isl_stream_new_file(ctx
, input
);
736 schedule
= isl_stream_read_schedule(s
);
743 #define TYPE_BASE schedule
744 #include "isl_read_from_str_templ.c"