disable experimental code for now
[libfirm] / ir / be / beabi.c
index d515e3b..bb0af7b 100644 (file)
@@ -5,9 +5,8 @@
  * @date   7.3.2005
  * @cvsid  $Id$
  */
-
 #ifdef HAVE_CONFIG_H
-# include "config.h"
+# include <config.h>
 #endif
 
 #include "obst.h"
@@ -28,6 +27,7 @@
 #include "height.h"
 #include "pdeq.h"
 #include "irtools.h"
+#include "raw_bitset.h"
 
 #include "be.h"
 #include "beabi.h"
@@ -87,6 +87,9 @@ struct _be_abi_irg_t {
        pmap                 *keep_map;     /**< mapping blocks to keep nodes. */
        pset                 *ignore_regs;  /**< Additional registers which shall be ignored. */
 
+       arch_register_req_t sp_req;
+       arch_register_req_t sp_cls_req;
+
        arch_irn_handler_t irn_handler;
        arch_irn_ops_t     irn_ops;
        DEBUG_ONLY(firm_dbg_module_t    *dbg;)          /**< The debugging module. */
@@ -644,9 +647,6 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp, i
        */
        be_node_set_reg_class(low_call, be_pos_Call_ptr, call->cls_addr);
 
-       /* Set input requirement for stack pointer. */
-       be_node_set_reg_class(low_call, be_pos_Call_sp, arch_get_irn_reg_class(isa->main_env->arch_env, curr_sp, -1));
-
        DBG((env->dbg, LEVEL_3, "\tcreated backend call %+F\n", low_call));
 
        /* Set the register classes and constraints of the Call parameters. */
@@ -660,19 +660,23 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp, i
 
        /* Set the register constraints of the results. */
        for (i = 0; res_projs[i]; ++i) {
-               ir_node *irn = res_projs[i];
-               int     proj = get_Proj_proj(irn);
+               int pn = get_Proj_proj(res_projs[i]);
 
                /* Correct Proj number since it has been adjusted! (see above) */
-               const be_abi_call_arg_t *arg = get_call_arg(call, 1, proj - pn_Call_max);
+               const be_abi_call_arg_t *arg = get_call_arg(call, 1, pn - pn_Call_max);
 
+               /* Matze: we need the information about the real mode for later
+                * transforms (signed/unsigend compares, stores...), so leave the fixup
+                * for the backend transform phase... */
+#if 0
                /* correct mode */
                const arch_register_class_t *cls = arch_register_get_class(arg->reg);
                ir_mode *mode = arch_register_class_mode(cls);
                set_irn_mode(irn, mode);
+#endif
 
                assert(arg->in_reg);
-               be_set_constr_single_reg(low_call, BE_OUT_POS(proj), arg->reg);
+               be_set_constr_single_reg(low_call, BE_OUT_POS(pn), arg->reg);
        }
        obstack_free(obst, in);
        exchange(irn, low_call);
@@ -871,8 +875,9 @@ static ir_node *adjust_free(be_abi_irg_t *env, ir_node *free, ir_node *curr_sp)
 {
        ir_node *block;
        ir_graph *irg;
-       ir_node *addsp, *mem, *res, *size;
+       ir_node *subsp, *mem, *res, *size, *sync;
        ir_type *type;
+       ir_node *in[2];
 
        if (get_Free_where(free) != stack_alloc) {
                assert(0);
@@ -897,12 +902,21 @@ static ir_node *adjust_free(be_abi_irg_t *env, ir_node *free, ir_node *curr_sp)
        /* The stack pointer will be modified in an unknown manner.
           We cannot omit it. */
        env->call->flags.bits.try_omit_fp = 0;
-       addsp = be_new_SubSP(env->isa->sp, irg, block, curr_sp, size);
+       subsp = be_new_SubSP(env->isa->sp, irg, block, curr_sp, size);
 
-       mem = new_r_Proj(irg, block, addsp, mode_M, pn_be_SubSP_M);
-       res = new_r_Proj(irg, block, addsp, mode_P_data, pn_be_SubSP_res);
+       mem = new_r_Proj(irg, block, subsp, mode_M, pn_be_SubSP_M);
+       res = new_r_Proj(irg, block, subsp, mode_P_data, pn_be_SubSP_res);
 
-       exchange(free, mem);
+       /* we need to sync the memory */
+       in[0] = get_Free_mem(free);
+       in[1] = mem;
+       sync = new_r_Sync(irg, block, 2, in);
+
+       /* and make the AddSP dependent on the former memory */
+       add_irn_dep(subsp, get_Free_mem(free));
+
+       /* kill the free */
+       exchange(free, sync);
        curr_sp = res;
 
        return curr_sp;
@@ -947,12 +961,9 @@ static int check_dependence(ir_node *curr, ir_node *tgt, ir_node *bl)
  */
 static int dependent_on(ir_node *n1, ir_node *n2)
 {
-       ir_node *bl   = get_nodes_block(n1);
-
-       assert(bl == get_nodes_block(n2));
+       assert(get_nodes_block(n1) == get_nodes_block(n2));
 
        return heights_reachable_in_block(ir_heights, n1, n2);
-       //return check_dependence(n1, n2, bl);
 }
 
 static int cmp_call_dependecy(const void *c1, const void *c2)
@@ -1789,13 +1800,13 @@ static void modify_irg(be_abi_irg_t *env)
 
        /* do the stack allocation BEFORE the barrier, or spill code
           might be added before it */
-       env->init_sp  = be_abi_reg_map_get(env->regs, sp);
+       env->init_sp = be_abi_reg_map_get(env->regs, sp);
        env->init_sp = be_new_IncSP(sp, irg, bl, env->init_sp, BE_STACK_FRAME_SIZE_EXPAND);
        be_abi_reg_map_set(env->regs, sp, env->init_sp);
 
        env->start_barrier = barrier = create_barrier(env, bl, &mem, env->regs, 0);
 
-       env->init_sp  = be_abi_reg_map_get(env->regs, sp);
+       env->init_sp = be_abi_reg_map_get(env->regs, sp);
        arch_set_irn_register(env->birg->main_env->arch_env, env->init_sp, sp);
 
        frame_pointer = be_abi_reg_map_get(env->regs, fp_reg);
@@ -1877,6 +1888,7 @@ be_abi_irg_t *be_abi_introduce(be_irg_t *birg)
        pmap_entry *ent;
        ir_node *dummy;
        optimization_state_t state;
+       unsigned *limited_bitset;
 
        be_omit_fp = birg->main_env->options->omit_fp;
 
@@ -1892,6 +1904,16 @@ be_abi_irg_t *be_abi_introduce(be_irg_t *birg)
        env->dce_survivor     = new_survive_dce();
        env->birg             = birg;
        env->stack_phis       = pset_new_ptr(16);
+
+       env->sp_req.type      = arch_register_req_type_limited;
+       env->sp_req.cls       = arch_register_get_class(env->isa->sp);
+       limited_bitset        = rbitset_obstack_alloc(&env->obst, env->sp_req.cls->n_regs);
+       rbitset_set(limited_bitset, arch_register_get_index(env->isa->sp));
+       env->sp_req.limited   = limited_bitset;
+
+       env->sp_cls_req.type  = arch_register_req_type_normal;
+       env->sp_cls_req.cls   = arch_register_get_class(env->isa->sp);
+
        /* Beware: later we replace this node by the real one, ensure it is not CSE'd
           to another Unknown or the stack pointer gets used */
        save_optimization_state(&state);
@@ -1924,8 +1946,9 @@ be_abi_irg_t *be_abi_introduce(be_irg_t *birg)
 
        /* Make some important node pointers survive the dead node elimination. */
        survive_dce_register_irn(env->dce_survivor, &env->init_sp);
-       pmap_foreach(env->regs, ent)
+       pmap_foreach(env->regs, ent) {
                survive_dce_register_irn(env->dce_survivor, (ir_node **) &ent->value);
+       }
 
        arch_env_push_irn_handler(env->birg->main_env->arch_env, &env->irn_handler);
 
@@ -2138,33 +2161,19 @@ static const void *abi_get_irn_ops(const arch_irn_handler_t *handler, const ir_n
        return res;
 }
 
-static void be_abi_limited(void *data, bitset_t *bs)
+static
+const arch_register_req_t *abi_get_irn_reg_req(const void *self,
+                                               const ir_node *irn, int pos)
 {
-       be_abi_irg_t *abi = data;
-       bitset_clear_all(bs);
-       bitset_set(bs, abi->isa->sp->index);
-}
-
-static const arch_register_req_t *abi_get_irn_reg_req(const void *self, arch_register_req_t *req, const ir_node *irn, int pos)
-{
-       be_abi_irg_t *abi          = get_abi_from_ops(self);
-       const arch_register_t *reg = abi->isa->sp;
-
-       memset(req, 0, sizeof(req[0]));
+       be_abi_irg_t *abi = get_abi_from_ops(self);
 
        if(pos == BE_OUT_POS(0)) {
-               req->cls         = reg->reg_class;
-               req->type        = arch_register_req_type_limited;
-               req->limited     = be_abi_limited;
-               req->limited_env = abi;
-       }
-
-       else if(pos >= 0 && pos < get_irn_arity(irn)) {
-               req->cls  = reg->reg_class;
-               req->type = arch_register_req_type_normal;
+               return &abi->sp_req;
+       } else if(pos >= 0 && pos < get_irn_arity(irn)) {
+               return &abi->sp_cls_req;
        }
 
-       return req;
+       return arch_no_register_req;
 }
 
 static void abi_set_irn_reg(const void *self, ir_node *irn, const arch_register_t *reg)