From: Daniel Grund Date: Fri, 10 Dec 2004 15:16:31 +0000 (+0000) Subject: Added construction of phi congruence classes. X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=9921b022ba50c4b98fe57a0b3b044cbe41f4562c;p=libfirm Added construction of phi congruence classes. --- diff --git a/ir/be/Makefile.in b/ir/be/Makefile.in index 2b4b5b4f7..bf1585906 100644 --- a/ir/be/Makefile.in +++ b/ir/be/Makefile.in @@ -20,7 +20,8 @@ INSTALL_HEADERS = be.h SOURCES = $(INSTALL_HEADERS) SOURCES += Makefile.in besched.h belistsched.h belistsched.c \ - beutil.h bemain.c besched.c bemain.c belive.c belive.h + beutil.h bemain.c besched.c bemain.c belive.c belive.h \ + bephicongr.c bephicongr_t.h phistat.c phistat.h include $(topdir)/MakeRules diff --git a/ir/be/bephicongr.c b/ir/be/bephicongr.c new file mode 100644 index 000000000..0b99aa7a3 --- /dev/null +++ b/ir/be/bephicongr.c @@ -0,0 +1,67 @@ +/** + * @author Daniel Grund + * @date 09.12.2004 + */ + +#include +#include + +#include "irgraph.h" +#include "irnode.h" +#include "irgwalk.h" +#include "irop.h" +#include "irprog.h" +#include "bephicongr_t.h" + + +size_t phi_irn_data_offset = 0; + +void be_phi_congr_class_init(void) { + phi_irn_data_offset = register_additional_node_data(sizeof(phi_info_t)); +} + + +#define set_phi_class(n,new_tgt) get_irn_phi_info(n)->phi_congr_class=new_tgt +#define set_phi_class_size(n,v)  get_irn_phi_info(n)->phi_class_size=v +#define inc_phi_class_size(n) get_irn_phi_info(n)->phi_class_size++ + +static void correct_phi_class(ir_node *n, ir_node *new_tgt){ + int i, max, check; + check = get_phi_class_size(n) + get_phi_class_size(new_tgt); + + for (i = 0, max = get_irn_arity(n); i < max; i++) { + ir_node *arg = get_irn_n(n, i); + set_phi_class(arg, new_tgt); + inc_phi_class_size(new_tgt); + } + + get_irn_phi_info(n)->phi_class_size=0; + //set_phi_class_size(n, 0); + + assert((check == get_phi_class_size(n) + get_phi_class_size(new_tgt)) && "Re-setting pointers went wrong."); +} + + +void det_phi_congr_class(ir_node *curr_phi) { + int i, n; + assert(is_Phi(curr_phi) && "This must be a phi node."); + + set_phi_class(curr_phi, curr_phi); + + for (i = 0, n = get_irn_arity(curr_phi); i < n; i++) { + ir_node *arg, *pc; + + arg = get_irn_n(curr_phi, i); + pc = get_phi_class(arg); + if (!pc) + set_phi_class(arg, curr_phi); + else + correct_phi_class(pc, curr_phi); + } +} + + +void be_det_phi_congr_classes(void) { + //forall phis: det_phi_congr_classes(n); + assert(0 && "NYI"); +} diff --git a/ir/be/bephicongr_t.h b/ir/be/bephicongr_t.h new file mode 100644 index 000000000..620666523 --- /dev/null +++ b/ir/be/bephicongr_t.h @@ -0,0 +1,27 @@ +/** + * @author Daniel Grund + * @date 09.12.2004 + */ + +#ifndef _BEPHICONGR_T_H +#define _BEPHICONGR_T_H + +#include "irnode.h" + +typedef struct _phi_info_t { + ir_node *phi_congr_class; + unsigned int phi_class_size; +} phi_info_t; + +extern size_t phi_irn_data_offset; + +#define get_irn_phi_info(irn) get_irn_data(irn, phi_info_t, phi_irn_data_offset) +#define get_phi_class(n) get_irn_phi_info(n)->phi_congr_class +#define get_phi_class_size(n) get_irn_phi_info(n)->phi_class_size + +void be_phi_congr_class_init(void); +void be_det_phi_congr_classes(void); + +void det_phi_congr_class(ir_node *curr_phi); + +#endif diff --git a/ir/be/phistat.c b/ir/be/phistat.c new file mode 100644 index 000000000..9d5b6e8fd --- /dev/null +++ b/ir/be/phistat.c @@ -0,0 +1,150 @@ +#include +#include + +#include "config.h" + +#include "irgraph.h" +#include "irnode.h" +#include "irgwalk.h" +#include "irop.h" +#include "irprog.h" +#include "irmode_t.h" +#include "bephicongr_t.h" + + +#define SUMMARY_FILE_NAME "all.phi" + +/* + * 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 + */ + +#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) + +static int curr_vals[ASIZE]; + +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]++; +} + +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; + + /* argument count */ + count = get_irn_arity(node); + if (count > ARG_CNT_MAX) + curr_vals[I_ARG_CNT_E]++; + else + curr_vals[I_ARG_CNT_S + count]++; + + /* type of argument */ + for (i = 0; i < count; i++) { + ir_node *arg = get_irn_n(node, i); + + if (iro_Const == get_irn_opcode(arg)) { + curr_vals[I_CONST]++; + 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)); + + if (block_of_arg == block_ith_pred) { + curr_vals[I_PRED]++; + continue; + } + + curr_vals[I_GLOB]++; + } + + /* phi congruence class */ + det_phi_congr_class(node); +} + + +static void dump_files(void) { + int i, sum1, sum2, next; + FILE *out; + char buf[200]; + + 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]; + + next = sprintf(buf, get_irp_prog_name()); + sprintf(buf+next, ".phi.argcount"); + + 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); + + 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); +} + + +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