copy result mode on final transformations (lea->add and sub->neg-add)
[libfirm] / ir / be / belower.c
index 061df35..d520766 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "ircons.h"
 #include "debug.h"
+#include "irhooks.h"
 
 #include "bearch.h"
 #include "belower.h"
@@ -261,12 +262,14 @@ static perm_cycle_t *get_perm_cycle(perm_cycle_t *cycle, reg_pair_t *pairs, int
 static void lower_perm_node(ir_node *irn, void *walk_env) {
        const arch_register_class_t *reg_class;
        const arch_env_t            *arch_env;
-       lower_env_t     *env   = walk_env;
-       perm_stat_t    **pstat = env->pstat;
+       lower_env_t     *env         = walk_env;
+       perm_stat_t    **pstat       = env->pstat;
+       int              pstat_idx   = -1;
+       int              real_size   = 0;
+       int              n, i, pn, do_copy, j, n_ops;
        reg_pair_t      *pairs;
        const ir_edge_t *edge;
        perm_cycle_t    *cycle;
-       int              n, i, pn, do_copy, j, pstat_idx = -1;
        ir_node         *sched_point, *block, *in[2];
        ir_node         *arg1, *arg2, *res1, *res2;
        ir_node         *cpyxchg = NULL;
@@ -294,6 +297,8 @@ static void lower_perm_node(ir_node *irn, void *walk_env) {
        pairs     = alloca(n * sizeof(pairs[0]));
 
        if (env->do_stat) {
+               unsigned i;
+
                /* determine index in statistics */
                for (i = 0; i < env->pstat_n; i++) {
                        if (strcmp(pstat[i]->cls->name, reg_class->name) == 0) {
@@ -356,11 +361,14 @@ static void lower_perm_node(ir_node *irn, void *walk_env) {
        if (env->do_stat && get_n_checked_pairs(pairs, n) < n) {
                pstat[pstat_idx]->num_real_perms++;
                pstat[pstat_idx]->real_perm_size_ar[n - 1]++;
+               real_size = n - get_n_checked_pairs(pairs, n);
        }
 
+       hook_be_block_stat_perm(reg_class->name, reg_class->n_regs, irn, block, n, real_size);
+
        /* check for cycles and chains */
        while (get_n_checked_pairs(pairs, n) < n) {
-               i = 0;
+               i = n_ops = 0;
 
                /* go to the first not-checked pair */
                while (pairs[i].checked) i++;
@@ -404,7 +412,6 @@ static void lower_perm_node(ir_node *irn, void *walk_env) {
 
                        res1 = get_node_for_register(pairs, n, cycle->elems[i], 1);
                        res2 = get_node_for_register(pairs, n, cycle->elems[i + 1], 1);
-
                        /*
                                If we have a cycle and don't copy: we need to create exchange nodes
                                NOTE: An exchange node is a perm node with 2 INs and 2 OUTs
@@ -450,6 +457,7 @@ static void lower_perm_node(ir_node *irn, void *walk_env) {
                                        irn, res1, cycle->elems[i]->name, res2, cycle->elems[i + 1]->name));
 
                                cpyxchg = be_new_Perm(reg_class, env->chord_env->irg, block, 2, in);
+                               n_ops++;
 
                                if (i > 0) {
                                        /* cycle is not done yet */
@@ -492,6 +500,7 @@ static void lower_perm_node(ir_node *irn, void *walk_env) {
 
                                cpyxchg = be_new_Copy(reg_class, env->chord_env->irg, block, arg1);
                                arch_set_irn_register(arch_env, cpyxchg, cycle->elems[i + 1]);
+                               n_ops++;
 
                                /* remove the proj from the schedule */
                                sched_remove(res2);
@@ -507,10 +516,17 @@ static void lower_perm_node(ir_node *irn, void *walk_env) {
                        }
                }
 
+               if (env->do_stat) {
+                       hook_be_block_stat_permcycle(reg_class->name, irn, block, \
+                               cycle->type == PERM_CHAIN, cycle->n_elems, n_ops);
+               }
+
                free((void *) cycle->elems);
                free(cycle);
        }
 
+
+
        /* remove the perm from schedule */
        sched_remove(irn);
 }
@@ -668,7 +684,8 @@ static void lower_nodes_after_ra_walker(ir_node *irn, void *walk_env) {
 }
 
 static void lower_print_perm_stat(lower_env_t *env) {
-       int i, j, total_len_chain, total_len_cycle, total_size_perm, total_size_real_perm;
+       int j, total_len_chain, total_len_cycle, total_size_perm, total_size_real_perm;
+       unsigned i;
 
        printf("=== IRG: %s ===\n", get_entity_name(get_irg_entity(env->chord_env->irg)));
        for (i = 0; i < env->pstat_n; i++) {