2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
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.
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.
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
22 * @brief Statistics for Firm. Dumping patterns.
23 * @author Michael Beck
34 #include "firmstat_t.h"
35 #include "pattern_dmp.h"
37 /* dumper operations */
38 typedef void (*DUMP_NEW_PATTERN_FUNC)(pattern_dumper_t *self, counter_t *cnt);
39 typedef void (*DUMP_FINISH_PATTERN_FUNC)(pattern_dumper_t *self);
40 typedef void (*DUMP_NODE_FUNC)(pattern_dumper_t *self, unsigned id, unsigned op_code, unsigned mode_code, void *attr);
41 typedef void (*DUMP_REF_FUNC)(pattern_dumper_t *self, unsigned id);
42 typedef void (*DUMP_EDGE_FUNC)(pattern_dumper_t *self, unsigned tgt, unsigned src, unsigned pos, unsigned mode_code);
43 typedef void (*DUMP_START_CHILDREN_FUNC)(pattern_dumper_t *self, unsigned id);
44 typedef void (*DUMP_FINISH_CHILDREN_FUNC)(pattern_dumper_t *self, unsigned id);
45 typedef void (*DUMP_START_FUNC)(pattern_dumper_t *self);
46 typedef void (*DUMP_END_FUNC)(pattern_dumper_t *self);
51 struct pattern_dumper_t {
52 DUMP_NEW_PATTERN_FUNC dump_new_pattern;
53 DUMP_FINISH_PATTERN_FUNC dump_finish_pattern;
54 DUMP_NODE_FUNC dump_node;
55 DUMP_REF_FUNC dump_ref;
56 DUMP_EDGE_FUNC dump_edge;
57 DUMP_START_CHILDREN_FUNC dump_start_children;
58 DUMP_FINISH_CHILDREN_FUNC dump_finish_children;
59 DUMP_START_FUNC dump_start;
60 DUMP_END_FUNC dump_end;
67 typedef struct vcg_private_t {
68 FILE *f; /**< file to dump to */
69 unsigned pattern_id; /**< ID of the pattern */
70 unsigned max_pattern; /**< maximum number of pattern to be dumped */
74 * Starts a new VCG graph.
76 static void vcg_dump_start(pattern_dumper_t *self)
78 vcg_private_t *priv = (vcg_private_t*)self->data;
81 "graph: { title: \"Most found pattern\"\n"
82 " display_edge_labels: no\n"
83 " layoutalgorithm: mindepth\n"
84 " manhattan_edges: yes\n"
86 " orientation: bottom_to_top\n"
88 } /* vcg_dump_start */
91 * Ends a new VCG graph.
93 static void vcg_dump_end(pattern_dumper_t *self)
95 vcg_private_t *priv = (vcg_private_t*)self->data;
97 fprintf(priv->f, "}\n");
102 * Starts a new pattern.
104 static void vcg_dump_new_pattern(pattern_dumper_t *self, counter_t *cnt)
106 vcg_private_t *priv = (vcg_private_t*)self->data;
107 static unsigned nr = 0;
109 if (priv->pattern_id > priv->max_pattern)
113 " graph: { title: \"g%u\" label: \"pattern %u\" status:clustered color:yellow\n",
114 priv->pattern_id, priv->pattern_id );
116 /* add a pseudo node for the count of this pattern */
118 " node: {title: \"c%u\" label: \"cnt: %u\" color:red }\n",
119 ++nr, cnt_to_uint(cnt)
121 } /* vcg_dump_new_pattern */
124 * Finish the current pattern.
126 static void vcg_dump_finish_pattern(pattern_dumper_t *self)
128 vcg_private_t *priv = (vcg_private_t*)self->data;
130 if (priv->pattern_id > priv->max_pattern)
133 fprintf(priv->f, " }\n");
135 if (priv->pattern_id > 0)
136 fprintf(priv->f, " edge: { sourcename: \"g%u\" targetname: \"g%u\" linestyle:invisible}\n",
138 priv->pattern_id - 1);
141 } /* vcg_dump_finish_pattern */
146 static void vcg_dump_node(pattern_dumper_t *self, unsigned id,
147 unsigned op_code, unsigned mode_code, void *attr)
149 vcg_private_t *priv = (vcg_private_t*)self->data;
150 ir_op *op = stat_get_op_from_opcode(op_code);
151 ir_mode *mode = get_irp_mode(mode_code);
152 long l = attr ? *(long *)attr : 0;
154 if (priv->pattern_id > priv->max_pattern)
158 fprintf(priv->f, " node: {title: \"n%u_%u\" label: \"%s%s %ld n%u\" }\n",
159 priv->pattern_id, id, get_id_str(op->name), mode ? get_mode_name(mode) : "", l, id);
161 fprintf(priv->f, " node: {title: \"n%u_%u\" label: \"%s%s n%u\" }\n",
162 priv->pattern_id, id, get_id_str(op->name), mode ? get_mode_name(mode) : "", id);
164 } /* vcg_dump_node */
169 static void vcg_dump_edge(pattern_dumper_t *self, unsigned tgt, unsigned src, unsigned pos, unsigned mode_code)
171 vcg_private_t *priv = (vcg_private_t*)self->data;
174 if (priv->pattern_id > priv->max_pattern)
177 fprintf(priv->f, " edge: { sourcename: \"n%u_%u\" targetname: \"n%u_%u\" label: \"%u\" }\n",
178 priv->pattern_id, src,
179 priv->pattern_id, tgt,
182 } /* vcg_dump_edge */
187 static pattern_dumper_t vcg_dump = {
188 vcg_dump_new_pattern,
189 vcg_dump_finish_pattern,
201 * Starts a new pattern.
203 static void stdout_dump_new_pattern(pattern_dumper_t *self, counter_t *cnt)
205 FILE *f = (FILE*)self->data;
207 fprintf(f, "%8u ", cnt_to_uint(cnt));
208 } /* stdout_dump_new_pattern */
212 * Finish the current pattern.
214 static void stdout_dump_finish_pattern(pattern_dumper_t *self)
216 FILE *f = (FILE*)self->data;
219 } /* stdout_dump_finish_pattern */
224 static void stdout_dump_node(pattern_dumper_t *self, unsigned id, unsigned op_code, unsigned mode_code, void *attr)
226 FILE *f = (FILE*)self->data;
227 ir_op *op = stat_get_op_from_opcode(op_code);
228 ir_mode *mode = get_irp_mode(mode_code);
231 /* if (env->options & OPT_ENC_GRAPH) */
232 fprintf(f, "%u:", id);
234 fprintf(f, "%s", get_id_str(op->name));
237 fprintf(f, "%s", get_mode_name(mode));
238 } /* stdout_dump_node */
243 static void stdout_dump_ref(pattern_dumper_t *self, unsigned id)
245 FILE *f = (FILE*)self->data;
247 fprintf(f, "REF:%u", id);
248 } /* stdout_dump_ref */
253 static void stdout_dump_edge(pattern_dumper_t *self, unsigned tgt, unsigned src, unsigned pos, unsigned mode_code)
255 FILE *f = (FILE*)self->data;
263 } /* stdout_dump_edge */
266 * Start the children dumper.
268 static void stdout_start_children(pattern_dumper_t *self, unsigned id)
270 FILE *f = (FILE*)self->data;
274 } /* stdout_start_children */
277 * Finish the children dumper.
279 static void stdout_finish_children(pattern_dumper_t *self, unsigned id)
281 FILE *f = (FILE*)self->data;
285 } /* stdout_finish_children */
290 static const pattern_dumper_t stdout_dump = {
291 stdout_dump_new_pattern,
292 stdout_dump_finish_pattern,
296 stdout_start_children,
297 stdout_finish_children,
303 /* ------------------------------------ API ------------------------------------- */
306 * Starts a new pattern.
308 void pattern_dump_new_pattern(pattern_dumper_t *self, counter_t *cnt)
310 if (self->dump_new_pattern)
311 self->dump_new_pattern(self, cnt);
312 } /* pattern_dump_new_pattern */
316 * Finish the current pattern.
318 void pattern_dump_finish_pattern(pattern_dumper_t *self)
320 if (self->dump_finish_pattern)
321 self->dump_finish_pattern(self);
322 } /* pattern_dump_finish_pattern */
328 void pattern_dump_node(pattern_dumper_t *self, unsigned id, unsigned op_code, unsigned mode_code, void *attr)
331 self->dump_node(self, id, op_code, mode_code, attr);
332 } /* pattern_dump_node */
337 void pattern_dump_ref(pattern_dumper_t *self, unsigned id)
340 self->dump_ref(self, id);
341 } /* pattern_dump_ref */
346 void pattern_dump_edge(pattern_dumper_t *self, unsigned tgt, unsigned src, unsigned pos, unsigned mode_code)
349 self->dump_edge(self, tgt, src, pos, mode_code);
350 } /* pattern_dump_edge */
353 * Start the children dumper.
355 void pattern_start_children(pattern_dumper_t *self, unsigned id)
357 if (self->dump_start_children)
358 self->dump_start_children(self, id);
359 } /* pattern_start_children */
362 * Finish the the children dumper.
364 void pattern_finish_children(pattern_dumper_t *self, unsigned id)
366 if (self->dump_finish_children)
367 self->dump_finish_children(self, id);
368 } /* pattern_finish_children */
371 * Finish the the dumper.
373 void pattern_end(pattern_dumper_t *self)
376 self->dump_end(self);
382 * pattern dumper factory for text dumper
384 pattern_dumper_t *new_text_dumper(void)
386 pattern_dumper_t *res = XMALLOC(pattern_dumper_t);
388 memcpy(res, &stdout_dump, sizeof(*res));
392 res->dump_start(res);
394 } /* new_text_dumper */
397 * pattern dumper factory for vcg dumper
399 pattern_dumper_t *new_vcg_dumper(const char *vcg_name, unsigned max_pattern)
401 pattern_dumper_t *res = (pattern_dumper_t*)malloc(sizeof(*res) + sizeof(vcg_private_t));
407 memcpy(res, &vcg_dump, sizeof(*res));
409 priv = (vcg_private_t *)(res + 1);
410 memset(priv, 0, sizeof(*priv));
412 f = fopen(vcg_name, "w");
414 priv->pattern_id = 0;
415 priv->max_pattern = max_pattern ? max_pattern : (unsigned)-1;
419 res->dump_start(res);
423 } /* new_vcg_dumper */