Correct comment: xvcg wants LF, not CR.
[libfirm] / ir / ir / irdumptxt.c
1 /*
2  * Copyright (C) 1995-2011 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 text representation of firm to file.
23  * @author  Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Hubert Schmidt,
24  *          Matthias Braun
25  */
26 #include "config.h"
27
28 #include <string.h>
29 #include <stdlib.h>
30 #include <stdarg.h>
31 #include <stdbool.h>
32
33 #include "irdump_t.h"
34 #include "irgraph_t.h"
35 #include "irnode_t.h"
36
37 #include "irprog_t.h"
38 #include "entity_t.h"
39 #include "trouts.h"
40 #include "irgwalk.h"
41 #include "tv_t.h"
42 #include "irprintf.h"
43 #include "error.h"
44
45 #include "irdom.h"
46
47 static ir_dump_verbosity_t  verbosity = dump_verbosity_max;
48
49 void ir_set_dump_verbosity(ir_dump_verbosity_t new_verbosity)
50 {
51         verbosity = new_verbosity;
52 }
53
54 ir_dump_verbosity_t ir_get_dump_verbosity(void)
55 {
56         return verbosity;
57 }
58
59 void dump_irnode_to_file(FILE *F, const ir_node *n)
60 {
61         char     comma;
62         ir_graph *irg;
63
64         dump_node_opcode(F, n);
65         fprintf(F, " %ld\n", get_irn_node_nr(n));
66
67         fprintf(F, "  index: %u\n", get_irn_idx(n));
68         if (ir_get_dump_flags() & ir_dump_flag_analysed_types)
69                 fprintf (F, "  addr:    %p\n", (void *)n);
70         fprintf (F, "  mode:    %s\n", get_mode_name(get_irn_mode(n)));
71         fprintf (F, "  visited: %lu\n", get_irn_visited(n));
72         irg = get_irn_irg(n);
73         if (irg != get_const_code_irg())
74                 fprintf (F, "  irg:     %s\n", get_ent_dump_name(get_irg_entity(irg)));
75
76         if (get_irn_pinned(n) == op_pin_state_floats &&
77                 get_irg_pinned(get_irn_irg(n)) == op_pin_state_floats) {
78                 fprintf(F, "  node was pinned in ");
79                 dump_node_opcode(F, get_irn_n(n, -1));
80                 fprintf(F, " %ld\n", get_irn_node_nr(get_irn_n(n, -1)));
81         }
82
83         fprintf(F, "  arity:   %d\n", get_irn_arity(n));
84         /* show all predecessor nodes */
85         fprintf(F, "  pred nodes:\n");
86         if (!is_Block(n)) {
87                 fprintf(F, "    -1:    ");
88                 dump_node_opcode(F, get_irn_n(n, -1));
89                 fprintf(F, " %ld\n", get_irn_node_nr(get_irn_n(n, -1)));
90         }
91
92         {
93                 int i;
94                 for (i = 0; i < get_irn_arity(n); ++i) {
95                         fprintf(F, "     %d: %s ", i, is_backedge(n, i) ? "be" : "  ");
96                         dump_node_opcode(F, get_irn_n(n, i));
97                         fprintf(F, " %ld\n", get_irn_node_nr(get_irn_n(n, i)));
98                 }
99         }
100
101         fprintf(F, "  Private Attributes:\n");
102
103         if (is_Proj(n)) {
104                 ir_node *pred = get_Proj_pred(n);
105                 long     pn   = get_Proj_proj(n);
106                 fprintf(F, "  proj nr: %ld\n", pn);
107                 if (is_Switch(pred)) {
108                         const ir_switch_table *table = get_Switch_table(pred);
109                         size_t n_entries = ir_switch_table_get_n_entries(table);
110                         size_t i;
111                         for (i = 0; i < n_entries; ++i) {
112                                 const ir_switch_table_entry *entry
113                                         = ir_switch_table_get_entry_const(table, i);
114                                 if (entry->pn == pn && entry->min != NULL && entry->max != NULL) {
115                                         ir_tarval *min = entry->min;
116                                         ir_tarval *max = entry->max;
117                                         if (min != max) {
118                                                 ir_fprintf(F, "  switch case %+F .. %+F\n", min, max);
119                                         } else {
120                                                 ir_fprintf(F, "  switch case %+F\n", min);
121                                         }
122                                 }
123                         }
124                 }
125         }
126
127         if (is_fragile_op(n)) {
128                 fprintf(F, "  pinned state: %s\n", get_op_pin_state_name(get_irn_pinned(n)));
129                 /* not dumped: frag array */
130         }
131
132         /* This is not nice, output it as a marker in the predecessor list. */
133         if (is_Block(n) || get_irn_op(n) == op_Phi) {
134             int i;
135                 fprintf(F, "  backedges:");
136                 comma = ' ';
137                 for (i = 0; i < get_irn_arity(n); i++)
138                         if (is_backedge(n, i)) { fprintf(F, "%c %d", comma, i); comma = ','; }
139                         fprintf(F, "\n");
140         }
141
142         /* Loop node.   Someone else please tell me what's wrong ... */
143         if (is_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_LOOPINFO)) {
144                 ir_loop *loop = get_irn_loop(n);
145                 if (loop != NULL) {
146                         fprintf(F, "  in loop %ld with depth %u\n",
147                                 get_loop_loop_nr(loop), get_loop_depth(loop));
148                 }
149         }
150
151         /* Source types */
152         switch (get_irn_opcode(n)) {
153         case iro_Block: {
154                 if (get_Block_entity(n) != NULL)
155                         fprintf(F, "  Label: %lu\n", get_entity_label(get_Block_entity(n)));
156                 fprintf(F, "  block visited: %lu\n", get_Block_block_visited(n));
157                 fprintf(F, "  block marked: %u\n", get_Block_mark(n));
158                 if (is_irg_state(get_irn_irg(n), IR_GRAPH_STATE_CONSISTENT_DOMINANCE)) {
159                         fprintf(F, "  dom depth %d\n", get_Block_dom_depth(n));
160                         fprintf(F, "  domtree pre num %u\n", get_Block_dom_tree_pre_num(n));
161                         fprintf(F, "  max subtree pre num %u\n", get_Block_dom_max_subtree_pre_num(n));
162                 }
163                 if (is_irg_state(get_irn_irg(n), IR_GRAPH_STATE_CONSISTENT_POSTDOMINANCE)) {
164                         fprintf(F, "  pdom depth %d\n", get_Block_postdom_depth(n));
165                         fprintf(F, "  pdomtree pre num %u\n", get_Block_pdom_tree_pre_num(n));
166                         fprintf(F, "  max pdomsubtree pre num %u\n", get_Block_pdom_max_subtree_pre_num(n));
167                 }
168
169                 /* not dumped: graph_arr */
170                 /* not dumped: mature    */
171         }  break;
172         case iro_Start: {
173                 size_t   i;
174                 ir_type *tp = get_entity_type(get_irg_entity(get_irn_irg(n)));
175                 ir_fprintf(F, "  start of method of type %+F\n", tp);
176                 for (i = 0; i < get_method_n_params(tp); ++i)
177                         ir_fprintf(F, "    param %d type: %+F\n", i, get_method_param_type(tp, i));
178         } break;
179         case iro_Cond: {
180                 if (get_Cond_jmp_pred(n) != COND_JMP_PRED_NONE) {
181                         fprintf(F, "  jump prediction: %s\n",
182                                 get_cond_jmp_predicate_name(get_Cond_jmp_pred(n)));
183                 }
184         } break;
185         case iro_Alloc: {
186                 ir_fprintf(F, "  allocating entity of type: %+F\n", get_Alloc_type(n));
187                 fprintf(F, "  allocating on: the %s\n", (get_Alloc_where(n) == stack_alloc) ? "stack" : "heap");
188         } break;
189         case iro_Free: {
190                 ir_fprintf(F, "  freeing entity of type %+F\n", get_Free_type(n));
191                 fprintf(F, "  allocated on: the %s\n", (get_Free_where(n) == stack_alloc) ? "stack" : "heap");
192         } break;
193         case iro_Sel: {
194                 ir_entity *ent = get_Sel_entity(n);
195                 if (ent) {
196                         fprintf(F, "  Selecting entity %s (%ld)\n", get_entity_name(ent), get_entity_nr(ent));
197                         ir_fprintf(F, "    of type    %+F\n",  get_entity_type(ent));
198                         ir_fprintf(F, "    with owner %+F.\n", get_entity_owner(ent));
199                 } else {
200                         fprintf(F, "  <NULL entity>\n");
201                 }
202         } break;
203         case iro_Call: {
204                 ir_type *tp = get_Call_type(n);
205                 ir_fprintf(F, "  calling method of type %+F\n", tp);
206                 if (get_unknown_type() != tp) {
207                         size_t i;
208                         for (i = 0; i < get_method_n_params(tp); ++i)
209                                 ir_fprintf(F, "    param %d type: %+F\n", i, get_method_param_type(tp, i));
210                         for (i = 0; i < get_method_n_ress(tp); ++i)
211                                 ir_fprintf(F, "    result %d type: %+F\n", i, get_method_res_type(tp, i));
212                 }
213                 if (Call_has_callees(n)) {
214                         size_t i;
215                         fprintf(F, "  possible callees:\n");
216                         for (i = 0; i < get_Call_n_callees(n); i++) {
217                                 ir_fprintf(F, "    %zu: %s\n", i, get_ent_dump_name(get_Call_callee(n, i)));
218                         }
219                 }
220         } break;
221         case iro_Cast: {
222                 ir_fprintf(F, "  cast to type: %+F\n", get_Cast_type(n));
223         } break;
224         case iro_Cmp: {
225                 ir_relation relation = get_Cmp_relation(n);
226                 ir_fprintf(F, "  relation: %s\n", get_relation_string(relation));
227         } break;
228         case iro_Return: {
229                 size_t   i;
230                 ir_type *tp = get_entity_type(get_irg_entity(get_irn_irg(n)));
231                 ir_fprintf(F, "  return in method of type %+F\n", tp);
232                 for (i = 0; i < get_method_n_ress(tp); ++i) {
233                         ir_fprintf(F, "    result %d type: %+F\n", i,
234                                            get_method_res_type(tp, i));
235                 }
236         } break;
237         case iro_SymConst: {
238                 switch (get_SymConst_kind(n)) {
239                 case symconst_addr_ent:
240                         fprintf(F, "  kind:   addr_ent\n");
241                         fprintf(F, "  entity: ");
242                         dump_entity_to_file(F, get_SymConst_entity(n));
243                         break;
244                 case symconst_ofs_ent:
245                         fprintf(F, "  kind:   offset\n");
246                         fprintf(F, "  entity: ");
247                         dump_entity_to_file(F, get_SymConst_entity(n));
248                         break;
249                 case symconst_type_size:
250                         fprintf(F, "  kind: size\n");
251                         fprintf(F, "  type: ");
252                         dump_type_to_file(F, get_SymConst_type(n));
253                         break;
254                 case symconst_type_align:
255                         fprintf(F, "  kind: alignment\n");
256                         fprintf(F, "  type: ");
257                         dump_type_to_file(F, get_SymConst_type(n));
258                         break;
259                 case symconst_enum_const:
260                         fprintf(F, "  kind: enumeration\n");
261                         fprintf(F, "  name: %s\n", get_enumeration_const_name(get_SymConst_enum(n)));
262                         break;
263                 }
264         } break;
265         case iro_Load:
266                 fprintf(F, "  mode of loaded value: %s\n", get_mode_name_ex(get_Load_mode(n), NULL));
267                 fprintf(F, "  volatility: %s\n", get_volatility_name(get_Load_volatility(n)));
268                 fprintf(F, "  align: %s\n", get_align_name(get_Load_unaligned(n)));
269                 break;
270         case iro_Store:
271                 fprintf(F, "  volatility: %s\n", get_volatility_name(get_Store_volatility(n)));
272                 fprintf(F, "  align: %s\n", get_align_name(get_Store_unaligned(n)));
273                 break;
274         case iro_Confirm:
275                 fprintf(F, "  compare operation: %s\n", get_relation_string(get_Confirm_relation(n)));
276                 break;
277         case iro_ASM: {
278                 const ir_asm_constraint *cons;
279                 ident **clobber;
280                 int l;
281
282                 fprintf(F, "  assembler text: %s", get_id_str(get_ASM_text(n)));
283                 l = get_ASM_n_input_constraints(n);
284                 if (l > 0) {
285                         int i;
286                         fprintf(F, "\n  inputs:  ");
287                         cons = get_ASM_input_constraints(n);
288                         for (i = 0; i < l; ++i)
289                                 fprintf(F, "%%%u %s ", cons[i].pos, get_id_str(cons[i].constraint));
290                 }
291                 l = get_ASM_n_output_constraints(n);
292                 if (l > 0) {
293                         int i;
294                         fprintf(F, "\n  outputs: ");
295                         cons = get_ASM_output_constraints(n);
296                         for (i = 0; i < l; ++i)
297                                 fprintf(F, "%%%u %s ", cons[i].pos, get_id_str(cons[i].constraint));
298                 }
299                 l = get_ASM_n_clobbers(n);
300                 if (l > 0) {
301                         int i;
302                         fprintf(F, "\n  clobber: ");
303                         clobber = get_ASM_clobbers(n);
304                         for (i = 0; i < l; ++i)
305                                 fprintf(F, "%s ", get_id_str(clobber[i]));
306                 }
307                 if (get_irn_pinned(n) != op_pin_state_floats)
308                         fprintf(F, "\n  volatile");
309                 fprintf(F, "\n");
310         } break;
311
312         default:
313                 break;
314         }
315
316         if (get_irg_typeinfo_state(get_irn_irg(n)) == ir_typeinfo_consistent  ||
317                 get_irg_typeinfo_state(get_irn_irg(n)) == ir_typeinfo_inconsistent  )
318                 if (get_irn_typeinfo_type(n) != get_none_type())
319                         ir_fprintf (F, "  Analysed type: %s\n", get_irn_typeinfo_type(n));
320 }
321
322 void dump_graph_as_text(FILE *out, ir_graph *irg)
323 {
324         fprintf(out, "graph %s\n", get_irg_dump_name(irg));
325 }
326
327 static int need_nl = 1;
328
329 static bool is_init_string(ir_initializer_t const* const init, ir_type *const type)
330 {
331         ir_type *const element_type = get_array_element_type(type);
332         ir_mode *      mode;
333         size_t         n;
334         size_t         i;
335
336         if (!is_Primitive_type(element_type))
337                 return false;
338
339         mode = get_type_mode(element_type);
340         if (!mode_is_int(mode) || get_mode_size_bits(mode) != 8)
341                 return false;
342
343         n = get_initializer_compound_n_entries(init);
344         for (i = 0; i != n; ++i) {
345                 ir_initializer_t const* const val = get_initializer_compound_value(init, i);
346                 ir_tarval*                    tv;
347                 long                          v;
348
349                 if (get_initializer_kind(val) != IR_INITIALIZER_TARVAL)
350                         return false;
351                 tv = get_initializer_tarval_value(val);
352
353                 if (!tarval_is_constant(tv))
354                         return false;
355
356                 v = get_tarval_long(tv);
357                 if (v != 0 && (v < 0x07 || 0x0D < v) && v != 0x1B && (v < 0x20 || 0x80 <= v) && (v < 0xA0 || 0x100 <= v))
358                         return false;
359         }
360
361         return true;
362 }
363
364 /**
365  * Dump initializers.
366  */
367 static void dump_ir_initializers_to_file(FILE *F, const char *prefix,
368                                          const ir_initializer_t *initializer,
369                                          ir_type *type)
370 {
371         ir_tarval *tv;
372         ir_node   *value;
373
374         if (need_nl) {
375                 fprintf(F, "\n%s    ", prefix);
376                 need_nl = 0;
377         }
378         switch (get_initializer_kind(initializer)) {
379         case IR_INITIALIZER_NULL:
380                 fprintf(F, "\t = <NOT_SET>");
381                 break;
382         case IR_INITIALIZER_TARVAL:
383                 tv = get_initializer_tarval_value(initializer);
384                 ir_fprintf(F, "\t = <TV>%F", tv);
385                 break;
386         case IR_INITIALIZER_CONST:
387                 value = get_initializer_const_value(initializer);
388                 ir_fprintf(F, "\t = %F", value);
389                 break;
390         case IR_INITIALIZER_COMPOUND:
391                 if (is_Array_type(type)) {
392                         size_t const n = get_initializer_compound_n_entries(initializer);
393                         size_t       i;
394
395                         if (is_init_string(initializer, type)) {
396                                 fprintf(F, "\t[0...%u] = '", (unsigned)n - 1);
397                                 for (i = 0; i != n; ++i) {
398                                         ir_initializer_t const* const val = get_initializer_compound_value(initializer, i);
399                                         ir_tarval*              const tv  = get_initializer_tarval_value(val);
400                                         long                    const v   = get_tarval_long(tv);
401
402                                         switch (v) {
403                                                 case 0x00: fprintf(F, "\\\\000");  break;
404                                                 case 0x07: fprintf(F, "\\\\a");    break;
405                                                 case 0x08: fprintf(F, "\\\\b");    break;
406                                                 case 0x09: fprintf(F, "\\\\t");    break;
407                                                 case 0x0A: fprintf(F, "\\\\n");    break;
408                                                 case 0x0B: fprintf(F, "\\\\v");    break;
409                                                 case 0x0C: fprintf(F, "\\\\f");    break;
410                                                 case 0x0D: fprintf(F, "\\\\r");    break;
411                                                 case 0x1B: fprintf(F, "\\\\033");  break;
412                                                 case 0x22: fprintf(F, "\\\\\\\""); break;
413                                                 case 0x5C: fprintf(F, "\\\\\\\\"); break;
414                                                 default:   fprintf(F, "%c", (unsigned char)v); break;
415                                         }
416                                 }
417                                 fprintf(F, "'");
418                         } else {
419                                 ir_type *const element_type = get_array_element_type(type);
420
421                                 for (i = 0; i < n; ++i) {
422                                         ir_initializer_t *sub_initializer
423                                                 = get_initializer_compound_value(initializer, i);
424
425                                         if (need_nl) {
426                                                 fprintf(F, "\n%s    ", prefix);
427                                                 need_nl = 0;
428                                         }
429                                         fprintf(F, "[%d]", (int) i);
430                                         dump_ir_initializers_to_file(F, prefix, sub_initializer, element_type);
431                                 }
432                         }
433                 } else {
434                         size_t i, n;
435                         assert(is_compound_type(type));
436                         n = get_compound_n_members(type);
437                         for (i = 0; i < n; ++i) {
438                                 ir_entity        *member    = get_compound_member(type, i);
439                                 ir_type          *subtype   = get_entity_type(member);
440                                 ir_initializer_t *sub_initializer;
441
442                                 assert(i < get_initializer_compound_n_entries(initializer));
443                                 sub_initializer
444                                         = get_initializer_compound_value(initializer, i);
445
446                                 if (need_nl) {
447                                         fprintf(F, "\n%s    ", prefix);
448                                         need_nl = 0;
449                                 }
450                                 ir_fprintf(F, ".%F", member);
451                                 dump_ir_initializers_to_file(F, prefix, sub_initializer, subtype);
452                         }
453                 }
454                 break;
455         default:
456                 panic("invalid ir_initializer kind found");
457         }
458         need_nl = 1;
459 }
460
461 static void dump_entity_linkage(FILE *F, const ir_entity *entity)
462 {
463         ir_linkage linkage = get_entity_linkage(entity);
464
465         if (linkage == IR_LINKAGE_DEFAULT) {
466                 fprintf(F, " default");
467                 return;
468         }
469         if (linkage & IR_LINKAGE_CONSTANT)
470                 fprintf(F, " constant");
471         if (linkage & IR_LINKAGE_WEAK)
472                 fprintf(F, " weak");
473         if (linkage & IR_LINKAGE_GARBAGE_COLLECT)
474                 fprintf(F, " garbage_collect");
475         if (linkage & IR_LINKAGE_MERGE)
476                 fprintf(F, " merge");
477         if (linkage & IR_LINKAGE_HIDDEN_USER)
478                 fprintf(F, " hidden_user");
479 }
480
481 static void dump_entity_to_file_prefix(FILE *F, ir_entity *ent, const char *prefix)
482 {
483         ir_type *owner, *type;
484
485         assert(is_entity(ent));
486         owner = get_entity_owner(ent);
487         type  = get_entity_type(ent);
488         if (verbosity & dump_verbosity_onlynames) {
489                 fprintf(F, "%sentity %s.%s (%ld)\n", prefix, get_compound_name(get_entity_owner(ent)),
490                         get_entity_name(ent), get_entity_nr(ent));
491                 return;
492         }
493
494         if (verbosity & dump_verbosity_entattrs) {
495                 fprintf(F, "%sentity %s (%ld)\n", prefix, get_entity_name(ent), get_entity_nr(ent));
496                 ir_fprintf(F, "%s  type:  %+F\n", prefix, type);
497                 ir_fprintf(F, "%s  owner: %+F\n", prefix, owner);
498
499                 if (is_Class_type(get_entity_owner(ent))) {
500                         if (get_entity_n_overwrites(ent) > 0) {
501                                 size_t i;
502                                 fprintf(F, "%s  overwrites:\n", prefix);
503                                 for (i = 0; i < get_entity_n_overwrites(ent); ++i) {
504                                         ir_entity *ov = get_entity_overwrites(ent, i);
505                                         ir_fprintf(F, "%s    %d: %s of class %+F\n", prefix, i,
506                                                 get_entity_name(ov), get_entity_owner(ov));
507                                 }
508                         } else {
509                                 fprintf(F, "%s  Does not overwrite other entities.\n", prefix);
510                         }
511                         if (get_entity_n_overwrittenby(ent) > 0) {
512                                 size_t i;
513                                 fprintf(F, "%s  overwritten by:\n", prefix);
514                                 for (i = 0; i < get_entity_n_overwrittenby(ent); ++i) {
515                                         ir_entity *ov = get_entity_overwrittenby(ent, i);
516                                         ir_fprintf(F, "%s    %d: %s of class %+F\n", prefix, i,
517                                                    get_entity_name(ov), get_entity_owner(ov));
518                                 }
519                         } else {
520                                 fprintf(F, "%s  Is not overwritten by other entities.\n",
521                                         prefix);
522                         }
523
524                         if (get_irp_inh_transitive_closure_state() != inh_transitive_closure_none) {
525                                 ir_entity *ov;
526                                 fprintf(F, "%s  transitive overwrites:\n", prefix);
527                                 for (ov = get_entity_trans_overwrites_first(ent);
528                                 ov;
529                                 ov = get_entity_trans_overwrites_next(ent)) {
530                                         ir_fprintf(F, "%s    : %s of class %+F\n", prefix,
531                                                    get_entity_name(ov), get_entity_owner(ov));
532                                 }
533                                 fprintf(F, "%s  transitive overwritten by:\n", prefix);
534                                 for (ov = get_entity_trans_overwrittenby_first(ent);
535                                 ov;
536                                 ov = get_entity_trans_overwrittenby_next(ent)) {
537                                         ir_fprintf(F, "%s    : %s of class %+F\n", prefix,
538                                                    get_entity_name(ov), get_entity_owner(ov));
539                                 }
540                         }
541                 }
542
543                 if (is_Method_type(get_entity_type(ent))) {
544                         unsigned mask = get_entity_additional_properties(ent);
545                         unsigned cc   = get_method_calling_convention(get_entity_type(ent));
546                         ir_graph *irg = get_entity_irg(ent);
547
548                         if (irg) {
549                                 fprintf(F, "%s  estimated node count: %u\n", prefix, get_irg_estimated_node_cnt(irg));
550                                 fprintf(F, "%s  maximum node index:   %u\n", prefix, get_irg_last_idx(irg));
551                         }
552
553                         if (mask) {
554                                 fprintf(F, "%s  additional prop: ", prefix);
555
556                                 if (mask & mtp_property_const)         fputs("const_function, ", F);
557                                 if (mask & mtp_property_pure)          fputs("pure_function, ", F);
558                                 if (mask & mtp_property_noreturn)      fputs("noreturn_function, ", F);
559                                 if (mask & mtp_property_nothrow)       fputs("nothrow_function, ", F);
560                                 if (mask & mtp_property_naked)         fputs("naked_function, ", F);
561                                 if (mask & mtp_property_malloc)        fputs("malloc_function, ", F);
562                                 if (mask & mtp_property_returns_twice) fputs("weak_function, ", F);
563                                 if (mask & mtp_property_intrinsic)     fputs("intrinsic_function, ", F);
564                                 if (mask & mtp_property_runtime)       fputs("runtime_function, ", F);
565                                 if (mask & mtp_property_private)       fputs("private_function, ", F);
566                                 if (mask & mtp_property_has_loop)      fputs("has_loop_function, ", F);
567                                 fputc('\n', F);
568                         }
569                         fprintf(F, "%s  calling convention: ", prefix);
570                         if (cc & cc_reg_param)           fputs("regparam, ", F);
571                         if (cc & cc_this_call)           fputs("thiscall, ", F);
572                         if (cc & cc_compound_ret)        fputs("compound_ret, ", F);
573                         if (cc & cc_frame_on_caller_stk) fputs("frame on caller's stack, ", F);
574                         cc &= ~(cc_compound_ret|cc_frame_on_caller_stk);
575                         if (IS_CDECL(cc))
576                                 fputs("cdecl", F);
577                         else if (IS_STDCALL(cc))
578                                 fputs("stdcall", F);
579                         else {
580                                 fputs(cc & cc_last_on_top      ? "last param on top, " : "first param on top, ", F);
581                                 fputs(cc & cc_callee_clear_stk ? "callee clear stack" : "caller clear stack", F);
582                         }
583                         fprintf(F, "\n%s  vtable number:        %u\n", prefix, get_entity_vtable_number(ent));
584                 }
585         } else {  /* no entattrs */
586                 ir_fprintf(F, "%s(%3d:%d) %+F: %s", prefix,
587                         get_entity_offset(ent), get_entity_offset_bits_remainder(ent),
588                         get_entity_type(ent), get_entity_name(ent));
589                 if (is_Method_type(get_entity_type(ent))) fputs("(...)", F);
590
591                 if (verbosity & dump_verbosity_accessStats) {
592                         dump_entity_linkage(F, ent);
593                 }
594                 fputc('\n', F);
595         }
596
597         if (verbosity & dump_verbosity_entconsts) {
598                 if (ent->initializer != NULL) {
599                         const ir_initializer_t *initializer = get_entity_initializer(ent);
600                         fprintf(F, "\n%s  Initializers:", prefix);
601                         need_nl = 1;
602                         dump_ir_initializers_to_file(F, prefix, initializer, get_entity_type(ent));
603                         fputc('\n', F);
604                 } else if (entity_has_compound_ent_values(ent)) {
605                         size_t i;
606                         fprintf(F, "%s  compound values:", prefix);
607                         for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
608                                 size_t j;
609                                 compound_graph_path *path = get_compound_ent_value_path(ent, i);
610                                 ir_entity *ent0 = get_compound_graph_path_node(path, 0);
611                                 fprintf(F, "\n%s    %3d:%d ", prefix, get_entity_offset(ent0), get_entity_offset_bits_remainder(ent0));
612                                 if (get_type_state(type) == layout_fixed)
613                                         fprintf(F, "(%3u:%u) ",   get_compound_ent_value_offset_bytes(ent, i), get_compound_ent_value_offset_bit_remainder(ent, i));
614                                 fprintf(F, "%s", get_entity_name(ent));
615                                 for (j = 0; j < get_compound_graph_path_length(path); ++j) {
616                                         ir_entity *node = get_compound_graph_path_node(path, j);
617                                         fprintf(F, ".%s", get_entity_name(node));
618                                         if (is_Array_type(get_entity_owner(node)))
619                                                 fprintf(F, "[%ld]", get_compound_graph_path_array_index(path, j));
620                                 }
621                                 fprintf(F, "\t = ");
622                                 dump_node_opcode(F, get_compound_ent_value(ent, i));
623                         }
624                         fputc('\n', F);
625                 }
626         }
627
628         if (verbosity & dump_verbosity_entattrs) {
629                 fprintf(F, "%s  linkage:", prefix);
630                 dump_entity_linkage(F, ent);
631                 fprintf(F, "\n%s  volatility:  %s", prefix, get_volatility_name(get_entity_volatility(ent)));
632                 fprintf(F, "\n%s  aligned:  %s", prefix, get_align_name(get_entity_aligned(ent)));
633                 fprintf(F, "\n%s  alignment:  %u", prefix, get_entity_alignment(ent));
634                 fprintf(F, "\n%s  ld_name: %s", prefix, ent->ld_name ? get_entity_ld_name(ent) : "no yet set");
635                 fprintf(F, "\n%s  offset:  %d bytes, %d rem bits", prefix, get_entity_offset(ent), get_entity_offset_bits_remainder(ent));
636                 if (is_Method_type(get_entity_type(ent))) {
637                         if (get_entity_irg(ent))   /* can be null */ {
638                                 fprintf(F, "\n%s  irg = %ld", prefix, get_irg_graph_nr(get_entity_irg(ent)));
639                         } else {
640                                 fprintf(F, "\n%s  irg = NULL", prefix);
641                         }
642                 }
643                 fputc('\n', F);
644         }
645 }
646
647 void dump_entity_to_file(FILE *out, ir_entity *ent)
648 {
649         dump_entity_to_file_prefix(out, ent, "");
650         fprintf(out, "\n");
651 }
652
653 void dump_type_to_file(FILE *F, ir_type *tp)
654 {
655         size_t i;
656
657         if ((is_Class_type(tp))       && (verbosity & dump_verbosity_noClassTypes)) return;
658         if ((is_Struct_type(tp))      && (verbosity & dump_verbosity_noStructTypes)) return;
659         if ((is_Union_type(tp))       && (verbosity & dump_verbosity_noUnionTypes)) return;
660         if ((is_Array_type(tp))       && (verbosity & dump_verbosity_noArrayTypes)) return;
661         if ((is_Pointer_type(tp))     && (verbosity & dump_verbosity_noPointerTypes)) return;
662         if ((is_Method_type(tp))      && (verbosity & dump_verbosity_noMethodTypes)) return;
663         if ((is_Primitive_type(tp))   && (verbosity & dump_verbosity_noPrimitiveTypes)) return;
664         if ((is_Enumeration_type(tp)) && (verbosity & dump_verbosity_noEnumerationTypes)) return;
665
666         ir_fprintf(F, "%+F", tp);
667         if (verbosity & dump_verbosity_onlynames) { fprintf(F, "\n"); return; }
668
669         switch (get_type_tpop_code(tp)) {
670
671         case tpo_class:
672                 if ((verbosity & dump_verbosity_methods) || (verbosity & dump_verbosity_fields)) {
673                         fprintf(F, "\n  members:\n");
674                 }
675                 for (i = 0; i < get_class_n_members(tp); ++i) {
676                         ir_entity *mem = get_class_member(tp, i);
677                         if (((verbosity & dump_verbosity_methods) &&  is_Method_type(get_entity_type(mem))) ||
678                                 ((verbosity & dump_verbosity_fields)  && !is_Method_type(get_entity_type(mem)))   ) {
679                                 if (!(verbosity & dump_verbosity_nostatic)) {
680                                         dump_entity_to_file_prefix(F, mem, "    ");
681                                 }
682                         }
683                 }
684                 if (verbosity & dump_verbosity_typeattrs) {
685                         fprintf(F, "  supertypes: ");
686                         for (i = 0; i < get_class_n_supertypes(tp); ++i) {
687                                 ir_type *stp = get_class_supertype(tp, i);
688                                 ir_fprintf(F, "\n    %d %+F", i, stp);
689                         }
690                         fprintf(F, "\n  subtypes: ");
691                         for (i = 0; i < get_class_n_subtypes(tp); ++i) {
692                                 ir_type *stp = get_class_subtype(tp, i);
693                                 ir_fprintf(F, "\n    %d %+F", i, stp);
694                         }
695
696                         if (get_irp_inh_transitive_closure_state() != inh_transitive_closure_none) {
697                                 ir_type *stp;
698                                 fprintf(F, "\n  transitive supertypes: ");
699                                 for (stp = get_class_trans_supertype_first(tp);
700                                 stp;
701                                 stp = get_class_trans_supertype_next(tp)) {
702                                         ir_fprintf(F, "\n    %+F", stp);
703                                 }
704                                 fprintf(F, "\n  transitive subtypes: ");
705                                 for (stp = get_class_trans_subtype_first(tp);
706                                 stp;
707                                 stp = get_class_trans_subtype_next(tp)) {
708                                         ir_fprintf(F, "\n    %+F", stp);
709                                 }
710                         }
711
712                         fprintf(F, "\n  flags:       ");
713                         if (is_class_final(tp))
714                                 fprintf(F, "final, ");
715                         if (is_class_interface(tp))
716                                 fprintf(F, "interface, ");
717                         if (is_class_abstract(tp))
718                                 fprintf(F, "abstract, ");
719                         fprintf(F, "\n");
720                 }
721                 break;
722
723         case tpo_union:
724         case tpo_struct:
725                 if (verbosity & dump_verbosity_fields) fprintf(F, "\n  members: ");
726                 for (i = 0; i < get_compound_n_members(tp); ++i) {
727                         ir_entity *mem = get_compound_member(tp, i);
728                         if (verbosity & dump_verbosity_fields) {
729                                 dump_entity_to_file_prefix(F, mem, "    ");
730                         }
731                 }
732                 break;
733
734         case tpo_array:
735                 if (verbosity & dump_verbosity_typeattrs) {
736                         size_t n_dim;
737                         ir_type *elem_tp = get_array_element_type(tp);
738
739                         fprintf(F, "\n  array ");
740
741                         n_dim = get_array_n_dimensions(tp);
742                         for (i = 0; i < n_dim; ++i) {
743                                 ir_node *lower, *upper;
744
745                                 lower = get_array_lower_bound(tp, i);
746                                 upper = get_array_upper_bound(tp, i);
747
748                                 fprintf(F, "[");
749
750                                 if (is_Const(lower)) {
751                                         fprintf(F, "%ld .. ", get_tarval_long(get_Const_tarval(lower)));
752                                 } else {
753                                         dump_node_opcode(F, lower);
754                                         fprintf(F, " %ld .. ", get_irn_node_nr(lower));
755                                 }
756
757                                 if (is_Const(upper)) {
758                                         fprintf(F, "%ld]", get_tarval_long(get_Const_tarval(lower)));
759                                 } else {
760                                         dump_node_opcode(F, upper);
761                                         fprintf(F, " %ld]", get_irn_node_nr(upper));
762                                 }
763                         }
764                         ir_fprintf(F, " of <%+F>", elem_tp);
765
766                         fprintf(F, "\n  order: ");
767                         for (i = 0; i < n_dim; ++i)
768                                 fprintf(F, "<%zu>", get_array_order(tp, i));
769
770                         fprintf(F, "\n");
771
772                         if (verbosity & dump_verbosity_fields) {
773                                 dump_entity_to_file_prefix(F, get_array_element_entity(tp),
774                                                            "    ");
775                         }
776                 }
777                 break;
778
779         case tpo_pointer:
780                 if (verbosity & dump_verbosity_typeattrs) {
781                         ir_type *tt = get_pointer_points_to_type(tp);
782                         ir_fprintf(F, "\n  points to %+F\n", tt);
783                 }
784                 break;
785
786         case tpo_method:
787                 if (verbosity & dump_verbosity_typeattrs) {
788                         mtp_additional_properties mtp = get_method_additional_properties(tp);
789                         unsigned cconv = get_method_calling_convention(tp);
790                         fprintf(F, "\n  variadicity: %s", get_variadicity_name(get_method_variadicity(tp)));
791                         fprintf(F, "\n  return types: %lu",
792                                 (unsigned long) get_method_n_ress(tp));
793                         for (i = 0; i < get_method_n_ress(tp); ++i) {
794                                 ir_type *rtp = get_method_res_type(tp, i);
795                                 ir_fprintf(F, "\n    %+F", rtp);
796                         }
797
798                         fprintf(F, "\n  parameter types: %lu",
799                                 (unsigned long) get_method_n_params(tp));
800                         for (i = 0; i < get_method_n_params(tp); ++i) {
801                                 ir_type *ptp = get_method_param_type(tp, i);
802                                 ir_fprintf(F, "\n    %+F", ptp);
803                         }
804                         fprintf(F, "\n  properties:");
805                         if (mtp & mtp_property_const)
806                                 fputs(" const", F);
807                         if (mtp & mtp_property_pure)
808                                 fputs(" pure", F);
809                         if (mtp & mtp_property_noreturn)
810                                 fputs(" noreturn", F);
811                         if (mtp & mtp_property_nothrow)
812                                 fputs(" nothrow", F);
813                         if (mtp & mtp_property_naked)
814                                 fputs(" naked", F);
815                         if (mtp & mtp_property_malloc)
816                                 fputs(" malloc", F);
817                         if (mtp & mtp_property_returns_twice)
818                                 fputs(" returns_twice", F);
819                         if (mtp & mtp_property_intrinsic)
820                                 fputs(" intrinsic", F);
821                         if (mtp & mtp_property_runtime)
822                                 fputs(" runtime", F);
823                         if (mtp & mtp_property_private)
824                                 fputs(" private", F);
825                         if (mtp & mtp_property_has_loop)
826                                 fputs(" has_Loop", F);
827
828                         fprintf(F, "\n  calling convention:");
829                         if (cconv & cc_reg_param)
830                                 fputs(" regparam", F);
831                         if (cconv & cc_last_on_top)
832                                 fputs(" last_on_top", F);
833                         if (cconv & cc_callee_clear_stk)
834                                 fputs(" calle_clear_stk", F);
835                         if (cconv & cc_this_call)
836                                 fputs(" this_call", F);
837                         if (cconv & cc_compound_ret)
838                                 fputs(" compound_ret", F);
839                         if (cconv & cc_frame_on_caller_stk)
840                                 fputs(" frame_on_caller_stk", F);
841                         if (cconv & cc_fpreg_param)
842                                 fputs(" fpreg_param", F);
843
844                         if (get_method_variadicity(tp)) {
845                                 fprintf(F, "\n    ...");
846                         }
847                         fprintf(F, "\n");
848                 }
849                 break;
850
851         case tpo_primitive:
852                 if (verbosity & dump_verbosity_typeattrs) {
853                         ir_type *base_tp = get_primitive_base_type(tp);
854                         if (base_tp != NULL)
855                                 ir_fprintf(F, "\n  base type: %+F", tp);
856                         fprintf(F, "\n");
857                 }
858                 break;
859
860         case tpo_none:
861         case tpo_unknown:
862                 fprintf(F, "\n");
863                 break;
864
865         default:
866                 if (verbosity & dump_verbosity_typeattrs) {
867                         fprintf(F, ": details not implemented\n");
868                 }
869         }
870
871         fprintf(F, "  state:      %s,\n", get_type_state_name(get_type_state(tp)));
872         fprintf(F, "  size:       %2u Bytes,\n", get_type_size_bytes(tp));
873         fprintf(F, "  alignment:  %2u Bytes,\n", get_type_alignment_bytes(tp));
874         if (is_atomic_type(tp) || is_Method_type(tp))
875                 fprintf(F, "  mode:       %s,\n",  get_mode_name(get_type_mode(tp)));
876
877         fprintf(F, "\n\n");
878 }
879
880 void dump_types_as_text(FILE *out)
881 {
882         size_t i, n_types = get_irp_n_types();
883
884         for (i = 0; i < n_types; ++i) {
885                 ir_type *type = get_irp_type(i);
886                 dump_type_to_file(out, type);
887         }
888 }
889
890 void dump_globals_as_text(FILE *out)
891 {
892         ir_type *global_type = get_glob_type();
893         size_t   n_members   = get_class_n_members(global_type);
894         size_t   i;
895
896         for (i = 0; i < n_members; ++i) {
897                 ir_entity *entity = get_class_member(global_type, i);
898                 dump_entity_to_file(out, entity);
899         }
900 }