#include "irouts.h"
#include "irhooks.h"
#include "ircons_t.h"
+#include "irpass.h"
DEBUG_ONLY(static firm_dbg_module_t *dbg);
ir_node *block = get_nodes_block(p);
n = get_irn_link(p);
- in[i++] = new_r_Jmp(irg, block);
+ in[i++] = new_r_Jmp(block);
// exchange(p, new_r_Bad(irg));
/* create a new block at start */
block = new_r_Block(irg, env->n_tail_calls + 1, in);
- jmp = new_r_Jmp(irg, block);
+ jmp = new_r_Jmp(block);
/* the old first block is now the second one */
set_Block_cfgpred(data.block, data.blk_idx, jmp);
/* build the memory phi */
i = 0;
- in[i] = new_r_Proj(irg, get_irg_start_block(irg), get_irg_start(irg), mode_M, pn_Start_M);
+ in[i] = new_r_Proj(get_irg_start_block(irg), get_irg_start(irg), mode_M, pn_Start_M);
set_irg_initial_mem(irg, in[i]);
++i;
}
assert(i == env->n_tail_calls + 1);
- phis[0] = new_r_Phi(irg, block, env->n_tail_calls + 1, in, mode_M);
+ phis[0] = new_r_Phi(block, env->n_tail_calls + 1, in, mode_M);
/* build the data Phi's */
if (n_params > 0) {
for (i = 0; i < n_params; ++i) {
ir_mode *mode = get_type_mode(get_method_param_type(method_tp, i));
- in[0] = new_r_Proj(irg, args_bl, args, mode, i);
+ in[0] = new_r_Proj(args_bl, args, mode, i);
for (j = 0; j < env->n_tail_calls; ++j)
in[j + 1] = call_params[j][i];
- phis[i + 1] = new_r_Phi(irg, block, env->n_tail_calls + 1, in, mode);
+ phis[i + 1] = new_r_Phi(block, env->n_tail_calls + 1, in, mode);
}
}
modes[i] = mode;
if (env->variants[i] == TR_ADD) {
- set_value(i, new_Const(mode, get_mode_null(mode)));
+ set_value(i, new_Const(get_mode_null(mode)));
} else if (env->variants[i] == TR_MUL) {
- set_value(i, new_Const(mode, get_mode_one(mode)));
+ set_value(i, new_Const(get_mode_one(mode)));
}
}
mature_immBlock(start_block);
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);
- set_Tuple_pred(call, pn_Call_M_except, mem);
set_Tuple_pred(call, pn_Call_P_value_res_base, bad);
for (i = 0; i < env->n_ress; ++i) {
* @return non-zero if it's ok to do tail recursion
*/
static int check_lifetime_of_locals(ir_graph *irg) {
- ir_node *irg_frame, *irg_val_param_base;
+ ir_node *irg_frame;
int i;
+ ir_type *frame_tp = get_irg_frame_type(irg);
irg_frame = get_irg_frame(irg);
for (i = get_irn_n_outs(irg_frame) - 1; i >= 0; --i) {
ir_node *succ = get_irn_out(irg_frame, i);
- if (is_Sel(succ) && is_address_taken(succ))
- return 0;
- }
-
- /* Check if we have compound arguments.
- For now, we cannot handle them, */
- irg_val_param_base = get_irg_value_param_base(irg);
- if (get_irn_n_outs(irg_val_param_base) > 0)
- return 0;
+ if (is_Sel(succ)) {
+ /* Check if we have compound arguments.
+ For now, we cannot handle them, */
+ if (get_entity_owner(get_Sel_entity(succ)) != frame_tp)
+ return 0;
+ if (is_address_taken(succ))
+ return 0;
+ }
+ }
return 1;
}
return n_tail_calls;
}
+ir_graph_pass_t *opt_tail_rec_irg_pass(const char *name)
+{
+ return def_graph_pass_ret(name ? name : "tailrec", opt_tail_rec_irg);
+}
+
/*
* optimize tail recursion away
*/
DB((dbg, LEVEL_1, "Performed tail recursion for %d of %d graphs\n",
n_opt_applications, get_irp_n_irgs()));
}
+
+ir_prog_pass_t *opt_tail_recursion_pass(const char *name)
+{
+ return def_prog_pass(name ? name : "tailrec", opt_tail_recursion);
+}