X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fana%2Firconsconfirm.c;h=3830849499aea56f32f095133b18ba50a15a22ea;hb=a0f13e7f9dc221a7283bb6ea0fd7dd54239c1ddb;hp=0a9f2508a0bd1bbc51759b6ca8bc532a8d005642;hpb=9d61e03d333104a4f31b4ca66b424c98c1d31e26;p=libfirm diff --git a/ir/ana/irconsconfirm.c b/ir/ana/irconsconfirm.c index 0a9f2508a..383084949 100644 --- a/ir/ana/irconsconfirm.c +++ b/ir/ana/irconsconfirm.c @@ -23,6 +23,8 @@ #include "irgmod.h" #include "iropt_dbg.h" #include "iredges_t.h" +#include "irgwalk.h" +#include "irprintf.h" /** * Walker environment. @@ -38,7 +40,7 @@ typedef struct _env_t { * * @param block the block which is entered by the branch * @param irn the node expressing the switch value - * @param pnc the branch label + * @param nr the branch label * @param env statistical environment * * Branch labels are a simple case. We can replace the value @@ -50,6 +52,9 @@ static void handle_case(ir_node *block, ir_node *irn, long nr, env_t *env) const ir_edge_t *edge, *next; ir_node *c = NULL; + if (is_Bad(irn)) + return; + for (edge = get_irn_out_edge_first(irn); edge; edge = next) { ir_node *succ = get_edge_src_irn(edge); ir_node *blk = get_nodes_block(succ); @@ -66,14 +71,15 @@ static void handle_case(ir_node *block, ir_node *irn, long nr, env_t *env) if (! c) { ir_mode *mode = get_irn_mode(irn); - type *tp = get_irn_type(irn); + ir_type *tp = get_irn_type(irn); tarval *tv = new_tarval_from_long(nr, mode); c = new_r_Const_type(current_ir_graph, block, mode, tv, tp); } pos = get_edge_src_pos(edge); set_irn_n(succ, pos, c); - DBG_OPT_CONFIRM(irn, c); + DBG_OPT_CONFIRM_C(irn, c); +// ir_printf("1 Replacing input %d of node %n with %n\n", pos, succ, c); env->num_consts += 1; } @@ -92,14 +98,17 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env) { ir_node *left = get_Cmp_left(cmp); ir_node *right = get_Cmp_right(cmp); + ir_op *op; const ir_edge_t *edge, *next; - /* remove unordered if it's an integer compare */ - if (mode_is_int(get_irn_mode(left))) - pnc &= ~pn_Cmp_Uo; + /* Beware of Bads */ + if (is_Bad(left) ||is_Bad(right)) + return; + + op = get_irn_op(left); - /* try to place the constant on the right side */ - if (get_irn_op(left) == op_Const) { + /* try to place the constant on the right side for a Confirm */ + if (op == op_Const || op == op_SymConst) { ir_node *t = left; left = right; @@ -110,7 +119,7 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env) /* * First case: both values are identical. - * replace the left one by the right one. + * replace the right one by the left one. */ if (pnc == pn_Cmp_Eq) { int pos; @@ -122,7 +131,7 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env) next = get_irn_out_edge_next(left, edge); if (block_dominates(block, blk)) { /* - * Ok, we found a user of left that is placed + * Ok, we found a user of right that is placed * in a block dominated by the branch block. * We can replace the input with right. */ @@ -130,6 +139,8 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env) set_irn_n(succ, pos, right); DBG_OPT_CONFIRM(left, right); +// ir_printf("2 Replacing input %d of node %n with %n\n", pos, succ, right); + env->num_eq += 1; } } @@ -145,17 +156,16 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env) next = get_irn_out_edge_next(left, edge); if (block_dominates(block, blk)) { /* - * Ok, we found a user of left that is placed + * Ok, we found a user of right that is placed * in a block dominated by the branch block. * We can replace the input with a Confirm(left, pnc, right). */ - if (! c) c = new_r_Confirm(current_ir_graph, block, left, right, pnc); pos = get_edge_src_pos(edge); set_irn_n(succ, pos, c); - DBG_OPT_CONFIRM(left, c); +// ir_printf("3 Replacing input %d of node %n with %n\n", pos, succ, c); env->num_confirms += 1; } @@ -205,8 +215,10 @@ static void insert_Confirm(ir_node *block, void *env) if (get_Proj_proj(proj) != pn_Cond_true) { /* it's the false branch */ - pnc = get_negated_pnc(pnc); + pnc = get_negated_pnc(pnc, mode); } +// ir_printf("At %n using %n Confirm %=\n", block, cmp, pnc); + handle_if(block, cmp, pnc, env); } else if (mode_is_int(mode)) { @@ -233,6 +245,9 @@ void construct_confirms(ir_graph *irg) compute_doms(irg); } + assert(get_irg_pinned(irg) == op_pin_state_pinned && + "Nodes must be placed to insert Confirms"); + if (! edges_active) { /* We need edges */ edges_activate(irg); @@ -253,9 +268,11 @@ void construct_confirms(ir_graph *irg) set_irg_loopinfo_inconsistent(irg); } - printf("No Confirms inserted : %u\n", env.num_confirms); - printf("No Const replacements: %u\n", env.num_consts); - printf("No node equalities : %u\n", env.num_eq); +#if 0 + printf("# Confirms inserted : %u\n", env.num_confirms); + printf("# Const replacements: %u\n", env.num_consts); + printf("# node equalities : %u\n", env.num_eq); +#endif /* deactivate edges if they where off */ if (! edges_active) @@ -263,11 +280,20 @@ void construct_confirms(ir_graph *irg) } /** - * Post-walker: Remove COnfirm nodes + * Post-walker: Remove Confirm nodes */ static void rem_Confirm(ir_node *n, void *env) { if (get_irn_op(n) == op_Confirm) { - exchange(n, get_Confirm_value(n)); + ir_node *value = get_Confirm_value(n); + if (value != n) + exchange(n, value); + else { + /* + * Strange: a Confirm is it's own bound. This can happen + * in dead blocks when Phi nodes are already removed. + */ + exchange(n, new_Bad()); + } } }