extract out the handling of skip conditions
[pet.git] / emit.c
blob37da99100db216246e55dd928412b15d4a852c2d
1 /*
2 * Copyright 2011 Leiden University. All rights reserved.
3 * Copyright 2013 Ecole Normale Superieure. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY LEIDEN UNIVERSITY ''AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LEIDEN UNIVERSITY OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * The views and conclusions contained in the software and documentation
30 * are those of the authors and should not be interpreted as
31 * representing official policies, either expressed or implied, of
32 * Leiden University.
33 */
35 #include <yaml.h>
37 #include "expr.h"
38 #include "scop.h"
39 #include "scop_yaml.h"
41 static int emit_string(yaml_emitter_t *emitter, const char *str)
43 yaml_event_t event;
45 if (!yaml_scalar_event_initialize(&event, NULL, NULL,
46 (yaml_char_t *) str, strlen(str),
47 1, 1, YAML_PLAIN_SCALAR_STYLE))
48 return -1;
49 if (!yaml_emitter_emit(emitter, &event))
50 return -1;
52 return 0;
55 /* Print the isl_id "id" to "emitter".
57 static int emit_id(yaml_emitter_t *emitter, __isl_keep isl_id *id)
59 return emit_string(emitter, isl_id_get_name(id));
62 /* Print the string "name" and the isl_id "id" to "emitter".
64 static int emit_named_id(yaml_emitter_t *emitter, const char *name,
65 __isl_keep isl_id *id)
67 if (emit_string(emitter, name) < 0)
68 return -1;
69 if (emit_id(emitter, id) < 0)
70 return -1;
71 return 0;
74 static int emit_int(yaml_emitter_t *emitter, int i)
76 char buffer[40];
78 snprintf(buffer, sizeof(buffer), "%d", i);
79 return emit_string(emitter, buffer);
82 static int emit_named_int(yaml_emitter_t *emitter, const char *name, int i)
84 if (emit_string(emitter, name) < 0)
85 return -1;
86 if (emit_int(emitter, i) < 0)
87 return -1;
88 return 0;
91 /* Print the unsigned integer "u" to "emitter".
93 static int emit_unsigned(yaml_emitter_t *emitter, unsigned u)
95 char buffer[40];
97 snprintf(buffer, sizeof(buffer), "%u", u);
98 return emit_string(emitter, buffer);
101 /* Print the string "name" and the unsigned integer "u" to "emitter".
103 static int emit_named_unsigned(yaml_emitter_t *emitter, const char *name,
104 unsigned u)
106 if (emit_string(emitter, name) < 0)
107 return -1;
108 if (emit_int(emitter, u) < 0)
109 return -1;
110 return 0;
113 static int emit_double(yaml_emitter_t *emitter, double d)
115 char buffer[40];
117 snprintf(buffer, sizeof(buffer), "%g", d);
118 return emit_string(emitter, buffer);
121 static int emit_map(yaml_emitter_t *emitter, __isl_keep isl_map *map)
123 isl_ctx *ctx = isl_map_get_ctx(map);
124 isl_printer *p;
125 char *str;
126 int r;
128 p = isl_printer_to_str(ctx);
129 p = isl_printer_print_map(p, map);
130 str = isl_printer_get_str(p);
131 isl_printer_free(p);
132 r = emit_string(emitter, str);
133 free(str);
134 return r;
137 /* Print the isl_val "val" to "emitter".
139 static int emit_val(yaml_emitter_t *emitter, __isl_keep isl_val *val)
141 isl_ctx *ctx = isl_val_get_ctx(val);
142 isl_printer *p;
143 char *str;
144 int r;
146 p = isl_printer_to_str(ctx);
147 p = isl_printer_print_val(p, val);
148 str = isl_printer_get_str(p);
149 isl_printer_free(p);
150 r = emit_string(emitter, str);
151 free(str);
152 return r;
155 /* Print the string "name" and the isl_val "val" to "emitter".
157 static int emit_named_val(yaml_emitter_t *emitter, const char *name,
158 __isl_keep isl_val *val)
160 if (emit_string(emitter, name) < 0)
161 return -1;
162 if (emit_val(emitter, val) < 0)
163 return -1;
164 return 0;
167 static int emit_set(yaml_emitter_t *emitter, __isl_keep isl_set *set)
169 isl_ctx *ctx = isl_set_get_ctx(set);
170 isl_printer *p;
171 char *str;
172 int r;
174 p = isl_printer_to_str(ctx);
175 p = isl_printer_print_set(p, set);
176 str = isl_printer_get_str(p);
177 isl_printer_free(p);
178 r = emit_string(emitter, str);
179 free(str);
180 return r;
183 static int emit_named_set(yaml_emitter_t *emitter, const char *name,
184 __isl_keep isl_set *set)
186 if (emit_string(emitter, name) < 0)
187 return -1;
188 if (emit_set(emitter, set) < 0)
189 return -1;
190 return 0;
193 /* Print the string "name" and the map "map" to "emitter".
195 static int emit_named_map(yaml_emitter_t *emitter, const char *name,
196 __isl_keep isl_map *map)
198 if (emit_string(emitter, name) < 0)
199 return -1;
200 if (emit_map(emitter, map) < 0)
201 return -1;
202 return 0;
205 /* Print the isl_multi_pw_aff "mpa" to "emitter".
207 static int emit_multi_pw_aff(yaml_emitter_t *emitter,
208 __isl_keep isl_multi_pw_aff *mpa)
210 isl_ctx *ctx = isl_multi_pw_aff_get_ctx(mpa);
211 isl_printer *p;
212 char *str;
213 int r;
215 p = isl_printer_to_str(ctx);
216 p = isl_printer_print_multi_pw_aff(p, mpa);
217 str = isl_printer_get_str(p);
218 isl_printer_free(p);
219 r = emit_string(emitter, str);
220 free(str);
221 return r;
224 /* Print the string "name" and the isl_multi_pw_aff "mpa" to "emitter".
226 static int emit_named_multi_pw_aff(yaml_emitter_t *emitter, const char *name,
227 __isl_keep isl_multi_pw_aff *mpa)
229 if (emit_string(emitter, name) < 0)
230 return -1;
231 if (emit_multi_pw_aff(emitter, mpa) < 0)
232 return -1;
233 return 0;
236 /* Print "type" to "emitter".
238 static int emit_type(yaml_emitter_t *emitter, struct pet_type *type)
240 yaml_event_t event;
242 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
243 YAML_BLOCK_MAPPING_STYLE))
244 return -1;
245 if (!yaml_emitter_emit(emitter, &event))
246 return -1;
248 if (emit_string(emitter, "name") < 0)
249 return -1;
250 if (emit_string(emitter, type->name) < 0)
251 return -1;
253 if (emit_string(emitter, "definition") < 0)
254 return -1;
255 if (emit_string(emitter, type->definition) < 0)
256 return -1;
258 if (!yaml_mapping_end_event_initialize(&event))
259 return -1;
260 if (!yaml_emitter_emit(emitter, &event))
261 return -1;
263 return 0;
266 /* Print the list of "n_type" "types", if any, to "emitter".
268 static int emit_types(yaml_emitter_t *emitter, int n_type,
269 struct pet_type **types)
271 int i;
272 yaml_event_t event;
274 if (n_type == 0)
275 return 0;
277 if (emit_string(emitter, "types") < 0)
278 return -1;
279 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
280 YAML_BLOCK_SEQUENCE_STYLE))
281 return -1;
282 if (!yaml_emitter_emit(emitter, &event))
283 return -1;
285 for (i = 0; i < n_type; ++i)
286 if (emit_type(emitter, types[i]) < 0)
287 return -1;
289 if (!yaml_sequence_end_event_initialize(&event))
290 return -1;
291 if (!yaml_emitter_emit(emitter, &event))
292 return -1;
294 return 0;
297 static int emit_array(yaml_emitter_t *emitter, struct pet_array *array)
299 yaml_event_t event;
301 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
302 YAML_BLOCK_MAPPING_STYLE))
303 return -1;
304 if (!yaml_emitter_emit(emitter, &event))
305 return -1;
307 if (emit_string(emitter, "context") < 0)
308 return -1;
309 if (emit_set(emitter, array->context) < 0)
310 return -1;
312 if (emit_string(emitter, "extent") < 0)
313 return -1;
314 if (emit_set(emitter, array->extent) < 0)
315 return -1;
317 if (array->value_bounds) {
318 if (emit_string(emitter, "value_bounds") < 0)
319 return -1;
320 if (emit_set(emitter, array->value_bounds) < 0)
321 return -1;
324 if (emit_string(emitter, "element_type") < 0)
325 return -1;
326 if (emit_string(emitter, array->element_type) < 0)
327 return -1;
328 if (emit_named_int(emitter, "element_size", array->element_size) < 0)
329 return -1;
331 if (array->element_is_record)
332 if (emit_named_int(emitter, "element_is_record",
333 array->element_is_record) < 0)
334 return -1;
336 if (array->live_out) {
337 if (emit_string(emitter, "live_out") < 0)
338 return -1;
339 if (emit_string(emitter, "1") < 0)
340 return -1;
343 if (array->uniquely_defined) {
344 if (emit_string(emitter, "uniquely_defined") < 0)
345 return -1;
346 if (emit_string(emitter, "1") < 0)
347 return -1;
350 if (array->declared && emit_named_int(emitter, "declared", 1) < 0)
351 return -1;
352 if (array->exposed && emit_named_int(emitter, "exposed", 1) < 0)
353 return -1;
355 if (!yaml_mapping_end_event_initialize(&event))
356 return -1;
357 if (!yaml_emitter_emit(emitter, &event))
358 return -1;
360 return 0;
363 static int emit_arrays(yaml_emitter_t *emitter, int n_array,
364 struct pet_array **arrays)
366 int i;
367 yaml_event_t event;
369 if (emit_string(emitter, "arrays") < 0)
370 return -1;
371 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
372 YAML_BLOCK_SEQUENCE_STYLE))
373 return -1;
374 if (!yaml_emitter_emit(emitter, &event))
375 return -1;
377 for (i = 0; i < n_array; ++i)
378 if (emit_array(emitter, arrays[i]) < 0)
379 return -1;
381 if (!yaml_sequence_end_event_initialize(&event))
382 return -1;
383 if (!yaml_emitter_emit(emitter, &event))
384 return -1;
386 return 0;
389 static int emit_expr_type(yaml_emitter_t *emitter, enum pet_expr_type type)
391 if (emit_string(emitter, pet_type_str(type)) < 0)
392 return -1;
393 return 0;
396 static int emit_expr(yaml_emitter_t *emitter, __isl_keep pet_expr *expr)
398 yaml_event_t event;
400 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
401 YAML_BLOCK_MAPPING_STYLE))
402 return -1;
403 if (!yaml_emitter_emit(emitter, &event))
404 return -1;
406 if (emit_string(emitter, "type") < 0)
407 return -1;
408 if (emit_expr_type(emitter, expr->type) < 0)
409 return -1;
411 switch (expr->type) {
412 case pet_expr_error:
413 return -1;
414 case pet_expr_int:
415 if (emit_named_val(emitter, "value", expr->i) < 0)
416 return -1;
417 break;
418 case pet_expr_double:
419 if (emit_string(emitter, "value") < 0)
420 return -1;
421 if (emit_double(emitter, expr->d.val) < 0)
422 return -1;
423 if (emit_string(emitter, "string") < 0)
424 return -1;
425 if (emit_string(emitter, expr->d.s) < 0)
426 return -1;
427 break;
428 case pet_expr_access:
429 if (emit_string(emitter, "relation") < 0)
430 return -1;
431 if (emit_map(emitter, expr->acc.access) < 0)
432 return -1;
433 if (emit_named_multi_pw_aff(emitter,
434 "index", expr->acc.index) < 0)
435 return -1;
436 if (expr->acc.ref_id &&
437 emit_named_id(emitter, "reference", expr->acc.ref_id) < 0)
438 return -1;
439 if (emit_string(emitter, "read") < 0)
440 return -1;
441 if (emit_int(emitter, expr->acc.read) < 0)
442 return -1;
443 if (emit_string(emitter, "write") < 0)
444 return -1;
445 if (emit_int(emitter, expr->acc.write) < 0)
446 return -1;
447 break;
448 case pet_expr_op:
449 if (emit_string(emitter, "operation") < 0)
450 return -1;
451 if (emit_string(emitter, pet_op_str(expr->op)) < 0)
452 return -1;
453 break;
454 case pet_expr_call:
455 if (emit_string(emitter, "name") < 0)
456 return -1;
457 if (emit_string(emitter, expr->name) < 0)
458 return -1;
459 break;
460 case pet_expr_cast:
461 if (emit_string(emitter, "type_name") < 0)
462 return -1;
463 if (emit_string(emitter, expr->type_name) < 0)
464 return -1;
465 break;
468 if (expr->n_arg > 0) {
469 int i;
471 if (emit_string(emitter, "arguments") < 0)
472 return -1;
473 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
474 YAML_BLOCK_SEQUENCE_STYLE))
475 return -1;
476 if (!yaml_emitter_emit(emitter, &event))
477 return -1;
479 for (i = 0; i < expr->n_arg; ++i)
480 if (emit_expr(emitter, expr->args[i]) < 0)
481 return -1;
483 if (!yaml_sequence_end_event_initialize(&event))
484 return -1;
485 if (!yaml_emitter_emit(emitter, &event))
486 return -1;
489 if (!yaml_mapping_end_event_initialize(&event))
490 return -1;
491 if (!yaml_emitter_emit(emitter, &event))
492 return -1;
494 return 0;
497 static int emit_stmt(yaml_emitter_t *emitter, struct pet_stmt *stmt)
499 yaml_event_t event;
501 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
502 YAML_BLOCK_MAPPING_STYLE))
503 return -1;
504 if (!yaml_emitter_emit(emitter, &event))
505 return -1;
507 if (emit_string(emitter, "line") < 0)
508 return -1;
509 if (emit_int(emitter, stmt->line) < 0)
510 return -1;
512 if (emit_string(emitter, "domain") < 0)
513 return -1;
514 if (emit_set(emitter, stmt->domain) < 0)
515 return -1;
517 if (emit_string(emitter, "schedule") < 0)
518 return -1;
519 if (emit_map(emitter, stmt->schedule) < 0)
520 return -1;
522 if (emit_string(emitter, "body") < 0)
523 return -1;
524 if (emit_expr(emitter, stmt->body) < 0)
525 return -1;
527 if (stmt->n_arg > 0) {
528 int i;
530 if (emit_string(emitter, "arguments") < 0)
531 return -1;
532 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
533 YAML_BLOCK_SEQUENCE_STYLE))
534 return -1;
535 if (!yaml_emitter_emit(emitter, &event))
536 return -1;
538 for (i = 0; i < stmt->n_arg; ++i)
539 if (emit_expr(emitter, stmt->args[i]) < 0)
540 return -1;
542 if (!yaml_sequence_end_event_initialize(&event))
543 return -1;
544 if (!yaml_emitter_emit(emitter, &event))
545 return -1;
548 if (!yaml_mapping_end_event_initialize(&event))
549 return -1;
550 if (!yaml_emitter_emit(emitter, &event))
551 return -1;
553 return 0;
556 static int emit_statements(yaml_emitter_t *emitter, int n_stmt,
557 struct pet_stmt **stmts)
559 int i;
560 yaml_event_t event;
562 if (emit_string(emitter, "statements") < 0)
563 return -1;
564 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
565 YAML_BLOCK_SEQUENCE_STYLE))
566 return -1;
567 if (!yaml_emitter_emit(emitter, &event))
568 return -1;
570 for (i = 0; i < n_stmt; ++i)
571 if (emit_stmt(emitter, stmts[i]) < 0)
572 return -1;
574 if (!yaml_sequence_end_event_initialize(&event))
575 return -1;
576 if (!yaml_emitter_emit(emitter, &event))
577 return -1;
579 return 0;
582 /* Print "implication" to "emitter".
584 static int emit_implication(yaml_emitter_t *emitter,
585 struct pet_implication *implication)
587 yaml_event_t event;
589 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
590 YAML_BLOCK_MAPPING_STYLE))
591 return -1;
592 if (!yaml_emitter_emit(emitter, &event))
593 return -1;
595 if (emit_named_int(emitter, "satisfied", implication->satisfied) < 0)
596 return -1;
598 if (emit_named_map(emitter, "extension", implication->extension) < 0)
599 return -1;
601 if (!yaml_mapping_end_event_initialize(&event))
602 return -1;
603 if (!yaml_emitter_emit(emitter, &event))
604 return -1;
606 return 0;
609 /* Print the list of "n_implication" "implications", if any, to "emitter".
611 static int emit_implications(yaml_emitter_t *emitter, int n_implication,
612 struct pet_implication **implications)
614 int i;
615 yaml_event_t event;
617 if (n_implication == 0)
618 return 0;
620 if (emit_string(emitter, "implications") < 0)
621 return -1;
622 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
623 YAML_BLOCK_SEQUENCE_STYLE))
624 return -1;
625 if (!yaml_emitter_emit(emitter, &event))
626 return -1;
628 for (i = 0; i < n_implication; ++i)
629 if (emit_implication(emitter, implications[i]) < 0)
630 return -1;
632 if (!yaml_sequence_end_event_initialize(&event))
633 return -1;
634 if (!yaml_emitter_emit(emitter, &event))
635 return -1;
637 return 0;
640 static int emit_scop(yaml_emitter_t *emitter, struct pet_scop *scop)
642 yaml_event_t event;
644 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
645 YAML_BLOCK_MAPPING_STYLE))
646 return -1;
647 if (!yaml_emitter_emit(emitter, &event))
648 return -1;
650 if (emit_named_unsigned(emitter, "start", scop->start) < 0)
651 return -1;
652 if (emit_named_unsigned(emitter, "end", scop->end) < 0)
653 return -1;
654 if (emit_string(emitter, "context") < 0)
655 return -1;
656 if (emit_set(emitter, scop->context) < 0)
657 return -1;
658 if (!isl_set_plain_is_universe(scop->context_value) &&
659 emit_named_set(emitter, "context_value", scop->context_value) < 0)
660 return -1;
662 if (emit_types(emitter, scop->n_type, scop->types) < 0)
663 return -1;
664 if (emit_arrays(emitter, scop->n_array, scop->arrays) < 0)
665 return -1;
667 if (emit_statements(emitter, scop->n_stmt, scop->stmts) < 0)
668 return -1;
670 if (emit_implications(emitter, scop->n_implication,
671 scop->implications) < 0)
672 return -1;
674 if (!yaml_mapping_end_event_initialize(&event))
675 return -1;
676 if (!yaml_emitter_emit(emitter, &event))
677 return -1;
679 return 0;
682 /* Print a YAML serialization of "scop" to "out".
684 int pet_scop_emit(FILE *out, struct pet_scop *scop)
686 yaml_emitter_t emitter;
687 yaml_event_t event;
689 yaml_emitter_initialize(&emitter);
691 yaml_emitter_set_output_file(&emitter, out);
693 yaml_stream_start_event_initialize(&event, YAML_UTF8_ENCODING);
694 if (!yaml_emitter_emit(&emitter, &event))
695 goto error;
697 if (!yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 1))
698 goto error;
699 if (!yaml_emitter_emit(&emitter, &event))
700 goto error;
702 if (emit_scop(&emitter, scop) < 0)
703 goto error;
705 if (!yaml_document_end_event_initialize(&event, 1))
706 goto error;
707 if (!yaml_emitter_emit(&emitter, &event))
708 goto error;
710 yaml_stream_end_event_initialize(&event);
711 if (!yaml_emitter_emit(&emitter, &event))
712 goto error;
714 yaml_emitter_delete(&emitter);
715 return 0;
716 error:
717 yaml_emitter_delete(&emitter);
718 return -1;