irdumptxt.c 25 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
/*
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
Christian Würdig's avatar
Christian Würdig committed
4
5
 */

Matthias Braun's avatar
Matthias Braun committed
6
7
/**
 * @file
8
9
10
 * @brief   Write text representation of firm to file.
 * @author  Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Hubert Schmidt,
 *          Matthias Braun
Götz Lindenmaier's avatar
Götz Lindenmaier committed
11
12
 */
#include <stdlib.h>
13
#include <stdbool.h>
Götz Lindenmaier's avatar
Götz Lindenmaier committed
14

15
#include "constbits.h"
16
#include "irdump_t.h"
17
#include "irgraph_t.h"
Matthias Braun's avatar
Matthias Braun committed
18
#include "irnode_t.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
19
20
21

#include "irprog_t.h"
#include "entity_t.h"
22
#include "irgwalk.h"
Michael Beck's avatar
Michael Beck committed
23
#include "tv_t.h"
Michael Beck's avatar
Michael Beck committed
24
#include "irprintf.h"
Matthias Braun's avatar
Matthias Braun committed
25
#include "panic.h"
26
#include "cgana.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
27

Götz Lindenmaier's avatar
Götz Lindenmaier committed
28
#include "irdom.h"
29

Matthias Braun's avatar
Matthias Braun committed
30
31
32
33
34
35
36
37
38
39
40
41
42
43
typedef struct bitflag_name_t {
	unsigned    flag;
	const char *name;
} bitflag_name_t;

static const bitflag_name_t ir_linkage_names[] = {
	{ IR_LINKAGE_CONSTANT,        "constant"        },
	{ IR_LINKAGE_WEAK,            "weak"            },
	{ IR_LINKAGE_GARBAGE_COLLECT, "garbage_collect" },
	{ IR_LINKAGE_MERGE,           "merge"           },
	{ IR_LINKAGE_HIDDEN_USER,     "hidden_user"     },
	{ 0,                          NULL              },
};
static const bitflag_name_t mtp_property_names[] = {
44
	{ mtp_property_no_write,           "no_write"           },
Matthias Braun's avatar
Matthias Braun committed
45
46
	{ mtp_property_pure,               "pure"               },
	{ mtp_property_noreturn,           "noreturn"           },
47
	{ mtp_property_terminates,         "terminates"         },
Matthias Braun's avatar
Matthias Braun committed
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
	{ mtp_property_nothrow,            "nothrow"            },
	{ mtp_property_naked,              "naked"              },
	{ mtp_property_malloc,             "malloc"             },
	{ mtp_property_returns_twice,      "returns_twice"      },
	{ mtp_property_private,            "private"            },
	{ mtp_property_always_inline,      "always_inline"      },
	{ mtp_property_noinline,           "noinline"           },
	{ mtp_property_inline_recommended, "inline_recommended" },
	{ mtp_temporary,                   "temporary"          },
	{ 0,                               NULL                 },
};
static const bitflag_name_t cc_names[] = {
	{ cc_reg_param,           "reg_param"           },
	{ cc_last_on_top,         "last_on_top"         },
	{ cc_callee_clear_stk,    "callee_clear_stk"    },
	{ cc_this_call,           "this_call"           },
	{ cc_compound_ret,        "compound_ret"        },
	{ cc_frame_on_caller_stk, "frame_on_caller_stk" },
	{ cc_fpreg_param,         "fpreg_param"         },
	{ 0,                      NULL                  },
};

Matthias Braun's avatar
Matthias Braun committed
70
static void print_bitflags(FILE *const F, const bitflag_name_t names[],
Matthias Braun's avatar
Matthias Braun committed
71
72
73
74
75
76
77
78
79
80
81
                           unsigned const bitset)
{
	for (size_t i = 0; names[i].name != 0; ++i) {
		if ((bitset & names[i].flag) != 0) {
			fputc(' ', F);
			fputs(names[i].name, F);
		}
	}
}

static ir_dump_verbosity_t verbosity = dump_verbosity_max;
82

83
void ir_set_dump_verbosity(ir_dump_verbosity_t new_verbosity)
84
{
85
86
	verbosity = new_verbosity;
}
Michael Beck's avatar
Michael Beck committed
87

88
89
90
ir_dump_verbosity_t ir_get_dump_verbosity(void)
{
	return verbosity;
91
92
}

Matthias Braun's avatar
Matthias Braun committed
93
void dump_irnode_to_file(FILE *const F, const ir_node *const n)
94
{
Michael Beck's avatar
Michael Beck committed
95
96
97
98
	dump_node_opcode(F, n);
	fprintf(F, " %ld\n", get_irn_node_nr(n));

	fprintf(F, "  index: %u\n", get_irn_idx(n));
Matthias Braun's avatar
Matthias Braun committed
99
100
101
	fprintf(F, "  mode:    %s\n", get_mode_name(get_irn_mode(n)));
	fprintf(F, "  visited: %lu\n", get_irn_visited(n));
	ir_graph *irg = get_irn_irg(n);
Michael Beck's avatar
Michael Beck committed
102
103
104
	if (irg != get_const_code_irg())
		fprintf (F, "  irg:     %s\n", get_ent_dump_name(get_irg_entity(irg)));

Matthias Braun's avatar
Matthias Braun committed
105
	if (!get_irn_pinned(n) &&
Michael Beck's avatar
Michael Beck committed
106
107
		get_irg_pinned(get_irn_irg(n)) == op_pin_state_floats) {
		fprintf(F, "  node was pinned in ");
108
109
110
		ir_node *const block = get_nodes_block(n);
		dump_node_opcode(F, block);
		fprintf(F, " %ld\n", get_irn_node_nr(block));
Michael Beck's avatar
Michael Beck committed
111
112
	}

113
114
	fprintf(F, "  arity:   %d\n", get_irn_arity(n));
	/* show all predecessor nodes */
115
	fprintf(F, "  pred nodes:\n");
116
117
	if (!is_Block(n)) {
		fprintf(F, "    -1:    ");
118
119
120
		ir_node *const block = get_nodes_block(n);
		dump_node_opcode(F, block);
		fprintf(F, " %ld\n", get_irn_node_nr(block));
121
	}
122

123
	foreach_irn_in(n, i, pred) {
Matthias Braun's avatar
Matthias Braun committed
124
		fprintf(F, "     %d: %s ", i, is_backedge(n, i) ? "be" : "  ");
125
126
		dump_node_opcode(F, pred);
		fprintf(F, " %ld\n", get_irn_node_nr(pred));
127
	}
Michael Beck's avatar
Michael Beck committed
128
129
130

	fprintf(F, "  Private Attributes:\n");

Matthias Braun's avatar
Matthias Braun committed
131
	if (is_Proj(n)) {
Matthias Braun's avatar
Matthias Braun committed
132
		const ir_node *pred = get_Proj_pred(n);
133
134
		unsigned       pn   = get_Proj_num(n);
		fprintf(F, "  proj nr: %u\n", pn);
Matthias Braun's avatar
Matthias Braun committed
135
136
		if (is_Switch(pred)) {
			const ir_switch_table *table = get_Switch_table(pred);
Matthias Braun's avatar
Matthias Braun committed
137
138
			for (size_t i = 0, n_entries = ir_switch_table_get_n_entries(table);
			     i < n_entries; ++i) {
Matthias Braun's avatar
Matthias Braun committed
139
140
141
142
143
144
145
146
147
148
149
150
151
152
				const ir_switch_table_entry *entry
					= ir_switch_table_get_entry_const(table, i);
				if (entry->pn == pn && entry->min != NULL && entry->max != NULL) {
					ir_tarval *min = entry->min;
					ir_tarval *max = entry->max;
					if (min != max) {
						ir_fprintf(F, "  switch case %+F .. %+F\n", min, max);
					} else {
						ir_fprintf(F, "  switch case %+F\n", min);
					}
				}
			}
		}
	}
Michael Beck's avatar
Michael Beck committed
153
154
155
156
157
158
159

	if (is_fragile_op(n)) {
		fprintf(F, "  pinned state: %s\n", get_op_pin_state_name(get_irn_pinned(n)));
		/* not dumped: frag array */
	}

	/* This is not nice, output it as a marker in the predecessor list. */
160
	if (is_Block(n) || is_Phi(n)) {
Michael Beck's avatar
Michael Beck committed
161
		fprintf(F, "  backedges:");
Matthias Braun's avatar
Matthias Braun committed
162
163
164
165
166
167
		char comma = ' ';
		for (int i = 0, arity = get_irn_arity(n); i < arity; i++) {
			if (is_backedge(n, i)) {
				fprintf(F, "%c %d", comma, i);
				comma = ',';
			}
Michael Beck's avatar
Michael Beck committed
168
			fprintf(F, "\n");
Matthias Braun's avatar
Matthias Braun committed
169
		}
Michael Beck's avatar
Michael Beck committed
170
171
172
	}

	/* Loop node.   Someone else please tell me what's wrong ... */
173
	if (irg_has_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO)) {
Matthias Braun's avatar
Matthias Braun committed
174
		const ir_loop *loop = get_irn_loop(n);
175
		if (loop != NULL) {
Matthias Braun's avatar
Matthias Braun committed
176
177
			fprintf(F, "  in loop %ld with depth %u\n",
			        get_loop_loop_nr(loop), get_loop_depth(loop));
178
		}
Michael Beck's avatar
Michael Beck committed
179
180
181
	}

	/* Source types */
Matthias Braun's avatar
Matthias Braun committed
182
	switch ((ir_opcode)get_irn_opcode(n)) {
Michael Beck's avatar
Michael Beck committed
183
	case iro_Block: {
Matthias Braun's avatar
Matthias Braun committed
184
		const ir_entity *const entity = get_Block_entity(n);
Christoph Mallon's avatar
Christoph Mallon committed
185
186
		if (entity != NULL)
			fprintf(F, "  Label: %lu\n", get_entity_label(entity));
187
		fprintf(F, "  block visited: %lu\n", get_Block_block_visited(n));
Michael Beck's avatar
Michael Beck committed
188
		fprintf(F, "  block marked: %u\n", get_Block_mark(n));
189
		if (irg_has_properties(get_irn_irg(n), IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE)) {
Michael Beck's avatar
Michael Beck committed
190
			fprintf(F, "  dom depth %d\n", get_Block_dom_depth(n));
191
192
			fprintf(F, "  domtree pre num %u\n", get_Block_dom_tree_pre_num(n));
			fprintf(F, "  max subtree pre num %u\n", get_Block_dom_max_subtree_pre_num(n));
Michael Beck's avatar
Michael Beck committed
193
		}
194
		if (irg_has_properties(get_irn_irg(n), IR_GRAPH_PROPERTY_CONSISTENT_POSTDOMINANCE)) {
195
			fprintf(F, "  pdom depth %d\n", get_Block_postdom_depth(n));
196
197
			fprintf(F, "  pdomtree pre num %u\n", get_Block_pdom_tree_pre_num(n));
			fprintf(F, "  max pdomsubtree pre num %u\n", get_Block_pdom_max_subtree_pre_num(n));
198
		}
Michael Beck's avatar
Michael Beck committed
199
200
201

		/* not dumped: graph_arr */
		/* not dumped: mature    */
Matthias Braun's avatar
Matthias Braun committed
202
203
		break;
	}
Michael Beck's avatar
Michael Beck committed
204
	case iro_Start: {
Matthias Braun's avatar
Matthias Braun committed
205
		const ir_type *tp = get_entity_type(get_irg_entity(get_irn_irg(n)));
206
		ir_fprintf(F, "  start of method of type %+F\n", tp);
Matthias Braun's avatar
Matthias Braun committed
207
208
		for (size_t i = 0, n_params = get_method_n_params(tp);
		     i < n_params; ++i) {
209
			ir_fprintf(F, "    param %d type: %+F\n", i, get_method_param_type(tp, i));
Matthias Braun's avatar
Matthias Braun committed
210
211
212
213
		}
		break;
	}
	case iro_Cond:
214
215
216
217
		if (get_Cond_jmp_pred(n) != COND_JMP_PRED_NONE) {
			fprintf(F, "  jump prediction: %s\n",
			        get_cond_jmp_predicate_name(get_Cond_jmp_pred(n)));
		}
Matthias Braun's avatar
Matthias Braun committed
218
219
		break;
	case iro_Alloc:
220
		ir_fprintf(F, "  alignment: %u\n", get_Alloc_alignment(n));
Matthias Braun's avatar
Matthias Braun committed
221
		break;
222
223
	case iro_Member: {
		const ir_entity *ent = get_Member_entity(n);
Matthias Braun's avatar
Matthias Braun committed
224
		if (ent != NULL) {
225
			ir_fprintf(F, "  Selecting entity %+F\n", ent);
226
227
			ir_fprintf(F, "    of type    %+F\n",  get_entity_type(ent));
			ir_fprintf(F, "    with owner %+F.\n", get_entity_owner(ent));
228
		} else {
Michael Beck's avatar
Michael Beck committed
229
230
			fprintf(F, "  <NULL entity>\n");
		}
Matthias Braun's avatar
Matthias Braun committed
231
232
		break;
	}
233
234
235
	case iro_Sel: {
		const ir_type *type = get_Sel_type(n);
		ir_fprintf(F, "  Array type: %+F\n", type);
Matthias Braun's avatar
Matthias Braun committed
236
		break;
237
	}
Michael Beck's avatar
Michael Beck committed
238
	case iro_Call: {
Matthias Braun's avatar
Matthias Braun committed
239
		const ir_type *tp = get_Call_type(n);
240
		ir_fprintf(F, "  calling method of type %+F\n", tp);
241
		if (get_unknown_type() != tp) {
Matthias Braun's avatar
Matthias Braun committed
242
243
244
245
246
247
248
249
250
251
			for (size_t i = 0, n_params = get_method_n_params(tp);
			     i < n_params; ++i) {
			    const ir_type *param_type = get_method_param_type(tp, i);
				ir_fprintf(F, "    param %d type: %+F\n", i, param_type);
			}
			for (size_t i = 0, n_ress = get_method_n_ress(tp);
			     i < n_ress; ++i) {
			    const ir_type *res_type = get_method_res_type(tp, i);
				ir_fprintf(F, "    result %d type: %+F\n", i, res_type);
			}
Michael Beck's avatar
Michael Beck committed
252
		}
253
		if (cg_call_has_callees(n)) {
254
			fprintf(F, "  possible callees:\n");
255
			for (size_t i = 0, n_callees = cg_get_call_n_callees(n);
Matthias Braun's avatar
Matthias Braun committed
256
			     i < n_callees; i++) {
257
				const ir_entity *callee = cg_get_call_callee(n, i);
Matthias Braun's avatar
Matthias Braun committed
258
				ir_fprintf(F, "    %zu: %s\n", i, get_ent_dump_name(callee));
Michael Beck's avatar
Michael Beck committed
259
260
			}
		}
Matthias Braun's avatar
Matthias Braun committed
261
262
		break;
	}
263
264
265
	case iro_Cmp: {
		ir_relation relation = get_Cmp_relation(n);
		ir_fprintf(F, "  relation: %s\n", get_relation_string(relation));
Matthias Braun's avatar
Matthias Braun committed
266
267
		break;
	}
Michael Beck's avatar
Michael Beck committed
268
	case iro_Return: {
Matthias Braun's avatar
Matthias Braun committed
269
		const ir_type *tp = get_entity_type(get_irg_entity(get_irn_irg(n)));
270
		ir_fprintf(F, "  return in method of type %+F\n", tp);
Matthias Braun's avatar
Matthias Braun committed
271
272
273
		for (size_t i = 0, n_ress = get_method_n_ress(tp); i < n_ress; ++i) {
			const ir_type *res_type = get_method_res_type(tp, i);
			ir_fprintf(F, "    result %d type: %+F\n", i, res_type);
Michael Beck's avatar
Michael Beck committed
274
		}
Matthias Braun's avatar
Matthias Braun committed
275
276
		break;
	}
277

278
279
280
281
282
283
284
285
286
	case iro_Address:
		fprintf(F, "  entity: ");
		dump_entity_to_file(F, get_Address_entity(n));
		break;

	case iro_Offset:
		fprintf(F, "  entity: ");
		dump_entity_to_file(F, get_Offset_entity(n));
		break;
287

288
289
290
291
292
293
294
295
	case iro_Align:
		fprintf(F, "  type: ");
		dump_type_to_file(F, get_Align_type(n));
		break;

	case iro_Size:
		fprintf(F, "  type: ");
		dump_type_to_file(F, get_Size_type(n));
Matthias Braun's avatar
Matthias Braun committed
296
		break;
297

Michael Beck's avatar
Michael Beck committed
298
	case iro_Load:
Christoph Mallon's avatar
Christoph Mallon committed
299
		fprintf(F, "  mode of loaded value: %s\n", get_mode_name(get_Load_mode(n)));
300
		ir_fprintf(F, "  type of object loaded from: %+F\n", get_Load_type(n));
Michael Beck's avatar
Michael Beck committed
301
		fprintf(F, "  volatility: %s\n", get_volatility_name(get_Load_volatility(n)));
302
		fprintf(F, "  align: %s\n", get_align_name(get_Load_unaligned(n)));
Michael Beck's avatar
Michael Beck committed
303
304
		break;
	case iro_Store:
305
		ir_fprintf(F, "  type of object stored to: %+F\n", get_Store_type(n));
Michael Beck's avatar
Michael Beck committed
306
		fprintf(F, "  volatility: %s\n", get_volatility_name(get_Store_volatility(n)));
307
		fprintf(F, "  align: %s\n", get_align_name(get_Store_unaligned(n)));
Michael Beck's avatar
Michael Beck committed
308
309
		break;
	case iro_Confirm:
310
		fprintf(F, "  compare operation: %s\n", get_relation_string(get_Confirm_relation(n)));
Michael Beck's avatar
Michael Beck committed
311
312
		break;
	case iro_ASM: {
Matthias Braun's avatar
Matthias Braun committed
313
		fprintf(F, "  assembler text: %s", get_id_str(get_ASM_text(n)));
314
315
		fprintf(F, "\n  inputs:  ");
		const ir_asm_constraint *in_cons = get_ASM_input_constraints(n);
Matthias Braun's avatar
Matthias Braun committed
316
		for (int i = 0, n_inputs = get_ASM_n_inputs(n); i < n_inputs; ++i) {
317
318
			fprintf(F, "%%%u %s ", in_cons[i].pos,
			        get_id_str(in_cons[i].constraint));
Michael Beck's avatar
Michael Beck committed
319
		}
320
321
		fprintf(F, "\n  outputs: ");
		const ir_asm_constraint *out_cons = get_ASM_output_constraints(n);
Matthias Braun's avatar
Matthias Braun committed
322
323
		for (int i = 0, n_outputs = get_ASM_n_output_constraints(n);
		     i < n_outputs; ++i) {
324
325
			fprintf(F, "%%%u %s ", out_cons[i].pos,
			        get_id_str(out_cons[i].constraint));
Michael Beck's avatar
Michael Beck committed
326
		}
327
328
329

		fprintf(F, "\n  clobber: ");
		ident **clobber = get_ASM_clobbers(n);
Matthias Braun's avatar
Matthias Braun committed
330
		for (int i = 0, n_clobbers = get_ASM_n_clobbers(n); i < n_clobbers; ++i)
331
			fprintf(F, "%s ", get_id_str(clobber[i]));
Matthias Braun's avatar
Matthias Braun committed
332
		if (get_irn_pinned(n))
Michael Beck's avatar
Michael Beck committed
333
334
			fprintf(F, "\n  volatile");
		fprintf(F, "\n");
335
336
		break;
	}
Michael Beck's avatar
Michael Beck committed
337
338
339

	default:
		break;
Michael Beck's avatar
Michael Beck committed
340
	}
341

342
	bitinfo const *const b = try_get_bitinfo(n);
343
344
345
346
	if (b) {
		fprintf(F, "\n  bitinfo: ");
		ir_tarval const* const z = b->z;
		ir_tarval const* const o = b->o;
347
		for (unsigned i = get_mode_size_bits(get_tarval_mode(z)); i-- != 0;) {
348
			fputc("0_?1"[tarval_get_bit(z, i) << 1 | tarval_get_bit(o, i)], F);
349
		}
350
351
352
353
354
355
		switch (b->state) {
		case BITINFO_INVALID:   fputs(" (invalid)",   F); break;
		case BITINFO_VALID:     /* nothing */             break;
		case BITINFO_IN_FLIGHT: fputs(" (in flight)", F); break;
		case BITINFO_UNSTABLE:  fputs(" (unstable)",  F); break;
		}
356
		fputc('\n', F);
357
	}
358
359
}

Matthias Braun's avatar
Matthias Braun committed
360
void dump_graph_as_text(FILE *const out, const ir_graph *const irg)
361
{
362
	fprintf(out, "graph %s\n", get_irg_dump_name(irg));
363
364
}

Matthias Braun's avatar
Matthias Braun committed
365
static bool need_nl = true;
366

Matthias Braun's avatar
Matthias Braun committed
367
368
static bool is_init_string(ir_initializer_t const* const init,
                           ir_type const* const type)
369
{
Matthias Braun's avatar
Matthias Braun committed
370
	const ir_type *const element_type = get_array_element_type(type);
371
372
373
	if (!is_Primitive_type(element_type))
		return false;

Matthias Braun's avatar
Matthias Braun committed
374
	const ir_mode *mode = get_type_mode(element_type);
375
376
377
	if (!mode_is_int(mode) || get_mode_size_bits(mode) != 8)
		return false;

Matthias Braun's avatar
Matthias Braun committed
378
379
	for (size_t i = 0, n = get_initializer_compound_n_entries(init);
	     i != n; ++i) {
380
		ir_initializer_t const* const val = get_initializer_compound_value(init, i);
Matthias Braun's avatar
Matthias Braun committed
381
382
		if (get_initializer_kind(val) != IR_INITIALIZER_TARVAL)
			return false;
Matthias Braun's avatar
Matthias Braun committed
383
		ir_tarval *tv = get_initializer_tarval_value(val);
Matthias Braun's avatar
Matthias Braun committed
384

385
386
387
		if (!tarval_is_constant(tv))
			return false;

Matthias Braun's avatar
Matthias Braun committed
388
		long v = get_tarval_long(tv);
389
		if (v != 0 && (v < 0x07 || 0x0D < v) && v != 0x1B && (v < 0x20 || 0x80 <= v) && (v < 0xA0 || 0x100 <= v))
390
391
392
393
394
395
			return false;
	}

	return true;
}

396
397
398
/**
 * Dump initializers.
 */
Matthias Braun's avatar
Matthias Braun committed
399
400
401
static void dump_ir_initializers_to_file(FILE *const F,
		const char *const prefix, const ir_initializer_t *const initializer,
		const ir_type *const type)
402
{
403
404
	if (need_nl) {
		fprintf(F, "\n%s    ", prefix);
Matthias Braun's avatar
Matthias Braun committed
405
		need_nl = false;
406
407
408
409
410
	}
	switch (get_initializer_kind(initializer)) {
	case IR_INITIALIZER_NULL:
		fprintf(F, "\t = <NOT_SET>");
		break;
Matthias Braun's avatar
Matthias Braun committed
411
412
	case IR_INITIALIZER_TARVAL: {
		ir_tarval *tv = get_initializer_tarval_value(initializer);
413
414
		ir_fprintf(F, "\t = <TV>%F", tv);
		break;
Matthias Braun's avatar
Matthias Braun committed
415
416
417
	}
	case IR_INITIALIZER_CONST: {
		ir_node *value = get_initializer_const_value(initializer);
418
		ir_fprintf(F, "\t = %F", value);
419
		break;
Matthias Braun's avatar
Matthias Braun committed
420
	}
421
422
	case IR_INITIALIZER_COMPOUND:
		if (is_Array_type(type)) {
423
424
425
426
			size_t const n = get_initializer_compound_n_entries(initializer);

			if (is_init_string(initializer, type)) {
				fprintf(F, "\t[0...%u] = '", (unsigned)n - 1);
Matthias Braun's avatar
Matthias Braun committed
427
				for (size_t i = 0; i != n; ++i) {
428
429
430
431
432
					ir_initializer_t const* const val = get_initializer_compound_value(initializer, i);
					ir_tarval*              const tv  = get_initializer_tarval_value(val);
					long                    const v   = get_tarval_long(tv);

					switch (v) {
433
						case 0x00: fprintf(F, "\\\\000");  break;
434
435
						case 0x07: fprintf(F, "\\\\a");    break;
						case 0x08: fprintf(F, "\\\\b");    break;
436
437
						case 0x09: fprintf(F, "\\\\t");    break;
						case 0x0A: fprintf(F, "\\\\n");    break;
438
						case 0x0B: fprintf(F, "\\\\v");    break;
439
440
441
442
443
						case 0x0C: fprintf(F, "\\\\f");    break;
						case 0x0D: fprintf(F, "\\\\r");    break;
						case 0x1B: fprintf(F, "\\\\033");  break;
						case 0x22: fprintf(F, "\\\\\\\""); break;
						case 0x5C: fprintf(F, "\\\\\\\\"); break;
444
445
446
447
448
						default:   fprintf(F, "%c", (unsigned char)v); break;
					}
				}
				fprintf(F, "'");
			} else {
Matthias Braun's avatar
Matthias Braun committed
449
				const ir_type *const element_type = get_array_element_type(type);
450

Matthias Braun's avatar
Matthias Braun committed
451
452
				for (size_t i = 0; i < n; ++i) {
					const ir_initializer_t *sub_initializer
453
						= get_initializer_compound_value(initializer, i);
454

455
456
					if (need_nl) {
						fprintf(F, "\n%s    ", prefix);
Matthias Braun's avatar
Matthias Braun committed
457
						need_nl = false;
458
459
460
					}
					fprintf(F, "[%d]", (int) i);
					dump_ir_initializers_to_file(F, prefix, sub_initializer, element_type);
461
462
463
				}
			}
		} else {
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
			if (!is_compound_type(type)) {
				fprintf(F, "\n%s BAD Initializer", prefix);
			} else {
				for (size_t i = 0,
				     n = get_initializer_compound_n_entries(initializer);
				     i < n; ++i) {
					if (i >= get_compound_n_members(type)) {
						fprintf(F, "\n%s BAD initializer", prefix);
						continue;
					}
					const ir_entity *member  = get_compound_member(type, i);
					const ir_type   *subtype = get_entity_type(member);
					assert(i < get_initializer_compound_n_entries(initializer));
					const ir_initializer_t *sub_initializer
						= get_initializer_compound_value(initializer, i);

					if (need_nl) {
						fprintf(F, "\n%s    ", prefix);
						need_nl = false;
					}
					ir_fprintf(F, ".%F", member);
					dump_ir_initializers_to_file(F, prefix, sub_initializer, subtype);
486
487
488
489
490
491
492
				}
			}
		}
		break;
	default:
		panic("invalid ir_initializer kind found");
	}
Matthias Braun's avatar
Matthias Braun committed
493
	need_nl = true;
494
495
}

Matthias Braun's avatar
Matthias Braun committed
496
static void dump_entity_linkage(FILE *const F, const ir_entity *const entity)
Matthias Braun's avatar
Matthias Braun committed
497
498
{
	ir_linkage linkage = get_entity_linkage(entity);
499
500
501
502
	if (linkage == IR_LINKAGE_DEFAULT) {
		fprintf(F, " default");
		return;
	}
Matthias Braun's avatar
Matthias Braun committed
503
	print_bitflags(F, ir_linkage_names, (unsigned)linkage);
Matthias Braun's avatar
Matthias Braun committed
504
}
505

Matthias Braun's avatar
Matthias Braun committed
506
507
508
static void dump_entity_to_file_prefix(FILE *const F,
                                       const ir_entity *const ent,
                                       const char *const prefix)
509
{
Matthias Braun's avatar
Matthias Braun committed
510
511
	const ir_type *owner = get_entity_owner(ent);
	const ir_type *type  = get_entity_type(ent);
Michael Beck's avatar
Michael Beck committed
512
	if (verbosity & dump_verbosity_onlynames) {
513
514
		ir_fprintf(F, "%sentity %s.%+F\n", prefix, get_compound_name(owner),
		           ent);
Michael Beck's avatar
Michael Beck committed
515
516
517
518
		return;
	}

	if (verbosity & dump_verbosity_entattrs) {
519
		ir_fprintf(F, "%sentity %+F\n", prefix, ent);
520
521
		ir_fprintf(F, "%s  type:  %+F\n", prefix, type);
		ir_fprintf(F, "%s  owner: %+F\n", prefix, owner);
Michael Beck's avatar
Michael Beck committed
522
523
524
525

		if (is_Class_type(get_entity_owner(ent))) {
			if (get_entity_n_overwrites(ent) > 0) {
				fprintf(F, "%s  overwrites:\n", prefix);
Matthias Braun's avatar
Matthias Braun committed
526
527
				for (size_t i = 0; i < get_entity_n_overwrites(ent); ++i) {
					const ir_entity *ov = get_entity_overwrites(ent, i);
528
529
					ir_fprintf(F, "%s    %d: %F of class %+F\n", prefix, i, ov,
					           get_entity_owner(ov));
Michael Beck's avatar
Michael Beck committed
530
531
				}
			} else {
532
				fprintf(F, "%s  Does not overwrite other entities.\n", prefix);
Michael Beck's avatar
Michael Beck committed
533
534
535
			}
			if (get_entity_n_overwrittenby(ent) > 0) {
				fprintf(F, "%s  overwritten by:\n", prefix);
Matthias Braun's avatar
Matthias Braun committed
536
537
				for (size_t i = 0; i < get_entity_n_overwrittenby(ent); ++i) {
					const ir_entity *ov = get_entity_overwrittenby(ent, i);
538
539
					ir_fprintf(F, "%s    %d: %F of class %+F\n", prefix, i, ov,
					           get_entity_owner(ov));
Michael Beck's avatar
Michael Beck committed
540
541
				}
			} else {
542
543
				fprintf(F, "%s  Is not overwritten by other entities.\n",
				        prefix);
Michael Beck's avatar
Michael Beck committed
544
545
546
547
			}

			if (get_irp_inh_transitive_closure_state() != inh_transitive_closure_none) {
				fprintf(F, "%s  transitive overwrites:\n", prefix);
Matthias Braun's avatar
Matthias Braun committed
548
549
				for (const ir_entity *ov = get_entity_trans_overwrites_first(ent);
				     ov != NULL; ov = get_entity_trans_overwrites_next(ent)) {
550
551
					ir_fprintf(F, "%s    : %F of class %+F\n", prefix, ov,
					           get_entity_owner(ov));
Michael Beck's avatar
Michael Beck committed
552
553
				}
				fprintf(F, "%s  transitive overwritten by:\n", prefix);
Matthias Braun's avatar
Matthias Braun committed
554
555
				for (const ir_entity *ov = get_entity_trans_overwrittenby_first(ent);
				     ov != NULL; ov = get_entity_trans_overwrittenby_next(ent)) {
556
557
					ir_fprintf(F, "%s    : %F of class %+F\n", prefix, ov,
					           get_entity_owner(ov));
Michael Beck's avatar
Michael Beck committed
558
559
560
561
				}
			}
		}

Matthias Braun's avatar
Matthias Braun committed
562
		if (is_Method_type(type)) {
563
564
			const unsigned mask = get_entity_additional_properties(ent);
			const unsigned cc   = get_method_calling_convention(type);
Michael Beck's avatar
Michael Beck committed
565

566
567
568
569
570
571
572
			if (is_method_entity(ent)) {
				const ir_graph *const irg = get_entity_irg(ent);

				if (irg != NULL) {
					fprintf(F, "%s  maximum node index:   %u\n", prefix,
					        get_irg_last_idx(irg));
				}
Michael Beck's avatar
Michael Beck committed
573
574
			}

575
			fprintf(F, "%s  additional prop: ", prefix);
Matthias Braun's avatar
Matthias Braun committed
576
			print_bitflags(F, mtp_property_names, (unsigned)mask);
577
578
			fputc('\n', F);

579
			fprintf(F, "%s  calling convention: ", prefix);
Matthias Braun's avatar
Matthias Braun committed
580
581
			print_bitflags(F, cc_names, (unsigned)cc);

582
583
584
585
			if (is_method_entity(ent)) {
				fprintf(F, "\n%s  vtable number:        %u\n", prefix,
					get_entity_vtable_number(ent));
			}
Michael Beck's avatar
Michael Beck committed
586
587
		}
	} else {  /* no entattrs */
588
		ir_fprintf(F, "%s %+F: %F", prefix, type, ent);
Matthias Braun's avatar
Matthias Braun committed
589
590
		if (is_Method_type(type))
			fputs("(...)", F);
591
		if (is_entity_compound_member(ent)) {
592
593
594
595
596
597
598
599
			ir_fprintf(F, " offset: %d", get_entity_offset(ent));
			unsigned bitfield_size = get_entity_bitfield_size(ent);
			if (bitfield_size > 0) {
				unsigned bitfield_offset = get_entity_bitfield_offset(ent);
				ir_fprintf(F, " bitfield offs %u size %u", bitfield_offset,
				           bitfield_size);
			}
		}
Michael Beck's avatar
Michael Beck committed
600
601

		if (verbosity & dump_verbosity_accessStats) {
Matthias Braun's avatar
Matthias Braun committed
602
			dump_entity_linkage(F, ent);
Michael Beck's avatar
Michael Beck committed
603
		}
604
		fputc('\n', F);
Michael Beck's avatar
Michael Beck committed
605
606
607
	}

	if (verbosity & dump_verbosity_entconsts) {
608
609
610
611
612
613
614
615
		if (get_entity_kind(ent) == IR_ENTITY_NORMAL) {
			ir_initializer_t const *const initializer = get_entity_initializer(ent);
			if (initializer) {
				fprintf(F, "\n%s  Initializers:", prefix);
				need_nl = true;
				dump_ir_initializers_to_file(F, prefix, initializer, get_entity_type(ent));
				fputc('\n', F);
			}
Michael Beck's avatar
Michael Beck committed
616
617
618
619
		}
	}

	if (verbosity & dump_verbosity_entattrs) {
Matthias Braun's avatar
Matthias Braun committed
620
621
		fprintf(F, "%s  linkage:", prefix);
		dump_entity_linkage(F, ent);
622
		fprintf(F, "\n%s  volatility:  %s", prefix, get_volatility_name(get_entity_volatility(ent)));
Matthias Braun's avatar
Matthias Braun committed
623
624
		fprintf(F, "\n%s  aligned:  %s", prefix, get_align_name(get_entity_aligned(ent)));
		fprintf(F, "\n%s  alignment:  %u", prefix, get_entity_alignment(ent));
Michael Beck's avatar
Michael Beck committed
625
		fprintf(F, "\n%s  ld_name: %s", prefix, ent->ld_name ? get_entity_ld_name(ent) : "no yet set");
626
627
628
629
630
631
632
633
634
		if (is_entity_compound_member(ent)) {
			fprintf(F, "\n%s  offset:  %d bytes", prefix, get_entity_offset(ent));
			unsigned bitfield_size   = get_entity_bitfield_size(ent);
			if (bitfield_size > 0) {
				unsigned bitfield_offset = get_entity_bitfield_offset(ent);
				fprintf(F, "\n%s  bitfield offset: %u", prefix, bitfield_offset);
				fprintf(F, "\n%s  bitfield size: %u", prefix, bitfield_size);
			}
		}
635
		if (is_Method_type(type) && is_method_entity(ent)) {
Matthias Braun's avatar
Matthias Braun committed
636
637
638
			const ir_graph *irg = get_entity_irg(ent);
			if (irg != NULL) {
				fprintf(F, "\n%s  irg = %ld", prefix, get_irg_graph_nr(irg));
Michael Beck's avatar
Michael Beck committed
639
640
641
642
			} else {
				fprintf(F, "\n%s  irg = NULL", prefix);
			}
		}
643
		fputc('\n', F);
Michael Beck's avatar
Michael Beck committed
644
	}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
645
646
}

Matthias Braun's avatar
Matthias Braun committed
647
void dump_entity_to_file(FILE *const out, const ir_entity *const ent)
648
{
649
650
	dump_entity_to_file_prefix(out, ent, "");
	fprintf(out, "\n");
Götz Lindenmaier's avatar
Götz Lindenmaier committed
651
652
}

653
654
655
656
657
658
659
660
static void dump_compound_members(FILE *const F, ir_type const *const type)
{
	if ((verbosity & (dump_verbosity_methods|dump_verbosity_fields)) == 0
	 || !(verbosity & dump_verbosity_nostatic))
		return;

	fprintf(F, "\n  members:\n");
	for (size_t i = 0, n = get_compound_n_members(type); i < n; ++i) {
661
662
663
		ir_entity const *const mem = get_compound_member(type, i);
		if (verbosity & (is_method_entity(mem) ? dump_verbosity_methods : dump_verbosity_fields))
			dump_entity_to_file_prefix(F, mem, "    ");
664
665
666
	}
}

667
static void dump_type_details(FILE *const F, ir_type const *const tp)
668
{
669
	switch (get_type_opcode(tp)) {
Michael Beck's avatar
Michael Beck committed
670
	case tpo_class:
671
		dump_compound_members(F, tp);
Michael Beck's avatar
Michael Beck committed
672
673
		if (verbosity & dump_verbosity_typeattrs) {
			fprintf(F, "  supertypes: ");
Matthias Braun's avatar
Matthias Braun committed
674
675
			for (size_t i = 0; i < get_class_n_supertypes(tp); ++i) {
				const ir_type *stp = get_class_supertype(tp, i);
676
				ir_fprintf(F, "\n    %d %+F", i, stp);
Michael Beck's avatar
Michael Beck committed
677
678
			}
			fprintf(F, "\n  subtypes: ");
Matthias Braun's avatar
Matthias Braun committed
679
680
			for (size_t i = 0; i < get_class_n_subtypes(tp); ++i) {
				const ir_type *stp = get_class_subtype(tp, i);
681
				ir_fprintf(F, "\n    %d %+F", i, stp);
Michael Beck's avatar
Michael Beck committed
682
683
684
685
			}

			if (get_irp_inh_transitive_closure_state() != inh_transitive_closure_none) {
				fprintf(F, "\n  transitive supertypes: ");
Matthias Braun's avatar
Matthias Braun committed
686
687
				for (const ir_type *stp = get_class_trans_supertype_first(tp);
				     stp != NULL; stp = get_class_trans_supertype_next(tp)) {
688
					ir_fprintf(F, "\n    %+F", stp);
Michael Beck's avatar
Michael Beck committed
689
690
				}
				fprintf(F, "\n  transitive subtypes: ");
Matthias Braun's avatar
Matthias Braun committed
691
692
				for (const ir_type *stp = get_class_trans_subtype_first(tp);
				     stp != NULL; stp = get_class_trans_subtype_next(tp)) {
693
					ir_fprintf(F, "\n    %+F", stp);
Michael Beck's avatar
Michael Beck committed
694
695
696
				}
			}
		}
697
		return;
Michael Beck's avatar
Michael Beck committed
698
699
700

	case tpo_union:
	case tpo_struct:
701
	case tpo_segment:
702
		dump_compound_members(F, tp);
703
		return;
Michael Beck's avatar
Michael Beck committed
704
705
706

	case tpo_array:
		if (verbosity & dump_verbosity_typeattrs) {
Matthias Braun's avatar
Matthias Braun committed
707
			const ir_type *elem_tp = get_array_element_type(tp);
Christoph Mallon's avatar
Christoph Mallon committed
708
			ir_fprintf(F, "\n  array [%.u] of <%+F>\n", get_array_size(tp), elem_tp);
Michael Beck's avatar
Michael Beck committed
709
		}
710
		return;
Michael Beck's avatar
Michael Beck committed
711
712
713

	case tpo_pointer:
		if (verbosity & dump_verbosity_typeattrs) {
Matthias Braun's avatar
Matthias Braun committed
714
			const ir_type *tt = get_pointer_points_to_type(tp);
715
			ir_fprintf(F, "\n  points to %+F\n", tt);
Michael Beck's avatar
Michael Beck committed
716
		}
717
		return;
Michael Beck's avatar
Michael Beck committed
718
719
720

	case tpo_method:
		if (verbosity & dump_verbosity_typeattrs) {
721
722
			mtp_additional_properties mtp = get_method_additional_properties(tp);
			unsigned cconv = get_method_calling_convention(tp);
723
			fprintf(F, "\n  variadic: %s", is_method_variadic(tp) ? "yes" : "no");
724
725
			fprintf(F, "\n  return types: %lu",
			        (unsigned long) get_method_n_ress(tp));
Matthias Braun's avatar
Matthias Braun committed
726
727
			for (size_t i = 0; i < get_method_n_ress(tp); ++i) {
				const ir_type *rtp = get_method_res_type(tp, i);
728
				ir_fprintf(F, "\n    %+F", rtp);
Michael Beck's avatar
Michael Beck committed
729
730
			}

731
732
			fprintf(F, "\n  parameter types: %lu",
			        (unsigned long) get_method_n_params(tp));
Matthias Braun's avatar
Matthias Braun committed
733
734
			for (size_t i = 0; i < get_method_n_params(tp); ++i) {
				const ir_type *ptp = get_method_param_type(tp, i);
735
				ir_fprintf(F, "\n    %+F", ptp);
Michael Beck's avatar
Michael Beck committed
736
			}
737
738
			if (is_method_variadic(tp))
				fprintf(F, "\n    ...");
739
			fprintf(F, "\n  properties:");
Matthias Braun's avatar
Matthias Braun committed
740
			print_bitflags(F, mtp_property_names, (unsigned)mtp);
741
742

			fprintf(F, "\n  calling convention:");
Matthias Braun's avatar
Matthias Braun committed
743
			print_bitflags(F, cc_names, (unsigned)cconv);
Michael Beck's avatar
Michael Beck committed
744
745
			fprintf(F, "\n");
		}
746
		return;
Michael Beck's avatar
Michael Beck committed
747
748
749

	case tpo_primitive:
	case tpo_unknown:
750
751
	case tpo_code:
	case tpo_uninitialized:
Michael Beck's avatar
Michael Beck committed
752
		fprintf(F, "\n");
753
		return;
Michael Beck's avatar
Michael Beck committed
754
	}
755
756
757
758
759
760
761
762
763
	panic("invalid type");
}

void dump_type_to_file(FILE *const F, const ir_type *const tp)
{
	ir_fprintf(F, "%+F", tp);
	if (verbosity & dump_verbosity_onlynames) { fprintf(F, "\n"); return; }

	dump_type_details(F, tp);
Michael Beck's avatar
Michael Beck committed
764
765

	fprintf(F, "  state:      %s,\n", get_type_state_name(get_type_state(tp)));
766
767
	fprintf(F, "  size:       %2u Bytes,\n", get_type_size(tp));
	fprintf(F, "  alignment:  %2u Bytes,\n", get_type_alignment(tp));
Michael Beck's avatar
Michael Beck committed
768
769
770
771
	if (is_atomic_type(tp) || is_Method_type(tp))
		fprintf(F, "  mode:       %s,\n",  get_mode_name(get_type_mode(tp)));

	fprintf(F, "\n\n");
Götz Lindenmaier's avatar
Götz Lindenmaier committed
772
773
}

Matthias Braun's avatar
Matthias Braun committed
774
void dump_types_as_text(FILE *const out)
775
{
Matthias Braun's avatar
Matthias Braun committed
776
777
	for (size_t i = 0, n_types = get_irp_n_types(); i < n_types; ++i) {
		const ir_type *type = get_irp_type(i);
778
		dump_type_to_file(out, type);
Michael Beck's avatar
Michael Beck committed
779
	}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
780
}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
781

Matthias Braun's avatar
Matthias Braun committed
782
void dump_globals_as_text(FILE *const out)
783
{
Matthias Braun's avatar
Matthias Braun committed
784
	const ir_type *global_type = get_glob_type();
785
	for (size_t i = 0, n_members = get_compound_n_members(global_type);
Matthias Braun's avatar
Matthias Braun committed
786
	     i < n_members; ++i) {
787
		const ir_entity *entity = get_compound_member(global_type, i);
788
		dump_entity_to_file(out, entity);
Michael Beck's avatar
Michael Beck committed
789
	}
Götz Lindenmaier's avatar
Götz Lindenmaier committed
790
}