X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Ftailrec.c;h=57a28f40a5be85e43d79347bc35922d6677de32c;hb=9146b50286358b71f99756e570baf3884709e7ef;hp=bf9e48f1913b247536c31f27defcbe395601e3ae;hpb=dddcc630819f338c3b45e2bc646233e6872d5bb6;p=libfirm diff --git a/ir/opt/tailrec.c b/ir/opt/tailrec.c index bf9e48f19..57a28f40a 100644 --- a/ir/opt/tailrec.c +++ b/ir/opt/tailrec.c @@ -24,9 +24,10 @@ #include "irgraph_t.h" #include "ircons.h" #include "irflag.h" -#include "tv.h" #include "firmstat.h" +static int n_opt_applications = 0; + /** * the environment for colelcting data */ @@ -190,6 +191,8 @@ static void do_opt_tail_rec(ir_graph *irg, ir_node *rets, int n_tail_calls) in[i] = get_Call_mem(calls); ++i; } + assert(i == n_tail_calls + 1); + phis[0] = new_rd_Phi(NULL, irg, block, n_tail_calls + 1, in, mode_M); /* build the data phi's */ @@ -252,8 +255,7 @@ void opt_tail_rec_irg(ir_graph *irg) n_preds = get_Block_n_cfgpreds(end_block); for (i = 0; i < n_preds; ++i) { ir_node *ret = get_Block_cfgpred(end_block, i); - ir_node *proj_m, *call, *call_ptr; - tarval *tv; + ir_node *call, *call_ptr; entity *ent; int j, n_ress; ir_node **ress; @@ -263,12 +265,7 @@ void opt_tail_rec_irg(ir_graph *irg) continue; /* check, if it's a Return self() */ - proj_m = get_Return_mem(ret); - - if (get_irn_op(proj_m) != op_Proj) - continue; - - call = get_Proj_pred(proj_m); + call = skip_Proj(get_Return_mem(ret)); if (get_irn_op(call) != op_Call) continue; @@ -278,6 +275,9 @@ void opt_tail_rec_irg(ir_graph *irg) if (get_irn_op(call_ptr) != op_SymConst) continue; + if (get_SymConst_kind(call_ptr) != symconst_addr_ent) + continue; + ent = get_SymConst_entity(call_ptr); if (!ent || get_entity_irg(ent) != irg) continue; @@ -287,23 +287,7 @@ void opt_tail_rec_irg(ir_graph *irg) ress = get_Return_res_arr(ret); for (j = 0; j < n_ress; ++j) { - ir_node *proj = ress[j]; - ir_node *proj_proj; - ir_node *irn; - - if (get_irn_op(proj) != op_Proj) { - /* not routed to a call */ - break; - } - - proj_proj = get_Proj_pred(proj); - - if (get_irn_op(proj) != op_Proj) { - /* not routed to a call */ - break; - } - - irn = get_Proj_pred(proj_proj); + ir_node *irn = skip_Proj(skip_Proj(ress[j])); if (irn != call) { /* not routed to a call */ @@ -327,6 +311,11 @@ void opt_tail_rec_irg(ir_graph *irg) if (! n_tail_calls) return; + 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); + n_opt_applications++; + do_opt_tail_rec(irg, rets, n_tail_calls); } @@ -340,9 +329,14 @@ void opt_tail_recursion(void) if (! get_opt_tail_recursion() || ! get_opt_optimize()) return; + n_opt_applications = 0; + for (i = 0; i < get_irp_n_irgs(); i++) { current_ir_graph = get_irp_irg(i); opt_tail_rec_irg(current_ir_graph); } + + if (get_opt_tail_recursion_verbose()) + printf("Performed tail recursion for %d of %d graphs\n", n_opt_applications, get_irp_n_irgs()); }