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