Comments, beautify
[libfirm] / ir / be / phistat.c
index 98bdb47..1a1802f 100644 (file)
 #include "irop.h"
 #include "irprog.h"
 #include "irmode_t.h"
-#include "bephicongr_t.h"
-#include "bechordal.h"
-
 
-#define SUMMARY_FILE_NAME "all.phistat"
+#include "bechordal.h"
+#include "phistat.h"
 
 #define MAX_ARITY 10
 #define MAX_CLS_SIZE 10
 
+/**
+ * For an explanation of these values see phi_stat_dump_pretty
+ */
 enum vals_t {
        I_ARG         = 0,
        I_CONST,
@@ -51,96 +52,42 @@ enum vals_t {
        ASIZE
 };
 
-static int curr_vals[ASIZE];
-
-
 /**
- * Dump statistic values and some annotations for current irp
+ * Holds current values. Values are added till next
+ * phi_stat_reset
  */
-static void dump_file(void) {
-       int i, next;
-       FILE *out;
-       char buf[200];
-
-       next = sprintf(buf, get_irp_prog_name());
-       sprintf(buf+next, ".phistat");
-       out = fopen(buf, "wt");
-
-       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]);
+static int curr_vals[ASIZE];
 
-       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]);
+void phi_stat_reset(void) {
+       int i;
 
-       fclose(out);
+       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;
 }
 
 
 /**
- * Updates the summary file with cumulated values
- */
-static void update_all_file(void) {
-    int i;
-       FILE *all;
-       int vals[ASIZE];
-
-       /* read in */
-       all = fopen(SUMMARY_FILE_NAME, "rt");
-    if (all) {
-               for (i = 0; i<ASIZE; i++) {
-                       if (i >= I_ARITY_S && i <= I_ARITY_E)
-                               fscanf(all, "%i %i\n", &vals[i], &vals[I_ALL_NODES]);
-                       else
-                               fscanf(all, "%i\n", &vals[i]);
-               }
-           fclose(all);
-       } else {
-               for (i = 0; i<ASIZE; i++)
-                       vals[i] = 0;
-       }
-
-       /* write out */
-       all = fopen(SUMMARY_FILE_NAME, "wt");
-       for (i = 0; i<ASIZE; i++) {
-               if (i >= I_ARITY_S && i <= I_ARITY_E)
-                       fprintf(all, "%i %i\n", vals[i]+curr_vals[i], vals[I_ALL_NODES]+curr_vals[I_ALL_NODES]);
-               else
-                       fprintf(all, "%i\n", vals[i]+curr_vals[i]);
-       }
-    fclose(all);
-}
-
-/**
- * Collect the statistical data
+ * Collect general data
  */
-static void phi_stat_walker(ir_node *node, void *env) {
-       int arity, i;
-
+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]++;
+}
+
 
-       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]++;
@@ -153,7 +100,7 @@ static void phi_stat_walker(ir_node *node, void *env) {
        else
                curr_vals[I_ARITY_S + arity]++;
 
-       /* type of argument */
+       /* 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);
@@ -173,72 +120,169 @@ static void phi_stat_walker(ir_node *node, void *env) {
 
                curr_vals[I_GLOB]++;
        }
-
 }
 
-static void phi_class_stat_walker(ir_node *node, void *env) {
+
+/**
+ * Collect phi class data
+ */
+static void phi_class_stat(pset *pc) {
        int i, o, size, doit, sth_interfered;
        ir_node **members, *p;
-       pset *pc;
-
-       pc = get_phi_class(node);
-       if (pc) {
 
-               /* phi class count */
-               curr_vals[I_PHICLS]++;
+       /* 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]++;
-
-               /* count interfering pairs / values */
-               members = (ir_node **) malloc(size * sizeof(ir_node*));
-
-               for (i=0, p = (ir_node *)pset_first(pc); p; p = (ir_node *)pset_next(pc))
-                       members[i++] = p;
-               assert(i == size);
-
-               /* determine interference of phi args */
-               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;
-                                       }
+       /* 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;
+
+       free(members);
+}
+
 
-               /* has this phi class an interference? */
-               curr_vals[I_PHICLSI] += sth_interfered;
-               free(members);
+void phi_stat_collect(ir_graph *irg, pset *all_phi_nodes, pset *all_phi_classes) {
+       ir_node *n;
+       pset *pc;
+
+       irg_walk_graph(irg, stat_walker, NULL, NULL);
+       curr_vals[I_BLOCKS] -= 2;
+
+       for (n = pset_first(all_phi_nodes); n; n = pset_next(all_phi_nodes))
+               phi_node_stat(n);
+
+       for (pc = pset_first(all_phi_classes); pc; pc = pset_next(all_phi_classes))
+               phi_class_stat(pc);
+}
+
+
+/**
+ * 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);
 }
 
 
-void do_phi_statistics(void) {
-       int i, n;
-       curr_vals[I_SPACE1] = -1;
-       curr_vals[I_SPACE2] = -1;
-       curr_vals[I_SPACE3] = -1;
+void phi_stat_update(char *filename) {
+    int i;
+       FILE *all;
+       int vals[ASIZE];
+
+       if (!filename)
+               return;
+
+       /* read in */
+       all = fopen(filename, "rt");
 
-       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_class_stat_walker, NULL, NULL);
-               curr_vals[I_BLOCKS] -= 2;
+    if (all) {
+               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++)
+                       vals[i] = 0;
        }
 
-       dump_file();
-       update_all_file();
+       /* add current values */
+       for (i = 0; i < ASIZE; i++)
+               vals[i] += curr_vals[i];
+
+       /* write out */
+       dump_file(filename, vals);
+}
+
+
+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;
+       }
+
+       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);
 }