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.
23 #include "pattern_dmp.h"
25 /* dumper operations */
26 typedef void (*DUMP_NEW_PATTERN_FUNC)(pattern_dumper_t *self, counter_t *cnt);
27 typedef void (*DUMP_FINISH_PATTERN_FUNC)(pattern_dumper_t *self);
28 typedef void (*DUMP_NODE_FUNC)(pattern_dumper_t *self, unsigned id, unsigned op_code, unsigned mode_code, void *attr);
29 typedef void (*DUMP_REF_FUNC)(pattern_dumper_t *self, unsigned id);
30 typedef void (*DUMP_EDGE_FUNC)(pattern_dumper_t *self, unsigned tgt, unsigned src, unsigned pos, unsigned mode_code);
31 typedef void (*DUMP_START_CHILDREN_FUNC)(pattern_dumper_t *self, unsigned id);
32 typedef void (*DUMP_FINISH_CHILDREN_FUNC)(pattern_dumper_t *self, unsigned id);
33 typedef void (*DUMP_START_FUNC)(pattern_dumper_t *self);
34 typedef void (*DUMP_END_FUNC)(pattern_dumper_t *self);
39 struct _pattern_dumper_t {
40 DUMP_NEW_PATTERN_FUNC dump_new_pattern;
41 DUMP_FINISH_PATTERN_FUNC dump_finish_pattern;
42 DUMP_NODE_FUNC dump_node;
43 DUMP_REF_FUNC dump_ref;
44 DUMP_EDGE_FUNC dump_edge;
45 DUMP_START_CHILDREN_FUNC dump_start_children;
46 DUMP_FINISH_CHILDREN_FUNC dump_finish_children;
47 DUMP_START_FUNC dump_start;
48 DUMP_END_FUNC dump_end;
55 typedef struct _vcg_private_t {
56 FILE *f; /**< file to dump to */
57 unsigned pattern_id; /**< ID of the pattern */
58 unsigned max_pattern; /**< maximum number of pattern to be dumped */
62 * starts a new VCG graph
64 static void vcg_dump_start(pattern_dumper_t *self)
66 vcg_private_t *priv = self->data;
69 "graph: { title: \"Most found pattern\"\n"
70 " display_edge_labels: no\n"
71 " layoutalgorithm: mindepth\n"
72 " manhattan_edges: yes\n"
74 " orientation: bottom_to_top\n"
79 * ends a new VCG graph
81 static void vcg_dump_end(pattern_dumper_t *self)
83 vcg_private_t *priv = self->data;
85 fprintf(priv->f, "}\n");
90 * starts a new pattern
92 static void vcg_dump_new_pattern(pattern_dumper_t *self, counter_t *cnt)
94 vcg_private_t *priv = self->data;
95 static unsigned nr = 0;
97 if (priv->pattern_id > priv->max_pattern)
101 " graph: { title: \"g%u\" label: \"pattern %u\" status:clustered color:yellow\n",
102 priv->pattern_id, priv->pattern_id );
104 /** add a pseudo node */
106 " node: {title: \"c%u\" label: \"cnt: %u\" color:red }\n",
112 * Finishes current pattern
114 static void vcg_dump_finish_pattern(pattern_dumper_t *self)
116 vcg_private_t *priv = self->data;
118 if (priv->pattern_id > priv->max_pattern)
121 fprintf(priv->f, " }\n");
123 if (priv->pattern_id > 0)
124 fprintf(priv->f, " edge: { sourcename: \"g%u\" targetname: \"g%u\" linestyle:invisible}\n",
126 priv->pattern_id - 1);
134 static void vcg_dump_node(pattern_dumper_t *self, unsigned id,
135 unsigned op_code, unsigned mode_code, void *attr)
137 vcg_private_t *priv = self->data;
138 ir_op *op = stat_get_op_from_opcode(op_code);
139 ir_mode *mode = (ir_mode *)mode_code;
140 long l = attr ? *(long *)attr : 0;
142 if (priv->pattern_id > priv->max_pattern)
146 fprintf(priv->f, " node: {title: \"n%u_%u\" label: \"%s%s %ld n%u\" }\n",
147 priv->pattern_id, id, get_id_str(op->name), mode ? get_mode_name(mode) : "", l, id);
150 fprintf(priv->f, " node: {title: \"n%u_%u\" label: \"%s%s n%u\" }\n",
151 priv->pattern_id, id, get_id_str(op->name), mode ? get_mode_name(mode) : "", id);
158 static void vcg_dump_edge(pattern_dumper_t *self, unsigned tgt, unsigned src, unsigned pos, unsigned mode_code)
160 vcg_private_t *priv = self->data;
162 if (priv->pattern_id > priv->max_pattern)
165 fprintf(priv->f, " edge: { sourcename: \"n%u_%u\" targetname: \"n%u_%u\" label: \"%u\" }\n",
166 priv->pattern_id, src,
167 priv->pattern_id, tgt,
175 static pattern_dumper_t vcg_dump = {
176 vcg_dump_new_pattern,
177 vcg_dump_finish_pattern,
189 * starts a new pattern
191 static void stdout_dump_new_pattern(pattern_dumper_t *self, counter_t *cnt)
193 FILE *f = self->data;
195 fprintf(f, "%8u ", cnt->cnt[0]);
200 * Finishes current pattern
202 static void stdout_dump_finish_pattern(pattern_dumper_t *self)
204 FILE *f = self->data;
212 static void stdout_dump_node(pattern_dumper_t *self, unsigned id, unsigned op_code, unsigned mode_code, void *attr)
214 FILE *f = self->data;
215 ir_op *op = stat_get_op_from_opcode(op_code);
216 ir_mode *mode = (ir_mode *)mode_code;
218 /* if (env->options & OPT_ENC_GRAPH) */
219 fprintf(f, "%u:", id);
221 fprintf(f, "%s", get_id_str(op->name));
224 fprintf(f, "%s", get_mode_name(mode));
230 static void stdout_dump_ref(pattern_dumper_t *self, unsigned id)
232 FILE *f = self->data;
234 fprintf(f, "REF:%u", id);
240 static void stdout_dump_edge(pattern_dumper_t *self, unsigned tgt, unsigned src, unsigned pos, unsigned mode_code)
242 FILE *f = self->data;
249 * Start children dumper
251 static void stdout_start_children(pattern_dumper_t *self, unsigned id)
253 FILE *f = self->data;
259 * finishes childred dumper
261 static void stdout_finish_children(pattern_dumper_t *self, unsigned id)
263 FILE *f = self->data;
271 static const pattern_dumper_t stdout_dump = {
272 stdout_dump_new_pattern,
273 stdout_dump_finish_pattern,
277 stdout_start_children,
278 stdout_finish_children,
284 /* ------------------------------------ API ------------------------------------- */
287 * starts a new pattern
289 void pattern_dump_new_pattern(pattern_dumper_t *self, counter_t *cnt)
291 if (self->dump_new_pattern)
292 self->dump_new_pattern(self, cnt);
297 * Finishes current pattern
299 void pattern_dump_finish_pattern(pattern_dumper_t *self)
301 if (self->dump_finish_pattern)
302 self->dump_finish_pattern(self);
309 void pattern_dump_node(pattern_dumper_t *self, unsigned id, unsigned op_code, unsigned mode_code, void *attr)
312 self->dump_node(self, id, op_code, mode_code, attr);
318 void pattern_dump_ref(pattern_dumper_t *self, unsigned id)
321 self->dump_ref(self, id);
327 void pattern_dump_edge(pattern_dumper_t *self, unsigned tgt, unsigned src, unsigned pos, unsigned mode_code)
330 self->dump_edge(self, tgt, src, pos, mode_code);
334 * Start children dumper
336 void pattern_start_children(pattern_dumper_t *self, unsigned id)
338 if (self->dump_start_children)
339 self->dump_start_children(self, id);
343 * finishes childred dumper
345 void pattern_finish_children(pattern_dumper_t *self, unsigned id)
347 if (self->dump_finish_children)
348 self->dump_finish_children(self, id);
352 * finishes the dumper
354 void pattern_end(pattern_dumper_t *self)
357 self->dump_end(self);
363 * pattern dumper factory for text dumper
365 pattern_dumper_t *new_text_dumper(void)
367 pattern_dumper_t *res = malloc(sizeof(*res));
370 memcpy(res, &stdout_dump, sizeof(*res));
374 res->dump_start(res);
380 * pattern dumper factory for vcg dumper
382 pattern_dumper_t *new_vcg_dumper(const char *vcg_name, unsigned max_pattern)
384 pattern_dumper_t *res = malloc(sizeof(*res) + sizeof(vcg_private_t));
390 memcpy(res, &vcg_dump, sizeof(*res));
392 priv = (vcg_private_t *)(res + 1);
393 memset(priv, 0, sizeof(*priv));
395 f = fopen(vcg_name, "w");
397 priv->pattern_id = 0;
398 priv->max_pattern = max_pattern ? max_pattern : (unsigned)-1;
402 res->dump_start(res);