Comments, beautify
[libfirm] / ir / be / phistat.c
index 9d5b6e8..1a1802f 100644 (file)
@@ -1,5 +1,11 @@
+/**
+ * @author Daniel Grund
+ * @date 09.12.2004
+ */
+
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 
 #include "config.h"
 
 #include "irop.h"
 #include "irprog.h"
 #include "irmode_t.h"
-#include "bephicongr_t.h"
 
+#include "bechordal.h"
+#include "phistat.h"
 
-#define SUMMARY_FILE_NAME "all.phi"
+#define MAX_ARITY 10
+#define MAX_CLS_SIZE 10
 
-/*
- * 0  to 10 arg-count of phi funct
- * 11 to 20 phi-congr-class size
- * 11 # of const args
- * 12 # of args defined in cf-pred block
- * 13 # of args defines elsewhere
- * 14 size of phi congruence class
+/**
+ * For an explanation of these values see phi_stat_dump_pretty
+ */
+enum vals_t {
+       I_ARG         = 0,
+       I_CONST,
+       I_PRED,
+       I_GLOB,
+
+       I_SPACE1,
+       I_BLOCKS,
+       I_PHIS,
+       I_PHICLS,
+       I_PHICLSI,
+       I_PAIRS,
+       I_PAIRSI,
+       I_VALUES,
+       I_VALUESI,
+
+       I_SPACE2,
+       I_ARITY_S,
+       I_ARITY_E    = I_ARITY_S+MAX_ARITY,
+
+       I_SPACE3,
+       I_CLS_SIZE_S,
+       I_CLS_SIZE_E = I_CLS_SIZE_S+MAX_CLS_SIZE,
+       I_ALL_NODES,
+       ASIZE
+};
+
+/**
+ * Holds current values. Values are added till next
+ * phi_stat_reset
  */
+static int curr_vals[ASIZE];
 
-#define ARG_CNT_MAX 10
-#define PHI_CLS_MAX 10
 
-#define I_ARG_CNT_S 0
-#define I_ARG_CNT_E (I_ARG_CNT_S+ARG_CNT_MAX)
-#define I_PHI_CLS_S (I_ARG_CNT_E+1)
-#define I_PHI_CLS_E (I_PHI_CLS_S+PHI_CLS_MAX)
-#define I_CONST (I_PHI_CLS_E+1)
-#define I_PRED (I_CONST+1)
-#define I_GLOB (I_PRED+1)
-#define ASIZE (I_GLOB+1)
+void phi_stat_reset(void) {
+       int i;
 
-static int curr_vals[ASIZE];
+       for (i = 0; i < ASIZE; ++i)
+               curr_vals[i] = 0;
+       curr_vals[I_SPACE1] = -1;
+       curr_vals[I_SPACE2] = -1;
+       curr_vals[I_SPACE3] = -1;
+}
 
-static void phi_stat_post_walker(ir_node *node, void *env) {
-       int size;
-       if (!(is_Phi(node) && mode_is_datab(get_irn_mode(node)))) return;
 
-       size = get_phi_class_size(node);
-       if (size > PHI_CLS_MAX)
-               curr_vals[I_PHI_CLS_E]++;
-       else
-               curr_vals[I_PHI_CLS_S + size]++;
+/**
+ * Collect general data
+ */
+static void stat_walker(ir_node *node, void *env) {
+       /* count all nodes */
+       curr_vals[I_ALL_NODES]++;
+
+       /* count all block nodes */
+       if (is_Block(node))
+               curr_vals[I_BLOCKS]++;
 }
 
-static void phi_stat_walker(ir_node *node, void *env) {
-       int count, i;
 
-       if (!(is_Phi(node) && mode_is_datab(get_irn_mode(node)))) return;
+/**
+ * Collect phi node data
+ */
+static void phi_node_stat(ir_node *node) {
+       int arity, i;
+
+       /* count all phi nodes */
+       curr_vals[I_PHIS]++;
 
        /* argument count */
-       count = get_irn_arity(node);
-       if (count > ARG_CNT_MAX)
-               curr_vals[I_ARG_CNT_E]++;
+       arity = get_irn_arity(node);
+       curr_vals[I_ARG] += arity;
+       if (arity > MAX_ARITY)
+               curr_vals[I_ARITY_E]++;
        else
-               curr_vals[I_ARG_CNT_S + count]++;
+               curr_vals[I_ARITY_S + arity]++;
 
-       /* type of argument */
-       for (i = 0; i < count; i++) {
+       /* type of argument {const, pred, glob} */
+       for (i = 0; i < arity; i++) {
+        ir_node *block_of_arg, *block_ith_pred;
                ir_node *arg = get_irn_n(node, i);
 
                if (iro_Const == get_irn_opcode(arg)) {
@@ -69,8 +110,8 @@ static void phi_stat_walker(ir_node *node, void *env) {
                        continue;
                }
 
-               ir_node *block_of_arg = get_nodes_block(arg);
-               ir_node *block_ith_pred = get_nodes_block(get_irn_n(get_nodes_block(node), i));
+               block_of_arg = get_nodes_block(arg);
+               block_ith_pred = get_nodes_block(get_irn_n(get_nodes_block(node), i));
 
                if (block_of_arg == block_ith_pred) {
                        curr_vals[I_PRED]++;
@@ -79,72 +120,169 @@ static void phi_stat_walker(ir_node *node, void *env) {
 
                curr_vals[I_GLOB]++;
        }
+}
+
+
+/**
+ * Collect phi class data
+ */
+static void phi_class_stat(pset *pc) {
+       int i, o, size, doit, sth_interfered;
+       ir_node **members, *p;
+
+       /* phi class count */
+       curr_vals[I_PHICLS]++;
+
+       /* phi class size */
+       size = pset_count(pc);
+       if (size > MAX_CLS_SIZE)
+               curr_vals[I_CLS_SIZE_E]++;
+       else
+               curr_vals[I_CLS_SIZE_S + size]++;
+
+       /* get an array of all members for double iterating */
+       members = malloc(size * sizeof(*members));
+       for (i = 0, p = pset_first(pc); p; p = pset_next(pc))
+               members[i++] = p;
+       assert(i == size);
+
+       /* determine interference of phi class members */
+       curr_vals[I_VALUES] += size;
+       sth_interfered = 0;
+       for (i = 0; i < size-1; ++i) {
+               doit = 1;
+               for (o = i+1; o < size; ++o) {
+                       curr_vals[I_PAIRS]++;
+                       if (phi_ops_interfere(members[i], members[o])) {
+                               sth_interfered = 1;
+                               curr_vals[I_PAIRSI]++;
+                               if (doit) {
+                                       curr_vals[I_VALUESI]++;
+                                       doit = 0;
+                               }
+                       }
+               }
+       }
+
+       /* Does this phi class have an inner interference? */
+       curr_vals[I_PHICLSI] += sth_interfered;
 
-       /* phi congruence class */
-       det_phi_congr_class(node);
+       free(members);
 }
 
 
-static void dump_files(void) {
-       int i, sum1, sum2, next;
-       FILE *out;
-       char buf[200];
+void phi_stat_collect(ir_graph *irg, pset *all_phi_nodes, pset *all_phi_classes) {
+       ir_node *n;
+       pset *pc;
 
-       sum1 = curr_vals[I_CONST] + curr_vals[I_PRED] + curr_vals[I_GLOB];
-       sum2 = 0;
-       for (i = I_ARG_CNT_S; i<=I_ARG_CNT_E; i++)
-               sum2 += curr_vals[i];
+       irg_walk_graph(irg, stat_walker, NULL, NULL);
+       curr_vals[I_BLOCKS] -= 2;
 
-       next = sprintf(buf, get_irp_prog_name());
-       sprintf(buf+next, ".phi.argcount");
+       for (n = pset_first(all_phi_nodes); n; n = pset_next(all_phi_nodes))
+               phi_node_stat(n);
 
-       out = fopen(buf, "wt");
-       for (i = I_ARG_CNT_S; i<=I_ARG_CNT_E; i++)
-               fprintf(out, "%2i %2.2f\n", i, (double) curr_vals[i] / sum2);
-       fclose(out);
+       for (pc = pset_first(all_phi_classes); pc; pc = pset_next(all_phi_classes))
+               phi_class_stat(pc);
+}
 
-       sprintf(buf+next, ".phi.defloc");
-       out = fopen(buf, "wt");
-       fopen(buf, "wt");
-       fprintf(out, "Const %2.2f\n", (double) curr_vals[I_CONST] / sum1);
-       fprintf(out, "Pred %2.2f\n", (double) curr_vals[I_PRED] / sum1);
-       fprintf(out, "Glob %2.2f\n", (double) curr_vals[I_GLOB] / sum1);
-       fclose(out);
+
+/**
+ * Dump statistic values in raw format
+ */
+static void dump_file(char *filename, int stat[ASIZE]) {
+       FILE *file;
+       int i;
+
+       if (! (file = fopen(filename, "wt"))) {
+               fprintf(stderr, "Cannot open file for writing: %s\n", filename);
+               return;
+       }
+
+       for (i = 0; i < ASIZE; i++) {
+               if (i >= I_ARITY_S && i <= I_ARITY_E)
+                       fprintf(file, "%i %i\n", stat[i], stat[I_PHIS]);
+               else if (i >= I_CLS_SIZE_S && i <= I_CLS_SIZE_E)
+                       fprintf(file, "%i %i\n", stat[i], stat[I_PHICLS]);
+               else
+                       fprintf(file, "%i\n", stat[i]);
+       }
+
+    fclose(file);
 }
 
 
-static void update_all_file(void) {
+void phi_stat_update(char *filename) {
     int i;
        FILE *all;
        int vals[ASIZE];
 
+       if (!filename)
+               return;
+
        /* read in */
-       all = fopen(SUMMARY_FILE_NAME, "rt");
+       all = fopen(filename, "rt");
+
     if (all) {
-               for (i = 0; i<ASIZE; i++)
-                       fscanf(all, "%i\n", &vals[i]);
+               for (i = 0; i < ASIZE; i++) {
+                       if (i >= I_ARITY_S && i <= I_ARITY_E)
+                               fscanf(all, "%i %i\n", &vals[i], &vals[I_PHIS]);
+                       else if (i >= I_CLS_SIZE_S && i <= I_CLS_SIZE_E)
+                               fscanf(all, "%i %i\n", &vals[i], &vals[I_PHICLS]);
+                       else
+                               fscanf(all, "%i\n", &vals[i]);
+               }
            fclose(all);
        } else {
-               for (i = 0; i<ASIZE; i++)
+               for (i = 0; i < ASIZE; i++)
                        vals[i] = 0;
        }
 
+       /* add current values */
+       for (i = 0; i < ASIZE; i++)
+               vals[i] += curr_vals[i];
+
        /* write out */
-       all = fopen(SUMMARY_FILE_NAME, "wt");
-       for (i = 0; i<ASIZE; i++)
-               fprintf(all, "%i\n", vals[i]+curr_vals[i]);
-    fclose(all);
+       dump_file(filename, vals);
 }
 
-void do_phi_statistics(void) {
-       int i, n;
 
-       for (i = 0, n = get_irp_n_irgs(); i < n; i++) {
-               ir_graph *irg = get_irp_irg(i);
-               irg_walk_graph(irg, phi_stat_walker, NULL, NULL);
-               irg_walk_graph(irg, phi_stat_post_walker, NULL, NULL);
+void phi_stat_dump(char *filename) {
+       if (filename)
+               dump_file(filename, curr_vals);
+}
+
+
+void phi_stat_dump_pretty(char *filename) {
+       int i;
+       FILE *out;
+
+       if (! (out = fopen(filename, "wt"))) {
+               fprintf(stderr, "Cannot open file for writing: %s\n", filename);
+               return;
        }
 
-       dump_files();
-       update_all_file();
+       fprintf(out, "\nPhi argument types\n");
+       fprintf(out, "Total     %4d\n", curr_vals[I_ARG]);
+       fprintf(out, "Constants %4d\n", curr_vals[I_CONST]);
+       fprintf(out, "CF-Pred   %4d\n", curr_vals[I_PRED]);
+       fprintf(out, "Others    %4d\n", curr_vals[I_GLOB]);
+
+       fprintf(out, "\nPhi class interference\n");
+       fprintf(out, "Blocks         %4d\n", curr_vals[I_BLOCKS]);
+       fprintf(out, "Phis           %4d\n", curr_vals[I_PHIS]);
+       fprintf(out, "Interf classes %4d of %4d\n", curr_vals[I_PHICLSI], curr_vals[I_PHICLS]);
+       fprintf(out, "Interf pairs   %4d of %4d\n", curr_vals[I_PAIRSI], curr_vals[I_PAIRS]);
+       fprintf(out, "Interf values  %4d of %4d\n", curr_vals[I_PAIRSI], curr_vals[I_VALUES]);
+
+       fprintf(out, "\nPhi arity\n");
+       for (i = I_ARITY_S; i<=I_ARITY_E; i++)
+               fprintf(out, "%2i %4d\n", i-I_ARITY_S, curr_vals[i]);
+
+       fprintf(out, "\nPhi class sizes\n");
+       for (i = I_CLS_SIZE_S; i<=I_CLS_SIZE_E; i++)
+               fprintf(out, "%2i %4d\n", i-I_CLS_SIZE_S, curr_vals[i]);
+
+       fprintf(out, "\n\nTotal nodes:    %4d\n", curr_vals[I_ALL_NODES]);
+
+       fclose(out);
 }