access routines for memops,
[libfirm] / ir / ir / irdumptxt.c
1 /*
2  * Project:     libFIRM
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
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1998-2003 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12
13 #include <string.h>
14 #include <stdlib.h>
15 #include <stdarg.h>
16
17 #include "irdump.h"
18
19 #include "firm_common_t.h"
20
21 #include "irgraph_t.h"
22 #include "irprog_t.h"
23 #include "entity_t.h"
24
25 #include "field_temperature.h"
26
27 int dump_node_opcode(FILE *F, ir_node *n); /* from irdump.c */
28
29
30
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) {
33   int i, j;
34   assert(ent && ent->kind == k_entity);
35   type *owner = get_entity_owner(ent);
36   type *type  = get_entity_type(ent);
37
38   if (verbosity & dump_verbosity_onlynames) {
39     fprintf(F, "%sentity %s (%ld)\n", prefix, get_entity_name(ent), get_entity_nr(ent));
40     return;
41   }
42
43   if (verbosity & dump_verbosity_entattrs) {
44     fprintf(F, "%sentity %s (%ld)\n", prefix, get_entity_name(ent), get_entity_nr(ent));
45     fprintf(F, "%s  type:  %s (%ld)\n", prefix, get_type_name(type),  get_type_nr(type));
46     fprintf(F, "%s  owner: %s (%ld)\n", prefix, get_type_name(owner), get_type_nr(owner));
47
48     if (is_class_type(get_entity_owner(ent))) {
49       if (get_entity_n_overwrites(ent) > 0) {
50         fprintf(F, "%s  overwrites:\n", prefix);
51         for (i = 0; i < get_entity_n_overwrites(ent); ++i) {
52           entity *ov = get_entity_overwrites(ent, i);
53           fprintf(F, "%s    %d: %s of class %s\n", prefix, i, get_entity_name(ov),
54                   get_type_name(get_entity_owner(ov)));
55         }
56       } else {
57         fprintf(F, "%s  Does not overwrite other entities. \n", prefix);
58       }
59       if (get_entity_n_overwrittenby(ent) > 0) {
60         fprintf(F, "%s  overwritten by:\n", prefix);
61         for (i = 0; i < get_entity_n_overwrittenby(ent); ++i) {
62           entity *ov = get_entity_overwrittenby(ent, i);
63           fprintf(F, "%s    %d: %s of class %s\n", prefix, i, get_entity_name(ov),
64                   get_type_name(get_entity_owner(ov)));
65         }
66       } else {
67         fprintf(F, "%s  Is not overwriten by other entities. \n", prefix);
68       }
69     }
70
71     fprintf(F, "%s  allocation:  ", prefix);
72     switch (get_entity_allocation(ent)) {
73       X(allocation_dynamic);
74       X(allocation_automatic);
75       X(allocation_static);
76       X(allocation_parameter);
77     }
78
79     fprintf(F, "\n%s  visibility:  ", prefix);
80     switch (get_entity_visibility(ent)) {
81       X(visibility_local);
82       X(visibility_external_visible);
83       X(visibility_external_allocated);
84     }
85
86     fprintf(F, "\n%s  variability: ", prefix);
87     switch (get_entity_variability(ent)) {
88       X(variability_uninitialized);
89       X(variability_initialized);
90       X(variability_part_constant);
91       X(variability_constant);
92     }
93     fprintf(F, "\n");
94   } else {  /* no entattrs */
95     fprintf(F, "%s(%3d) %*s: %s", prefix,
96             get_entity_offset_bits(ent), -40, get_type_name(get_entity_type(ent)), get_entity_name(ent));
97     if (is_method_type(get_entity_type(ent))) fprintf(F, "(...)");
98
99     if (verbosity & dump_verbosity_accessStats) {
100       if (get_entity_allocation(ent) == allocation_static) {
101         fprintf(F, " (stat)");
102       } else {
103         if (get_entity_peculiarity(ent) == peculiarity_description) fprintf(F, " (desc)");
104         if (get_entity_peculiarity(ent) == peculiarity_inherited)   fprintf(F, " (inh)");
105       }
106     }
107     fprintf(F, "\n");
108   }
109
110   if (verbosity & dump_verbosity_entconsts) {
111     if (get_entity_variability(ent) != variability_uninitialized) {
112       if (is_atomic_entity(ent)) {
113         fprintf(F, "%s  atomic value: ", prefix);
114         dump_node_opcode(F, get_atomic_ent_value(ent));
115       } else {
116         fprintf(F, "%s  compound values:", prefix);
117         for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
118           compound_graph_path *path = get_compound_ent_value_path(ent, i);
119           entity *ent0 = get_compound_graph_path_node(path, 0);
120           fprintf(F, "\n%s    %3d ", prefix, get_entity_offset_bits(ent0));
121           if (get_type_state(type) == layout_fixed)
122             fprintf(F, "(%3d) ",   get_compound_ent_value_offset_bits(ent, i));
123           fprintf(F, "%s", get_entity_name(ent0));
124           for (j = 0; j < get_compound_graph_path_length(path); ++j) {
125             entity *node = get_compound_graph_path_node(path, j);
126             fprintf(F, ".%s", get_entity_name(node));
127             if (is_array_type(get_entity_owner(node)))
128               fprintf(F, "[%d]", get_compound_graph_path_array_index(path, j));
129           }
130           fprintf(F, "\t = ");
131           dump_node_opcode(F, get_compound_ent_value(ent, i));
132         }
133       }
134       fprintf(F, "\n");
135     }
136   }
137
138
139   if (verbosity & dump_verbosity_entattrs) {
140     fprintf(F, "%s  volatility:  ", prefix);
141     switch (get_entity_volatility(ent)) {
142       X(volatility_non_volatile);
143       X(volatility_is_volatile);
144     }
145
146     fprintf(F, "\n%s  peculiarity: %s", prefix, get_peculiarity_string(get_entity_peculiarity(ent)));
147     fprintf(F, "\n%s  ld_name: %s", prefix, ent->ld_name ? get_entity_ld_name(ent) : "no yet set");
148     fprintf(F, "\n%s  offset:  %d", prefix, get_entity_offset_bits(ent));
149     if (is_method_type(get_entity_type(ent))) {
150       if (get_entity_irg(ent))   /* can be null */ {
151         fprintf(F, "\n%s  irg = %ld", prefix, get_irg_graph_nr(get_entity_irg(ent)));
152         if (get_irp_callgraph_state() == irp_callgraph_and_calltree_consistent) {
153           fprintf(F, "\n%s    recursion depth %d", prefix, get_irg_recursion_depth(get_entity_irg(ent)));
154           fprintf(F, "\n%s    loop depth      %d", prefix, get_irg_loop_depth(get_entity_irg(ent)));
155         }
156       } else {
157         fprintf(F, "\n%s  irg = NULL", prefix);
158       }
159     }
160     fprintf(F, "\n");
161   }
162
163   if (verbosity & dump_verbosity_accessStats) {
164     int n_acc = get_entity_n_accesses(ent);
165     fprintf(F, "%s  Access Stats", prefix);
166     char comma = ':';
167     for (i = 0; i < n_acc; ++i) {
168       ir_node *acc = get_entity_access(ent, i);
169       if (get_irn_op(acc) == op_Load) {
170         fprintf(F, "%c L", comma);
171       } else if (get_irn_op(acc) == op_Store) {
172         fprintf(F, "%c S", comma);
173       } else {
174         assert(0);
175       }
176       fprintf(F, " %d", get_weighted_loop_depth(acc));
177       comma = ',';
178     }
179     fprintf(F, "\n");
180   }
181
182
183 }
184 #undef X
185
186 void    dump_entity_to_file (FILE *F, entity *ent, unsigned verbosity) {
187   dump_entity_to_file_prefix (F, ent, "", verbosity);
188   fprintf(F, "\n");
189 }
190
191 void dump_entity (entity *ent) {
192   dump_entity_to_file(stdout, ent, dump_verbosity_max);
193 }
194
195 void dump_type_to_file (FILE *F, type *tp, dump_verbosity verbosity) {
196   int i;
197
198   if ((is_class_type(tp))       && (verbosity & dump_verbosity_noClassTypes)) return;
199   if ((is_struct_type(tp))      && (verbosity & dump_verbosity_noStructTypes)) return;
200   if ((is_union_type(tp))       && (verbosity & dump_verbosity_noUnionTypes)) return;
201   if ((is_array_type(tp))       && (verbosity & dump_verbosity_noArrayTypes)) return;
202   if ((is_pointer_type(tp))     && (verbosity & dump_verbosity_noPointerTypes)) return;
203   if ((is_method_type(tp))      && (verbosity & dump_verbosity_noMethodTypes)) return;
204   if ((is_primitive_type(tp))   && (verbosity & dump_verbosity_noPrimitiveTypes)) return;
205   if ((is_enumeration_type(tp)) && (verbosity & dump_verbosity_noEnumerationTypes)) return;
206
207   fprintf(F, "%s type %s (%ld)", get_tpop_name(get_type_tpop(tp)), get_type_name(tp), get_type_nr(tp));
208   if (verbosity & dump_verbosity_onlynames) { fprintf(F, "\n"); return; }
209
210   switch (get_type_tpop_code(tp)) {
211
212   case tpo_class:
213     if ((verbosity & dump_verbosity_methods) || (verbosity & dump_verbosity_fields)) {
214       fprintf(F, "\n  members: \n");
215     }
216     for (i = 0; i < get_class_n_members(tp); ++i) {
217       entity *mem = get_class_member(tp, i);
218       if (((verbosity & dump_verbosity_methods) &&  is_method_type(get_entity_type(mem))) ||
219           ((verbosity & dump_verbosity_fields)  && !is_method_type(get_entity_type(mem)))   ) {
220         dump_entity_to_file_prefix(F, mem, "    ", verbosity);
221       }
222     }
223     if (verbosity & dump_verbosity_typeattrs) {
224       fprintf(F, "  supertypes: ");
225       for (i = 0; i < get_class_n_supertypes(tp); ++i) {
226         type *stp = get_class_supertype(tp, i);
227         fprintf(F, "\n    %s", get_type_name(stp));
228       }
229       fprintf(F, "\n  subtypes: ");
230       for (i = 0; i < get_class_n_subtypes(tp); ++i) {
231         type *stp = get_class_subtype(tp, i);
232         fprintf(F, "\n    %s", get_type_name(stp));
233       }
234
235       fprintf(F, "\n  peculiarity: %s", get_peculiarity_string(get_class_peculiarity(tp)));
236     }
237     break;
238
239   case tpo_union:
240   case tpo_struct:
241     if (verbosity & dump_verbosity_fields) fprintf(F, "\n  members: ");
242     for (i = 0; i < get_compound_n_members(tp); ++i) {
243       entity *mem = get_compound_member(tp, i);
244       if (verbosity & dump_verbosity_fields) {
245         dump_entity_to_file_prefix(F, mem, "    ", verbosity);
246       }
247     }
248     break;
249
250   case tpo_pointer: {
251     if (verbosity & dump_verbosity_typeattrs) {
252       type *tt = get_pointer_points_to_type(tp);
253       fprintf(F, "\n  points to %s (%ld)", get_type_name(tt), get_type_nr(tt));
254     }
255
256   } break;
257
258   default:
259     if (verbosity & dump_verbosity_typeattrs) {
260       fprintf(F, ": details not implemented\n");
261     }
262   }
263   fprintf(F, "\n\n");
264 }
265
266 void dump_type(type *tp) {
267   dump_type_to_file (stdout, tp, dump_verbosity_max);
268 }
269
270
271
272 static FILE *text_open (const char *basename, const char * suffix1, const char *suffix2) {
273   FILE *F;
274   int len = strlen(basename), i, j;
275   char *fname;  /* filename to put the vcg information in */
276
277   if (!basename) assert(basename);
278   if (!suffix1) suffix1 = "";
279   if (!suffix2) suffix2 = "";
280
281   /* open file for vcg graph */
282   fname = malloc (strlen(basename)*2 + strlen(suffix1) + strlen(suffix2) + 5); /* *2: space for excapes. */
283
284   j = 0;
285   for (i = 0; i < len; ++i) {  /* replase '/' in the name: escape by @. */
286     if (basename[i] == '/') {
287       fname[j] = '@'; j++; fname[j] = '1'; j++;
288     } else if (basename[i] == '@') {
289       fname[j] = '@'; j++; fname[j] = '2'; j++;
290     } else {
291       fname[j] = basename[i]; j++;
292     }
293   }
294   fname[j] = '\0';
295   strcat (fname, suffix1);  /* append file suffix */
296   strcat (fname, suffix2);  /* append file suffix */
297   strcat (fname, ".txt");   /* append the .txt suffix */
298
299   F = fopen (fname, "w");   /* open file for writing */
300   if (!F) {
301     assert(0);
302   }
303   free(fname);
304
305   return F;
306 }
307
308 void dump_types_as_text(unsigned verbosity, const char *suffix) {
309   const char *basename;
310   FILE *F;
311   int i, n_types = get_irp_n_types();
312
313   if (get_irp_prog_ident() == new_id_from_str("no_name_set")) {
314     basename = "TextTypes";
315   } else {
316     basename = get_irp_prog_name();
317   }
318   F = text_open (basename, suffix, "-types");
319
320   for (i = 0; i < n_types; ++i) {
321     type *t = get_irp_type(i);
322
323     if (is_jack_rts_class(t)) continue;
324
325     dump_type_to_file(F, t, verbosity);
326   }
327
328   fclose (F);
329 }