Add ALLOCAN() and ALLOCANZ().
[libfirm] / ir / be / ia32 / ia32_transform.c
index 3b07ee9..6fe28ab 100644 (file)
@@ -24,9 +24,7 @@
  * @author      Christian Wuerdig, Matthias Braun
  * @version     $Id$
  */
-#ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
 
 #include <limits.h>
 #include <stdbool.h>
@@ -498,7 +496,7 @@ static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
 
        /* construct load address */
        memset(addr, 0, sizeof(addr[0]));
-       ia32_create_address_mode(addr, ptr, /*force=*/0);
+       ia32_create_address_mode(addr, ptr, 0);
 
        noreg_gp    = ia32_new_NoReg_gp(env_cg);
        addr->base  = addr->base  ? be_transform_node(addr->base)  : noreg_gp;
@@ -506,7 +504,8 @@ static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
        addr->mem   = be_transform_node(mem);
 }
 
-static void build_address(ia32_address_mode_t *am, ir_node *node)
+static void build_address(ia32_address_mode_t *am, ir_node *node,
+                          ia32_create_am_flags_t flags)
 {
        ir_node        *noreg_gp = ia32_new_NoReg_gp(env_cg);
        ia32_address_t *addr     = &am->addr;
@@ -537,7 +536,7 @@ static void build_address(ia32_address_mode_t *am, ir_node *node)
        am->am_node  = node;
 
        /* construct load address */
-       ia32_create_address_mode(addr, ptr, /*force=*/0);
+       ia32_create_address_mode(addr, ptr, flags);
 
        addr->base  = addr->base  ? be_transform_node(addr->base)  : noreg_gp;
        addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
@@ -698,7 +697,7 @@ static void match_arguments(ia32_address_mode_t *am, ir_node *block,
        noreg_gp = ia32_new_NoReg_gp(env_cg);
        if (new_op2 == NULL &&
            use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
-               build_address(am, op2);
+               build_address(am, op2, 0);
                new_op1     = (op1 == NULL ? NULL : be_transform_node(op1));
                if (mode_is_float(mode)) {
                        new_op2 = ia32_new_NoReg_vfp(env_cg);
@@ -710,7 +709,7 @@ static void match_arguments(ia32_address_mode_t *am, ir_node *block,
                       use_am &&
                       ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
                ir_node *noreg;
-               build_address(am, op1);
+               build_address(am, op1, 0);
 
                if (mode_is_float(mode)) {
                        noreg = ia32_new_NoReg_vfp(env_cg);
@@ -1077,7 +1076,7 @@ static ir_node *gen_Add(ir_node *node)
         *   3. Otherwise -> Lea
         */
        memset(&addr, 0, sizeof(addr));
-       ia32_create_address_mode(&addr, node, /*force=*/1);
+       ia32_create_address_mode(&addr, node, ia32_create_am_force);
        add_immediate_op = NULL;
 
        dbgi      = get_irn_dbg_info(node);
@@ -1861,7 +1860,7 @@ static ir_node *gen_Load(ir_node *node)
 
        /* construct load address */
        memset(&addr, 0, sizeof(addr));
-       ia32_create_address_mode(&addr, ptr, /*force=*/0);
+       ia32_create_address_mode(&addr, ptr, 0);
        base  = addr.base;
        index = addr.index;
 
@@ -1944,25 +1943,10 @@ static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
                return 0;
        }
 
-       if (is_Sync(mem)) {
-               int i;
-
-               for (i = get_Sync_n_preds(mem) - 1; i >= 0; --i) {
-                       ir_node *const pred = get_Sync_pred(mem, i);
-
-                       if (is_Proj(pred) && get_Proj_pred(pred) == load)
-                               continue;
-
-                       if (get_nodes_block(pred) == block &&
-                           heights_reachable_in_block(heights, pred, load)) {
-                               return 0;
-                       }
-               }
-       } else {
-               /* Store should be attached to the load */
-               if (!is_Proj(mem) || get_Proj_pred(mem) != load)
-                       return 0;
-       }
+       if (prevents_AM(block, load, mem))
+               return 0;
+       /* Store should be attached to the load via mem */
+       assert(heights_reachable_in_block(heights, mem, load));
 
        return 1;
 }
@@ -1992,10 +1976,10 @@ static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
        commutative = (flags & match_commutative) != 0;
 
        if (use_dest_am(src_block, op1, mem, ptr, op2)) {
-               build_address(&am, op1);
+               build_address(&am, op1, ia32_create_am_double_use);
                new_op = create_immediate_or_transform(op2, 0);
        } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
-               build_address(&am, op2);
+               build_address(&am, op2, ia32_create_am_double_use);
                new_op = create_immediate_or_transform(op1, 0);
        } else {
                return NULL;
@@ -2044,12 +2028,12 @@ static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
        ir_node  *mem_proj;
        ia32_address_mode_t  am;
        ia32_address_t *addr = &am.addr;
-       memset(&am, 0, sizeof(am));
 
        if (!use_dest_am(src_block, op, mem, ptr, NULL))
                return NULL;
 
-       build_address(&am, op);
+       memset(&am, 0, sizeof(am));
+       build_address(&am, op, ia32_create_am_double_use);
 
        dbgi     = get_irn_dbg_info(node);
        block    = be_transform_node(src_block);
@@ -2155,14 +2139,14 @@ static ir_node *try_create_dest_am(ir_node *node)
        case iro_Add:
                op1      = get_Add_left(val);
                op2      = get_Add_right(val);
-               if (is_Const_1(op2)) {
-                       new_node = dest_am_unop(val, op1, mem, ptr, mode,
-                                               new_rd_ia32_IncMem);
-                       break;
-               } else if (is_Const_Minus_1(op2)) {
-                       new_node = dest_am_unop(val, op1, mem, ptr, mode,
-                                               new_rd_ia32_DecMem);
-                       break;
+               if (ia32_cg_config.use_incdec) {
+                       if (is_Const_1(op2)) {
+                               new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_IncMem);
+                               break;
+                       } else if (is_Const_Minus_1(op2)) {
+                               new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_DecMem);
+                               break;
+                       }
                }
                new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
                                         new_rd_ia32_AddMem, new_rd_ia32_AddMem8Bit,
@@ -2177,8 +2161,7 @@ static ir_node *try_create_dest_am(ir_node *node)
                }
                new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
                                         new_rd_ia32_SubMem, new_rd_ia32_SubMem8Bit,
-                                        match_dest_am | match_immediate |
-                                        match_immediate);
+                                        match_dest_am | match_immediate);
                break;
        case iro_And:
                op1      = get_And_left(val);
@@ -2281,7 +2264,8 @@ static int is_float_to_int_conv(const ir_node *node)
 }
 
 /**
- * Transform a Store(floatConst).
+ * Transform a Store(floatConst) into a sequence of
+ * integer stores.
  *
  * @return the created ia32 Store node
  */
@@ -2361,11 +2345,11 @@ static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node
        return new_node;
 }
 /**
- * Transforms a normal Store.
+ * Transforms a general (no special case) Store.
  *
  * @return the created ia32 Store node
  */
-static ir_node *gen_normal_Store(ir_node *node)
+static ir_node *gen_general_Store(ir_node *node)
 {
        ir_node  *val       = get_Store_value(node);
        ir_mode  *mode      = get_irn_mode(val);
@@ -2386,7 +2370,7 @@ static ir_node *gen_normal_Store(ir_node *node)
 
        /* construct store address */
        memset(&addr, 0, sizeof(addr));
-       ia32_create_address_mode(&addr, ptr, /*force=*/0);
+       ia32_create_address_mode(&addr, ptr, 0);
 
        if (addr.base == NULL) {
                addr.base = noreg;
@@ -2469,18 +2453,14 @@ static ir_node *gen_Store(ir_node *node)
        ir_mode  *mode = get_irn_mode(val);
 
        if (mode_is_float(mode) && is_Const(val)) {
-               int transform;
-
-               /* we are storing a floating point constant */
-               if (ia32_cg_config.use_sse2) {
-                       transform = !is_simple_sse_Const(val);
-               } else {
-                       transform = !is_simple_x87_Const(val);
-               }
-               if (transform)
-                       return gen_float_const_Store(node, val);
+               /* We can transform every floating const store
+                  into a sequence of integer stores.
+                  If the constant is already in a register,
+                  it would be better to use it, but we don't
+                  have this information here. */
+               return gen_float_const_Store(node, val);
        }
-       return gen_normal_Store(node);
+       return gen_general_Store(node);
 }
 
 /**
@@ -3524,7 +3504,7 @@ static ir_node *gen_be_Return(ir_node *node)
 
        /* create a new barrier */
        arity = get_irn_arity(barrier);
-       in = alloca(arity * sizeof(in[0]));
+       in    = ALLOCAN(ir_node*, arity);
        for (i = 0; i < arity; ++i) {
                ir_node *new_in;
 
@@ -4326,8 +4306,7 @@ static ir_node *gen_Proj_be_Call(ir_node *node)
        long      proj        = get_Proj_proj(node);
        ir_mode  *mode        = get_irn_mode(node);
        ir_node  *sse_load;
-       const arch_register_class_t *cls;
-       ir_node                     *res;
+       ir_node  *res;
 
        /* The following is kinda tricky: If we're using SSE, then we have to
         * move the result value of the call in floating point registers to an
@@ -4391,7 +4370,7 @@ static ir_node *gen_Proj_be_Call(ir_node *node)
 
        /* transform call modes */
        if (mode_is_data(mode)) {
-               cls  = arch_get_irn_reg_class(node, -1);
+               const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
                mode = cls->mode;
        }
 
@@ -4401,7 +4380,7 @@ static ir_node *gen_Proj_be_Call(ir_node *node)
        } else if (proj == pn_be_Call_M_regular) {
                proj = pn_ia32_Call_M;
        } else {
-               arch_register_req_t const *const req    = arch_get_register_req(node, BE_OUT_POS(proj));
+               arch_register_req_t const *const req    = arch_get_register_req_out(node);
                int                        const n_outs = get_ia32_n_res(new_call);
                int                              i;