3 * File name: ir/ir/pattern_dmp.c
4 * Purpose: Statistics for Firm.
8 * Copyright: (c) 2004 Universität Karlsruhe
9 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
24 #include "firmstat_t.h"
25 #include "pattern_dmp.h"
27 /* dumper operations */
28 typedef void (*DUMP_NEW_PATTERN_FUNC)(pattern_dumper_t *self, counter_t *cnt);
29 typedef void (*DUMP_FINISH_PATTERN_FUNC)(pattern_dumper_t *self);
30 typedef void (*DUMP_NODE_FUNC)(pattern_dumper_t *self, unsigned id, unsigned op_code, unsigned mode_code, void *attr);
31 typedef void (*DUMP_REF_FUNC)(pattern_dumper_t *self, unsigned id);
32 typedef void (*DUMP_EDGE_FUNC)(pattern_dumper_t *self, unsigned tgt, unsigned src, unsigned pos, unsigned mode_code);
33 typedef void (*DUMP_START_CHILDREN_FUNC)(pattern_dumper_t *self, unsigned id);
34 typedef void (*DUMP_FINISH_CHILDREN_FUNC)(pattern_dumper_t *self, unsigned id);
35 typedef void (*DUMP_START_FUNC)(pattern_dumper_t *self);
36 typedef void (*DUMP_END_FUNC)(pattern_dumper_t *self);
41 struct _pattern_dumper_t {
42 DUMP_NEW_PATTERN_FUNC dump_new_pattern;
43 DUMP_FINISH_PATTERN_FUNC dump_finish_pattern;
44 DUMP_NODE_FUNC dump_node;
45 DUMP_REF_FUNC dump_ref;
46 DUMP_EDGE_FUNC dump_edge;
47 DUMP_START_CHILDREN_FUNC dump_start_children;
48 DUMP_FINISH_CHILDREN_FUNC dump_finish_children;
49 DUMP_START_FUNC dump_start;
50 DUMP_END_FUNC dump_end;
57 typedef struct _vcg_private_t {
58 FILE *f; /**< file to dump to */
59 unsigned pattern_id; /**< ID of the pattern */
60 unsigned max_pattern; /**< maximum number of pattern to be dumped */
64 * starts a new VCG graph
66 static void vcg_dump_start(pattern_dumper_t *self)
68 vcg_private_t *priv = self->data;
71 "graph: { title: \"Most found pattern\"\n"
72 " display_edge_labels: no\n"
73 " layoutalgorithm: mindepth\n"
74 " manhattan_edges: yes\n"
76 " orientation: bottom_to_top\n"
81 * ends a new VCG graph
83 static void vcg_dump_end(pattern_dumper_t *self)
85 vcg_private_t *priv = self->data;
87 fprintf(priv->f, "}\n");
92 * starts a new pattern
94 static void vcg_dump_new_pattern(pattern_dumper_t *self, counter_t *cnt)
96 vcg_private_t *priv = self->data;
97 static unsigned nr = 0;
99 if (priv->pattern_id > priv->max_pattern)
103 " graph: { title: \"g%u\" label: \"pattern %u\" status:clustered color:yellow\n",
104 priv->pattern_id, priv->pattern_id );
106 /** add a pseudo node */
108 " node: {title: \"c%u\" label: \"cnt: %u\" color:red }\n",
109 ++nr, cnt_to_uint(cnt)
114 * Finishes current pattern
116 static void vcg_dump_finish_pattern(pattern_dumper_t *self)
118 vcg_private_t *priv = self->data;
120 if (priv->pattern_id > priv->max_pattern)
123 fprintf(priv->f, " }\n");
125 if (priv->pattern_id > 0)
126 fprintf(priv->f, " edge: { sourcename: \"g%u\" targetname: \"g%u\" linestyle:invisible}\n",
128 priv->pattern_id - 1);
136 static void vcg_dump_node(pattern_dumper_t *self, unsigned id,
137 unsigned op_code, unsigned mode_code, void *attr)
139 vcg_private_t *priv = self->data;
140 ir_op *op = stat_get_op_from_opcode(op_code);
141 ir_mode *mode = (ir_mode *)mode_code;
142 long l = attr ? *(long *)attr : 0;
144 if (priv->pattern_id > priv->max_pattern)
148 fprintf(priv->f, " node: {title: \"n%u_%u\" label: \"%s%s %ld n%u\" }\n",
149 priv->pattern_id, id, get_id_str(op->name), mode ? get_mode_name(mode) : "", l, id);
152 fprintf(priv->f, " node: {title: \"n%u_%u\" label: \"%s%s n%u\" }\n",
153 priv->pattern_id, id, get_id_str(op->name), mode ? get_mode_name(mode) : "", id);
160 static void vcg_dump_edge(pattern_dumper_t *self, unsigned tgt, unsigned src, unsigned pos, unsigned mode_code)
162 vcg_private_t *priv = self->data;
164 if (priv->pattern_id > priv->max_pattern)
167 fprintf(priv->f, " edge: { sourcename: \"n%u_%u\" targetname: \"n%u_%u\" label: \"%u\" }\n",
168 priv->pattern_id, src,
169 priv->pattern_id, tgt,
177 static pattern_dumper_t vcg_dump = {
178 vcg_dump_new_pattern,
179 vcg_dump_finish_pattern,
191 * starts a new pattern
193 static void stdout_dump_new_pattern(pattern_dumper_t *self, counter_t *cnt)
195 FILE *f = self->data;
197 fprintf(f, "%8u ", cnt_to_uint(cnt));
202 * Finishes current pattern
204 static void stdout_dump_finish_pattern(pattern_dumper_t *self)
206 FILE *f = self->data;
214 static void stdout_dump_node(pattern_dumper_t *self, unsigned id, unsigned op_code, unsigned mode_code, void *attr)
216 FILE *f = self->data;
217 ir_op *op = stat_get_op_from_opcode(op_code);
218 ir_mode *mode = (ir_mode *)mode_code;
220 /* if (env->options & OPT_ENC_GRAPH) */
221 fprintf(f, "%u:", id);
223 fprintf(f, "%s", get_id_str(op->name));
226 fprintf(f, "%s", get_mode_name(mode));
232 static void stdout_dump_ref(pattern_dumper_t *self, unsigned id)
234 FILE *f = self->data;
236 fprintf(f, "REF:%u", id);
242 static void stdout_dump_edge(pattern_dumper_t *self, unsigned tgt, unsigned src, unsigned pos, unsigned mode_code)
244 FILE *f = self->data;
251 * Start children dumper
253 static void stdout_start_children(pattern_dumper_t *self, unsigned id)
255 FILE *f = self->data;
261 * finishes the children dumper
263 static void stdout_finish_children(pattern_dumper_t *self, unsigned id)
265 FILE *f = self->data;
273 static const pattern_dumper_t stdout_dump = {
274 stdout_dump_new_pattern,
275 stdout_dump_finish_pattern,
279 stdout_start_children,
280 stdout_finish_children,
286 /* ------------------------------------ API ------------------------------------- */
289 * starts a new pattern
291 void pattern_dump_new_pattern(pattern_dumper_t *self, counter_t *cnt)
293 if (self->dump_new_pattern)
294 self->dump_new_pattern(self, cnt);
299 * Finishes current pattern
301 void pattern_dump_finish_pattern(pattern_dumper_t *self)
303 if (self->dump_finish_pattern)
304 self->dump_finish_pattern(self);
311 void pattern_dump_node(pattern_dumper_t *self, unsigned id, unsigned op_code, unsigned mode_code, void *attr)
314 self->dump_node(self, id, op_code, mode_code, attr);
320 void pattern_dump_ref(pattern_dumper_t *self, unsigned id)
323 self->dump_ref(self, id);
329 void pattern_dump_edge(pattern_dumper_t *self, unsigned tgt, unsigned src, unsigned pos, unsigned mode_code)
332 self->dump_edge(self, tgt, src, pos, mode_code);
336 * Start children dumper
338 void pattern_start_children(pattern_dumper_t *self, unsigned id)
340 if (self->dump_start_children)
341 self->dump_start_children(self, id);
345 * finishes the children dumper
347 void pattern_finish_children(pattern_dumper_t *self, unsigned id)
349 if (self->dump_finish_children)
350 self->dump_finish_children(self, id);
354 * finishes the dumper
356 void pattern_end(pattern_dumper_t *self)
359 self->dump_end(self);
365 * pattern dumper factory for text dumper
367 pattern_dumper_t *new_text_dumper(void)
369 pattern_dumper_t *res = malloc(sizeof(*res));
372 memcpy(res, &stdout_dump, sizeof(*res));
376 res->dump_start(res);
382 * pattern dumper factory for vcg dumper
384 pattern_dumper_t *new_vcg_dumper(const char *vcg_name, unsigned max_pattern)
386 pattern_dumper_t *res = malloc(sizeof(*res) + sizeof(vcg_private_t));
392 memcpy(res, &vcg_dump, sizeof(*res));
394 priv = (vcg_private_t *)(res + 1);
395 memset(priv, 0, sizeof(*priv));
397 f = fopen(vcg_name, "w");
399 priv->pattern_id = 0;
400 priv->max_pattern = max_pattern ? max_pattern : (unsigned)-1;
404 res->dump_start(res);