2 * Project: libFIRM/extension module/graph rewriting system
3 * File name: ext/grs/ana_vs.c
4 * Purpose: implements the interfaces in analyze.h by a
5 * v-structure (vs) statistic (see [D"orr95],[Batz05b])
7 * Created: 22. June 2005
9 * Copyright: (c) 2005 Universität Karlsruhe
10 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
14 * @file ext/grs/ana_vs.c
15 * @brief implements the interfaces in analyze.h by a
16 * v-structure (vs) statistic (see [D"orr95],[Batz05b])
19 #include "iredges_t.h"
24 #include "auxilary_t.h"
30 /* counter for isomorphic arguments and result uses during analyses */
31 static int *n_isomorphics;
32 static int op_dim, mode_dim;
33 #define N_ISOMORPHICS(opc, mc) n_isomorphics[(opc)*mode_dim + (mc)]
36 /* Counts isomorphic edeges incident at the current node
37 * and stores some information in vs table.
38 * To be called by an irg walker
40 * node the current ir node
41 * env the vs statistics object of the current ir graph
43 static void ana_nodes_vs(ir_node *node, void *env)
46 ext_grs_vs_stat_t *vs_stat = (ext_grs_vs_stat_t *) env;
47 ir_graph *irg = vs_stat->irg;
48 ext_grs_irg_private_t *pr_g = _ext_grs_get_irg_private(irg);
49 ext_grs_irn_private_t *pr_n = _ext_grs_get_irn_private(node);
51 const ir_edge_t *edge;
54 int n_ins = get_irn_arity(node);
56 int i = -1; /* for non Block nodes start at pos -1 */
57 ir_opcode opc = get_irn_opcode(node);
58 modecode mc = get_irn_modecode(node);
62 assert(vs_stat->irg == get_irn_irg(node) && "got wrong vs statistics");
67 /* add the current node to the appropriate node list */
68 lc_list_add(& pr_n->node_list, & _ext_grs_NODE_LIST(pr_g, opc, mc));
69 /* increment the node counter counting the node in that list */
70 (_ext_grs_N_INSTANCES(pr_g, opc, mc))++;
71 /* increment the counter counting the instances of an op for ANY mode */
73 (_ext_grs_N_INSTANCES(pr_g, opc, irm_ANY))++;
75 /* count isomorphic arguments of the current node */
76 if (get_irn_op(node) == op_Block) i = 0;
77 for ( ; i < n_ins; i++) {
79 ir_node *arg = get_irn_n(node, i);
80 ir_opcode opc_arg = get_irn_opcode(arg);
81 modecode mc_arg = get_irn_modecode(arg);
82 ir_opcode super_opc_arg;
85 int n_super_ops = ARR_LEN(_ext_grs_all_super_ops_of_op[opc_arg]);
87 /* increment counters for the apropriate op and all super ops */
88 for (j = 0; j < n_super_ops; j++) {
89 super_opc_arg = get_op_code(_ext_grs_all_super_ops_of_op[opc_arg][j]);
90 N_ISOMORPHICS(super_opc_arg, mc_arg)++;
91 N_ISOMORPHICS(super_opc_arg, irm_ANY)++;
94 /* store resulting number of v structures */
96 if (get_irn_op(node) == op_Block) i = 0;
97 n_ins = get_irn_arity(node);
98 for ( ; i < n_ins; i++) {
100 ir_node *arg = get_irn_n(node, i);
101 ir_opcode opc_arg = get_irn_opcode(arg);
102 modecode mc_arg = get_irn_modecode(arg);
103 ir_opcode super_opc_arg;
108 int n_occ_any_add = 0;
109 int n_any_occ_add = 0;
110 int n_any_occ_any_add = 0;
113 int n_super_ops = ARR_LEN(_ext_grs_all_super_ops_of_op[opc_arg]);
115 for (j = 0; j < n_super_ops; j++) {
116 super_opc_arg = get_op_code(_ext_grs_all_super_ops_of_op[opc_arg][j]);
117 if (N_ISOMORPHICS(super_opc_arg, mc_arg) > 0) {
118 double x = _log2(N_ISOMORPHICS(super_opc_arg, mc_arg));
121 /* count the occurence of nodes with such an edge */
127 /* accumulate multiplicity of such an edge */
129 /* and also add for all super ops of curent nodes op */
130 int n_super_ops_func = ARR_LEN(_ext_grs_all_super_ops_of_op[opc]);
131 for (k = 0; k < n_super_ops_func; k++) {
132 ir_opcode super_opc_func = get_op_code(_ext_grs_all_super_ops_of_op[opc][k]);
135 vs_stat, super_opc_func, mc, super_opc_arg, mc_arg, ext_grs_in, x);
137 _add_n_v_structures(vs_stat,
138 super_opc_func, irm_ANY, super_opc_arg, mc_arg, ext_grs_in, x);
142 N_ISOMORPHICS(super_opc_arg, mc_arg) = 0;
144 if (N_ISOMORPHICS(super_opc_arg, irm_ANY) > 0) {
145 double x = _log2(N_ISOMORPHICS(super_opc_arg, irm_ANY));
148 /* count the occurence of nodes with such an edge */
154 /* accumulate multiplicity of such an edge */
156 /* and also add for all super ops of curent nodes op */
157 int n_super_ops_func = ARR_LEN(_ext_grs_all_super_ops_of_op[opc]);
158 for (k = 0; k < n_super_ops_func; k++) {
159 ir_opcode super_opc_func = get_op_code(_ext_grs_all_super_ops_of_op[opc][k]);
162 vs_stat, super_opc_func, mc, super_opc_arg, irm_ANY, ext_grs_in, x);
164 _add_n_v_structures(vs_stat,
165 super_opc_func, irm_ANY, super_opc_arg, irm_ANY, ext_grs_in, x);
168 N_ISOMORPHICS(super_opc_arg, irm_ANY) = 0;
173 _add_n_occurence(vs_stat, opc, mc, opc_arg, mc_arg, ext_grs_in, n_occ_add);
174 if (n_occ_any_add > 0)
175 _add_n_occurence(vs_stat, opc, irm_ANY, opc_arg, mc_arg, ext_grs_in, n_any_occ_add);
176 if (n_any_occ_add > 0)
177 _add_n_occurence(vs_stat, opc, mc, opc_arg, irm_ANY, ext_grs_in, n_occ_any_add);
178 if (n_any_occ_any_add > 0)
179 _add_n_occurence(vs_stat, opc, irm_ANY, opc_arg, irm_ANY, ext_grs_in, n_any_occ_any_add);
186 /* count isomorphic uses of the current nodes result */
187 foreach_out_edge(node, edge) {
189 ir_node *res = get_edge_src_irn(edge);
190 ir_opcode opc_res = get_irn_opcode(res);
191 modecode mc_res = get_irn_modecode(res);
193 modecode super_opc_res;
195 int n_super_ops = ARR_LEN( _ext_grs_all_super_ops_of_op[opc_res]);
197 /* increment counters for the apropriate op and all super ops */
198 for (j = 0; j < n_super_ops; j++) {
199 super_opc_res = get_op_code(_ext_grs_all_super_ops_of_op[opc_res][j]);
200 N_ISOMORPHICS(super_opc_res, mc_res)++;
201 N_ISOMORPHICS(super_opc_res, irm_ANY)++;
204 /* store resulting number of v structures */
205 foreach_out_edge(node, edge) {
207 ir_node *res = get_edge_src_irn(edge);
208 ir_opcode opc_res = get_irn_opcode(res);
209 modecode mc_res = get_irn_modecode(res);
210 modecode super_opc_res;
214 int n_occ_any_add = 0;
215 int n_any_occ_add = 0;
216 int n_any_occ_any_add = 0;
219 int n_super_ops = ARR_LEN( _ext_grs_all_super_ops_of_op[opc_res]);
221 for (j = 0; j < n_super_ops; j++) {
222 super_opc_res = get_op_code(_ext_grs_all_super_ops_of_op[opc_res][j]);
223 if (N_ISOMORPHICS(super_opc_res, mc_res) > 0) {
225 double x = _log2(N_ISOMORPHICS(super_opc_res, mc_res));
228 /* count the occurence of nodes with such an edge */
234 /* accumulate multiplicity of such an edge */
236 /* and also add for all super ops of curent nodes op */
237 int n_super_ops_func = ARR_LEN(_ext_grs_all_super_ops_of_op[opc]);
238 for (k = 0; k < n_super_ops_func; k++) {
239 ir_opcode super_opc_func = get_op_code(_ext_grs_all_super_ops_of_op[opc][k]);
242 vs_stat, super_opc_func, mc, super_opc_res, mc_res, ext_grs_out, x);
244 _add_n_v_structures(vs_stat,
245 super_opc_func, irm_ANY, super_opc_res, mc_res, ext_grs_out, x);
248 N_ISOMORPHICS(super_opc_res, mc_res) = 0;
250 if (N_ISOMORPHICS(super_opc_res, irm_ANY) > 0) {
252 double x = _log2(N_ISOMORPHICS(super_opc_res, irm_ANY));
255 /* count the occurence of nodes with such an edge */
261 /* accumulate multiplicity of such an edge */
263 /* and also add for all super ops of curent nodes op */
264 int n_super_ops_func = ARR_LEN(_ext_grs_all_super_ops_of_op[opc]);
265 for (k = 0; k < n_super_ops_func; k++) {
266 ir_opcode super_opc_func = get_op_code(_ext_grs_all_super_ops_of_op[opc][k]);
269 vs_stat, super_opc_func, mc, super_opc_res, irm_ANY, ext_grs_out, x);
271 _add_n_v_structures(vs_stat,
272 super_opc_func, irm_ANY, super_opc_res, irm_ANY, ext_grs_out, x);
275 N_ISOMORPHICS(super_opc_res, irm_ANY) = 0;
280 _add_n_occurence(vs_stat, opc, mc, opc_res, mc_res, ext_grs_out, n_occ_add);
281 if (n_any_occ_add > 0)
282 _add_n_occurence(vs_stat, opc, irm_ANY, opc_res, mc_res, ext_grs_out, n_any_occ_add);
283 if (n_occ_any_add > 0)
284 _add_n_occurence(vs_stat, opc, mc, opc_res, irm_ANY, ext_grs_out, n_occ_add);
285 if (n_any_occ_any_add > 0)
286 _add_n_occurence(vs_stat, opc, irm_ANY, opc_res, irm_ANY, ext_grs_out, n_any_occ_add);
293 /* initialize an vs analyzer */
294 static void init(ext_grs_analyzer_t *alz) {
296 ext_grs_ana_vs_private_t *pr_a = malloc(sizeof(*pr_a));
298 /* init isomorphic edge counters with 0 */
301 n_isomorphics = malloc(170*25*sizeof(int));
302 memset(n_isomorphics, 0, 170*25*sizeof(int));
304 /* init the pset mapping ir_graphs to that ir_graphs vs statistic */
305 pr_a->ana_results = lc_pset_new(_stat_cmp_func, 256);
306 /* init the global vs statistic */
307 pr_a->global_vs_stat.irg = NULL;
308 pr_a->global_vs_stat.stat = lc_pset_new(_vs_cmp_func, 256);
309 obstack_init(& pr_a->global_vs_stat.obst);
314 /* perform string v structure analysis for a given graph */
315 static void analyze(ext_grs_analyzer_t *alz, ir_graph *irg)
318 ext_grs_irg_private_t *pr_g = _ext_grs_get_irg_private(irg);
319 ext_grs_vs_stat_t *vs_stat;
321 assert(pr_g->matching_enabled && "matching not enabled for this graph");
325 /* check whether the array of instance counters is great enough */
326 if (_ext_grs_max_opcode >= op_dim) {
328 op_dim = _ext_grs_max_opcode + 50;
329 n_isomorphics = malloc(op_dim*mode_dim*sizeof(int));
330 memset(n_isomorphics, 0, op_dim*mode_dim*sizeof(int));
333 if (_ext_grs_max_modecode >= mode_dim) {
335 mode_dim = _ext_grs_max_modecode + 50;
336 n_isomorphics = malloc(op_dim*mode_dim*sizeof(int));
337 memset(n_isomorphics, 0, op_dim*mode_dim*sizeof(int));
341 /* init the op list heads */
342 for (j = 0; j < _ext_grs_irgpr_op_dim; j++)
343 for (k = 0; k < _ext_grs_irgpr_mode_dim; k++) {
344 LC_INIT_LIST_HEAD(& _ext_grs_NODE_LIST(pr_g, j, k));
345 _ext_grs_N_INSTANCES(pr_g, j, k) = 0;
347 /* init the number of (op,mode)-instances with zero */
348 memset(pr_g->n_instances, 0,
349 _ext_grs_irgpr_op_dim * _ext_grs_irgpr_mode_dim *
350 sizeof(*(pr_g->n_instances)));
352 /* get the statistics object of the given irg and remove its complete contents */
353 vs_stat = _get_irg_vs_stat(alz, irg);
354 assert(vs_stat->irg == irg);
356 lc_pset_del(vs_stat->stat);
357 vs_stat->stat = lc_pset_new(_vs_cmp_func, 256);
358 obstack_free(& vs_stat->obst, NULL);
359 obstack_init(& vs_stat->obst);
363 irg_walk_graph(irg, ana_nodes_vs, NULL, vs_stat);
366 static void free_ana_result(ext_grs_analyzer_t *alz, ir_graph *irg)
368 ext_grs_vs_stat_t *vs_stat = _get_irg_vs_stat(alz, irg);
371 lc_pset_del(vs_stat->stat);
372 vs_stat->stat = lc_pset_new(_vs_cmp_func, 256);
375 obstack_free(& vs_stat->obst, NULL);
376 obstack_init(& vs_stat->obst);
379 /* dump the current analysis result for a given ir graph */
380 static void dump_ana_result(ext_grs_analyzer_t *alz, ir_graph *irg)
384 ext_grs_vs_stat_t *vs_stat = _get_irg_vs_stat(alz, irg);
385 ext_grs_irg_private_t *pr_g = _ext_grs_get_irg_private(irg);
387 printf("Dump vs-statistics for ir graph %ld...\n", get_irg_graph_nr(irg));
389 for (i=0; i <= _ext_grs_max_opcode; i++)
390 for (j=0; j <= _ext_grs_max_modecode; j++)
391 for (k=0; k <= _ext_grs_max_opcode; k++)
392 for (l=0; l <= _ext_grs_max_modecode; l++) {
393 x = _get_n_v_structures(vs_stat,i,j,k,l,ext_grs_in);
396 int occ = _get_n_occurence(vs_stat, i, j, k, l, ext_grs_in);
398 double acc_div_occ = 0.0;
399 double acc_div_inst = 0.0;
401 /* compute the number of instances present for the
402 * func node (including all sub ops) */
403 for (r = 0; r < ARR_LEN(_ext_grs_all_sub_ops_of_op[i]); r++) {
404 ir_opcode sub_opc = get_op_code(_ext_grs_all_sub_ops_of_op[i][r]);
405 n_inst += _ext_grs_N_INSTANCES(pr_g, sub_opc, j);
409 acc_div_occ = x / occ;
412 acc_div_inst = x / (double)n_inst;
414 printf("# (%s, %s) -in-> (%s, %s): acc, occ, n_inst, acc/n_inst\n",
415 get_op_name(_ext_grs_op_map[i]),
416 get_mode_name(_ext_grs_mode_map[j]),
417 get_op_name(_ext_grs_op_map[k]),
418 get_mode_name(_ext_grs_mode_map[l])
420 printf("(%d,%d,%d,%d,in): %lf, %d, %d, %lf\n",
426 x = _get_n_v_structures(vs_stat,i,j,k,l,ext_grs_out);
429 int occ = _get_n_occurence(vs_stat, i, j, k, l, ext_grs_out);
431 double acc_div_occ = 0.0;
432 double acc_div_inst = 0.0;
434 /* compute the number of instnaces present for the
435 * func node (including all sub ops) */
436 for (r = 0; r < ARR_LEN(_ext_grs_all_sub_ops_of_op[i]); r++) {
437 ir_opcode sub_opc = get_op_code(_ext_grs_all_sub_ops_of_op[i][r]);
438 n_inst += _ext_grs_N_INSTANCES(pr_g, sub_opc, j);
442 acc_div_occ = x / occ;
445 acc_div_inst = x / (double)n_inst;
447 printf("# (%s, %s) <-out- (%s, %s): acc, occ, n_inst, acc/n_inst\n",
448 get_op_name(_ext_grs_op_map[i]),
449 get_mode_name(_ext_grs_mode_map[j]),
450 get_op_name(_ext_grs_op_map[k]),
451 get_mode_name(_ext_grs_mode_map[l])
453 printf("(%d,%d,%d,%d,out): %lf, %d, %d, %lf\n",
461 for (i=0; i <= _ext_grs_max_opcode; i++)
462 for (j=0; j <= _ext_grs_max_modecode; j++) {
465 const char *modename;
467 for (r = 0; r < ARR_LEN(_ext_grs_all_sub_ops_of_op[i]); r++) {
468 ir_opcode sub_opc = get_op_code(_ext_grs_all_sub_ops_of_op[i][r]);
469 n_inst += _ext_grs_N_INSTANCES(pr_g, sub_opc, j);
472 if (_ext_grs_op_map[i] != NULL)
473 opname = get_op_name(_ext_grs_op_map[i]);
476 if (_ext_grs_mode_map[j] != NULL)
477 modename = get_mode_name(_ext_grs_mode_map[j]);
478 else modename = NULL;
480 if (opname == NULL) opname = "dummy";
481 if (modename == NULL) modename = "dummy";
483 if (n_inst != 0 || _ext_grs_N_INSTANCES(pr_g, i,j) != 0)
484 printf("Number of instances (%s, %s): direct = %d, with sub ops = %d\n",
485 opname, modename, _ext_grs_N_INSTANCES(pr_g, i,j), n_inst);
500 static ext_grs_analyzer_t vs_analyzer;
503 /** yields an analyzer performing a v-structure statisitc */
504 ext_grs_analyzer_t *ext_grs_get_vs_analyzer(void)
506 memset(&vs_analyzer, 0, sizeof(vs_analyzer));
507 vs_analyzer.tag = "vs_analyzer";
508 vs_analyzer.dump_ana_result = dump_ana_result;
509 vs_analyzer.analyze = analyze;
510 vs_analyzer.free_ana_result = free_ana_result;