X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fphistat.c;h=1a1802f5b6001787e79bb7deaf23625c8a868bda;hb=321ae93c651a24f17e2b7540e67a959db803c40d;hp=9d5b6e8fd659a593b0dc452623d6c956419a560a;hpb=9921b022ba50c4b98fe57a0b3b044cbe41f4562c;p=libfirm diff --git a/ir/be/phistat.c b/ir/be/phistat.c index 9d5b6e8fd..1a1802f5b 100644 --- a/ir/be/phistat.c +++ b/ir/be/phistat.c @@ -1,5 +1,11 @@ +/** + * @author Daniel Grund + * @date 09.12.2004 + */ + #include #include +#include #include "config.h" @@ -9,59 +15,94 @@ #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= 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