fixed irg finishing
[libfirm] / ir / be / ia32 / bearch_ia32.c
index c0071c0..1aa1e76 100644 (file)
@@ -313,7 +313,7 @@ ia32_irn_ops_t ia32_irn_ops = {
 static void check_for_alloca(ir_node *irn, void *env) {
        int *has_alloca = env;
 
-       if (get_irn_opcode(irn) == iro_Alloc) {
+       if (get_irn_op(irn) == op_Alloc) {
                if (get_Alloc_where(irn) == stack_alloc) {
                        *has_alloca = 1;
                }
@@ -356,7 +356,7 @@ static void ia32_finish_irg(ir_graph *irg, ia32_code_gen_t *cg) {
        ir_node          **returns, **in, **new_in;
        ir_node           *stack_reserve, *sched_point;
        ir_node           *stack_free, *new_ret, *return_block;
-       int                stack_size = 0, i, n_res;
+       int                stack_size = 0, i, n_arg;
        arch_register_t   *stack_reg;
        tarval            *stack_size_tv;
        dbg_info          *frame_dbg;
@@ -372,18 +372,28 @@ static void ia32_finish_irg(ir_graph *irg, ia32_code_gen_t *cg) {
        /* If frame is used, then we need to reserve some stackspace. */
        if (get_irn_n_edges(frame) > 0) {
                /* The initial stack reservation. */
+               stack_size    = get_type_size_bytes(get_irg_frame_type(irg));
                frame_dbg     = get_irn_dbg_info(frame);
-               stack_reserve = new_rd_ia32_Sub_i(frame_dbg, irg, get_nodes_block(frame), frame, mode_Is);
+               stack_reserve = new_rd_ia32_Sub_i(frame_dbg, irg, get_nodes_block(frame), new_NoMem(), mode_Is);
                stack_size_tv = new_tarval_from_long(stack_size, mode_Is);
-               set_ia32_am_const(stack_reserve, stack_size_tv);
+               set_ia32_Immop_tarval(stack_reserve, stack_size_tv);
+
+               assert(stack_size && "bOrken stack layout");
+
+               /* reroute all edges from frame pointer to corrected frame pointer */
                edges_reroute(frame, stack_reserve, irg);
+               set_irn_n(stack_reserve, 0, frame);
+
+               /* schedule frame pointer */
+               if (! sched_is_scheduled(frame)) {
+                       sched_add_after(get_irg_start(irg), frame);
+               }
 
                /* set register */
                arch_set_irn_register(cg->arch_env, frame, stack_reg);
                arch_set_irn_register(cg->arch_env, stack_reserve, stack_reg);
 
                /* insert into schedule */
-               sched_add_after(get_irg_start(irg), frame);
                sched_add_after(frame, stack_reserve);
 
                /* Free stack for each Return node */
@@ -395,15 +405,15 @@ static void ia32_finish_irg(ir_graph *irg, ia32_code_gen_t *cg) {
 
                        /* free the stack */
                        stack_free = new_rd_ia32_Add_i(frame_dbg, irg, return_block, stack_reserve, mode_Is);
-                       set_ia32_am_const(stack_free, stack_size_tv);
+                       set_ia32_Immop_tarval(stack_free, stack_size_tv);
                        arch_set_irn_register(cg->arch_env, stack_free, stack_reg);
 
                        DBG((mod, LEVEL_1, "examining %+F, %+F created, block %+F", returns[i], stack_free, return_block));
 
                        /* get the old Return arguments */
-                       n_res  = get_Return_n_ress(returns[i]);
+                       n_arg  = get_Return_n_ress(returns[i]);
                        in     = get_Return_res_arr(returns[i]);
-                       new_in = malloc((n_res + 1) * sizeof(new_in[0]));
+                       new_in = xmalloc((n_arg + 2) * sizeof(new_in[0]));
 
                        if (!new_in) {
                                printf("\nMUAAAAHAHAHAHAHAHAHAH\n");
@@ -411,14 +421,22 @@ static void ia32_finish_irg(ir_graph *irg, ia32_code_gen_t *cg) {
                        }
 
                        /* copy the old to the new in's */
-                       memcpy(new_in, in, n_res * sizeof(in[0]));
-                       in[n_res] = stack_free;
+                       memcpy(new_in, in, n_arg * sizeof(in[0]));
+                       new_in[n_arg++] = stack_free;
+                       new_in[n_arg++] = get_Return_mem(returns[i]);
 
                        /* create the new return node */
-//                     edges_deactivate(irg);
-                       new_ret     = new_rd_ia32_Return(get_irn_dbg_info(returns[i]), irg, return_block, n_res + 1, new_in);
-//                     edges_activate(irg);
-                       sched_point = sched_prev(returns[i]);
+                       new_ret = new_rd_ia32_Return(get_irn_dbg_info(returns[i]), irg, return_block, n_arg, new_in);
+
+                       /* In case the return node is the only node in the block, */
+                       /* it is not scheduled, so we need this work-around.      */
+                       if (! sched_is_scheduled(returns[i])) {
+                               sched_point = return_block;
+                       }
+                       else {
+                               sched_point = sched_prev(returns[i]);
+                               sched_remove(returns[i]);
+                       }
 
                        /* exchange the old return with the new one */
                        exchange(returns[i], new_ret);
@@ -426,9 +444,8 @@ static void ia32_finish_irg(ir_graph *irg, ia32_code_gen_t *cg) {
                        DB((mod, LEVEL_1, " ... replaced with %+F\n", new_ret));
 
                        /* remove the old one from schedule and add the new nodes properly */
-                       sched_remove(returns[i]);
                        sched_add_after(sched_point, new_ret);
-                       sched_add_before(new_ret, stack_free);
+                       sched_add_after(sched_point, stack_free);
                }
        }
 }
@@ -532,7 +549,7 @@ static void ia32_codegen(void *self) {
 
        ia32_finish_irg(irg, cg);
        dump_ir_block_graph_sched(irg, "-finished");
-       ia32_gen_routine(out, irg, cg->arch_env);
+       ia32_gen_routine(out, irg, cg);
 
        cur_reg_set = NULL;
 
@@ -559,7 +576,7 @@ static const arch_code_generator_if_t ia32_code_gen_if = {
  */
 static void *ia32_cg_init(FILE *F, ir_graph *irg, const arch_env_t *arch_env) {
        ia32_isa_t      *isa = (ia32_isa_t *)arch_env->isa;
-       ia32_code_gen_t *cg  = malloc(sizeof(*cg));
+       ia32_code_gen_t *cg  = xmalloc(sizeof(*cg));
 
        cg->impl       = &ia32_code_gen_if;
        cg->irg        = irg;
@@ -599,7 +616,7 @@ static void *ia32_cg_init(FILE *F, ir_graph *irg, const arch_env_t *arch_env) {
  */
 static void *ia32_init(void) {
        static int inited = 0;
-       ia32_isa_t *isa   = malloc(sizeof(*isa));
+       ia32_isa_t *isa   = xmalloc(sizeof(*isa));
 
        isa->impl = &ia32_isa_if;