fix mode of call-result proj
[libfirm] / ir / opt / tailrec.c
index 230dd6b..3712193 100644 (file)
@@ -151,16 +151,10 @@ static void do_opt_tail_rec(ir_graph *irg, tr_env *env)
 
        assert(env->n_tail_calls > 0);
 
-       /* we add new nodes, so the outs are inconsistent */
-       set_irg_outs_inconsistent(irg);
-
        /* we add new blocks and change the control flow */
        set_irg_doms_inconsistent(irg);
        set_irg_extblk_inconsistent(irg);
 
-       /* we add a new loop */
-       set_irg_loopinfo_inconsistent(irg);
-
        /* calls are removed */
        set_trouts_inconsistent();
 
@@ -234,7 +228,6 @@ static void do_opt_tail_rec(ir_graph *irg, tr_env *env)
        if (n_params > 0) {
                ir_node *calls;
                ir_node *args;
-               ir_node *args_bl;
 
                NEW_ARR_A(ir_node **, call_params, env->n_tail_calls);
 
@@ -247,7 +240,6 @@ static void do_opt_tail_rec(ir_graph *irg, tr_env *env)
 
                /* build new Proj's and Phi's */
                args    = get_irg_args(irg);
-               args_bl = get_nodes_block(args);
                for (i = 0; i < n_params; ++i) {
                        ir_mode *mode = get_type_mode(get_method_param_type(method_tp, i));
 
@@ -274,7 +266,6 @@ static void do_opt_tail_rec(ir_graph *irg, tr_env *env)
 
        /* tail recursion was done, all info is invalid */
        set_irg_doms_inconsistent(irg);
-       set_irg_outs_inconsistent(irg);
        set_irg_extblk_inconsistent(irg);
        set_irg_loopinfo_state(irg, loopinfo_cf_inconsistent);
        set_trouts_inconsistent();
@@ -292,7 +283,7 @@ static void do_opt_tail_rec(ir_graph *irg, tr_env *env)
        }
 
        if (n_locs > 0) {
-               ir_node *bad, *start_block;
+               ir_node *start_block;
                ir_node **in;
                ir_mode **modes;
 
@@ -318,8 +309,6 @@ static void do_opt_tail_rec(ir_graph *irg, tr_env *env)
                mature_immBlock(start_block);
 
                /* no: we can kill all returns */
-               bad = get_irg_bad(irg);
-
                for (p = env->rets; p; p = n) {
                        ir_node *block = get_nodes_block(p);
                        ir_node *call, *mem, *jmp, *tuple;
@@ -338,20 +327,21 @@ static void do_opt_tail_rec(ir_graph *irg, tr_env *env)
                        set_optimize(rem);
 
                        for (i = 0; i < env->n_ress; ++i) {
+                               ir_mode *mode = modes[i];
                                if (env->variants[i] != TR_DIRECT) {
-                                       in[i] = get_r_value(irg, i, modes[i]);
+                                       in[i] = get_r_value(irg, i, mode);
                                } else {
-                                       in[i] = bad;
+                                       in[i] = new_r_Bad(irg, mode);
                                }
                        }
                        /* create a new tuple for the return values */
                        tuple = new_r_Tuple(block, env->n_ress, in);
 
-                       turn_into_tuple(call, pn_Call_max);
-                       set_Tuple_pred(call, pn_Call_M,                mem);
-                       set_Tuple_pred(call, pn_Call_X_regular,        jmp);
-                       set_Tuple_pred(call, pn_Call_X_except,         bad);
-                       set_Tuple_pred(call, pn_Call_T_result,         tuple);
+                       turn_into_tuple(call, pn_Call_max+1);
+                       set_Tuple_pred(call, pn_Call_M,         mem);
+                       set_Tuple_pred(call, pn_Call_X_regular, jmp);
+                       set_Tuple_pred(call, pn_Call_X_except,  new_r_Bad(irg, mode_X));
+                       set_Tuple_pred(call, pn_Call_T_result,  tuple);
 
                        for (i = 0; i < env->n_ress; ++i) {
                                ir_node *res = get_Return_res(p, i);
@@ -360,7 +350,7 @@ static void do_opt_tail_rec(ir_graph *irg, tr_env *env)
                                }
                        }
 
-                       exchange(p, bad);
+                       exchange(p, new_r_Bad(irg, mode_X));
                }
 
                /* finally fix all other returns */
@@ -402,7 +392,7 @@ static void do_opt_tail_rec(ir_graph *irg, tr_env *env)
                }
                ssa_cons_finish(irg);
        } else {
-               ir_node *bad = get_irg_bad(irg);
+               ir_node *bad = new_r_Bad(irg, mode_X);
 
                /* no: we can kill all returns */
                for (p = env->rets; p; p = n) {