X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbetranshlp.c;h=9a723544fc125d3c11e9fb19cdf8726203748143;hb=a1e9069afa4fa1e16e2d176bcd7905d6a1ed4677;hp=3d423de40245fa366a9e545f3638b72a316861d4;hpb=8183865ab718e14484641b6a2c7e2c87fbfe1d29;p=libfirm diff --git a/ir/be/betranshlp.c b/ir/be/betranshlp.c index 3d423de40..9a723544f 100644 --- a/ir/be/betranshlp.c +++ b/ir/be/betranshlp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2010 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -160,8 +160,9 @@ ir_node *be_duplicate_node(ir_node *node) ir_node *be_transform_node(ir_node *node) { - ir_op *op; - ir_node *new_node = be_get_transformed_node(node); + ir_op *op; + ir_node *new_node = be_get_transformed_node(node); + be_transform_func *transform; if (new_node != NULL) return new_node; @@ -172,7 +173,7 @@ ir_node *be_transform_node(ir_node *node) if (op->ops.generic == NULL) { panic("No transform function registered for node %+F.", node); } - be_transform_func *transform = (be_transform_func *)op->ops.generic; + transform = (be_transform_func *)op->ops.generic; new_node = transform(node); assert(new_node != NULL); @@ -255,7 +256,7 @@ static void fix_loops(ir_node *node) } if (changed) { - identify_remember(current_ir_graph->value_table, node); + identify_remember(node); } } @@ -360,7 +361,6 @@ static void transform_nodes(ir_graph *irg, arch_pretrans_nodes *pre_transform) fix_loops(anchor); set_irn_n(new_anchor, i, anchor); } - set_nodes_block(new_anchor, get_irg_anchor(irg, anchor_end_block)); del_waitq(env.worklist); free_End(old_end); @@ -374,7 +374,6 @@ static ir_node *gen_Block(ir_node *node) { ir_graph *irg = current_ir_graph; dbg_info *dbgi = get_irn_dbg_info(node); - ir_node *macroblock = get_Block_MacroBlock(node); ir_node *block; block = new_ir_node(dbgi, irg, NULL, get_irn_op(node), get_irn_mode(node), @@ -382,14 +381,6 @@ static ir_node *gen_Block(ir_node *node) copy_node_attr(irg, node, block); block->node_nr = node->node_nr; - if (node == macroblock) { - /* this node is a macroblock header */ - set_Block_MacroBlock(block, block); - } else { - macroblock = be_transform_node(macroblock); - set_Block_MacroBlock(block, macroblock); - } - /* put the preds in the worklist */ be_enqueue_preds(node); @@ -444,8 +435,7 @@ void be_transform_graph(ir_graph *irg, arch_pretrans_nodes *func) irg_invalidate_phases(irg); /* create new value table for CSE */ - del_identities(irg->value_table); - irg->value_table = new_identities(); + new_identities(irg); /* enter special helper */ op_Block->ops.generic = (op_func)gen_Block; @@ -477,3 +467,78 @@ void be_transform_graph(ir_graph *irg, arch_pretrans_nodes *func) edges_deactivate(irg); edges_activate(irg); } + +int be_mux_is_abs(ir_node *sel, ir_node *mux_true, ir_node *mux_false) +{ + ir_node *cmp_left; + ir_node *cmp_right; + ir_node *cmp; + ir_mode *mode; + pn_Cmp pnc; + + if (!is_Proj(sel)) + return 0; + cmp = get_Proj_pred(sel); + if (!is_Cmp(cmp)) + return 0; + + /** + * Note further that these optimization work even for floating point + * with NaN's because -NaN == NaN. + * However, if +0 and -0 is handled differently, we cannot use the Abs/-Abs + * transformations. + */ + mode = get_irn_mode(mux_true); + if (mode_honor_signed_zeros(mode)) + return 0; + + /* must be <, <=, >=, > */ + pnc = get_Proj_proj(sel); + switch (pnc) { + case pn_Cmp_Ge: + case pn_Cmp_Gt: + case pn_Cmp_Le: + case pn_Cmp_Lt: + case pn_Cmp_Uge: + case pn_Cmp_Ug: + case pn_Cmp_Ul: + case pn_Cmp_Ule: + break; + default: + return 0; + } + + if (!is_negated_value(mux_true, mux_false)) + return 0; + + /* must be x cmp 0 */ + cmp_right = get_Cmp_right(cmp); + if (!is_Const(cmp_right) || !is_Const_null(cmp_right)) + return 0; + + cmp_left = get_Cmp_left(cmp); + if (cmp_left == mux_false) { + if (pnc & pn_Cmp_Lt) { + return 1; + } else { + assert(pnc & pn_Cmp_Gt); + return -1; + } + } else if (cmp_left == mux_true) { + if (pnc & pn_Cmp_Lt) { + return -1; + } else { + assert(pnc & pn_Cmp_Gt); + return 1; + } + } + + return 0; +} + +ir_node *be_get_abs_op(ir_node *sel) +{ + ir_node *cmp = get_Proj_pred(sel); + ir_node *cmp_left = get_Cmp_left(cmp); + return cmp_left; +}