PetScan::extract_scop: clear writes at outer level
[pet.git] / emit.c
blob8ae46dfbcd63aa3974c5a0734c530f83308bf19d
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 isl_id "id" to "emitter".
58 static int emit_id(yaml_emitter_t *emitter, __isl_keep isl_id *id)
60 return emit_string(emitter, isl_id_get_name(id));
63 /* Print the string "name" and the isl_id "id" to "emitter".
65 static int emit_named_id(yaml_emitter_t *emitter, const char *name,
66 __isl_keep isl_id *id)
68 if (emit_string(emitter, name) < 0)
69 return -1;
70 if (emit_id(emitter, id) < 0)
71 return -1;
72 return 0;
75 static int emit_int(yaml_emitter_t *emitter, int i)
77 char buffer[40];
79 snprintf(buffer, sizeof(buffer), "%d", i);
80 return emit_string(emitter, buffer);
83 static int emit_named_int(yaml_emitter_t *emitter, const char *name, int i)
85 if (emit_string(emitter, name) < 0)
86 return -1;
87 if (emit_int(emitter, i) < 0)
88 return -1;
89 return 0;
92 /* Print the unsigned integer "u" to "emitter".
94 static int emit_unsigned(yaml_emitter_t *emitter, unsigned u)
96 char buffer[40];
98 snprintf(buffer, sizeof(buffer), "%u", u);
99 return emit_string(emitter, buffer);
102 /* Print the string "name" and the unsigned integer "u" to "emitter".
104 static int emit_named_unsigned(yaml_emitter_t *emitter, const char *name,
105 unsigned u)
107 if (emit_string(emitter, name) < 0)
108 return -1;
109 if (emit_int(emitter, u) < 0)
110 return -1;
111 return 0;
114 static int emit_double(yaml_emitter_t *emitter, double d)
116 char buffer[40];
118 snprintf(buffer, sizeof(buffer), "%g", d);
119 return emit_string(emitter, buffer);
122 static int emit_map(yaml_emitter_t *emitter, __isl_keep isl_map *map)
124 isl_ctx *ctx = isl_map_get_ctx(map);
125 isl_printer *p;
126 char *str;
127 int r;
129 p = isl_printer_to_str(ctx);
130 p = isl_printer_print_map(p, map);
131 str = isl_printer_get_str(p);
132 isl_printer_free(p);
133 r = emit_string(emitter, str);
134 free(str);
135 return r;
138 /* Print the isl_val "val" to "emitter".
140 static int emit_val(yaml_emitter_t *emitter, __isl_keep isl_val *val)
142 isl_ctx *ctx = isl_val_get_ctx(val);
143 isl_printer *p;
144 char *str;
145 int r;
147 p = isl_printer_to_str(ctx);
148 p = isl_printer_print_val(p, val);
149 str = isl_printer_get_str(p);
150 isl_printer_free(p);
151 r = emit_string(emitter, str);
152 free(str);
153 return r;
156 /* Print the string "name" and the isl_val "val" to "emitter".
158 static int emit_named_val(yaml_emitter_t *emitter, const char *name,
159 __isl_keep isl_val *val)
161 if (emit_string(emitter, name) < 0)
162 return -1;
163 if (emit_val(emitter, val) < 0)
164 return -1;
165 return 0;
168 static int emit_set(yaml_emitter_t *emitter, __isl_keep isl_set *set)
170 isl_ctx *ctx = isl_set_get_ctx(set);
171 isl_printer *p;
172 char *str;
173 int r;
175 p = isl_printer_to_str(ctx);
176 p = isl_printer_print_set(p, set);
177 str = isl_printer_get_str(p);
178 isl_printer_free(p);
179 r = emit_string(emitter, str);
180 free(str);
181 return r;
184 static int emit_named_set(yaml_emitter_t *emitter, const char *name,
185 __isl_keep isl_set *set)
187 if (emit_string(emitter, name) < 0)
188 return -1;
189 if (emit_set(emitter, set) < 0)
190 return -1;
191 return 0;
194 /* Print the string "name" and the map "map" to "emitter".
196 static int emit_named_map(yaml_emitter_t *emitter, const char *name,
197 __isl_keep isl_map *map)
199 if (emit_string(emitter, name) < 0)
200 return -1;
201 if (emit_map(emitter, map) < 0)
202 return -1;
203 return 0;
206 /* Print the isl_multi_pw_aff "mpa" to "emitter".
208 static int emit_multi_pw_aff(yaml_emitter_t *emitter,
209 __isl_keep isl_multi_pw_aff *mpa)
211 isl_ctx *ctx = isl_multi_pw_aff_get_ctx(mpa);
212 isl_printer *p;
213 char *str;
214 int r;
216 p = isl_printer_to_str(ctx);
217 p = isl_printer_print_multi_pw_aff(p, mpa);
218 str = isl_printer_get_str(p);
219 isl_printer_free(p);
220 r = emit_string(emitter, str);
221 free(str);
222 return r;
225 /* Print the string "name" and the isl_multi_pw_aff "mpa" to "emitter".
227 static int emit_named_multi_pw_aff(yaml_emitter_t *emitter, const char *name,
228 __isl_keep isl_multi_pw_aff *mpa)
230 if (emit_string(emitter, name) < 0)
231 return -1;
232 if (emit_multi_pw_aff(emitter, mpa) < 0)
233 return -1;
234 return 0;
237 /* Print "type" to "emitter".
239 static int emit_type(yaml_emitter_t *emitter, struct pet_type *type)
241 yaml_event_t event;
243 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
244 YAML_BLOCK_MAPPING_STYLE))
245 return -1;
246 if (!yaml_emitter_emit(emitter, &event))
247 return -1;
249 if (emit_string(emitter, "name") < 0)
250 return -1;
251 if (emit_string(emitter, type->name) < 0)
252 return -1;
254 if (emit_string(emitter, "definition") < 0)
255 return -1;
256 if (emit_string(emitter, type->definition) < 0)
257 return -1;
259 if (!yaml_mapping_end_event_initialize(&event))
260 return -1;
261 if (!yaml_emitter_emit(emitter, &event))
262 return -1;
264 return 0;
267 /* Print the list of "n_type" "types", if any, to "emitter".
269 static int emit_types(yaml_emitter_t *emitter, int n_type,
270 struct pet_type **types)
272 int i;
273 yaml_event_t event;
275 if (n_type == 0)
276 return 0;
278 if (emit_string(emitter, "types") < 0)
279 return -1;
280 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
281 YAML_BLOCK_SEQUENCE_STYLE))
282 return -1;
283 if (!yaml_emitter_emit(emitter, &event))
284 return -1;
286 for (i = 0; i < n_type; ++i)
287 if (emit_type(emitter, types[i]) < 0)
288 return -1;
290 if (!yaml_sequence_end_event_initialize(&event))
291 return -1;
292 if (!yaml_emitter_emit(emitter, &event))
293 return -1;
295 return 0;
298 static int emit_array(yaml_emitter_t *emitter, struct pet_array *array)
300 yaml_event_t event;
302 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
303 YAML_BLOCK_MAPPING_STYLE))
304 return -1;
305 if (!yaml_emitter_emit(emitter, &event))
306 return -1;
308 if (emit_string(emitter, "context") < 0)
309 return -1;
310 if (emit_set(emitter, array->context) < 0)
311 return -1;
313 if (emit_string(emitter, "extent") < 0)
314 return -1;
315 if (emit_set(emitter, array->extent) < 0)
316 return -1;
318 if (array->value_bounds) {
319 if (emit_string(emitter, "value_bounds") < 0)
320 return -1;
321 if (emit_set(emitter, array->value_bounds) < 0)
322 return -1;
325 if (emit_string(emitter, "element_type") < 0)
326 return -1;
327 if (emit_string(emitter, array->element_type) < 0)
328 return -1;
329 if (emit_named_int(emitter, "element_size", array->element_size) < 0)
330 return -1;
332 if (array->element_is_record)
333 if (emit_named_int(emitter, "element_is_record",
334 array->element_is_record) < 0)
335 return -1;
337 if (array->live_out) {
338 if (emit_string(emitter, "live_out") < 0)
339 return -1;
340 if (emit_string(emitter, "1") < 0)
341 return -1;
344 if (array->uniquely_defined) {
345 if (emit_string(emitter, "uniquely_defined") < 0)
346 return -1;
347 if (emit_string(emitter, "1") < 0)
348 return -1;
351 if (array->declared && emit_named_int(emitter, "declared", 1) < 0)
352 return -1;
353 if (array->exposed && emit_named_int(emitter, "exposed", 1) < 0)
354 return -1;
356 if (!yaml_mapping_end_event_initialize(&event))
357 return -1;
358 if (!yaml_emitter_emit(emitter, &event))
359 return -1;
361 return 0;
364 static int emit_arrays(yaml_emitter_t *emitter, int n_array,
365 struct pet_array **arrays)
367 int i;
368 yaml_event_t event;
370 if (emit_string(emitter, "arrays") < 0)
371 return -1;
372 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
373 YAML_BLOCK_SEQUENCE_STYLE))
374 return -1;
375 if (!yaml_emitter_emit(emitter, &event))
376 return -1;
378 for (i = 0; i < n_array; ++i)
379 if (emit_array(emitter, arrays[i]) < 0)
380 return -1;
382 if (!yaml_sequence_end_event_initialize(&event))
383 return -1;
384 if (!yaml_emitter_emit(emitter, &event))
385 return -1;
387 return 0;
390 static int emit_expr_type(yaml_emitter_t *emitter, enum pet_expr_type type)
392 if (emit_string(emitter, pet_type_str(type)) < 0)
393 return -1;
394 return 0;
397 static int emit_expr(yaml_emitter_t *emitter, __isl_keep pet_expr *expr)
399 yaml_event_t event;
401 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
402 YAML_BLOCK_MAPPING_STYLE))
403 return -1;
404 if (!yaml_emitter_emit(emitter, &event))
405 return -1;
407 if (emit_string(emitter, "type") < 0)
408 return -1;
409 if (emit_expr_type(emitter, expr->type) < 0)
410 return -1;
412 switch (expr->type) {
413 case pet_expr_error:
414 return -1;
415 case pet_expr_int:
416 if (emit_named_val(emitter, "value", expr->i) < 0)
417 return -1;
418 break;
419 case pet_expr_double:
420 if (emit_string(emitter, "value") < 0)
421 return -1;
422 if (emit_double(emitter, expr->d.val) < 0)
423 return -1;
424 if (emit_string(emitter, "string") < 0)
425 return -1;
426 if (emit_string(emitter, expr->d.s) < 0)
427 return -1;
428 break;
429 case pet_expr_access:
430 if (emit_string(emitter, "relation") < 0)
431 return -1;
432 if (emit_map(emitter, expr->acc.access) < 0)
433 return -1;
434 if (emit_named_multi_pw_aff(emitter,
435 "index", expr->acc.index) < 0)
436 return -1;
437 if (expr->acc.ref_id &&
438 emit_named_id(emitter, "reference", expr->acc.ref_id) < 0)
439 return -1;
440 if (emit_string(emitter, "read") < 0)
441 return -1;
442 if (emit_int(emitter, expr->acc.read) < 0)
443 return -1;
444 if (emit_string(emitter, "write") < 0)
445 return -1;
446 if (emit_int(emitter, expr->acc.write) < 0)
447 return -1;
448 break;
449 case pet_expr_op:
450 if (emit_string(emitter, "operation") < 0)
451 return -1;
452 if (emit_string(emitter, pet_op_str(expr->op)) < 0)
453 return -1;
454 break;
455 case pet_expr_call:
456 if (emit_string(emitter, "name") < 0)
457 return -1;
458 if (emit_string(emitter, expr->name) < 0)
459 return -1;
460 break;
461 case pet_expr_cast:
462 if (emit_string(emitter, "type_name") < 0)
463 return -1;
464 if (emit_string(emitter, expr->type_name) < 0)
465 return -1;
466 break;
469 if (expr->n_arg > 0) {
470 int i;
472 if (emit_string(emitter, "arguments") < 0)
473 return -1;
474 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
475 YAML_BLOCK_SEQUENCE_STYLE))
476 return -1;
477 if (!yaml_emitter_emit(emitter, &event))
478 return -1;
480 for (i = 0; i < expr->n_arg; ++i)
481 if (emit_expr(emitter, expr->args[i]) < 0)
482 return -1;
484 if (!yaml_sequence_end_event_initialize(&event))
485 return -1;
486 if (!yaml_emitter_emit(emitter, &event))
487 return -1;
490 if (!yaml_mapping_end_event_initialize(&event))
491 return -1;
492 if (!yaml_emitter_emit(emitter, &event))
493 return -1;
495 return 0;
498 static int emit_stmt(yaml_emitter_t *emitter, struct pet_stmt *stmt)
500 yaml_event_t event;
502 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
503 YAML_BLOCK_MAPPING_STYLE))
504 return -1;
505 if (!yaml_emitter_emit(emitter, &event))
506 return -1;
508 if (emit_string(emitter, "line") < 0)
509 return -1;
510 if (emit_int(emitter, pet_loc_get_line(stmt->loc)) < 0)
511 return -1;
513 if (emit_string(emitter, "domain") < 0)
514 return -1;
515 if (emit_set(emitter, stmt->domain) < 0)
516 return -1;
518 if (emit_string(emitter, "schedule") < 0)
519 return -1;
520 if (emit_map(emitter, stmt->schedule) < 0)
521 return -1;
523 if (emit_string(emitter, "body") < 0)
524 return -1;
525 if (emit_expr(emitter, stmt->body) < 0)
526 return -1;
528 if (stmt->n_arg > 0) {
529 int i;
531 if (emit_string(emitter, "arguments") < 0)
532 return -1;
533 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
534 YAML_BLOCK_SEQUENCE_STYLE))
535 return -1;
536 if (!yaml_emitter_emit(emitter, &event))
537 return -1;
539 for (i = 0; i < stmt->n_arg; ++i)
540 if (emit_expr(emitter, stmt->args[i]) < 0)
541 return -1;
543 if (!yaml_sequence_end_event_initialize(&event))
544 return -1;
545 if (!yaml_emitter_emit(emitter, &event))
546 return -1;
549 if (!yaml_mapping_end_event_initialize(&event))
550 return -1;
551 if (!yaml_emitter_emit(emitter, &event))
552 return -1;
554 return 0;
557 static int emit_statements(yaml_emitter_t *emitter, int n_stmt,
558 struct pet_stmt **stmts)
560 int i;
561 yaml_event_t event;
563 if (emit_string(emitter, "statements") < 0)
564 return -1;
565 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
566 YAML_BLOCK_SEQUENCE_STYLE))
567 return -1;
568 if (!yaml_emitter_emit(emitter, &event))
569 return -1;
571 for (i = 0; i < n_stmt; ++i)
572 if (emit_stmt(emitter, stmts[i]) < 0)
573 return -1;
575 if (!yaml_sequence_end_event_initialize(&event))
576 return -1;
577 if (!yaml_emitter_emit(emitter, &event))
578 return -1;
580 return 0;
583 /* Print "implication" to "emitter".
585 static int emit_implication(yaml_emitter_t *emitter,
586 struct pet_implication *implication)
588 yaml_event_t event;
590 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
591 YAML_BLOCK_MAPPING_STYLE))
592 return -1;
593 if (!yaml_emitter_emit(emitter, &event))
594 return -1;
596 if (emit_named_int(emitter, "satisfied", implication->satisfied) < 0)
597 return -1;
599 if (emit_named_map(emitter, "extension", implication->extension) < 0)
600 return -1;
602 if (!yaml_mapping_end_event_initialize(&event))
603 return -1;
604 if (!yaml_emitter_emit(emitter, &event))
605 return -1;
607 return 0;
610 /* Print the list of "n_implication" "implications", if any, to "emitter".
612 static int emit_implications(yaml_emitter_t *emitter, int n_implication,
613 struct pet_implication **implications)
615 int i;
616 yaml_event_t event;
618 if (n_implication == 0)
619 return 0;
621 if (emit_string(emitter, "implications") < 0)
622 return -1;
623 if (!yaml_sequence_start_event_initialize(&event, NULL, NULL, 1,
624 YAML_BLOCK_SEQUENCE_STYLE))
625 return -1;
626 if (!yaml_emitter_emit(emitter, &event))
627 return -1;
629 for (i = 0; i < n_implication; ++i)
630 if (emit_implication(emitter, implications[i]) < 0)
631 return -1;
633 if (!yaml_sequence_end_event_initialize(&event))
634 return -1;
635 if (!yaml_emitter_emit(emitter, &event))
636 return -1;
638 return 0;
641 static int emit_scop(yaml_emitter_t *emitter, struct pet_scop *scop)
643 yaml_event_t event;
645 if (!yaml_mapping_start_event_initialize(&event, NULL, NULL, 1,
646 YAML_BLOCK_MAPPING_STYLE))
647 return -1;
648 if (!yaml_emitter_emit(emitter, &event))
649 return -1;
651 if (emit_named_unsigned(emitter,
652 "start", pet_loc_get_start(scop->loc)) < 0)
653 return -1;
654 if (emit_named_unsigned(emitter, "end", pet_loc_get_end(scop->loc)) < 0)
655 return -1;
656 if (emit_string(emitter, "context") < 0)
657 return -1;
658 if (emit_set(emitter, scop->context) < 0)
659 return -1;
660 if (!isl_set_plain_is_universe(scop->context_value) &&
661 emit_named_set(emitter, "context_value", scop->context_value) < 0)
662 return -1;
664 if (emit_types(emitter, scop->n_type, scop->types) < 0)
665 return -1;
666 if (emit_arrays(emitter, scop->n_array, scop->arrays) < 0)
667 return -1;
669 if (emit_statements(emitter, scop->n_stmt, scop->stmts) < 0)
670 return -1;
672 if (emit_implications(emitter, scop->n_implication,
673 scop->implications) < 0)
674 return -1;
676 if (!yaml_mapping_end_event_initialize(&event))
677 return -1;
678 if (!yaml_emitter_emit(emitter, &event))
679 return -1;
681 return 0;
684 /* Print a YAML serialization of "scop" to "out".
686 int pet_scop_emit(FILE *out, struct pet_scop *scop)
688 yaml_emitter_t emitter;
689 yaml_event_t event;
691 yaml_emitter_initialize(&emitter);
693 yaml_emitter_set_output_file(&emitter, out);
695 yaml_stream_start_event_initialize(&event, YAML_UTF8_ENCODING);
696 if (!yaml_emitter_emit(&emitter, &event))
697 goto error;
699 if (!yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 1))
700 goto error;
701 if (!yaml_emitter_emit(&emitter, &event))
702 goto error;
704 if (emit_scop(&emitter, scop) < 0)
705 goto error;
707 if (!yaml_document_end_event_initialize(&event, 1))
708 goto error;
709 if (!yaml_emitter_emit(&emitter, &event))
710 goto error;
712 yaml_stream_end_event_initialize(&event);
713 if (!yaml_emitter_emit(&emitter, &event))
714 goto error;
716 yaml_emitter_delete(&emitter);
717 return 0;
718 error:
719 yaml_emitter_delete(&emitter);
720 return -1;