X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fstat%2Fpattern_dmp.c;h=4ae89c2718f18049febc0a2a07117cc88f43bff0;hb=e39b02362169921f82ac6b1070960dca07dd878b;hp=ae6badc43ee01d2e4b047a9d39be09bb2c199167;hpb=1580176436dd0df7f1a0b608aef904d5f6d24e5a;p=libfirm diff --git a/ir/stat/pattern_dmp.c b/ir/stat/pattern_dmp.c index ae6badc43..4ae89c271 100644 --- a/ir/stat/pattern_dmp.c +++ b/ir/stat/pattern_dmp.c @@ -1,183 +1,427 @@ /* - * Project: libFIRM - * File name: ir/ir/pattern_dmp.c - * Purpose: Statistics for Firm. - * Author: Michael Beck - * Created: - * CVS-ID: $Id$ - * Copyright: (c) 2004 Universität Karlsruhe - * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. + * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. + * + * This file is part of libFirm. + * + * This file may be distributed and/or modified under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation and appearing in the file LICENSE.GPL included in the + * packaging of this file. + * + * Licensees holding valid libFirm Professional Edition licenses may use + * this file in accordance with the libFirm Commercial License. + * Agreement provided with the Software. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +/** + * @file + * @brief Statistics for Firm. Dumping patterns. + * @author Michael Beck + * @version $Id$ + */ +#include "config.h" + +#ifdef FIRM_STATISTICS #include +#include #include "ident.h" #include "irop_t.h" #include "irmode.h" +#include "firmstat_t.h" #include "pattern_dmp.h" +/* dumper operations */ +typedef void (*DUMP_NEW_PATTERN_FUNC)(pattern_dumper_t *self, counter_t *cnt); +typedef void (*DUMP_FINISH_PATTERN_FUNC)(pattern_dumper_t *self); +typedef void (*DUMP_NODE_FUNC)(pattern_dumper_t *self, unsigned id, unsigned op_code, unsigned mode_code, void *attr); +typedef void (*DUMP_REF_FUNC)(pattern_dumper_t *self, unsigned id); +typedef void (*DUMP_EDGE_FUNC)(pattern_dumper_t *self, unsigned tgt, unsigned src, unsigned pos, unsigned mode_code); +typedef void (*DUMP_START_CHILDREN_FUNC)(pattern_dumper_t *self, unsigned id); +typedef void (*DUMP_FINISH_CHILDREN_FUNC)(pattern_dumper_t *self, unsigned id); +typedef void (*DUMP_START_FUNC)(pattern_dumper_t *self); +typedef void (*DUMP_END_FUNC)(pattern_dumper_t *self); + +/** + * the pattern dumper + */ +struct pattern_dumper_t { + DUMP_NEW_PATTERN_FUNC dump_new_pattern; + DUMP_FINISH_PATTERN_FUNC dump_finish_pattern; + DUMP_NODE_FUNC dump_node; + DUMP_REF_FUNC dump_ref; + DUMP_EDGE_FUNC dump_edge; + DUMP_START_CHILDREN_FUNC dump_start_children; + DUMP_FINISH_CHILDREN_FUNC dump_finish_children; + DUMP_START_FUNC dump_start; + DUMP_END_FUNC dump_end; + void *data; +}; + +/** + * VCG private data + */ +typedef struct vcg_private_t { + FILE *f; /**< file to dump to */ + unsigned pattern_id; /**< ID of the pattern */ + unsigned max_pattern; /**< maximum number of pattern to be dumped */ +} vcg_private_t; + /** - * starts a new VCG graph + * Starts a new VCG graph. */ static void vcg_dump_start(pattern_dumper_t *self) { - FILE *f; + vcg_private_t *priv = (vcg_private_t*)self->data; - f = fopen("firmpattern.vcg", "w"); - - fprintf(f, - "graph: { title: \"Most found pattern\"\n" - " display_edge_labels: no\n" - " layoutalgorithm: mindepth\n" - " manhattan_edges: yes\n" - " port_sharing: no\n" - " orientation: bottom_to_top\n" - ); -} + fprintf(priv->f, + "graph: { title: \"Most found pattern\"\n" + " display_edge_labels: no\n" + " layoutalgorithm: mindepth\n" + " manhattan_edges: yes\n" + " port_sharing: no\n" + " orientation: bottom_to_top\n" + ); +} /* vcg_dump_start */ /** - * ends a new VCG graph + * Ends a new VCG graph. */ static void vcg_dump_end(pattern_dumper_t *self) { - fprintf(f, "}\n"); - fclose(f); -} + vcg_private_t *priv = (vcg_private_t*)self->data; + + fprintf(priv->f, "}\n"); + fclose(priv->f); +} /* vcg_dump_end */ + +/** + * Starts a new pattern. + */ +static void vcg_dump_new_pattern(pattern_dumper_t *self, counter_t *cnt) +{ + vcg_private_t *priv = (vcg_private_t*)self->data; + static unsigned nr = 0; + + if (priv->pattern_id > priv->max_pattern) + return; + + fprintf(priv->f, + " graph: { title: \"g%u\" label: \"pattern %u\" status:clustered color:yellow\n", + priv->pattern_id, priv->pattern_id ); + + /* add a pseudo node for the count of this pattern */ + fprintf(priv->f, + " node: {title: \"c%u\" label: \"cnt: %u\" color:red }\n", + ++nr, cnt_to_uint(cnt) + ); +} /* vcg_dump_new_pattern */ + +/** + * Finish the current pattern. + */ +static void vcg_dump_finish_pattern(pattern_dumper_t *self) +{ + vcg_private_t *priv = (vcg_private_t*)self->data; + + if (priv->pattern_id > priv->max_pattern) + return; + + fprintf(priv->f, " }\n"); + + if (priv->pattern_id > 0) + fprintf(priv->f, " edge: { sourcename: \"g%u\" targetname: \"g%u\" linestyle:invisible}\n", + priv->pattern_id, + priv->pattern_id - 1); + ++priv->pattern_id; +} /* vcg_dump_finish_pattern */ + +/** + * Dumps a node. + */ static void vcg_dump_node(pattern_dumper_t *self, unsigned id, - unsigned op_code, unsigned mode_code) + unsigned op_code, unsigned mode_code, void *attr) { - ir_op *op = (ir_op *)op_code; - ir_mode *mode = (ir_mode *)mode_code; + vcg_private_t *priv = (vcg_private_t*)self->data; + ir_op *op = stat_get_op_from_opcode(op_code); + ir_mode *mode = get_irp_mode(mode_code); + long l = attr ? *(long *)attr : 0; - fprintf(f, " node: {title: \"n%u\" label: \"%s%s n%u\" }\n", - id, get_id_str(op->name), mode ? get_mode_name(mode) : "", id); -} + if (priv->pattern_id > priv->max_pattern) + return; -static void vcg_dump_edge(pattern_dumper_t *self, unsigned id, unsigned parent, unsigned position) + if (attr) { + fprintf(priv->f, " node: {title: \"n%u_%u\" label: \"%s%s %ld n%u\" }\n", + priv->pattern_id, id, get_id_str(op->name), mode ? get_mode_name(mode) : "", l, id); + } else { + fprintf(priv->f, " node: {title: \"n%u_%u\" label: \"%s%s n%u\" }\n", + priv->pattern_id, id, get_id_str(op->name), mode ? get_mode_name(mode) : "", id); + } /* if */ +} /* vcg_dump_node */ + +/** + * Dumps an edge. + */ +static void vcg_dump_edge(pattern_dumper_t *self, unsigned tgt, unsigned src, unsigned pos, unsigned mode_code) { - fprintf(f, " edge: { sourcename: \"n%u\" targetname: \"n78\"}\n", parent, id); -} + vcg_private_t *priv = (vcg_private_t*)self->data; + (void) mode_code; + + if (priv->pattern_id > priv->max_pattern) + return; + + fprintf(priv->f, " edge: { sourcename: \"n%u_%u\" targetname: \"n%u_%u\" label: \"%u\" }\n", + priv->pattern_id, src, + priv->pattern_id, tgt, + pos + ); +} /* vcg_dump_edge */ /** * The VCG dumper. */ -pattern_dumper_t vcg_dump = { - vcg_dump_node, - NULL, - vcg_dump_edge, - NULL, - NULL, +static pattern_dumper_t vcg_dump = { + vcg_dump_new_pattern, + vcg_dump_finish_pattern, + vcg_dump_node, + NULL, + vcg_dump_edge, + NULL, + NULL, + vcg_dump_start, + vcg_dump_end, + NULL }; /** - * Dumps a node + * Starts a new pattern. */ -static void stdout_dump_node(pattern_dumper_t *self, unsigned id, unsigned op_code, unsigned mode_code) +static void stdout_dump_new_pattern(pattern_dumper_t *self, counter_t *cnt) { - ir_op *op = (ir_op *)op_code; - ir_mode *mode = (ir_mode *)mode_code; + FILE *f = (FILE*)self->data; - /* if (env->options & OPT_ENC_GRAPH) */ - printf("%u:", id); + fprintf(f, "%8u ", cnt_to_uint(cnt)); +} /* stdout_dump_new_pattern */ - printf("%s", get_id_str(op->name)); - if (mode) - printf("%s", get_mode_name(mode)); -} +/** + * Finish the current pattern. + */ +static void stdout_dump_finish_pattern(pattern_dumper_t *self) +{ + FILE *f = (FILE*)self->data; + + fprintf(f, "\n"); +} /* stdout_dump_finish_pattern */ + +/** + * Dumps a node. + */ +static void stdout_dump_node(pattern_dumper_t *self, unsigned id, unsigned op_code, unsigned mode_code, void *attr) +{ + FILE *f = (FILE*)self->data; + ir_op *op = stat_get_op_from_opcode(op_code); + ir_mode *mode = get_irp_mode(mode_code); + (void) attr; + + /* if (env->options & OPT_ENC_GRAPH) */ + fprintf(f, "%u:", id); + + fprintf(f, "%s", get_id_str(op->name)); + + if (mode) + fprintf(f, "%s", get_mode_name(mode)); +} /* stdout_dump_node */ /** * Dump a ref */ static void stdout_dump_ref(pattern_dumper_t *self, unsigned id) { - printf("REF:%u", id); -} + FILE *f = (FILE*)self->data; + + fprintf(f, "REF:%u", id); +} /* stdout_dump_ref */ /** - * Dump an edge + * Dump an edge. */ -static void stdout_dump_edge(pattern_dumper_t *self, unsigned id, unsigned parent, unsigned position) +static void stdout_dump_edge(pattern_dumper_t *self, unsigned tgt, unsigned src, unsigned pos, unsigned mode_code) { - if (position > 0) - printf(", "); -} + FILE *f = (FILE*)self->data; + (void) tgt; + (void) src; + (void) pos; + (void) mode_code; + + if (pos > 0) + fprintf(f, ", "); +} /* stdout_dump_edge */ /** - * Start children dumper + * Start the children dumper. */ static void stdout_start_children(pattern_dumper_t *self, unsigned id) { - printf("("); -} + FILE *f = (FILE*)self->data; + (void) id; + + fprintf(f, "("); +} /* stdout_start_children */ /** - * finishes childred dumper + * Finish the children dumper. */ static void stdout_finish_children(pattern_dumper_t *self, unsigned id) { - printf(")"); -} + FILE *f = (FILE*)self->data; + (void) id; + + fprintf(f, ")"); +} /* stdout_finish_children */ /** * The stdout dumper. */ -pattern_dumper_t stdout_dump = { - stdout_dump_node, - stdout_dump_ref, - stdout_dump_edge, - stdout_start_children, - stdout_finish_children, +static const pattern_dumper_t stdout_dump = { + stdout_dump_new_pattern, + stdout_dump_finish_pattern, + stdout_dump_node, + stdout_dump_ref, + stdout_dump_edge, + stdout_start_children, + stdout_finish_children, + NULL, + NULL, + NULL }; /* ------------------------------------ API ------------------------------------- */ /* - * Dumps a node + * Starts a new pattern. */ -void pattern_dump_node(pattern_dumper_t *self, unsigned id, unsigned op_code, unsigned mode_code) +void pattern_dump_new_pattern(pattern_dumper_t *self, counter_t *cnt) { - if (self->dump_node) - self->dump_node(self, id, op_code, mode_code); -} + if (self->dump_new_pattern) + self->dump_new_pattern(self, cnt); +} /* pattern_dump_new_pattern */ + /* - * Dump a ref + * Finish the current pattern. + */ +void pattern_dump_finish_pattern(pattern_dumper_t *self) +{ + if (self->dump_finish_pattern) + self->dump_finish_pattern(self); +} /* pattern_dump_finish_pattern */ + + +/* + * Dumps a node. + */ +void pattern_dump_node(pattern_dumper_t *self, unsigned id, unsigned op_code, unsigned mode_code, void *attr) +{ + if (self->dump_node) + self->dump_node(self, id, op_code, mode_code, attr); +} /* pattern_dump_node */ + +/* + * Dump a ref. */ void pattern_dump_ref(pattern_dumper_t *self, unsigned id) { - if (self->dump_ref) - self->dump_ref(self, id); -} + if (self->dump_ref) + self->dump_ref(self, id); +} /* pattern_dump_ref */ /* - * Dump an edge + * Dump an edge. */ -void pattern_dump_edge(pattern_dumper_t *self, unsigned id, unsigned parent, unsigned position) +void pattern_dump_edge(pattern_dumper_t *self, unsigned tgt, unsigned src, unsigned pos, unsigned mode_code) { - if (self->dump_edge) - self->dump_edge(self, id, parent, position); -} + if (self->dump_edge) + self->dump_edge(self, tgt, src, pos, mode_code); +} /* pattern_dump_edge */ /* - * Start children dumper + * Start the children dumper. */ void pattern_start_children(pattern_dumper_t *self, unsigned id) { - if (self->dump_start_children) - self->dump_start_children(self, id); -} + if (self->dump_start_children) + self->dump_start_children(self, id); +} /* pattern_start_children */ /* - * finishes childred dumper + * Finish the the children dumper. */ void pattern_finish_children(pattern_dumper_t *self, unsigned id) { - if (self->dump_finish_children) - self->dump_finish_children(self, id); -} + if (self->dump_finish_children) + self->dump_finish_children(self, id); +} /* pattern_finish_children */ + +/* + * Finish the the dumper. + */ +void pattern_end(pattern_dumper_t *self) +{ + if (self->dump_end) + self->dump_end(self); + + free(self); +} /* pattern_end */ + +/** + * pattern dumper factory for text dumper + */ +pattern_dumper_t *new_text_dumper(void) +{ + pattern_dumper_t *res = XMALLOC(pattern_dumper_t); + + memcpy(res, &stdout_dump, sizeof(*res)); + res->data = stdout; + + if (res->dump_start) + res->dump_start(res); + return res; +} /* new_text_dumper */ + +/** + * pattern dumper factory for vcg dumper + */ +pattern_dumper_t *new_vcg_dumper(const char *vcg_name, unsigned max_pattern) +{ + pattern_dumper_t *res = (pattern_dumper_t*)malloc(sizeof(*res) + sizeof(vcg_private_t)); + vcg_private_t *priv; + + if (res) { + FILE *f; + + memcpy(res, &vcg_dump, sizeof(*res)); + + priv = (vcg_private_t *)(res + 1); + memset(priv, 0, sizeof(*priv)); + + f = fopen(vcg_name, "w"); + priv->f = f; + priv->pattern_id = 0; + priv->max_pattern = max_pattern ? max_pattern : (unsigned)-1; + res->data = priv; + + if (res->dump_start) + res->dump_start(res); + } /* if */ + + return res; +} /* new_vcg_dumper */ + +#endif /* FIRM_STATISTICS */