+static void stat_reg_pressure_block(ir_node *block, void *data) {
+ pressure_walker_env_t *env = data;
+
+ if(env->cls != NULL) {
+ check_reg_pressure_class(env, block, env->cls);
+ } else {
+ const arch_env_t *arch_env = be_get_birg_arch_env(env->birg);
+ int i, n;
+
+ n = arch_env_get_n_reg_class(arch_env);
+ for (i = 0; i < n; i++) {
+ const arch_register_class_t *cls
+ = arch_env_get_reg_class(arch_env, i);
+
+ check_reg_pressure_class(env, block, cls);
+ }
+ }
+}
+
+void be_do_stat_reg_pressure(be_irg_t *birg) {
+ pressure_walker_env_t env;
+ ir_graph *irg = be_get_birg_irg(birg);
+ double average_pressure;
+
+ env.birg = birg;
+ env.insn_count = 0;
+ env.max_pressure = 0;
+ env.regpressure = 0;
+ be_liveness_assure_sets(be_assure_liveness(birg));
+ env.lv = be_get_birg_liveness(birg);
+
+ // hack for now, TODO: remove me later
+#if 0
+ env.cls = NULL;
+#else
+ env.cls = arch_env_get_reg_class(be_get_birg_arch_env(birg), 2);
+#endif
+
+ /* Collect register pressure information for each block */
+ irg_block_walk_graph(irg, stat_reg_pressure_block, NULL, &env);
+
+ average_pressure = env.regpressure / env.insn_count;
+ stat_ev_emit("average_register_pressure", average_pressure);
+ stat_ev_emit("maximum_register_pressure", env.max_pressure);
+}
+
+/**
+ * Notify statistic module about amount of ready nodes.
+ */
+void be_do_stat_sched_ready(ir_node *block, const ir_nodeset_t *ready_set) {
+ if (stat_is_active()) {
+ stat_be_block_sched_ready(get_irn_irg(block), block, MIN(ir_nodeset_size(ready_set), 5));
+ }
+}
+
+/**
+ * Pass information about a perm to the statistic module.
+ */
+void be_do_stat_perm(const char *class_name, int n_regs, ir_node *perm, ir_node *block, int n, int real_size) {
+ if (stat_is_active()) {
+ stat_be_block_stat_perm(class_name, n_regs, perm, block, n, real_size);
+ }
+}
+
+/**
+ * Pass information about a cycle or chain in a perm to the statistic module.
+ */
+void be_do_stat_permcycle(const char *class_name, ir_node *perm, ir_node *block, int is_chain, int n_elems, int n_ops) {
+ if (stat_is_active()) {
+ stat_be_block_stat_permcycle(class_name, perm, block, is_chain, n_elems, n_ops);
+ }
+}
+
+/**
+ * Updates nodes statistics.
+ */
+static void do_nodes_stat(ir_node *irn, void *env) {
+ be_stat_phase_t *phase = env;
+ ir_mode *mode;
+ ir_opcode opc;
+ arch_irn_class_t irn_class;
+
+ if (is_Block(irn))
+ return;
+
+ mode = get_irn_mode(irn);
+ opc = get_irn_opcode(irn);
+
+ phase->num_nodes++;
+
+ /* check for nodes we want to ignore */
+ if (be_is_Keep(irn) ||
+ be_is_CopyKeep(irn) ||
+ opc == iro_Start ||
+ opc == iro_End)
+ return;
+
+ if (is_Proj(irn) && (mode != mode_X)) {
+ phase->num_proj++;
+ return;
+ }
+ else if (is_Phi(irn)) {
+ phase->num_phi++;
+ return;
+ }
+ else if (mode_is_datab(mode) || ((mode == mode_T) && ! is_be_node(irn)) || (is_Proj(irn) && (mode == mode_X)))
+ phase->num_data++;
+
+ if (opc == iro_Load)
+ phase->num_load++;
+ else if (opc == iro_Store)
+ phase->num_store++;
+
+ irn_class = arch_irn_classify(phase->arch_env, irn);
+ if (irn_class & arch_irn_class_spill)
+ phase->num_spill++;
+ else if (irn_class & arch_irn_class_reload)
+ phase->num_reload++;
+ else if (irn_class & arch_irn_class_stackparam)
+ phase->num_load++;
+ else if (irn_class & arch_irn_class_load)
+ phase->num_load++;
+ else if (irn_class & arch_irn_class_store)
+ phase->num_store++;
+}
+
+/**
+ * Collects node statistics.
+ *
+ * @param irg the to do statistics for
+ * @param phase the phase to collect the statistic for
+ */
+void be_do_stat_nodes(ir_graph *irg, const char *phase) {
+ be_stat_irg_t *irg_entry;
+ be_stat_phase_t *phase_entry, phase_key;