d524faa567fb07c83d1a0a3dad4381f0d21d2c12
[libfirm] / ir / ir / irio.c
1 /*
2  * Copyright (C) 1995-2009 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief   Write textual representation of firm to file.
23  * @author  Moritz Kroll
24  * @version $Id$
25  */
26 #include "config.h"
27
28 #include <string.h>
29
30 #include "irio.h"
31
32 #include "irnode_t.h"
33 #include "irprog.h"
34 #include "irgraph_t.h"
35 #include "ircons.h"
36 #include "irgmod.h"
37 #include "irflag_t.h"
38 #include "irgwalk.h"
39 #include "tv.h"
40 #include "array.h"
41 #include "error.h"
42 #include "adt/set.h"
43
44 #define SYMERROR ((unsigned) ~0)
45
46 typedef struct io_env_t
47 {
48         FILE *file;
49         set *idset;               /**< id_entry set, which maps from file ids to new Firm elements */
50         int ignoreblocks;
51         int line, col;
52         ir_type **fixedtypes;
53 } io_env_t;
54
55 typedef struct lex_state_t
56 {
57         long offs;
58         int line, col;
59 } lex_state_t;
60
61 typedef enum typetag_t
62 {
63         tt_align,
64         tt_allocation,
65         tt_builtin,
66         tt_initializer,
67         tt_iro,
68         tt_keyword,
69         tt_peculiarity,
70         tt_pin_state,
71         tt_tpo,
72         tt_type_state,
73         tt_variability,
74         tt_visibility,
75         tt_volatility
76 } typetag_t;
77
78 typedef enum keyword_t
79 {
80         kw_constirg,
81         kw_entity,
82         kw_frametype,
83         kw_irg,
84         kw_valuetype,
85         kw_type,
86         kw_typegraph
87 } keyword_t;
88
89 typedef struct symbol_t
90 {
91         const char *str;      /**< The name of this symbol. */
92         typetag_t   typetag;  /**< The type tag of this symbol. */
93         unsigned    code;     /**< The value of this symbol. */
94 } symbol_t;
95
96 typedef struct id_entry
97 {
98         long id;
99         void *elem;
100 } id_entry;
101
102 /** The symbol table, a set of symbol_t elements. */
103 static set *symtbl;
104
105
106 /**
107  * Calculate a hash value for a string.
108  */
109 static unsigned string_hash(const char *str, int len)
110 {
111         return str[0] * 27893 ^ str[len-1] * 81 ^ str[len >> 1];
112 }
113
114 /**
115  * Compare two symbol table entries.
116  */
117 static int symbol_cmp(const void *elt, const void *key, size_t size)
118 {
119         int res;
120         const symbol_t *entry = (const symbol_t *) elt;
121         const symbol_t *keyentry = (const symbol_t *) key;
122         (void) size;
123         res = entry->typetag - keyentry->typetag;
124         if(res) return res;
125         return strcmp(entry->str, keyentry->str);
126 }
127
128 static int id_cmp(const void *elt, const void *key, size_t size)
129 {
130         const id_entry *entry = (const id_entry *) elt;
131         const id_entry *keyentry = (const id_entry *) key;
132         (void) size;
133         return entry->id - keyentry->id;
134 }
135
136 /** Initializes the symbol table. May be called more than once without problems. */
137 static void symtbl_init(void)
138 {
139         symbol_t key;
140
141         /* Only initialize once */
142         if(symtbl != NULL)
143                 return;
144
145         symtbl = new_set(symbol_cmp, 256);
146
147 #define INSERT(s, tt, cod)                                       \
148         key.str = (s);                                               \
149         key.typetag = (tt);                                          \
150         key.code = (cod);                                            \
151         set_insert(symtbl, &key, sizeof(key), string_hash(s, sizeof(s)-1) + tt * 17)
152
153 #define INSERTENUM(tt, e) INSERT(#e, tt, e)
154 #define INSERTKEYWORD(k) INSERT(#k, tt_keyword, kw_##k)
155
156         INSERT("array", tt_tpo, tpo_array);
157         INSERT("class", tt_tpo, tpo_class);
158         INSERT("method", tt_tpo, tpo_method);
159         INSERT("pointer", tt_tpo, tpo_pointer);
160         INSERT("primitive", tt_tpo, tpo_primitive);
161         INSERT("struct", tt_tpo, tpo_struct);
162         INSERT("union", tt_tpo, tpo_union);
163         INSERT("Unknown", tt_tpo, tpo_unknown);
164
165         INSERTKEYWORD(constirg);
166         INSERTKEYWORD(entity);
167         INSERTKEYWORD(frametype);
168         INSERTKEYWORD(irg);
169         INSERTKEYWORD(valuetype);
170         INSERTKEYWORD(type);
171         INSERTKEYWORD(typegraph);
172
173 #include "gen_irio_lex.inl"
174
175         INSERTENUM(tt_align, align_non_aligned);
176         INSERTENUM(tt_align, align_is_aligned);
177
178         INSERTENUM(tt_allocation, allocation_automatic);
179         INSERTENUM(tt_allocation, allocation_parameter);
180         INSERTENUM(tt_allocation, allocation_dynamic);
181         INSERTENUM(tt_allocation, allocation_static);
182
183         INSERTENUM(tt_pin_state, op_pin_state_floats);
184         INSERTENUM(tt_pin_state, op_pin_state_pinned);
185         INSERTENUM(tt_pin_state, op_pin_state_exc_pinned);
186         INSERTENUM(tt_pin_state, op_pin_state_mem_pinned);
187
188         INSERTENUM(tt_type_state, layout_undefined);
189         INSERTENUM(tt_type_state, layout_fixed);
190
191         INSERTENUM(tt_variability, variability_uninitialized);
192         INSERTENUM(tt_variability, variability_initialized);
193         INSERTENUM(tt_variability, variability_part_constant);
194         INSERTENUM(tt_variability, variability_constant);
195
196         INSERTENUM(tt_visibility, visibility_local);
197         INSERTENUM(tt_visibility, visibility_external_visible);
198         INSERTENUM(tt_visibility, visibility_external_allocated);
199
200         INSERTENUM(tt_volatility, volatility_non_volatile);
201         INSERTENUM(tt_volatility, volatility_is_volatile);
202
203         INSERTENUM(tt_peculiarity, peculiarity_description);
204         INSERTENUM(tt_peculiarity, peculiarity_inherited);
205         INSERTENUM(tt_peculiarity, peculiarity_existent);
206
207         INSERTENUM(tt_initializer, IR_INITIALIZER_CONST);
208         INSERTENUM(tt_initializer, IR_INITIALIZER_TARVAL);
209         INSERTENUM(tt_initializer, IR_INITIALIZER_NULL);
210         INSERTENUM(tt_initializer, IR_INITIALIZER_COMPOUND);
211
212         INSERTENUM(tt_builtin, ir_bk_trap);
213         INSERTENUM(tt_builtin, ir_bk_debugbreak);
214         INSERTENUM(tt_builtin, ir_bk_return_address);
215         INSERTENUM(tt_builtin, ir_bk_frame_addess);
216         INSERTENUM(tt_builtin, ir_bk_prefetch);
217         INSERTENUM(tt_builtin, ir_bk_ffs);
218         INSERTENUM(tt_builtin, ir_bk_clz);
219         INSERTENUM(tt_builtin, ir_bk_ctz);
220         INSERTENUM(tt_builtin, ir_bk_popcount);
221         INSERTENUM(tt_builtin, ir_bk_parity);
222         INSERTENUM(tt_builtin, ir_bk_bswap);
223         INSERTENUM(tt_builtin, ir_bk_inport);
224         INSERTENUM(tt_builtin, ir_bk_outport);
225         INSERTENUM(tt_builtin, ir_bk_inner_trampoline);
226
227 #undef INSERTENUM
228 #undef INSERT
229 }
230
231 /** Returns the according symbol value for the given string and tag, or SYMERROR if none was found. */
232 static unsigned symbol(const char *str, typetag_t typetag)
233 {
234         symbol_t key, *entry;
235
236         key.str = str;
237         key.typetag = typetag;
238
239         entry = set_find(symtbl, &key, sizeof(key), string_hash(str, strlen(str)) + typetag * 17);
240         return entry ? entry->code : SYMERROR;
241 }
242
243 static void *get_id(io_env_t *env, long id)
244 {
245         id_entry key, *entry;
246         key.id = id;
247
248         entry = set_find(env->idset, &key, sizeof(key), (unsigned) id);
249         return entry ? entry->elem : NULL;
250 }
251
252 static void set_id(io_env_t *env, long id, void *elem)
253 {
254         id_entry key;
255         key.id = id;
256         key.elem = elem;
257         set_insert(env->idset, &key, sizeof(key), (unsigned) id);
258 }
259
260 static void write_mode(io_env_t *env, ir_mode *mode)
261 {
262         fputs(get_mode_name(mode), env->file);
263         fputc(' ', env->file);
264 }
265
266 static void write_tarval(io_env_t *env, tarval *tv)
267 {
268         char buf[1024];
269         write_mode(env, get_tarval_mode(tv));
270         tarval_snprintf(buf, sizeof(buf), tv);
271         fputs(buf, env->file);
272         fputc(' ', env->file);
273 }
274
275 static void write_pin_state(io_env_t *env, ir_node *irn)
276 {
277         fputs(get_op_pin_state_name(get_irn_pinned(irn)), env->file);
278         fputc(' ', env->file);
279 }
280
281 static void write_volatility(io_env_t *env, ir_node *irn)
282 {
283         ir_volatility vol;
284
285         if(is_Load(irn)) vol = get_Load_volatility(irn);
286         else if(is_Store(irn)) vol = get_Store_volatility(irn);
287         else assert(0 && "Invalid optype for write_volatility");
288
289         fputs(get_volatility_name(vol), env->file);
290         fputc(' ', env->file);
291 }
292
293 static void write_align(io_env_t *env, ir_node *irn)
294 {
295         ir_align align;
296
297         if(is_Load(irn)) align = get_Load_align(irn);
298         else if(is_Store(irn)) align = get_Store_align(irn);
299         else assert(0 && "Invalid optype for write_align");
300
301         fputs(get_align_name(align), env->file);
302         fputc(' ', env->file);
303 }
304
305 static void write_builtin_kind(io_env_t *env, ir_node *irn)
306 {
307         fputs(get_builtin_kind_name(get_Builtin_kind(irn)), env->file);
308         fputc(' ', env->file);
309 }
310
311 static void write_initializer(io_env_t *env, ir_initializer_t *ini)
312 {
313         FILE *f = env->file;
314         ir_initializer_kind_t ini_kind = get_initializer_kind(ini);
315
316         fputs(get_initializer_kind_name(ini_kind), f);
317         fputc(' ', f);
318
319         switch(ini_kind)
320         {
321                 case IR_INITIALIZER_CONST:
322                         fprintf(f, "%ld ", get_irn_node_nr(get_initializer_const_value(ini)));
323                         break;
324
325                 case IR_INITIALIZER_TARVAL:
326                         write_tarval(env, get_initializer_tarval_value(ini));
327                         break;
328
329                 case IR_INITIALIZER_NULL:
330                         break;
331
332                 case IR_INITIALIZER_COMPOUND:
333                 {
334                         unsigned i, n = get_initializer_compound_n_entries(ini);
335                         fprintf(f, "%d ", n);
336                         for(i = 0; i < n; i++)
337                                 write_initializer(env, get_initializer_compound_value(ini, i));
338                         break;
339                 }
340
341                 default:
342                         panic("Unknown initializer kind");
343         }
344 }
345
346 static void export_type(io_env_t *env, ir_type *tp)
347 {
348         FILE *f = env->file;
349         int i;
350         fprintf(f, "\t%s %ld %s \"%s\" %u %u %s %s ",
351                         is_frame_type(tp) ? "frametype" : is_value_param_type(tp) ? "valuetype" : "type",
352                         get_type_nr(tp),
353                         get_type_tpop_name(tp),
354                         get_type_name(tp),
355                         get_type_size_bytes(tp),
356                         get_type_alignment_bytes(tp),
357                         get_type_state_name(get_type_state(tp)),
358                         get_visibility_name(get_type_visibility(tp)));
359
360         switch(get_type_tpop_code(tp))
361         {
362                 case tpo_array:
363                 {
364                         int n = get_array_n_dimensions(tp);
365                         fprintf(f, "%i %ld ", n, get_type_nr(get_array_element_type(tp)));
366                         for(i = 0; i < n; i++)
367                         {
368                                 ir_node *lower = get_array_lower_bound(tp, i);
369                                 ir_node *upper = get_array_upper_bound(tp, i);
370
371                                 if(is_Const(lower)) fprintf(f, "%ld ", get_tarval_long(get_Const_tarval(lower)));
372                                 else panic("Lower array bound is not constant");
373
374                                 if(is_Const(upper)) fprintf(f, "%ld ", get_tarval_long(get_Const_tarval(upper)));
375                                 else if(is_Unknown(upper)) fputs("unknown ", f);
376                                 else panic("Upper array bound is not constant");
377                         }
378                         break;
379                 }
380
381                 case tpo_class:
382                         /* TODO: inheritance stuff not supported yet */
383                         printf("Inheritance of classes not supported yet!\n");
384                         break;
385
386                 case tpo_method:
387                 {
388                         int nparams = get_method_n_params(tp);
389                         int nresults = get_method_n_ress(tp);
390                         fprintf(f, "0x%X 0x%X %i %i ", get_method_calling_convention(tp),
391                                 get_method_additional_properties(tp), nparams, nresults);
392                         for(i = 0; i < nparams; i++)
393                                 fprintf(f, "%ld ", get_type_nr(get_method_param_type(tp, i)));
394                         for(i = 0; i < nresults; i++)
395                                 fprintf(f, "%ld ", get_type_nr(get_method_res_type(tp, i)));
396                         break;
397                 }
398
399                 case tpo_pointer:
400                         write_mode(env, get_type_mode(tp));
401                         fprintf(f, "%ld ", get_type_nr(get_pointer_points_to_type(tp)));
402                         break;
403
404                 case tpo_primitive:
405                         write_mode(env, get_type_mode(tp));
406                         break;
407
408                 case tpo_struct:
409                         break;
410
411                 case tpo_union:
412                         break;
413
414                 case tpo_unknown:
415                         break;
416
417                 default:
418                         printf("export_type: Unknown type code \"%s\".\n", get_type_tpop_name(tp));
419                         break;
420         }
421         fputc('\n', f);
422 }
423
424 static void export_entity(io_env_t *env, ir_entity *ent)
425 {
426         ir_type *owner = get_entity_owner(ent);
427         fprintf(env->file, "\tentity %ld \"%s\" \"%s\" %ld %ld %d %u %s %s %s %s %s ",
428                         get_entity_nr(ent),
429                         get_entity_name(ent),
430                         ent->ld_name ? get_id_str(ent->ld_name) : "",
431                         get_type_nr(get_entity_type(ent)),
432                         get_type_nr(owner),
433                         get_entity_offset(ent),
434                         (unsigned) get_entity_offset_bits_remainder(ent),
435                         get_allocation_name(get_entity_allocation(ent)),
436                         get_visibility_name(get_entity_visibility(ent)),
437                         get_variability_name(get_entity_variability(ent)),
438                         get_peculiarity_name(get_entity_peculiarity(ent)),
439                         get_volatility_name(get_entity_volatility(ent)));
440
441         // TODO: inheritance stuff for class entities not supported yet
442         if(is_Class_type(owner) && owner != get_glob_type())
443                 printf("Inheritance of class entities not supported yet!\n");
444
445         if(get_entity_variability(ent) != variability_uninitialized
446                 && get_entity_visibility(ent) != visibility_external_allocated)
447         {
448                 if(is_compound_entity(ent))
449                 {
450                         if(has_entity_initializer(ent))
451                         {
452                                 fputs("initializer ", env->file);
453                                 write_initializer(env, get_entity_initializer(ent));
454                         }
455                         else
456                         {
457                                 int i, n = get_compound_ent_n_values(ent);
458                                 fputs("noninitializer ", env->file);
459                                 fprintf(env->file, "%d ", n);
460                                 for(i = 0; i < n; i++)
461                                 {
462                                         ir_entity *member = get_compound_ent_value_member(ent, i);
463                                         ir_node   *irn    = get_compound_ent_value(ent, i);
464                                         fprintf(env->file, "%ld %ld ", get_entity_nr(member), get_irn_node_nr(irn));
465                                 }
466                         }
467                 }
468                 else
469                 {
470                         ir_node *irn = get_atomic_ent_value(ent);
471                         fprintf(env->file, "%ld ", get_irn_node_nr(irn));
472                 }
473         }
474
475         fputc('\n', env->file);
476 }
477
478 static void export_type_or_ent(type_or_ent tore, void *ctx)
479 {
480         io_env_t *env = (io_env_t *) ctx;
481
482         switch(get_kind(tore.ent))
483         {
484                 case k_entity:
485                         export_entity(env, tore.ent);
486                         break;
487
488                 case k_type:
489                         export_type(env, tore.typ);
490                         break;
491
492                 default:
493                         printf("export_type_or_ent: Unknown type or entity.\n");
494                         break;
495         }
496 }
497
498 static void export_node(ir_node *irn, void *ctx)
499 {
500         io_env_t *env = (io_env_t *) ctx;
501         int i, n;
502         unsigned opcode = get_irn_opcode(irn);
503
504         if(env->ignoreblocks && opcode == iro_Block)
505                 return;
506
507         n = get_irn_arity(irn);
508
509         fprintf(env->file, "\t%s %ld [ ", get_irn_opname(irn), get_irn_node_nr(irn));
510
511         for(i = -1; i < n; i++)
512         {
513                 ir_node *pred = get_irn_n(irn, i);
514                 if(pred == NULL) {
515                         /* Anchor node may have NULL predecessors */
516                         assert(is_Anchor(irn));
517                         fputs("-1 ", env->file);
518                 } else {
519                         fprintf(env->file, "%ld ", get_irn_node_nr(pred));
520                 }
521         }
522
523         fprintf(env->file, "] { ");
524
525         switch(opcode)
526         {
527                 #include "gen_irio_export.inl"
528         }
529         fputs("}\n", env->file);
530 }
531
532 /** Exports the whole irp to the given file in a textual form. */
533 void ir_export(const char *filename)
534 {
535         io_env_t env;
536         int i, n_irgs = get_irp_n_irgs(), n_pseudoirgs = get_irp_n_pseudo_irgs();
537
538         env.file = fopen(filename, "wt");
539         if(!env.file)
540         {
541                 perror(filename);
542                 return;
543         }
544
545         fputs("typegraph {\n", env.file);
546
547         type_walk_plus_frames(NULL, export_type_or_ent, &env);
548         /* TODO: Visit frame types and "types for value params"? */
549
550         for(i = 0; i < n_irgs; i++)
551         {
552                 ir_graph *irg = get_irp_irg(i);
553                 ir_type *valuetype = get_irg_value_param_type(irg);
554
555                 fprintf(env.file, "}\n\nirg %ld %ld %ld {\n", get_entity_nr(get_irg_entity(irg)),
556                         get_type_nr(get_irg_frame_type(irg)),
557                         valuetype == NULL ? -1 : get_type_nr(valuetype));
558
559                 env.ignoreblocks = 0;
560                 irg_block_walk_graph(irg, NULL, export_node, &env);
561
562                 env.ignoreblocks = 1;
563                 irg_walk_anchors(irg, NULL, export_node, &env);
564         }
565
566         fputs("}\n\nconstirg {\n", env.file);
567         walk_const_code(NULL, export_node, &env);
568         fputs("}\n", env.file);
569
570         fclose(env.file);
571 }
572
573 /** Exports the given irg to the given file. */
574 void ir_export_irg(ir_graph *irg, const char *filename)
575 {
576         io_env_t env;
577
578         env.file = fopen(filename, "wt");
579         if(!env.file)
580         {
581                 perror(filename);
582                 return;
583         }
584
585         fputs("typegraph {\n", env.file);
586
587         type_walk_irg(irg, NULL, export_type_or_ent, &env);
588
589         fprintf(env.file, "}\n\nirg %ld {\n", get_entity_nr(get_irg_entity(irg)));
590
591         env.ignoreblocks = 0;
592         irg_block_walk_graph(irg, NULL, export_node, &env);
593
594         env.ignoreblocks = 1;
595         irg_walk_anchors(irg, NULL, export_node, &env);
596
597         /* TODO: Only output needed constants */
598         fputs("}\n\nconstirg {\n", env.file);
599         walk_const_code(NULL, export_node, &env);
600         fputs("}\n", env.file);
601
602         fclose(env.file);
603 }
604
605 static void save_lex_state(io_env_t *env, lex_state_t *state)
606 {
607         state->offs = ftell(env->file);
608         state->line = env->line;
609         state->col  = env->col;
610 }
611
612 static void restore_lex_state(io_env_t *env, lex_state_t *state)
613 {
614         fseek(env->file, state->offs, SEEK_SET);
615         env->line = state->line;
616         env->col  = state->col;
617 }
618
619 static int read_c(io_env_t *env)
620 {
621         int ch = fgetc(env->file);
622         switch(ch)
623         {
624                 case '\t':
625                         env->col += 4;
626                         break;
627
628                 case '\n':
629                         env->col = 0;
630                         env->line++;
631                         break;
632
633                 default:
634                         env->col++;
635                         break;
636         }
637         return ch;
638 }
639
640 /** Returns the first non-whitespace character or EOF. **/
641 static int skip_ws(io_env_t *env)
642 {
643         while(1)
644         {
645                 int ch = read_c(env);
646                 switch(ch)
647                 {
648                         case ' ':
649                         case '\t':
650                         case '\n':
651                         case '\r':
652                                 break;
653
654                         default:
655                                 return ch;
656                 }
657         }
658 }
659
660 static void skip_to(io_env_t *env, char to_ch)
661 {
662         int ch;
663         do
664         {
665                 ch = read_c(env);
666         }
667         while(ch != to_ch && ch != EOF);
668 }
669
670 static int expect_char(io_env_t *env, char ch)
671 {
672         int curch = skip_ws(env);
673         if(curch != ch)
674         {
675                 printf("Unexpected char '%c', expected '%c' in line %i:%i\n", curch, ch, env->line, env->col);
676                 return 0;
677         }
678         return 1;
679 }
680
681 #define EXPECT(c) if(expect_char(env, (c))) {} else return 0
682 #define EXPECT_OR_EXIT(c) if(expect_char(env, (c))) {} else exit(1)
683
684 inline static const char *read_str_to(io_env_t *env, char *buf, size_t bufsize)
685 {
686         size_t i;
687         for(i = 0; i < bufsize - 1; i++)
688         {
689                 int ch = read_c(env);
690                 if(ch == EOF) break;
691                 switch(ch)
692                 {
693                         case ' ':
694                         case '\t':
695                         case '\n':
696                         case '\r':
697                                 if(i != 0)
698                                         goto endofword;
699                                 i--;    // skip whitespace
700                                 break;
701
702                         default:
703                                 buf[i] = ch;
704                                 break;
705                 }
706         }
707 endofword:
708         buf[i] = 0;
709         return buf;
710 }
711
712 static const char *read_str(io_env_t *env)
713 {
714         static char buf[1024];
715         return read_str_to(env, buf, sizeof(buf));
716 }
717
718 static const char *read_qstr_to(io_env_t *env, char *buf, size_t bufsize)
719 {
720         size_t i;
721         EXPECT_OR_EXIT('\"');
722         for(i = 0; i < bufsize - 1; i++)
723         {
724                 int ch = read_c(env);
725                 if(ch == EOF)
726                 {
727                         printf("Unexpected end of quoted string!\n");
728                         exit(1);
729                 }
730                 if(ch == '\"') break;
731
732                 buf[i] = ch;
733         }
734         if(i == bufsize - 1)
735         {
736                 printf("Quoted string too long!\n");
737                 exit(1);
738         }
739         buf[i] = 0;
740         return buf;
741 }
742
743 static long read_long2(io_env_t *env, char **endptr)
744 {
745         static char buf[1024];
746         return strtol(read_str_to(env, buf, sizeof(buf)), endptr, 0);
747 }
748
749 static long read_long(io_env_t *env)
750 {
751         return read_long2(env, NULL);
752 }
753
754 static ir_node *get_node_or_null(io_env_t *env, long nodenr)
755 {
756         ir_node *node = (ir_node *) get_id(env, nodenr);
757         if(node && node->kind != k_ir_node)
758         {
759                 panic("Irn ID %ld collides with something else in line %i:%i\n", nodenr, env->line, env->col);
760         }
761         return node;
762 }
763
764 static ir_node *get_node(io_env_t *env, long nodenr)
765 {
766         ir_node *node = get_node_or_null(env, nodenr);
767         if(!node)
768                 panic("Unknown node: %ld in line %i:%i\n", nodenr, env->line, env->col);
769
770         return node;
771 }
772
773 static ir_node *get_node_or_dummy(io_env_t *env, long nodenr)
774 {
775         ir_node *node = get_node_or_null(env, nodenr);
776         if(!node)
777         {
778                 node = new_Dummy(mode_X);
779                 set_id(env, nodenr, node);
780         }
781         return node;
782 }
783
784 static ir_type *get_type(io_env_t *env, long typenr)
785 {
786         ir_type *type = (ir_type *) get_id(env, typenr);
787         if(!type)
788         {
789                 panic("Unknown type: %ld in line %i:%i\n", typenr, env->line, env->col);
790         }
791         else if(type->kind != k_type)
792         {
793                 panic("Type ID %ld collides with something else in line %i:%i\n", typenr, env->line, env->col);
794         }
795         return type;
796 }
797
798 static ir_type *read_type(io_env_t *env)
799 {
800         return get_type(env, read_long(env));
801 }
802
803 static ir_entity *get_entity(io_env_t *env, long entnr)
804 {
805         ir_entity *entity = (ir_entity *) get_id(env, entnr);
806         if(!entity)
807         {
808                 printf("Unknown entity: %ld in line %i:%i\n", entnr, env->line, env->col);
809                 exit(1);
810         }
811         else if(entity->kind != k_entity)
812         {
813                 panic("Entity ID %ld collides with something else in line %i:%i\n", entnr, env->line, env->col);
814         }
815         return entity;
816 }
817
818 static ir_entity *read_entity(io_env_t *env)
819 {
820         return get_entity(env, read_long(env));
821 }
822
823 static ir_mode *read_mode(io_env_t *env)
824 {
825         static char buf[128];
826         int i, n;
827
828         read_str_to(env, buf, sizeof(buf));
829
830         n = get_irp_n_modes();
831         for(i = 0; i < n; i++)
832         {
833                 ir_mode *mode = get_irp_mode(i);
834                 if(!strcmp(buf, get_mode_name(mode)))
835                         return mode;
836         }
837
838         printf("Unknown mode \"%s\" in line %i:%i\n", buf, env->line, env->col);
839         return mode_ANY;
840 }
841
842 static const char *get_typetag_name(typetag_t typetag)
843 {
844         switch(typetag)
845         {
846                 case tt_align:       return "align";
847                 case tt_allocation:  return "allocation";
848                 case tt_builtin:     return "builtin kind";
849                 case tt_initializer: return "initializer kind";
850                 case tt_iro:         return "opcode";
851                 case tt_peculiarity: return "peculiarity";
852                 case tt_pin_state:   return "pin state";
853                 case tt_tpo:         return "type";
854                 case tt_type_state:  return "type state";
855                 case tt_variability: return "variability";
856                 case tt_visibility:  return "visibility";
857                 case tt_volatility:  return "volatility";
858                 default: return "<UNKNOWN>";
859         }
860 }
861
862 /**
863  * Read and decode an enum constant.
864  */
865 static unsigned read_enum(io_env_t *env, typetag_t typetag)
866 {
867         static char buf[128];
868         unsigned code = symbol(read_str_to(env, buf, sizeof(buf)), typetag);
869         if(code != SYMERROR)
870                 return code;
871
872         printf("Invalid %s: \"%s\" in %i:%i\n", get_typetag_name(typetag), buf, env->line, env->col);
873         return 0;
874 }
875
876 #define read_align(env)            ((ir_align)              read_enum(env, tt_align))
877 #define read_allocation(env)       ((ir_allocation)         read_enum(env, tt_allocation))
878 #define read_peculiarity(env)      ((ir_peculiarity)        read_enum(env, tt_peculiarity))
879 #define read_pin_state(env)        ((op_pin_state)          read_enum(env, tt_pin_state))
880 #define read_type_state(env)       ((ir_type_state)         read_enum(env, tt_type_state))
881 #define read_variability(env)      ((ir_variability)        read_enum(env, tt_variability))
882 #define read_visibility(env)       ((ir_visibility)         read_enum(env, tt_visibility))
883 #define read_volatility(env)       ((ir_volatility)         read_enum(env, tt_volatility))
884 #define read_initializer_kind(env) ((ir_initializer_kind_t) read_enum(env, tt_initializer))
885 #define read_builtin_kind(env)     ((ir_builtin_kind)       read_enum(env, tt_builtin))
886
887 static ir_cons_flags get_cons_flags(io_env_t *env)
888 {
889         ir_cons_flags flags = cons_none;
890
891         op_pin_state pinstate = read_pin_state(env);
892         switch(pinstate)
893         {
894                 case op_pin_state_floats: flags |= cons_floats; break;
895                 case op_pin_state_pinned: break;
896                 default:
897                         panic("Error in %i:%i: Invalid pinstate: %s", env->line, env->col, get_op_pin_state_name(pinstate));
898         }
899
900         if(read_volatility(env) == volatility_is_volatile) flags |= cons_volatile;
901         if(read_align(env) == align_non_aligned) flags |= cons_unaligned;
902
903         return flags;
904 }
905
906 static tarval *read_tv(io_env_t *env)
907 {
908         static char buf[128];
909         ir_mode *tvmode = read_mode(env);
910         read_str_to(env, buf, sizeof(buf));
911         return new_tarval_from_str(buf, strlen(buf), tvmode);
912 }
913
914 static ir_initializer_t *read_initializer(io_env_t *env)
915 {
916         FILE *f = env->file;
917         ir_initializer_kind_t ini_kind = read_initializer_kind(env);
918
919         switch(ini_kind)
920         {
921                 case IR_INITIALIZER_CONST:
922                 {
923                         ir_node *irn = get_node_or_dummy(env, read_long(env));
924                         return create_initializer_const(irn);
925                 }
926
927                 case IR_INITIALIZER_TARVAL:
928                         return create_initializer_tarval(read_tv(env));
929
930                 case IR_INITIALIZER_NULL:
931                         return get_initializer_null();
932
933                 case IR_INITIALIZER_COMPOUND:
934                 {
935                         unsigned i, n = (unsigned) read_long(env);
936                         ir_initializer_t *ini = create_initializer_compound(n);
937                         for(i = 0; i < n; i++)
938                         {
939                                 ir_initializer_t *curini = read_initializer(env);
940                                 set_initializer_compound_value(ini, i, curini);
941                         }
942                         return ini;
943                 }
944
945                 default:
946                         panic("Unknown initializer kind");
947         }
948 }
949
950
951 /** Reads a type description and remembers it by its id. */
952 static void import_type(io_env_t *env, keyword_t kwkind)
953 {
954         char           buf[1024];
955         int            i;
956         ir_type       *type;
957         long           typenr = read_long(env);
958         const char    *tpop   = read_str(env);
959         const char    *name   = read_qstr_to(env, buf, sizeof(buf));
960         unsigned       size   = (unsigned) read_long(env);
961         unsigned       align  = (unsigned) read_long(env);
962         ir_type_state  state  = read_type_state(env);
963         ir_visibility  vis    = read_visibility(env);
964
965         ident         *id     = new_id_from_str(name);
966
967         const char    *kindstr;
968
969         if(kwkind == kw_frametype)
970         {
971                 if(symbol(tpop, tt_tpo) != tpo_class)
972                 {
973                         printf("Frame type must be a class type in line %i:%i\n", env->line, env->col);
974                         skip_to(env, '\n');
975                         return;
976                 }
977
978                 type = new_type_frame(id);
979                 set_type_size_bytes(type, size);
980
981                 kindstr = "frametype";
982         }
983         else if(kwkind == kw_valuetype)
984         {
985                 if(symbol(tpop, tt_tpo) != tpo_struct)
986                 {
987                         printf("Value type must be a struct type in line %i:%i\n", env->line, env->col);
988                         skip_to(env, '\n');
989                         return;
990                 }
991
992                 type = new_type_value(id);
993                 set_type_size_bytes(type, size);
994
995                 kindstr = "valuetype";
996         }
997         else
998         {
999                 switch(symbol(tpop, tt_tpo))
1000                 {
1001                         case tpo_array:
1002                         {
1003                                 int ndims = (int) read_long(env);
1004                                 long elemtypenr = read_long(env);
1005                                 ir_type *elemtype = get_type(env, elemtypenr);
1006
1007                                 type = new_type_array(id, ndims, elemtype);
1008                                 for(i = 0; i < ndims; i++)
1009                                 {
1010                                         const char *str = read_str(env);
1011                                         if(strcmp(str, "unknown"))
1012                                         {
1013                                                 long lowerbound = strtol(str, NULL, 0);
1014                                                 set_array_lower_bound_int(type, i, lowerbound);
1015                                         }
1016                                         str = read_str(env);
1017                                         if(strcmp(str, "unknown"))
1018                                         {
1019                                                 long upperbound = strtol(str, NULL, 0);
1020                                                 set_array_upper_bound_int(type, i, upperbound);
1021                                         }
1022                                 }
1023                                 set_type_size_bytes(type, size);
1024                                 break;
1025                         }
1026
1027                         case tpo_class:
1028                                 type = new_type_class(id);
1029                                 set_type_size_bytes(type, size);
1030                                 break;
1031
1032                         case tpo_method:
1033                         {
1034                                 unsigned callingconv = (unsigned) read_long(env);
1035                                 unsigned addprops    = (unsigned) read_long(env);
1036                                 int nparams          = (int)      read_long(env);
1037                                 int nresults         = (int)      read_long(env);
1038
1039                                 type = new_type_method(id, nparams, nresults);
1040
1041                                 for(i = 0; i < nparams; i++)
1042                                 {
1043                                         long     typenr = read_long(env);
1044                                         ir_type *paramtype = get_type(env, typenr);
1045
1046                                         set_method_param_type(type, i, paramtype);
1047                                 }
1048                                 for(i = 0; i < nresults; i++)
1049                                 {
1050                                         long typenr = read_long(env);
1051                                         ir_type *restype = get_type(env, typenr);
1052
1053                                         set_method_res_type(type, i, restype);
1054                                 }
1055
1056                                 set_method_calling_convention(type, callingconv);
1057                                 set_method_additional_properties(type, addprops);
1058                                 break;
1059                         }
1060
1061                         case tpo_pointer:
1062                         {
1063                                 ir_mode *mode = read_mode(env);
1064                                 ir_type *pointsto = get_type(env, read_long(env));
1065                                 type = new_type_pointer(id, pointsto, mode);
1066                                 break;
1067                         }
1068
1069                         case tpo_primitive:
1070                         {
1071                                 ir_mode *mode = read_mode(env);
1072                                 type = new_type_primitive(id, mode);
1073                                 break;
1074                         }
1075
1076                         case tpo_struct:
1077                                 type = new_type_struct(id);
1078                                 set_type_size_bytes(type, size);
1079                                 break;
1080
1081                         case tpo_union:
1082                                 type = new_type_union(id);
1083                                 set_type_size_bytes(type, size);
1084                                 break;
1085
1086                         case tpo_unknown:
1087                                 return;   // ignore unknown type
1088
1089                         default:
1090                                 if(typenr != 0)  // ignore global type
1091                                         printf("Unknown type kind: \"%s\" in line %i:%i\n", tpop, env->line, env->col);
1092                                 skip_to(env, '\n');
1093                                 return;
1094                 }
1095                 kindstr = "type";
1096         }
1097
1098         set_type_alignment_bytes(type, align);
1099         set_type_visibility(type, vis);
1100
1101         if(state == layout_fixed)
1102                 ARR_APP1(ir_type *, env->fixedtypes, type);
1103
1104         set_id(env, typenr, type);
1105         printf("Insert %s %s %ld\n", kindstr, name, typenr);
1106 }
1107
1108 /** Reads an entity description and remembers it by its id. */
1109 static void import_entity(io_env_t *env)
1110 {
1111         char          buf[1024], buf2[1024];
1112         long          entnr       = read_long(env);
1113         const char   *name        = read_qstr_to(env, buf, sizeof(buf));
1114         const char   *ld_name     = read_qstr_to(env, buf2, sizeof(buf2));
1115         long          typenr      = read_long(env);
1116         long          ownertypenr = read_long(env);
1117
1118         ir_type   *type      = get_type(env, typenr);
1119         ir_type   *ownertype = !ownertypenr ? get_glob_type() : get_type(env, ownertypenr);
1120         ir_entity *entity    = new_entity(ownertype, new_id_from_str(name), type);
1121
1122         if(*ld_name) set_entity_ld_ident(entity, new_id_from_str(ld_name));
1123         set_entity_offset     (entity, (int) read_long(env));
1124         set_entity_offset_bits_remainder(entity, (unsigned char) read_long(env));
1125         set_entity_allocation (entity, read_allocation(env));
1126         set_entity_visibility (entity, read_visibility(env));
1127         set_entity_variability(entity, read_variability(env));
1128         set_entity_peculiarity(entity, read_peculiarity(env));
1129         set_entity_volatility (entity, read_volatility(env));
1130
1131         if(get_entity_variability(entity) != variability_uninitialized
1132                 && get_entity_visibility(entity) != visibility_external_allocated)
1133         {
1134                 if(is_compound_entity(entity))
1135                 {
1136                         if(!strcmp(read_str_to(env, buf2, sizeof(buf2)), "initializer"))
1137                         {
1138                                 set_entity_initializer(entity, read_initializer(env));
1139                         }
1140                         else
1141                         {
1142                                 int i, n = (int) read_long(env);
1143                                 for(i = 0; i < n; i++)
1144                                 {
1145                                         ir_entity *member = get_entity(env, read_long(env));
1146                                         ir_node   *irn    = get_node_or_dummy(env, read_long(env));
1147                                         add_compound_ent_value(entity, irn, member);
1148                                 }
1149                         }
1150                 }
1151                 else
1152                 {
1153                         ir_node *irn = get_node_or_dummy(env, read_long(env));
1154                         set_atomic_ent_value(entity, irn);
1155                 }
1156         }
1157
1158         set_id(env, entnr, entity);
1159         printf("Insert entity %s %ld\n", name, entnr);
1160 }
1161
1162 /** Parses the whole type graph. */
1163 static int parse_typegraph(io_env_t *env)
1164 {
1165         const char *kind;
1166         lex_state_t oldstate;
1167
1168         EXPECT('{');
1169
1170         save_lex_state(env, &oldstate);
1171
1172         current_ir_graph = get_const_code_irg();
1173
1174         // parse all types first
1175         while(1)
1176         {
1177                 int isframetype = 0;
1178
1179                 kind = read_str(env);
1180                 if(kind[0] == '}' && !kind[1]) break;
1181
1182                 keyword_t kwkind = (keyword_t) symbol(kind, tt_keyword);
1183                 switch(kwkind)
1184                 {
1185                         case kw_type:
1186                         case kw_frametype:
1187                         case kw_valuetype:
1188                                 import_type(env, kwkind);
1189                                 break;
1190
1191                         default:
1192                                 skip_to(env, '\n');
1193                                 break;
1194                 }
1195         }
1196
1197         // now parse rest
1198         restore_lex_state(env, &oldstate);
1199
1200         while(1)
1201         {
1202                 kind = read_str(env);
1203                 if(kind[0] == '}' && !kind[1]) break;
1204
1205                 switch(symbol(kind, tt_keyword))
1206                 {
1207                         case kw_type:
1208                         case kw_frametype:
1209                         case kw_valuetype:
1210                                 skip_to(env, '\n');
1211                                 break;
1212
1213                         case kw_entity:
1214                                 import_entity(env);
1215                                 break;
1216
1217                         default:
1218                                 printf("Type graph element not supported yet: \"%s\"\n", kind);
1219                                 skip_to(env, '\n');
1220                                 break;
1221                 }
1222         }
1223         return 1;
1224 }
1225
1226 static int read_node_header(io_env_t *env, long *nodenr, long **preds, const char **nodename)
1227 {
1228         int numpreds;
1229         *nodename = read_str(env);
1230         if((*nodename)[0] == '}' && !(*nodename)[1]) return -1;  // end-of-graph
1231
1232         *nodenr = read_long(env);
1233
1234         ARR_RESIZE(ir_node *, *preds, 0);
1235
1236         EXPECT('[');
1237         for(numpreds = 0; !feof(env->file); numpreds++)
1238         {
1239                 char *endptr;
1240                 ARR_APP1(long, *preds, read_long2(env, &endptr));
1241                 if(*endptr == ']') break;
1242         }
1243         return numpreds;
1244 }
1245
1246 /** Parses an IRG. */
1247 static int parse_graph(io_env_t *env, ir_graph *irg)
1248 {
1249         long       *preds = NEW_ARR_F(long, 16);
1250         ir_node   **prednodes = NEW_ARR_F(ir_node *, 16);
1251         int         i, numpreds, ret = 1;
1252         long        nodenr;
1253         const char *nodename;
1254         ir_node    *node, *newnode;
1255
1256         current_ir_graph = irg;
1257
1258         EXPECT('{');
1259
1260         while(1)
1261         {
1262                 numpreds = read_node_header(env, &nodenr, &preds, &nodename);
1263                 if(numpreds == -1) break;  // end-of-graph
1264                 if(!numpreds)
1265                 {
1266                         printf("Node %s %ld is missing predecessors!", nodename, nodenr);
1267                         ret = 0;
1268                         break;
1269                 }
1270
1271                 ARR_RESIZE(ir_node *, prednodes, numpreds);
1272                 for(i = 0; i < numpreds - 1; i++)
1273                         prednodes[i] = get_node_or_dummy(env, preds[i + 1]);
1274
1275                 node = get_node_or_null(env, nodenr);
1276                 newnode = NULL;
1277
1278                 EXPECT('{');
1279
1280                 switch(symbol(nodename, tt_iro))
1281                 {
1282                         case iro_End:
1283                         {
1284                                 ir_node *newendblock = get_node(env, preds[0]);
1285                                 newnode = get_irg_end(current_ir_graph);
1286                                 exchange(get_nodes_block(newnode), newendblock);
1287                                 for(i = 0; i < numpreds - 1; i++)
1288                                         add_irn_n(newnode, prednodes[i]);
1289                                 break;
1290                         }
1291
1292                         case iro_Start:
1293                         {
1294                                 ir_node *newstartblock = get_node(env, preds[0]);
1295                                 newnode = get_irg_start(current_ir_graph);
1296                                 exchange(get_nodes_block(newnode), newstartblock);
1297                                 break;
1298                         }
1299
1300                         case iro_Block:
1301                         {
1302                                 if(preds[0] != nodenr)
1303                                 {
1304                                         printf("Invalid block: preds[0] != nodenr (%ld != %ld)\n",
1305                                                 preds[0], nodenr);
1306                                         ret = 0;
1307                                         goto endloop;
1308                                 }
1309
1310                                 newnode = new_Block(numpreds - 1, prednodes);
1311                                 break;
1312                         }
1313
1314                         case iro_Anchor:
1315                                 newnode = current_ir_graph->anchor;
1316                                 for(i = 0; i < numpreds - 1; i++)
1317                                         set_irn_n(newnode, i, prednodes[i]);
1318                                 set_irn_n(newnode, -1, get_node(env, preds[0]));
1319                                 break;
1320
1321                         case iro_SymConst:
1322                         {
1323                                 long entnr = read_long(env);
1324                                 union symconst_symbol sym;
1325                                 sym.entity_p = get_entity(env, entnr);
1326                                 newnode = new_SymConst(mode_P, sym, symconst_addr_ent);
1327                                 break;
1328                         }
1329
1330                         #include "gen_irio_import.inl"
1331
1332                         default:
1333                                 goto notsupported;
1334                 }
1335
1336                 EXPECT('}');
1337
1338                 if(!newnode)
1339                 {
1340 notsupported:
1341                         panic("Node type not supported yet: %s in line %i:%i\n", nodename, env->line, env->col);
1342                 }
1343
1344                 if(node)
1345                         exchange(node, newnode);
1346                 /* Always update hash entry to avoid more uses of id nodes */
1347                 set_id(env, nodenr, newnode);
1348                 //printf("Insert %s %ld\n", nodename, nodenr);
1349         }
1350
1351 endloop:
1352         DEL_ARR_F(preds);
1353         DEL_ARR_F(prednodes);
1354
1355         return ret;
1356 }
1357
1358 /** Imports an previously exported textual representation of an (maybe partial) irp */
1359 void ir_import(const char *filename)
1360 {
1361         int oldoptimize = get_optimize();
1362         firm_verification_t oldver = get_node_verification_mode();
1363         io_env_t ioenv;
1364         io_env_t *env = &ioenv;
1365         int i, n;
1366
1367         symtbl_init();
1368
1369         memset(env, 0, sizeof(*env));
1370         env->idset = new_set(id_cmp, 128);
1371         env->fixedtypes = NEW_ARR_F(ir_type *, 0);
1372
1373         env->file = fopen(filename, "rt");
1374         if(!env->file)
1375         {
1376                 perror(filename);
1377                 exit(1);
1378         }
1379
1380         set_optimize(0);
1381         do_node_verification(FIRM_VERIFICATION_OFF);
1382
1383         while(1)
1384         {
1385                 const char *str = read_str(env);
1386                 if(!*str) break;
1387                 switch(symbol(str, tt_keyword))
1388                 {
1389                         case kw_typegraph:
1390                                 if(!parse_typegraph(env)) goto end;
1391                                 break;
1392
1393                         case kw_irg:
1394                         {
1395                                 ir_entity *irgent = get_entity(env, read_long(env));
1396                                 long valuetypeid;
1397                                 ir_graph *irg = new_ir_graph(irgent, 0);
1398                                 set_irg_frame_type(irg, get_type(env, read_long(env)));
1399                                 valuetypeid = read_long(env);
1400                                 if(valuetypeid != -1)
1401                                         set_method_value_param_type(get_entity_type(irgent),
1402                                                         get_type(env, valuetypeid));
1403
1404                                 if(!parse_graph(env, irg)) goto end;
1405                                 break;
1406                         }
1407
1408                         case kw_constirg:
1409                                 if(!parse_graph(env, get_const_code_irg())) goto end;
1410                                 break;
1411                 }
1412         }
1413
1414 end:
1415         n = ARR_LEN(env->fixedtypes);
1416         for(i = 0; i < n; i++)
1417                 set_type_state(env->fixedtypes[i], layout_fixed);
1418
1419         DEL_ARR_F(env->fixedtypes);
1420
1421         del_set(env->idset);
1422
1423         irp_finalize_cons();
1424
1425         do_node_verification(oldver);
1426         set_optimize(oldoptimize);
1427
1428         fclose(env->file);
1429 }