- further refactoring and finally eliminated the callback for get_out_reg_reqs
[libfirm] / ir / be / arm / arm_optimize.c
index 06f909c..5b5aa0c 100644 (file)
  * @author      Michael Beck
  * @version     $Id: $
  */
-#ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
 
 #include "irgmod.h"
 #include "ircons.h"
 #include "error.h"
 
-#include "benode_t.h"
+#include "benode.h"
 #include "bepeephole.h"
 #include "besched.h"
 
@@ -39,7 +37,6 @@
 #include "gen_arm_regalloc_if.h"
 #include "gen_arm_new_nodes.h"
 
-static const arch_env_t *arch_env;
 static arm_code_gen_t  *cg;
 
 /** Execute ARM ROL. */
@@ -105,77 +102,6 @@ unsigned int arm_decode_imm_w_shift(long imm_value) {
        return arm_rol(l & 0xFF, rol);
 }
 
-/**
- * Creates a Mov node.
- */
-static ir_node *create_mov_node(ir_node *sched_point, dbg_info *dbg, ir_node *block, long value) {
-       ir_graph *irg = current_ir_graph;
-       ir_node  *mov;
-
-       mov = new_rd_arm_Mov_i(dbg, irg, block, mode_Iu, value);
-       arch_set_irn_register(arch_env, mov, &arm_gp_regs[REG_R12]);
-       sched_add_before(sched_point, mov);
-       return mov;
-}
-
-/**
- * Creates a Mvn node.
- */
-static ir_node *create_mvn_node(ir_node *sched_point, dbg_info *dbg, ir_node *block, long value) {
-       ir_graph *irg = current_ir_graph;
-       ir_node  *mvn;
-
-       mvn = new_rd_arm_Mvn_i(dbg, irg, block, mode_Iu, value);
-       arch_set_irn_register(arch_env, mvn, &arm_gp_regs[REG_R12]);
-       sched_add_before(sched_point, mvn);
-       return mvn;
-}
-
-/**
- * Creates a possible DAG for an constant and schedule it before
- * the node sched_point.
- * The Dag deliveres it's result in register R12.
- */
-static ir_node *create_const_graph_value(ir_node *sched_point, unsigned int value) {
-       dbg_info *dbg;
-       ir_node  *block, *result;
-       arm_vals v, vn;
-       int      cnt;
-
-       arm_gen_vals_from_word(value, &v);
-       arm_gen_vals_from_word(~value, &vn);
-
-       dbg   = get_irn_dbg_info(sched_point);
-       block = get_nodes_block(sched_point);
-
-       if (vn.ops < v.ops) {
-               /* remove bits */
-               result = create_mvn_node(sched_point, dbg, block, arm_encode_imm_w_shift(vn.shifts[0], vn.values[0]));
-
-               for (cnt = 1; cnt < vn.ops; ++cnt) {
-                       long value = arm_encode_imm_w_shift(vn.shifts[cnt], vn.values[cnt]);
-                       ir_node *bic_i_node = new_rd_arm_Bic_i(dbg, current_ir_graph, block, result, mode_Iu, value);
-                       arch_set_irn_register(arch_env, bic_i_node, &arm_gp_regs[REG_R12]);
-                       sched_add_before(sched_point, bic_i_node);
-                       result = bic_i_node;
-               }
-       }
-       else {
-               /* add bits */
-               result = create_mov_node(sched_point,  dbg, block, arm_encode_imm_w_shift(v.shifts[0], v.values[0]));
-
-               for (cnt = 1; cnt < v.ops; ++cnt) {
-                       long value = arm_encode_imm_w_shift(v.shifts[cnt], v.values[cnt]);
-                       ir_node *orr_i_node = new_rd_arm_Or_i(dbg, current_ir_graph, block, result, mode_Iu, value);
-                       arch_set_irn_register(arch_env, orr_i_node, &arm_gp_regs[REG_R12]);
-                       sched_add_before(sched_point, orr_i_node);
-                       result = orr_i_node;
-               }
-       }
-       return result;
-}
-
-
 /**
  * Returns non.zero if the given offset can be directly encoded into an ARM instruction.
  */
@@ -188,13 +114,12 @@ static int allowed_arm_immediate(int offset, arm_vals *result) {
  * Fix an IncSP node if the offset gets too big
  */
 static void peephole_be_IncSP(ir_node *node) {
-       ir_graph *irg;
        ir_node  *block;
        int      offset, cnt, align, sign = 1;
        arm_vals v;
 
        /* first optimize incsp->incsp combinations */
-       be_peephole_IncSP_IncSP(node);
+       node = be_peephole_IncSP_IncSP(node);
 
        offset = be_get_IncSP_offset(node);
        /* can be transformed into Add OR Sub */
@@ -205,14 +130,13 @@ static void peephole_be_IncSP(ir_node *node) {
        if (allowed_arm_immediate(offset, &v))
                return;
 
-       be_set_IncSP_offset(node, (int)arm_encode_imm_w_shift(v.shifts[0], v.values[0]) * sign);
+       be_set_IncSP_offset(node, (int)arm_rol(v.values[0], v.shifts[0]) * sign);
 
-       irg   = current_ir_graph;
        block = get_nodes_block(node);
        align = be_get_IncSP_align(node);
        for (cnt = 1; cnt < v.ops; ++cnt) {
-               int value = (int)arm_encode_imm_w_shift(v.shifts[cnt], v.values[cnt]);
-               ir_node *next = be_new_IncSP(&arm_gp_regs[REG_SP], irg, block, node, value * sign, align);
+               int value = (int)arm_rol(v.values[cnt], v.shifts[cnt]);
+               ir_node *next = be_new_IncSP(&arm_gp_regs[REG_SP], block, node, value * sign, align);
                sched_add_after(node, next);
                node = next;
        }
@@ -223,20 +147,19 @@ static void peephole_be_IncSP(ir_node *node) {
  */
 static ir_node *gen_ptr_add(ir_node *node, ir_node *frame, arm_vals *v)
 {
-       ir_graph *irg   = current_ir_graph;
        dbg_info *dbg   = get_irn_dbg_info(node);
        ir_node  *block = get_nodes_block(node);
        int     cnt;
        ir_node *ptr;
 
-       ptr = new_rd_arm_Add_i(dbg, irg, block, frame, mode_Iu, arm_encode_imm_w_shift(v->shifts[0], v->values[0]));
-       arch_set_irn_register(arch_env, ptr, &arm_gp_regs[REG_R12]);
+       ptr = new_bd_arm_Add_i(dbg, block, frame, mode_Iu, arm_encode_imm_w_shift(v->shifts[0], v->values[0]));
+       arch_set_irn_register(ptr, &arm_gp_regs[REG_R12]);
        sched_add_before(node, ptr);
 
        for (cnt = 1; cnt < v->ops; ++cnt) {
                long value = arm_encode_imm_w_shift(v->shifts[cnt], v->values[cnt]);
-               ir_node *next = new_rd_arm_Add_i(dbg, irg, block, ptr, mode_Iu, value);
-               arch_set_irn_register(arch_env, next, &arm_gp_regs[REG_R12]);
+               ir_node *next = new_bd_arm_Add_i(dbg, block, ptr, mode_Iu, value);
+               arch_set_irn_register(next, &arm_gp_regs[REG_R12]);
                sched_add_before(node, next);
                ptr = next;
        }
@@ -248,20 +171,19 @@ static ir_node *gen_ptr_add(ir_node *node, ir_node *frame, arm_vals *v)
 */
 static ir_node *gen_ptr_sub(ir_node *node, ir_node *frame, arm_vals *v)
 {
-       ir_graph *irg   = current_ir_graph;
        dbg_info *dbg   = get_irn_dbg_info(node);
        ir_node  *block = get_nodes_block(node);
        int     cnt;
        ir_node *ptr;
 
-       ptr = new_rd_arm_Sub_i(dbg, irg, block, frame, mode_Iu, arm_encode_imm_w_shift(v->shifts[0], v->values[0]));
-       arch_set_irn_register(arch_env, ptr, &arm_gp_regs[REG_R12]);
+       ptr = new_bd_arm_Sub_i(dbg, block, frame, mode_Iu, arm_encode_imm_w_shift(v->shifts[0], v->values[0]));
+       arch_set_irn_register(ptr, &arm_gp_regs[REG_R12]);
        sched_add_before(node, ptr);
 
        for (cnt = 1; cnt < v->ops; ++cnt) {
                long value = arm_encode_imm_w_shift(v->shifts[cnt], v->values[cnt]);
-               ir_node *next = new_rd_arm_Sub_i(dbg, irg, block, ptr, mode_Iu, value);
-               arch_set_irn_register(arch_env, next, &arm_gp_regs[REG_R12]);
+               ir_node *next = new_bd_arm_Sub_i(dbg, block, ptr, mode_Iu, value);
+               arch_set_irn_register(next, &arm_gp_regs[REG_R12]);
                sched_add_before(node, next);
                ptr = next;
        }
@@ -303,23 +225,20 @@ static void peephole_be_Spill(ir_node *node) {
        if (mode_is_float(mode)) {
                if (USE_FPA(cg->isa)) {
                        /* transform into fpaStf */
-                       store = new_rd_arm_fpaStf(dbg, irg, block, ptr, value, get_irg_no_mem(irg), mode);
+                       store = new_bd_arm_fpaStf(dbg, block, ptr, value, get_irg_no_mem(irg), mode);
                        sched_add_before(node, store);
                } else {
                        panic("peephole_be_Spill: spill not supported for this mode");
                }
        } else if (mode_is_dataM(mode)) {
                 /* transform into Store */;
-                store = new_rd_arm_Store(dbg, irg, block, ptr, value, get_irg_no_mem(irg));
+                store = new_bd_arm_Store(dbg, block, ptr, value, get_irg_no_mem(irg));
                 sched_add_before(node, store);
        } else {
                panic("peephole_be_Spill: spill not supported for this mode");
        }
 
-       be_peephole_before_exchange(node, store);
-       sched_remove(node);
-       exchange(node, store);
-       be_peephole_after_exchange(store);
+       be_peephole_exchange(node, store);
 }
 
 /**
@@ -331,7 +250,6 @@ static void peephole_be_Reload(ir_node *node) {
        ir_node   *block, *ptr, *frame, *load, *mem, *proj;
        ir_mode   *mode;
        dbg_info  *dbg;
-       ir_graph  *irg;
        arm_vals  v;
        const arch_register_t *reg;
 
@@ -349,37 +267,33 @@ static void peephole_be_Reload(ir_node *node) {
                ptr = gen_ptr_sub(node, frame, &v);
        }
 
-       reg   = arch_get_irn_register(arch_env, node);
+       reg   = arch_get_irn_register(node);
        mem   = be_get_Reload_mem(node);
        mode  = get_irn_mode(node);
-       irg   = current_ir_graph;
        dbg   = get_irn_dbg_info(node);
        block = get_nodes_block(node);
 
        if (mode_is_float(mode)) {
                if (USE_FPA(cg->isa)) {
                        /* transform into fpaLdf */
-                       load = new_rd_arm_fpaLdf(dbg, irg, block, ptr, mem, mode);
+                       load = new_bd_arm_fpaLdf(dbg, block, ptr, mem, mode);
                        sched_add_before(node, load);
-                       proj = new_rd_Proj(dbg, irg, block, load, mode, pn_arm_fpaLdf_res);
-                       arch_set_irn_register(arch_env, proj, reg);
+                       proj = new_rd_Proj(dbg, block, load, mode, pn_arm_fpaLdf_res);
+                       arch_set_irn_register(proj, reg);
                } else {
                        panic("peephole_be_Spill: spill not supported for this mode");
                }
        } else if (mode_is_dataM(mode)) {
                /* transform into Store */;
-               load = new_rd_arm_Load(dbg, irg, block, ptr, mem);
+               load = new_bd_arm_Load(dbg, block, ptr, mem);
                sched_add_before(node, load);
-               proj = new_rd_Proj(dbg, irg, block, load, mode_Iu, pn_arm_Load_res);
-               arch_set_irn_register(arch_env, proj, reg);
+               proj = new_rd_Proj(dbg, block, load, mode_Iu, pn_arm_Load_res);
+               arch_set_irn_register(proj, reg);
        } else {
                panic("peephole_be_Spill: spill not supported for this mode");
        }
 
-       be_peephole_before_exchange(node, proj);
-       sched_remove(node);
-       exchange(node, proj);
-       be_peephole_after_exchange(proj);
+       be_peephole_exchange(node, proj);
 }
 
 /**
@@ -393,8 +307,7 @@ static void register_peephole_optimisation(ir_op *op, peephole_opt_func func) {
 /* Perform peephole-optimizations. */
 void arm_peephole_optimization(arm_code_gen_t *new_cg)
 {
-       cg       = new_cg;
-       arch_env = cg->arch_env;
+       cg = new_cg;
 
        /* register peephole optimizations */
        clear_irp_opcodes_generic_func();