X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=ir%2Fopt%2Fopt_osr.c;h=fa320562a70d49dc5316142777c10919a96d961f;hb=8f530048146e640fdfeb16b8ebe8bc997a1c8abe;hp=a7701cd02962d06ccb22e2f4197f2684893a4e52;hpb=49703d116401e0ceb30dc364e24b5df262b43647;p=libfirm diff --git a/ir/opt/opt_osr.c b/ir/opt/opt_osr.c index a7701cd02..fa320562a 100644 --- a/ir/opt/opt_osr.c +++ b/ir/opt/opt_osr.c @@ -51,6 +51,7 @@ #include "array.h" #include "firmstat.h" #include "error.h" +#include "irpass_t.h" /** The debug handle. */ DEBUG_ONLY(static firm_dbg_module_t *dbg;) @@ -303,19 +304,18 @@ static ir_node *find_location(ir_node *block1, ir_node *block2) { * @return the newly created node */ static ir_node *do_apply(ir_opcode code, dbg_info *db, ir_node *op1, ir_node *op2, ir_mode *mode) { - ir_graph *irg = current_ir_graph; ir_node *result; ir_node *block = find_location(get_nodes_block(op1), get_nodes_block(op2)); switch (code) { case iro_Mul: - result = new_rd_Mul(db, irg, block, op1, op2, mode); + result = new_rd_Mul(db, block, op1, op2, mode); break; case iro_Add: - result = new_rd_Add(db, irg, block, op1, op2, mode); + result = new_rd_Add(db, block, op1, op2, mode); break; case iro_Sub: - result = new_rd_Sub(db, irg, block, op1, op2, mode); + result = new_rd_Sub(db, block, op1, op2, mode); break; default: panic("Unsupported opcode"); @@ -1077,7 +1077,7 @@ static void assign_po(ir_node *block, void *ctx) { */ static ir_node *applyOneEdge(ir_node *iv, ir_node *rc, LFTR_edge *e, iv_env *env) { if (env->osr_flags & osr_flag_lftr_with_ov_check) { - tarval *tv_l, *tv_r, *tv, *tv_init, *tv_incr; + tarval *tv_l, *tv_r, *tv, *tv_init, *tv_incr, *tv_end; tarval_int_overflow_mode_t ovmode; scc *pscc; @@ -1136,15 +1136,15 @@ static ir_node *applyOneEdge(ir_node *iv, ir_node *rc, LFTR_edge *e, iv_env *env } if (pscc->code == iro_Add) { - tv = tarval_add(tv, tv_incr); + tv_end = tarval_add(tv, tv_incr); } else { assert(pscc->code == iro_Sub); - tv = tarval_sub(tv, tv_incr, NULL); + tv_end = tarval_sub(tv, tv_incr, NULL); } tarval_set_integer_overflow_mode(ovmode); - if (tv == tarval_bad || tv_init == tarval_bad) { + if (tv == tarval_bad || tv_init == tarval_bad || tv_end == tarval_bad) { DB((dbg, LEVEL_4, " = OVERFLOW")); return NULL; } @@ -1321,6 +1321,11 @@ void remove_phi_cycles(ir_graph *irg) { current_ir_graph = rem; } /* remove_phi_cycles */ +ir_graph_pass_t *remove_phi_cycles_pass(const char *name, int verify, int dump) +{ + return def_graph_pass(name ? name : "remove_phi_cycles", verify, dump, remove_phi_cycles); +} /* remove_phi_cycles_pass */ + /** * Post-walker: fix Add and Sub nodes that where results of I<->P conversions. */ @@ -1337,14 +1342,14 @@ static void fix_adds_and_subs(ir_node *irn, void *ctx) { if (get_irn_mode(pred) != mode) { ir_node *block = get_nodes_block(pred); - pred = new_r_Conv(current_ir_graph, block, pred, mode); + pred = new_r_Conv(block, pred, mode); set_Add_left(irn, pred); } pred = get_Add_right(irn); if (get_irn_mode(pred) != mode) { ir_node *block = get_nodes_block(pred); - pred = new_r_Conv(current_ir_graph, block, pred, mode); + pred = new_r_Conv(block, pred, mode); set_Add_right(irn, pred); } } @@ -1361,13 +1366,13 @@ static void fix_adds_and_subs(ir_node *irn, void *ctx) { if (l_mode != mode) { ir_node *block = get_nodes_block(left); - left = new_r_Conv(current_ir_graph, block, left, mode); + left = new_r_Conv(block, left, mode); set_Sub_left(irn, left); } if (r_mode != mode) { ir_node *block = get_nodes_block(right); - right = new_r_Conv(current_ir_graph, block, right, mode); + right = new_r_Conv(block, right, mode); set_Sub_right(irn, right); } } @@ -1435,7 +1440,7 @@ void opt_osr(ir_graph *irg, unsigned flags) { irg_walk_graph(irg, NULL, fix_adds_and_subs, &env); /* try linear function test replacements */ - //lftr(irg, &env); // currently buggy :-( + lftr(irg, &env); (void)lftr; set_irg_outs_inconsistent(irg); @@ -1453,3 +1458,35 @@ void opt_osr(ir_graph *irg, unsigned flags) { current_ir_graph = rem; } /* opt_osr */ + +struct pass_t { + ir_graph_pass_t pass; + unsigned flags; +}; + +/** +* Wrapper for running opt_osr() as an ir_graph pass. +*/ +static int pass_wrapper(ir_graph *irg, void *context) { + struct pass_t *pass = context; + opt_osr(irg, pass->flags); + return 0; +} /* pass_wrapper */ + +ir_graph_pass_t *opt_osr_pass(const char *name, int verify, int dump, unsigned flags) +{ + struct pass_t *pass = xmalloc(sizeof(*pass)); + + pass->pass.kind = k_ir_prog_pass; + pass->pass.run_on_irg = pass_wrapper; + pass->pass.context = pass; + pass->pass.name = name ? name : "osr"; + pass->pass.verify = verify != 0; + pass->pass.dump = dump != 0; + + pass->flags = flags; + + INIT_LIST_HEAD(&pass->pass.list); + + return &pass->pass; +} /* opt_osr_pass */