X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fifconv.c;h=58f90348eee86b7c25089f824bd338e496a5c797;hb=2af743bb2ff323523cf6cf4f7dc593d4f7f95434;hp=07d2dcd7d6ffa12a8439f0e3eb2ef40a7309be67;hpb=78c21f853b6f687251810a6a007ef1f9678a2ab5;p=libfirm diff --git a/ir/opt/ifconv.c b/ir/opt/ifconv.c index 07d2dcd7d..58f90348e 100644 --- a/ir/opt/ifconv.c +++ b/ir/opt/ifconv.c @@ -42,6 +42,19 @@ DEBUG_ONLY(firm_dbg_module_t *dbg); +/** allow every Psi to be created. */ +static int default_allow_ifconv(ir_node *sel, ir_node* phi_list, int i, int j) +{ + return 1; +} + +/** + * Default options. + */ +static const opt_if_conv_info_t default_info = { + 0, /* doesn't matter for Psi */ + default_allow_ifconv +}; /** * Additional block info. @@ -238,6 +251,7 @@ static void if_conv_walker(ir_node* block, void* env) { int arity; int i; + opt_if_conv_info_t *opt_info = env; /* Bail out, if there are no Phis at all */ if (get_block_blockinfo(block)->phi == NULL) return; @@ -259,6 +273,7 @@ restart: cond = get_Proj_pred(projx0); if (get_irn_op(cond) != op_Cond) continue; + /* We only handle boolean decisions, no switches */ if (get_irn_mode(get_Cond_selector(cond)) != mode_b) continue; @@ -266,7 +281,7 @@ restart: ir_node* projx1; ir_node* conds[1]; ir_node* vals[2]; - ir_node* psi; + ir_node* psi = NULL; ir_node* psi_block; ir_node* phi; @@ -278,6 +293,9 @@ restart: if (projx1 == NULL) continue; + phi = get_block_blockinfo(block)->phi; + if (!opt_info->allow_ifconv(get_Cond_selector(cond), phi, i, j)) continue; + DB((dbg, LEVEL_1, "Found Cond %+F with proj %+F and %+F\n", cond, projx0, projx1 )); @@ -289,7 +307,6 @@ restart: conds[0] = get_Cond_selector(cond); psi_block = get_nodes_block(cond); - phi = get_block_blockinfo(block)->phi; do { ir_node* val_i = get_irn_n(phi, i); ir_node* val_j = get_irn_n(phi, j); @@ -309,12 +326,14 @@ restart: vals[0] = val_j; vals[1] = val_i; } + psi = new_r_Psi( current_ir_graph, psi_block, 1, conds, vals, get_irn_mode(phi) ); DB((dbg, LEVEL_2, "Generating %+F for %+F\n", psi, phi)); } + /* only exchange if we have a Psi */ if (arity == 2) { exchange(phi, psi); } else { @@ -604,10 +623,17 @@ static void optimise_psis(ir_node* node, void* env) void opt_if_conv(ir_graph *irg, const opt_if_conv_info_t *params) { struct obstack obst; + opt_if_conv_info_t p; - if (!get_opt_if_conversion()) + if (! get_opt_if_conversion()) return; + /* get the parameters */ + if (params) + memcpy(&p, params, sizeof(p)); + else + memcpy(&p, &default_info, sizeof(p)); + FIRM_DBG_REGISTER(dbg, "firm.opt.ifconv"); DB((dbg, LEVEL_1, "Running if-conversion on %+F\n", irg)); @@ -621,7 +647,7 @@ void opt_if_conv(ir_graph *irg, const opt_if_conv_info_t *params) obstack_init(&obst); irg_block_walk_graph(irg, init_block_link, NULL, &obst); irg_walk_graph(irg, collect_phis, NULL, NULL); - irg_block_walk_graph(irg, NULL, if_conv_walker, NULL); + irg_block_walk_graph(irg, NULL, if_conv_walker, &p); local_optimize_graph(irg);