scop.c: stmt_collect_params: use pet_expr_foreach_access_expr
[pet.git] / emit.c
blob97bac2278c5310fce4bffa31556db19fee7d1b01
1 /*
2 * Copyright 2011 Leiden University. All rights reserved.
3 * Copyright 2013-2014 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 "loc.h"
39 #include "scop.h"
40 #include "scop_yaml.h"
42 static int emit_string(yaml_emitter_t *emitter, const char *str)
44 yaml_event_t event;
46 if (!yaml_scalar_event_initialize(&event, NULL, NULL,
47 (yaml_char_t *) str, strlen(str),
48 1, 1, YAML_PLAIN_SCALAR_STYLE))
49 return -1;
50 if (!yaml_emitter_emit(emitter, &event))
51 return -1;
53 return 0;
56 /* Print the string "name" and the string "str" to "emitter".
58 static int emit_named_string(yaml_emitter_t *emitter, const char *name,
59 const char *str)
61 if (emit_string(emitter, name) < 0)
62 return -1;
63 if (emit_string(emitter, str) < 0)
64 return -1;
65 return 0;
68 /* Print the isl_id "id" to "emitter".
70 static int emit_id(yaml_emitter_t *emitter, __isl_keep isl_id *id)
72 return emit_string(emitter, isl_id_get_name(id));
75 /* Print the string "name" and the isl_id "id" to "emitter".
77 static int emit_named_id(yaml_emitter_t *emitter, const char *name,
78 __isl_keep isl_id *id)
80 if (emit_string(emitter, name) < 0)
81 return -1;
82 if (emit_id(emitter, id) < 0)
83 return -1;
84 return 0;
87 static int emit_int(yaml_emitter_t *emitter, int i)
89 char buffer[40];
91 snprintf(buffer, sizeof(buffer), "%d", i);
92 return emit_string(emitter, buffer);
95 static int emit_named_int(yaml_emitter_t *emitter, const char *name, int i)
97 if (emit_string(emitter, name) < 0)
98 return -1;
99 if (emit_int(emitter, i) < 0)
100 return -1;
101 return 0;
104 /* Print the unsigned integer "u" to "emitter".
106 static int emit_unsigned(yaml_emitter_t *emitter, unsigned u)
108 char buffer[40];
110 snprintf(buffer, sizeof(buffer), "%u", u);
111 return emit_string(emitter, buffer);
114 /* Print the string "name" and the unsigned integer "u" to "emitter".
116 static int emit_named_unsigned(yaml_emitter_t *emitter, const char *name,
117 unsigned u)
119 if (emit_string(emitter, name) < 0)
120 return -1;
121 if (emit_int(emitter, u) < 0)
122 return -1;
123 return 0;
126 static int emit_double(yaml_emitter_t *emitter, double d)
128 char buffer[40];
130 snprintf(buffer, sizeof(buffer), "%g", d);
131 return emit_string(emitter, buffer);
134 static int emit_map(yaml_emitter_t *emitter, __isl_keep isl_map *map)
136 isl_ctx *ctx = isl_map_get_ctx(map);
137 isl_printer *p;
138 char *str;
139 int r;
141 p = isl_printer_to_str(ctx);
142 p = isl_printer_print_map(p, map);
143 str = isl_printer_get_str(p);
144 isl_printer_free(p);
145 r = emit_string(emitter, str);
146 free(str);
147 return r;
150 /* Print the isl_val "val" to "emitter".
152 static int emit_val(yaml_emitter_t *emitter, __isl_keep isl_val *val)
154 isl_ctx *ctx = isl_val_get_ctx(val);
155 isl_printer *p;
156 char *str;
157 int r;
159 p = isl_printer_to_str(ctx);
160 p = isl_printer_print_val(p, val);
161 str = isl_printer_get_str(p);
162 isl_printer_free(p);
163 r = emit_string(emitter, str);
164 free(str);
165 return r;
168 /* Print the string "name" and the isl_val "val" to "emitter".
170 static int emit_named_val(yaml_emitter_t *emitter, const char *name,
171 __isl_keep isl_val *val)
173 if (emit_string(emitter, name) < 0)
174 return -1;
175 if (emit_val(emitter, val) < 0)
176 return -1;
177 return 0;
180 static int emit_set(yaml_emitter_t *emitter, __isl_keep isl_set *set)
182 isl_ctx *ctx = isl_set_get_ctx(set);
183 isl_printer *p;
184 char *str;
185 int r;
187 p = isl_printer_to_str(ctx);
188 p = isl_printer_print_set(p, set);
189 str = isl_printer_get_str(p);
190 isl_printer_free(p);
191 r = emit_string(emitter, str);
192 free(str);
193 return r;
196 static int emit_named_set(yaml_emitter_t *emitter, const char *name,
197 __isl_keep isl_set *set)
199 if (emit_string(emitter, name) < 0)
200 return -1;
201 if (emit_set(emitter, set) < 0)
202 return -1;
203 return 0;
206 /* Print the string "name" and the map "map" to "emitter".
208 static int emit_named_map(yaml_emitter_t *emitter, const char *name,
209 __isl_keep isl_map *map)
211 if (emit_string(emitter, name) < 0)
212 return -1;
213 if (emit_map(emitter, map) < 0)
214 return -1;
215 return 0;
218 /* Print the isl_multi_pw_aff "mpa" to "emitter".
220 static int emit_multi_pw_aff(yaml_emitter_t *emitter,
221 __isl_keep isl_multi_pw_aff *mpa)
223 isl_ctx *ctx = isl_multi_pw_aff_get_ctx(mpa);
224 isl_printer *p;
225 char *str;
226 int r;
228 p = isl_printer_to_str(ctx);
229 p = isl_printer_print_multi_pw_aff(p, mpa);
230 str = isl_printer_get_str(p);
231 isl_printer_free(p);
232 r = emit_string(emitter, str);
233 free(str);
234 return r;
237 /* Print the string "name" and the isl_multi_pw_aff "mpa" to "emitter".
239 static int emit_named_multi_pw_aff(yaml_emitter_t *emitter, const char *name,
240 __isl_keep isl_multi_pw_aff *mpa)
242 if (emit_string(emitter, name) < 0)
243 return -1;
244 if (emit_multi_pw_aff(emitter, mpa) < 0)
245 return -1;
246 return 0;
249 /* Print "type" to "emitter".
251 static int emit_type(yaml_emitter_t *emitter, struct pet_type *type)
253 yaml_event_t event;
255 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
256 YAML_BLOCK_MAPPING_STYLE))
257 return -1;
258 if (!yaml_emitter_emit(emitter, &event))
259 return -1;
261 if (emit_string(emitter, "name") < 0)
262 return -1;
263 if (emit_string(emitter, type->name) < 0)
264 return -1;
266 if (emit_string(emitter, "definition") < 0)
267 return -1;
268 if (emit_string(emitter, type->definition) < 0)
269 return -1;
271 if (!yaml_mapping_end_event_initialize(&event))
272 return -1;
273 if (!yaml_emitter_emit(emitter, &event))
274 return -1;
276 return 0;
279 /* Print the list of "n_type" "types", if any, to "emitter".
281 static int emit_types(yaml_emitter_t *emitter, int n_type,
282 struct pet_type **types)
284 int i;
285 yaml_event_t event;
287 if (n_type == 0)
288 return 0;
290 if (emit_string(emitter, "types") < 0)
291 return -1;
292 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
293 YAML_BLOCK_SEQUENCE_STYLE))
294 return -1;
295 if (!yaml_emitter_emit(emitter, &event))
296 return -1;
298 for (i = 0; i < n_type; ++i)
299 if (emit_type(emitter, types[i]) < 0)
300 return -1;
302 if (!yaml_sequence_end_event_initialize(&event))
303 return -1;
304 if (!yaml_emitter_emit(emitter, &event))
305 return -1;
307 return 0;
310 static int emit_array(yaml_emitter_t *emitter, struct pet_array *array)
312 yaml_event_t event;
314 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
315 YAML_BLOCK_MAPPING_STYLE))
316 return -1;
317 if (!yaml_emitter_emit(emitter, &event))
318 return -1;
320 if (emit_string(emitter, "context") < 0)
321 return -1;
322 if (emit_set(emitter, array->context) < 0)
323 return -1;
325 if (emit_string(emitter, "extent") < 0)
326 return -1;
327 if (emit_set(emitter, array->extent) < 0)
328 return -1;
330 if (array->value_bounds) {
331 if (emit_string(emitter, "value_bounds") < 0)
332 return -1;
333 if (emit_set(emitter, array->value_bounds) < 0)
334 return -1;
337 if (emit_string(emitter, "element_type") < 0)
338 return -1;
339 if (emit_string(emitter, array->element_type) < 0)
340 return -1;
341 if (emit_named_int(emitter, "element_size", array->element_size) < 0)
342 return -1;
344 if (array->element_is_record)
345 if (emit_named_int(emitter, "element_is_record",
346 array->element_is_record) < 0)
347 return -1;
349 if (array->live_out) {
350 if (emit_string(emitter, "live_out") < 0)
351 return -1;
352 if (emit_string(emitter, "1") < 0)
353 return -1;
356 if (array->uniquely_defined) {
357 if (emit_string(emitter, "uniquely_defined") < 0)
358 return -1;
359 if (emit_string(emitter, "1") < 0)
360 return -1;
363 if (array->declared && emit_named_int(emitter, "declared", 1) < 0)
364 return -1;
365 if (array->exposed && emit_named_int(emitter, "exposed", 1) < 0)
366 return -1;
368 if (!yaml_mapping_end_event_initialize(&event))
369 return -1;
370 if (!yaml_emitter_emit(emitter, &event))
371 return -1;
373 return 0;
376 static int emit_arrays(yaml_emitter_t *emitter, int n_array,
377 struct pet_array **arrays)
379 int i;
380 yaml_event_t event;
382 if (emit_string(emitter, "arrays") < 0)
383 return -1;
384 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
385 YAML_BLOCK_SEQUENCE_STYLE))
386 return -1;
387 if (!yaml_emitter_emit(emitter, &event))
388 return -1;
390 for (i = 0; i < n_array; ++i)
391 if (emit_array(emitter, arrays[i]) < 0)
392 return -1;
394 if (!yaml_sequence_end_event_initialize(&event))
395 return -1;
396 if (!yaml_emitter_emit(emitter, &event))
397 return -1;
399 return 0;
402 static int emit_expr_type(yaml_emitter_t *emitter, enum pet_expr_type type)
404 if (emit_string(emitter, pet_type_str(type)) < 0)
405 return -1;
406 return 0;
409 static int emit_expr(yaml_emitter_t *emitter, __isl_keep pet_expr *expr)
411 yaml_event_t event;
413 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
414 YAML_BLOCK_MAPPING_STYLE))
415 return -1;
416 if (!yaml_emitter_emit(emitter, &event))
417 return -1;
419 if (emit_string(emitter, "type") < 0)
420 return -1;
421 if (emit_expr_type(emitter, expr->type) < 0)
422 return -1;
424 switch (expr->type) {
425 case pet_expr_error:
426 return -1;
427 case pet_expr_int:
428 if (emit_named_val(emitter, "value", expr->i) < 0)
429 return -1;
430 break;
431 case pet_expr_double:
432 if (emit_string(emitter, "value") < 0)
433 return -1;
434 if (emit_double(emitter, expr->d.val) < 0)
435 return -1;
436 if (emit_string(emitter, "string") < 0)
437 return -1;
438 if (emit_string(emitter, expr->d.s) < 0)
439 return -1;
440 break;
441 case pet_expr_access:
442 if (emit_string(emitter, "relation") < 0)
443 return -1;
444 if (emit_map(emitter, expr->acc.access) < 0)
445 return -1;
446 if (emit_named_multi_pw_aff(emitter,
447 "index", expr->acc.index) < 0)
448 return -1;
449 if (expr->acc.ref_id &&
450 emit_named_id(emitter, "reference", expr->acc.ref_id) < 0)
451 return -1;
452 if (emit_string(emitter, "read") < 0)
453 return -1;
454 if (emit_int(emitter, expr->acc.read) < 0)
455 return -1;
456 if (emit_string(emitter, "write") < 0)
457 return -1;
458 if (emit_int(emitter, expr->acc.write) < 0)
459 return -1;
460 break;
461 case pet_expr_op:
462 if (emit_string(emitter, "operation") < 0)
463 return -1;
464 if (emit_string(emitter, pet_op_str(expr->op)) < 0)
465 return -1;
466 break;
467 case pet_expr_call:
468 if (emit_string(emitter, "name") < 0)
469 return -1;
470 if (emit_string(emitter, expr->name) < 0)
471 return -1;
472 break;
473 case pet_expr_cast:
474 if (emit_string(emitter, "type_name") < 0)
475 return -1;
476 if (emit_string(emitter, expr->type_name) < 0)
477 return -1;
478 break;
481 if (expr->n_arg > 0) {
482 int i;
484 if (emit_string(emitter, "arguments") < 0)
485 return -1;
486 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
487 YAML_BLOCK_SEQUENCE_STYLE))
488 return -1;
489 if (!yaml_emitter_emit(emitter, &event))
490 return -1;
492 for (i = 0; i < expr->n_arg; ++i)
493 if (emit_expr(emitter, expr->args[i]) < 0)
494 return -1;
496 if (!yaml_sequence_end_event_initialize(&event))
497 return -1;
498 if (!yaml_emitter_emit(emitter, &event))
499 return -1;
502 if (!yaml_mapping_end_event_initialize(&event))
503 return -1;
504 if (!yaml_emitter_emit(emitter, &event))
505 return -1;
507 return 0;
510 static int emit_stmt(yaml_emitter_t *emitter, struct pet_stmt *stmt)
512 yaml_event_t event;
514 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
515 YAML_BLOCK_MAPPING_STYLE))
516 return -1;
517 if (!yaml_emitter_emit(emitter, &event))
518 return -1;
520 if (emit_string(emitter, "line") < 0)
521 return -1;
522 if (emit_int(emitter, pet_loc_get_line(stmt->loc)) < 0)
523 return -1;
525 if (emit_string(emitter, "domain") < 0)
526 return -1;
527 if (emit_set(emitter, stmt->domain) < 0)
528 return -1;
530 if (emit_string(emitter, "schedule") < 0)
531 return -1;
532 if (emit_map(emitter, stmt->schedule) < 0)
533 return -1;
535 if (emit_string(emitter, "body") < 0)
536 return -1;
537 if (emit_expr(emitter, stmt->body) < 0)
538 return -1;
540 if (stmt->n_arg > 0) {
541 int i;
543 if (emit_string(emitter, "arguments") < 0)
544 return -1;
545 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
546 YAML_BLOCK_SEQUENCE_STYLE))
547 return -1;
548 if (!yaml_emitter_emit(emitter, &event))
549 return -1;
551 for (i = 0; i < stmt->n_arg; ++i)
552 if (emit_expr(emitter, stmt->args[i]) < 0)
553 return -1;
555 if (!yaml_sequence_end_event_initialize(&event))
556 return -1;
557 if (!yaml_emitter_emit(emitter, &event))
558 return -1;
561 if (!yaml_mapping_end_event_initialize(&event))
562 return -1;
563 if (!yaml_emitter_emit(emitter, &event))
564 return -1;
566 return 0;
569 static int emit_statements(yaml_emitter_t *emitter, int n_stmt,
570 struct pet_stmt **stmts)
572 int i;
573 yaml_event_t event;
575 if (emit_string(emitter, "statements") < 0)
576 return -1;
577 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
578 YAML_BLOCK_SEQUENCE_STYLE))
579 return -1;
580 if (!yaml_emitter_emit(emitter, &event))
581 return -1;
583 for (i = 0; i < n_stmt; ++i)
584 if (emit_stmt(emitter, stmts[i]) < 0)
585 return -1;
587 if (!yaml_sequence_end_event_initialize(&event))
588 return -1;
589 if (!yaml_emitter_emit(emitter, &event))
590 return -1;
592 return 0;
595 /* Print "implication" to "emitter".
597 static int emit_implication(yaml_emitter_t *emitter,
598 struct pet_implication *implication)
600 yaml_event_t event;
602 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
603 YAML_BLOCK_MAPPING_STYLE))
604 return -1;
605 if (!yaml_emitter_emit(emitter, &event))
606 return -1;
608 if (emit_named_int(emitter, "satisfied", implication->satisfied) < 0)
609 return -1;
611 if (emit_named_map(emitter, "extension", implication->extension) < 0)
612 return -1;
614 if (!yaml_mapping_end_event_initialize(&event))
615 return -1;
616 if (!yaml_emitter_emit(emitter, &event))
617 return -1;
619 return 0;
622 /* Print the list of "n_implication" "implications", if any, to "emitter".
624 static int emit_implications(yaml_emitter_t *emitter, int n_implication,
625 struct pet_implication **implications)
627 int i;
628 yaml_event_t event;
630 if (n_implication == 0)
631 return 0;
633 if (emit_string(emitter, "implications") < 0)
634 return -1;
635 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
636 YAML_BLOCK_SEQUENCE_STYLE))
637 return -1;
638 if (!yaml_emitter_emit(emitter, &event))
639 return -1;
641 for (i = 0; i < n_implication; ++i)
642 if (emit_implication(emitter, implications[i]) < 0)
643 return -1;
645 if (!yaml_sequence_end_event_initialize(&event))
646 return -1;
647 if (!yaml_emitter_emit(emitter, &event))
648 return -1;
650 return 0;
653 static int emit_scop(yaml_emitter_t *emitter, struct pet_scop *scop)
655 yaml_event_t event;
657 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
658 YAML_BLOCK_MAPPING_STYLE))
659 return -1;
660 if (!yaml_emitter_emit(emitter, &event))
661 return -1;
663 if (emit_named_unsigned(emitter,
664 "start", pet_loc_get_start(scop->loc)) < 0)
665 return -1;
666 if (emit_named_unsigned(emitter, "end", pet_loc_get_end(scop->loc)) < 0)
667 return -1;
668 if (emit_named_string(emitter,
669 "indent", pet_loc_get_indent(scop->loc)) < 0)
670 return -1;
671 if (emit_string(emitter, "context") < 0)
672 return -1;
673 if (emit_set(emitter, scop->context) < 0)
674 return -1;
675 if (!isl_set_plain_is_universe(scop->context_value) &&
676 emit_named_set(emitter, "context_value", scop->context_value) < 0)
677 return -1;
679 if (emit_types(emitter, scop->n_type, scop->types) < 0)
680 return -1;
681 if (emit_arrays(emitter, scop->n_array, scop->arrays) < 0)
682 return -1;
684 if (emit_statements(emitter, scop->n_stmt, scop->stmts) < 0)
685 return -1;
687 if (emit_implications(emitter, scop->n_implication,
688 scop->implications) < 0)
689 return -1;
691 if (!yaml_mapping_end_event_initialize(&event))
692 return -1;
693 if (!yaml_emitter_emit(emitter, &event))
694 return -1;
696 return 0;
699 /* Print a YAML serialization of "scop" to "out".
701 int pet_scop_emit(FILE *out, struct pet_scop *scop)
703 yaml_emitter_t emitter;
704 yaml_event_t event;
706 yaml_emitter_initialize(&emitter);
708 yaml_emitter_set_output_file(&emitter, out);
710 yaml_stream_start_event_initialize(&event, YAML_UTF8_ENCODING);
711 if (!yaml_emitter_emit(&emitter, &event))
712 goto error;
714 if (!yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 1))
715 goto error;
716 if (!yaml_emitter_emit(&emitter, &event))
717 goto error;
719 if (emit_scop(&emitter, scop) < 0)
720 goto error;
722 if (!yaml_document_end_event_initialize(&event, 1))
723 goto error;
724 if (!yaml_emitter_emit(&emitter, &event))
725 goto error;
727 yaml_stream_end_event_initialize(&event);
728 if (!yaml_emitter_emit(&emitter, &event))
729 goto error;
731 yaml_emitter_delete(&emitter);
732 return 0;
733 error:
734 yaml_emitter_delete(&emitter);
735 return -1;