X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fopt_osr.c;h=cdab2205802781dd15e7170d61f19e297a0abbb1;hb=8c9921a1fc166552f6e416434fd8394a4fc210a3;hp=1d3908409bd915e42235e077d493b1bc9963fda5;hpb=e88385016800d3c56c3fa09770e9f7995c42e106;p=libfirm diff --git a/ir/opt/opt_osr.c b/ir/opt/opt_osr.c index 1d3908409..cdab22058 100644 --- a/ir/opt/opt_osr.c +++ b/ir/opt/opt_osr.c @@ -22,7 +22,6 @@ * @brief Operator Strength Reduction. * @date 12.5.2006 * @author Michael Beck - * @version $Id$ * @brief * Implementation of the Operator Strength Reduction algorithm * by Keith D. Cooper, L. Taylor Simpson, Christopher A. Vick. @@ -46,6 +45,7 @@ #include "set.h" #include "tv.h" #include "hashptr.h" +#include "util.h" #include "irtools.h" #include "irloop_t.h" #include "array.h" @@ -608,13 +608,12 @@ static int is_counter_iv(ir_node *iv, iv_env *env) */ static int check_users_for_reg_pressure(ir_node *iv, iv_env *env) { - ir_node *irn, *header; + ir_node *irn; ir_node *have_user = NULL; ir_node *have_cmp = NULL; node_entry *e = get_irn_ne(iv, env); scc *pscc = e->pscc; - header = e->header; for (irn = pscc->head; irn != NULL; irn = e->next) { const ir_edge_t *edge; @@ -1156,6 +1155,12 @@ static ir_node *applyOneEdge(ir_node *iv, ir_node *rc, LFTR_edge *e, iv_env *env panic("Unsupported opcode"); } + if (tv == tarval_bad || tv_init == tarval_bad) { + tarval_set_integer_overflow_mode(ovmode); + DB((dbg, LEVEL_4, " = OVERFLOW")); + return NULL; + } + if (pscc->code == iro_Add) { tv_end = tarval_add(tv, tv_incr); } else { @@ -1165,7 +1170,7 @@ static ir_node *applyOneEdge(ir_node *iv, ir_node *rc, LFTR_edge *e, iv_env *env tarval_set_integer_overflow_mode(ovmode); - if (tv == tarval_bad || tv_init == tarval_bad || tv_end == tarval_bad) { + if (tv_end == tarval_bad) { DB((dbg, LEVEL_4, " = OVERFLOW")); return NULL; } @@ -1275,7 +1280,8 @@ static void lftr(ir_graph *irg, iv_env *env) */ static void clear_and_fix(ir_node *irn, void *env) { - int *moved = (int*)env; + (void)env; + set_irn_link(irn, NULL); if (is_Proj(irn)) { @@ -1284,7 +1290,6 @@ static void clear_and_fix(ir_node *irn, void *env) if (get_nodes_block(irn) != pred_block) { set_nodes_block(irn, pred_block); - *moved = 1; } } } /* clear_and_fix */ @@ -1294,7 +1299,6 @@ static void clear_and_fix(ir_node *irn, void *env) void remove_phi_cycles(ir_graph *irg) { iv_env env; - int projs_moved; FIRM_DBG_REGISTER(dbg, "firm.opt.remove_phi"); @@ -1317,10 +1321,7 @@ void remove_phi_cycles(ir_graph *irg) * the same block as their predecessors. * This can improve the placement of new nodes. */ - projs_moved = 0; - irg_walk_graph(irg, NULL, clear_and_fix, &projs_moved); - if (projs_moved) - set_irg_outs_inconsistent(irg); + irg_walk_graph(irg, NULL, clear_and_fix, NULL); /* we need outs for calculating the post order */ assure_irg_outs(irg); @@ -1334,7 +1335,6 @@ void remove_phi_cycles(ir_graph *irg) ir_free_resources(irg, IR_RESOURCE_IRN_LINK); if (env.replaced) { - set_irg_outs_inconsistent(irg); DB((dbg, LEVEL_1, "remove_phi_cycles: %u Cycles removed\n\n", env.replaced)); } @@ -1398,6 +1398,19 @@ static void fix_adds_and_subs(ir_node *irn, void *ctx) set_Sub_right(irn, right); } } + } else if (mode_is_reference(mode)) { + ir_node *left = get_Sub_left(irn); + ir_node *right = get_Sub_right(irn); + ir_mode *l_mode = get_irn_mode(left); + ir_mode *r_mode = get_irn_mode(right); + if (mode_is_int(l_mode)) { + /* Usually, Sub(I*,P) is an error, hence the verifier rejects it. + * However, it is correct in this case, so add Conv to make verifier happy. */ + ir_node *block = get_nodes_block(right); + ir_node *lconv = new_r_Conv(block, left, r_mode); + assert(mode_is_reference(r_mode)); + set_Sub_left(irn, lconv); + } } } } /* fix_adds_and_subs */ @@ -1407,7 +1420,6 @@ void opt_osr(ir_graph *irg, unsigned flags) { iv_env env; int edges; - int projs_moved; FIRM_DBG_REGISTER(dbg, "firm.opt.osr"); @@ -1427,13 +1439,10 @@ void opt_osr(ir_graph *irg, unsigned flags) env.process_scc = process_scc; /* Clear all links and move Proj nodes into the - the same block as it's predecessors. - This can improve the placement of new nodes. + * the same block as its predecessors. + * This can improve the placement of new nodes. */ - projs_moved = 0; - irg_walk_graph(irg, NULL, clear_and_fix, &projs_moved); - if (projs_moved) - set_irg_outs_inconsistent(irg); + irg_walk_graph(irg, NULL, clear_and_fix, NULL); /* we need dominance */ assure_doms(irg); @@ -1456,7 +1465,6 @@ void opt_osr(ir_graph *irg, unsigned flags) lftr(irg, &env); (void)lftr; - set_irg_outs_inconsistent(irg); DB((dbg, LEVEL_1, "Replacements: %u + %u (lftr)\n\n", env.replaced, env.lftr_replaced)); } ir_free_resources(irg, IR_RESOURCE_IRN_LINK);