3 * File name: ir/ir/irdump.c
4 * Purpose: Write vcg representation of firm to file.
5 * Author: Martin Trapp, Christian Schaefer
6 * Modified by: Goetz Lindenmaier, Hubert Schmidt
9 * Copyright: (c) 1998-2003 Universität Karlsruhe
10 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
19 #include "firm_common_t.h"
21 #include "irgraph_t.h"
25 #include "field_temperature.h"
27 int dump_node_opcode(FILE *F, ir_node *n); /* from irdump.c */
31 #define X(a) case a: fprintf(F, #a); break
32 void dump_entity_to_file_prefix (FILE *F, entity *ent, char *prefix, unsigned verbosity) {
34 assert(ent && ent->kind == k_entity);
35 type *owner = get_entity_owner(ent);
36 type *type = get_entity_type(ent);
38 if (verbosity & dump_verbosity_onlynames) {
39 fprintf(F, "%sentity %s.%s (%ld)\n", prefix, get_type_name(get_entity_owner(ent)),
40 get_entity_name(ent), get_entity_nr(ent));
44 if (verbosity & dump_verbosity_entattrs) {
45 fprintf(F, "%sentity %s (%ld)\n", prefix, get_entity_name(ent), get_entity_nr(ent));
46 fprintf(F, "%s type: %s (%ld)\n", prefix, get_type_name(type), get_type_nr(type));
47 fprintf(F, "%s owner: %s (%ld)\n", prefix, get_type_name(owner), get_type_nr(owner));
49 if (is_class_type(get_entity_owner(ent))) {
50 if (get_entity_n_overwrites(ent) > 0) {
51 fprintf(F, "%s overwrites:\n", prefix);
52 for (i = 0; i < get_entity_n_overwrites(ent); ++i) {
53 entity *ov = get_entity_overwrites(ent, i);
54 fprintf(F, "%s %d: %s of class %s\n", prefix, i, get_entity_name(ov),
55 get_type_name(get_entity_owner(ov)));
58 fprintf(F, "%s Does not overwrite other entities. \n", prefix);
60 if (get_entity_n_overwrittenby(ent) > 0) {
61 fprintf(F, "%s overwritten by:\n", prefix);
62 for (i = 0; i < get_entity_n_overwrittenby(ent); ++i) {
63 entity *ov = get_entity_overwrittenby(ent, i);
64 fprintf(F, "%s %d: %s of class %s\n", prefix, i, get_entity_name(ov),
65 get_type_name(get_entity_owner(ov)));
68 fprintf(F, "%s Is not overwriten by other entities. \n", prefix);
72 fprintf(F, "%s allocation: ", prefix);
73 switch (get_entity_allocation(ent)) {
74 X(allocation_dynamic);
75 X(allocation_automatic);
77 X(allocation_parameter);
80 fprintf(F, "\n%s visibility: ", prefix);
81 switch (get_entity_visibility(ent)) {
83 X(visibility_external_visible);
84 X(visibility_external_allocated);
87 fprintf(F, "\n%s variability: ", prefix);
88 switch (get_entity_variability(ent)) {
89 X(variability_uninitialized);
90 X(variability_initialized);
91 X(variability_part_constant);
92 X(variability_constant);
95 } else { /* no entattrs */
96 fprintf(F, "%s(%3d) %*s: %s", prefix,
97 get_entity_offset_bits(ent), -40, get_type_name(get_entity_type(ent)), get_entity_name(ent));
98 if (is_method_type(get_entity_type(ent))) fprintf(F, "(...)");
100 if (verbosity & dump_verbosity_accessStats) {
101 if (get_entity_allocation(ent) == allocation_static) {
102 fprintf(F, " (stat)");
104 if (get_entity_peculiarity(ent) == peculiarity_description) fprintf(F, " (desc)");
105 if (get_entity_peculiarity(ent) == peculiarity_inherited) fprintf(F, " (inh)");
111 if (verbosity & dump_verbosity_entconsts) {
112 if (get_entity_variability(ent) != variability_uninitialized) {
113 if (is_atomic_entity(ent)) {
114 fprintf(F, "%s atomic value: ", prefix);
115 dump_node_opcode(F, get_atomic_ent_value(ent));
117 fprintf(F, "%s compound values:", prefix);
118 for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
119 compound_graph_path *path = get_compound_ent_value_path(ent, i);
120 entity *ent0 = get_compound_graph_path_node(path, 0);
121 fprintf(F, "\n%s %3d ", prefix, get_entity_offset_bits(ent0));
122 if (get_type_state(type) == layout_fixed)
123 fprintf(F, "(%3d) ", get_compound_ent_value_offset_bits(ent, i));
124 fprintf(F, "%s", get_entity_name(ent0));
125 for (j = 0; j < get_compound_graph_path_length(path); ++j) {
126 entity *node = get_compound_graph_path_node(path, j);
127 fprintf(F, ".%s", get_entity_name(node));
128 if (is_array_type(get_entity_owner(node)))
129 fprintf(F, "[%d]", get_compound_graph_path_array_index(path, j));
132 dump_node_opcode(F, get_compound_ent_value(ent, i));
140 if (verbosity & dump_verbosity_entattrs) {
141 fprintf(F, "%s volatility: ", prefix);
142 switch (get_entity_volatility(ent)) {
143 X(volatility_non_volatile);
144 X(volatility_is_volatile);
147 fprintf(F, "\n%s peculiarity: %s", prefix, get_peculiarity_string(get_entity_peculiarity(ent)));
148 fprintf(F, "\n%s ld_name: %s", prefix, ent->ld_name ? get_entity_ld_name(ent) : "no yet set");
149 fprintf(F, "\n%s offset: %d", prefix, get_entity_offset_bits(ent));
150 if (is_method_type(get_entity_type(ent))) {
151 if (get_entity_irg(ent)) /* can be null */ {
152 fprintf(F, "\n%s irg = %ld", prefix, get_irg_graph_nr(get_entity_irg(ent)));
153 if (get_irp_callgraph_state() == irp_callgraph_and_calltree_consistent) {
154 fprintf(F, "\n%s recursion depth %d", prefix, get_irg_recursion_depth(get_entity_irg(ent)));
155 fprintf(F, "\n%s loop depth %d", prefix, get_irg_loop_depth(get_entity_irg(ent)));
158 fprintf(F, "\n%s irg = NULL", prefix);
164 if (verbosity & dump_verbosity_accessStats) {
165 int n_acc = get_entity_n_accesses(ent);
166 fprintf(F, "%s Access Stats", prefix);
168 for (i = 0; i < n_acc; ++i) {
169 ir_node *acc = get_entity_access(ent, i);
170 if (get_irn_op(acc) == op_Load) {
171 fprintf(F, "%c L", comma);
172 } else if (get_irn_op(acc) == op_Store) {
173 fprintf(F, "%c S", comma);
177 fprintf(F, " %d", get_weighted_loop_depth(acc));
187 void dump_entity_to_file (FILE *F, entity *ent, unsigned verbosity) {
188 dump_entity_to_file_prefix (F, ent, "", verbosity);
192 void dump_entity (entity *ent) {
193 dump_entity_to_file(stdout, ent, dump_verbosity_max);
196 void dump_type_to_file (FILE *F, type *tp, dump_verbosity verbosity) {
199 if ((is_class_type(tp)) && (verbosity & dump_verbosity_noClassTypes)) return;
200 if ((is_struct_type(tp)) && (verbosity & dump_verbosity_noStructTypes)) return;
201 if ((is_union_type(tp)) && (verbosity & dump_verbosity_noUnionTypes)) return;
202 if ((is_array_type(tp)) && (verbosity & dump_verbosity_noArrayTypes)) return;
203 if ((is_pointer_type(tp)) && (verbosity & dump_verbosity_noPointerTypes)) return;
204 if ((is_method_type(tp)) && (verbosity & dump_verbosity_noMethodTypes)) return;
205 if ((is_primitive_type(tp)) && (verbosity & dump_verbosity_noPrimitiveTypes)) return;
206 if ((is_enumeration_type(tp)) && (verbosity & dump_verbosity_noEnumerationTypes)) return;
208 fprintf(F, "%s type %s (%ld)", get_tpop_name(get_type_tpop(tp)), get_type_name(tp), get_type_nr(tp));
209 if (verbosity & dump_verbosity_onlynames) { fprintf(F, "\n"); return; }
211 switch (get_type_tpop_code(tp)) {
214 if ((verbosity & dump_verbosity_methods) || (verbosity & dump_verbosity_fields)) {
215 fprintf(F, "\n members: \n");
217 for (i = 0; i < get_class_n_members(tp); ++i) {
218 entity *mem = get_class_member(tp, i);
219 if (((verbosity & dump_verbosity_methods) && is_method_type(get_entity_type(mem))) ||
220 ((verbosity & dump_verbosity_fields) && !is_method_type(get_entity_type(mem))) ) {
221 dump_entity_to_file_prefix(F, mem, " ", verbosity);
224 if (verbosity & dump_verbosity_typeattrs) {
225 fprintf(F, " supertypes: ");
226 for (i = 0; i < get_class_n_supertypes(tp); ++i) {
227 type *stp = get_class_supertype(tp, i);
228 fprintf(F, "\n %s", get_type_name(stp));
230 fprintf(F, "\n subtypes: ");
231 for (i = 0; i < get_class_n_subtypes(tp); ++i) {
232 type *stp = get_class_subtype(tp, i);
233 fprintf(F, "\n %s", get_type_name(stp));
236 fprintf(F, "\n peculiarity: %s", get_peculiarity_string(get_class_peculiarity(tp)));
242 if (verbosity & dump_verbosity_fields) fprintf(F, "\n members: ");
243 for (i = 0; i < get_compound_n_members(tp); ++i) {
244 entity *mem = get_compound_member(tp, i);
245 if (verbosity & dump_verbosity_fields) {
246 dump_entity_to_file_prefix(F, mem, " ", verbosity);
252 if (verbosity & dump_verbosity_typeattrs) {
253 type *tt = get_pointer_points_to_type(tp);
254 fprintf(F, "\n points to %s (%ld)", get_type_name(tt), get_type_nr(tt));
260 if (verbosity & dump_verbosity_typeattrs) {
261 fprintf(F, ": details not implemented\n");
265 if (verbosity & dump_verbosity_accessStats) {
266 int n_all = get_type_n_allocations(tp);
267 fprintf(F, " Access Stats");
269 for (i = 0; i < n_all; ++i) {
270 ir_node *all = get_type_allocation(tp, i);
271 fprintf(F, "%c A", comma);
272 fprintf(F, " %d", get_weighted_loop_depth(all));
281 void dump_type(type *tp) {
282 dump_type_to_file (stdout, tp, dump_verbosity_max);
287 static FILE *text_open (const char *basename, const char * suffix1, const char *suffix2) {
289 int len = strlen(basename), i, j;
290 char *fname; /* filename to put the vcg information in */
292 if (!basename) assert(basename);
293 if (!suffix1) suffix1 = "";
294 if (!suffix2) suffix2 = "";
296 /* open file for vcg graph */
297 fname = malloc (strlen(basename)*2 + strlen(suffix1) + strlen(suffix2) + 5); /* *2: space for excapes. */
300 for (i = 0; i < len; ++i) { /* replase '/' in the name: escape by @. */
301 if (basename[i] == '/') {
302 fname[j] = '@'; j++; fname[j] = '1'; j++;
303 } else if (basename[i] == '@') {
304 fname[j] = '@'; j++; fname[j] = '2'; j++;
306 fname[j] = basename[i]; j++;
310 strcat (fname, suffix1); /* append file suffix */
311 strcat (fname, suffix2); /* append file suffix */
312 strcat (fname, ".txt"); /* append the .txt suffix */
314 F = fopen (fname, "w"); /* open file for writing */
323 void dump_types_as_text(unsigned verbosity, const char *suffix) {
324 const char *basename;
326 int i, n_types = get_irp_n_types();
328 if (get_irp_prog_ident() == new_id_from_str("no_name_set")) {
329 basename = "TextTypes";
331 basename = get_irp_prog_name();
333 F = text_open (basename, suffix, "-types");
335 for (i = 0; i < n_types; ++i) {
336 type *t = get_irp_type(i);
338 if (is_jack_rts_class(t)) continue;
340 dump_type_to_file(F, t, verbosity);