X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Ftailrec.c;h=f9b6e1a29a9027a71e8ee657b427f4f4a565f81e;hb=ff0e8d7fcb34481652f0bf521ba04b1eca5e2106;hp=89e94ecf20d8d6f05b70f00fd97f6caca8fac5d3;hpb=b1eb4087b64d4d44d2c90f2bfef7dc90168db111;p=libfirm diff --git a/ir/opt/tailrec.c b/ir/opt/tailrec.c index 89e94ecf2..f9b6e1a29 100644 --- a/ir/opt/tailrec.c +++ b/ir/opt/tailrec.c @@ -47,7 +47,7 @@ typedef struct _collect_t { ir_node *proj_X; /**< initial exec proj */ ir_node *block; /**< old first block */ int blk_idx; /**< cfgpred index of the initial exec in block */ - ir_node *proj_m; /**< linked list of memory from start proj's */ + ir_node *proj_m; /**< memory from start proj's */ ir_node *proj_data; /**< linked list of all parameter access proj's */ } collect_t; @@ -70,25 +70,16 @@ static void collect_data(ir_node *node, void *env) if (get_irn_op(start) == op_Start) { if (get_Proj_proj(pred) == pn_Start_T_args) { - /* found Proj(ProjT(Start)) */ - set_irn_link(node, data->proj_data); - data->proj_data = node; + /* found Proj(ProjT(Start)) */ + set_irn_link(node, data->proj_data); + data->proj_data = node; } } } else if (op == op_Start) { - switch (get_Proj_proj(node)) { - case pn_Start_M: - /* found ProjM(Start) */ - set_irn_link(node, data->proj_m); - data->proj_m = node; - break; - case pn_Start_X_initial_exec: - /* found ProjX(Start) */ - data->proj_X = node; - break; - default: - break; + if (get_Proj_proj(node) == pn_Start_X_initial_exec) { + /* found ProjX(Start) */ + data->proj_X = node; } } break; @@ -98,12 +89,12 @@ static void collect_data(ir_node *node, void *env) /* * the first block has the initial exec as cfg predecessor */ - if (node != current_ir_graph->start_block) { + if (node != get_irg_start_block(current_ir_graph)) { for (i = 0; i < n_pred; ++i) { if (get_Block_cfgpred(node, i) == data->proj_X) { - data->block = node; - data->blk_idx = i; - break; + data->block = node; + data->blk_idx = i; + break; } } } @@ -128,7 +119,7 @@ static void do_opt_tail_rec(ir_graph *irg, ir_node *rets, int n_tail_calls) ir_node **in; ir_node **phis; ir_node ***call_params; - ir_node *p; + ir_node *p, *n; int i, j, n_params; collect_t data; int rem = get_optimize(); @@ -157,7 +148,7 @@ static void do_opt_tail_rec(ir_graph *irg, ir_node *rets, int n_tail_calls) data.proj_X = NULL; data.block = NULL; data.blk_idx = -1; - data.proj_m = NULL; + data.proj_m = get_irg_initial_mem(irg); data.proj_data = NULL; irg_walk_graph(irg, NULL, collect_data, &data); @@ -167,7 +158,7 @@ static void do_opt_tail_rec(ir_graph *irg, ir_node *rets, int n_tail_calls) assert(data.proj_X && "Could not find initial exec from Start"); assert(data.block && "Could not find first block"); - assert(data.proj_m && "Could not find ProjM(Start)"); + assert(data.proj_m && "Could not find initial memory"); assert((data.proj_data || n_params == 0) && "Could not find Proj(ProjT(Start)) of non-void function"); /* allocate in's for phi and block construction */ @@ -176,14 +167,13 @@ static void do_opt_tail_rec(ir_graph *irg, ir_node *rets, int n_tail_calls) in[0] = data.proj_X; /* turn Return's into Jmp's */ - for (i = 1, p = rets; p; p = get_irn_link(p)) { - ir_node *jmp; + for (i = 1, p = rets; p; p = n) { ir_node *block = get_nodes_block(p); - jmp = new_r_Jmp(irg, block); + n = get_irn_link(p); + in[i++] = new_r_Jmp(irg, block); exchange(p, new_r_Bad(irg)); - in[i++] = jmp; /* we might generate an endless loop, so add * the block to the keep-alive list */ @@ -203,6 +193,7 @@ static void do_opt_tail_rec(ir_graph *irg, ir_node *rets, int n_tail_calls) /* 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); + set_irg_initial_mem(irg, in[i]); ++i; for (calls = call; calls; calls = get_irn_link(calls)) { @@ -213,9 +204,11 @@ static void do_opt_tail_rec(ir_graph *irg, ir_node *rets, int n_tail_calls) phis[0] = new_r_Phi(irg, block, n_tail_calls + 1, in, mode_M); - /* build the data phi's */ + /* build the data Phi's */ if (n_params > 0) { ir_node *calls; + ir_node *args; + ir_node *args_bl; NEW_ARR_A(ir_node **, call_params, n_tail_calls); @@ -225,11 +218,13 @@ static void do_opt_tail_rec(ir_graph *irg, ir_node *rets, int n_tail_calls) ++i; } - /* build new projs and Phi's */ + /* 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)); - in[0] = new_r_Proj(irg, block, irg->args, mode, i); + in[0] = new_r_Proj(irg, args_bl, args, mode, i); for (j = 0; j < n_tail_calls; ++j) in[j + 1] = call_params[j][i]; @@ -241,13 +236,15 @@ static void do_opt_tail_rec(ir_graph *irg, ir_node *rets, int n_tail_calls) * ok, we are here, so we have build and collected all needed Phi's * now exchange all Projs into links to Phi */ - for (p = data.proj_m; p; p = get_irn_link(p)) { + for (p = data.proj_m; p; p = n) { + n = get_irn_link(p); exchange(p, phis[0]); } - for (p = data.proj_data; p; p = get_irn_link(p)) { + for (p = data.proj_data; p; p = n) { long proj = get_Proj_proj(p); assert(0 <= proj && proj < n_params); + n = get_irn_link(p); exchange(p, phis[proj + 1]); } @@ -348,8 +345,8 @@ int opt_tail_rec_irg(ir_graph *irg) ir_node *irn = skip_Proj(skip_Proj(ress[j])); if (irn != call) { - /* not routed to a call */ - break; + /* not routed to a call */ + break; } } if (j >= 0) @@ -392,7 +389,7 @@ int opt_tail_rec_irg(ir_graph *irg) if (get_opt_tail_recursion_verbose() && get_firm_verbosity() > 1) printf(" Performing tail recursion for graph %s and %d Calls\n", - get_entity_ld_name(get_irg_entity(irg)), n_tail_calls); + get_entity_ld_name(get_irg_entity(irg)), n_tail_calls); hook_tail_rec(irg, n_tail_calls); do_opt_tail_rec(irg, rets, n_tail_calls);