Added construction of phi congruence classes.
authorDaniel Grund <grund@cs.uni-saarland.de>
Fri, 10 Dec 2004 15:16:31 +0000 (15:16 +0000)
committerDaniel Grund <grund@cs.uni-saarland.de>
Fri, 10 Dec 2004 15:16:31 +0000 (15:16 +0000)
ir/be/Makefile.in
ir/be/bephicongr.c [new file with mode: 0644]
ir/be/bephicongr_t.h [new file with mode: 0644]
ir/be/phistat.c [new file with mode: 0644]
ir/be/phistat.h [new file with mode: 0644]

index 2b4b5b4..bf15859 100644 (file)
@@ -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 (file)
index 0000000..0b99aa7
--- /dev/null
@@ -0,0 +1,67 @@
+/**
+ * @author Daniel Grund
+ * @date 09.12.2004
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#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 (file)
index 0000000..6206665
--- /dev/null
@@ -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 (file)
index 0000000..9d5b6e8
--- /dev/null
@@ -0,0 +1,150 @@
+#include <stdio.h>
+#include <string.h>
+
+#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<ASIZE; i++)
+                       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++)
+               fprintf(all, "%i\n", vals[i]+curr_vals[i]);
+    fclose(all);
+}
+
+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);
+       }
+
+       dump_files();
+       update_all_file();
+}
diff --git a/ir/be/phistat.h b/ir/be/phistat.h
new file mode 100644 (file)
index 0000000..4841bbf
--- /dev/null
@@ -0,0 +1,11 @@
+/**
+ * @author Daniel Grund
+ * @date 09.12.2004
+ */
+
+#ifndef _PHISTAT_H
+#define _PHISTAT_H
+
+void do_phi_statistics(void);
+
+#endif