extended node attribute initializer for execution unit parameter
[libfirm] / ir / be / beabi.c
index bc29eee..57f1674 100644 (file)
@@ -69,6 +69,8 @@ struct _be_abi_irg_t {
        ir_node              *init_sp;      /**< The node representing the stack pointer
                                                                             at the start of the function. */
 
+       ir_node              *start_barrier; /**< The barrier of the start block */
+
        ir_node              *reg_params;   /**< The reg params node. */
        pmap                 *regs;         /**< A map of all callee-save and ignore regs to
                                                                                        their Projs to the RegParams node. */
@@ -407,11 +409,12 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp, i
        for(i = 0; i < n_params; ++i) {
                be_abi_call_arg_t *arg = get_call_arg(call, 0, i);
                assert(arg);
-               if(arg->on_stack) {
-                       stack_size += arg->space_before;
-                       stack_size =  round_up2(stack_size, arg->alignment);
-                       stack_size += get_type_size_bytes(get_method_param_type(mt, i));
-                       stack_size += arg->space_after;
+               if (arg->on_stack) {
+                       int arg_size = get_type_size_bytes(get_method_param_type(mt, i));
+
+                       stack_size += round_up2(arg->space_before, arg->alignment);
+                       stack_size += round_up2(arg_size, arg->alignment);
+                       stack_size += round_up2(arg->space_after, arg->alignment);
                        obstack_int_grow(obst, i);
                        n_pos++;
                }
@@ -810,7 +813,6 @@ static ir_node *adjust_free(be_abi_irg_t *env, ir_node *free, ir_node *curr_sp)
                ir_node *bl        = get_nodes_block(free);
                ir_graph *irg      = get_irn_irg(bl);
                ir_node *addsp, *mem, *res;
-               dbg_info *db = get_irn_dbg_info(free);
 
                /* The stack pointer will be modified in an unknown manner.
                   We cannot omit it. */
@@ -1405,7 +1407,8 @@ static void lower_frame_sels_walker(ir_node *irn, void *data)
                        nw = be_new_FrameAddr(env->isa->sp->reg_class, irg, bl, frame, ent);
                        exchange(irn, nw);
 
-                       if (ptr == param_base) {
+                       /* check, if it's a param sel and if have not seen this entity immediatly before */
+                       if (ptr == param_base && ctx->value_param_list != ent) {
                                set_entity_link(ent, ctx->value_param_list);
                                ctx->value_param_list = ent;
                        }
@@ -1621,6 +1624,7 @@ static void modify_irg(be_abi_irg_t *env)
        pmap_insert(env->regs, (void *) isa->bp, NULL);
        reg_params_bl   = get_irg_start_block(irg);
        env->reg_params = be_new_RegParams(irg, reg_params_bl, pmap_count(env->regs));
+       add_irn_dep(env->reg_params, get_irg_start(irg));
 
        /*
         * make proj nodes for the callee save registers.
@@ -1673,7 +1677,7 @@ static void modify_irg(be_abi_irg_t *env)
        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);
 
-       barrier = create_barrier(env, bl, &mem, env->regs, 0);
+       env->start_barrier = barrier = create_barrier(env, bl, &mem, env->regs, 0);
 
        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);
@@ -1799,6 +1803,7 @@ be_abi_irg_t *be_abi_introduce(be_irg_t *birg)
        arch_env_push_irn_handler(env->birg->main_env->arch_env, &env->irn_handler);
 
        env->call->cb->done(env->cb);
+       env->cb = NULL;
        return env;
 }
 
@@ -1967,6 +1972,18 @@ ir_node *be_abi_get_callee_save_irn(be_abi_irg_t *abi, const arch_register_t *re
        return pmap_get(abi->regs, (void *) reg);
 }
 
+ir_node *be_abi_get_ignore_irn(be_abi_irg_t *abi, const arch_register_t *reg)
+{
+       assert(arch_register_type_is(reg, ignore));
+       assert(pmap_contains(abi->regs, (void *) reg));
+       return pmap_get(abi->regs, (void *) reg);
+}
+
+ir_node *be_abi_get_start_barrier(be_abi_irg_t *abi)
+{
+       return abi->start_barrier;
+}
+
 /*
   _____ _____  _   _   _    _                 _ _
  |_   _|  __ \| \ | | | |  | |               | | |
@@ -2079,3 +2096,11 @@ static const arch_irn_ops_if_t abi_irn_ops = {
 static const arch_irn_handler_t abi_irn_handler = {
        abi_get_irn_ops
 };
+
+/**
+ * Returns non-zero if the ABI has omitted the frame pointer in
+ * the current graph.
+ */
+int be_abi_omit_fp(const be_abi_irg_t *abi) {
+       return abi->call->flags.bits.try_omit_fp;
+}