X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fconvopt.c;h=e3b0e2583e357a4d5af32510ffe54395ffb6c954;hb=b27ae245166bb695bc4e418ff416d91bc37d0f28;hp=4787c3f129a6410b32dc88d03eacae274d5a9534;hpb=cbe8608ae6f9a523d007919691104b444c92d004;p=libfirm diff --git a/ir/opt/convopt.c b/ir/opt/convopt.c index 4787c3f12..e3b0e2583 100644 --- a/ir/opt/convopt.c +++ b/ir/opt/convopt.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -77,7 +77,7 @@ static bool is_optimizable_node(const ir_node *node) } } -static tarval* conv_const_tv(const ir_node* cnst, ir_mode* dest_mode) +static ir_tarval* conv_const_tv(const ir_node* cnst, ir_mode* dest_mode) { return tarval_convert_to(get_Const_tarval(cnst), dest_mode); } @@ -93,8 +93,8 @@ static int is_downconv(ir_mode *src_mode, ir_mode *dest_mode) static int get_conv_costs(const ir_node *node, ir_mode *dest_mode) { ir_mode *mode = get_irn_mode(node); - size_t arity; - size_t i; + int arity; + int i; int costs; if (mode == dest_mode) @@ -120,8 +120,8 @@ static int get_conv_costs(const ir_node *node, ir_mode *dest_mode) /* Take the minimum of the conversion costs for Phi predecessors as only one * branch is actually executed at a time */ if (is_Phi(node)) { - size_t i; - size_t arity = get_Phi_n_preds(node); + int i; + int arity = get_Phi_n_preds(node); int costs; costs = get_conv_costs(get_Phi_pred(node, 0), dest_mode); @@ -173,20 +173,24 @@ static ir_node *place_conv(ir_node *node, ir_mode *dest_mode) static ir_node *conv_transform(ir_node *node, ir_mode *dest_mode) { - ir_mode *mode = get_irn_mode(node); - size_t arity; - size_t i; + ir_mode *mode = get_irn_mode(node); + ir_graph *irg = get_irn_irg(node); + int arity; + int conv_arity; + int i; + ir_node *new_node; + ir_node **ins; if (mode == dest_mode) return node; if (is_Const(node)) { /* TODO tarval module is incomplete and can't convert floats to ints */ - tarval *tv = conv_const_tv(node, dest_mode); + ir_tarval *tv = conv_const_tv(node, dest_mode); if (tv == tarval_bad) { return place_conv(node, dest_mode); } else { - return new_Const(tv); + return new_r_Const(irg, tv); } } @@ -218,9 +222,13 @@ static ir_node *conv_transform(ir_node *node, ir_mode *dest_mode) return place_conv(node, dest_mode); } + // We want to create a new node with the right mode + arity = get_irn_arity(node); + ins = ALLOCAN(ir_node *, arity); + // The shift count does not participate in the conv optimisation - arity = is_Shl(node) ? 1 : get_irn_arity(node); - for (i = 0; i < arity; i++) { + conv_arity = is_Shl(node) ? 1 : arity; + for (i = 0; i < conv_arity; i++) { ir_node *pred = get_irn_n(node, i); ir_node *transformed; if (get_conv_costs(pred, dest_mode) > 0) { @@ -228,24 +236,24 @@ static ir_node *conv_transform(ir_node *node, ir_mode *dest_mode) } else { transformed = conv_transform(pred, dest_mode); } - set_irn_n(node, i, transformed); + ins[i] = transformed; } - set_irn_mode(node, dest_mode); - return node; -} -/* TODO, backends (at least ia32) can't handle it at the moment, - and it's probably not more efficient on most archs */ -#if 0 -static void try_optimize_cmp(ir_node *node) -{ - ir_node *left = get_Cmp_left(node); - ir_node *right = get_Cmp_right(node); - ir_node *conv = NULL; + for (i = conv_arity; i < arity; i++) { + ins[i] = get_irn_n(node, i); + } + + new_node = new_ir_node(get_irn_dbg_info(node), + irg, + get_nodes_block(node), + get_irn_op(node), + dest_mode, + arity, + ins); + copy_node_attr(irg, node, new_node); - if (is_downconv + return new_node; } -#endif static void conv_opt_walker(ir_node *node, void *data) { @@ -254,14 +262,7 @@ static void conv_opt_walker(ir_node *node, void *data) ir_mode *pred_mode; ir_mode *mode; int costs; - bool *changed = data; - -#if 0 - if (is_Cmp(node)) { - try_optimize_cmp(node); - return; - } -#endif + bool *changed = (bool*)data; if (!is_Conv(node)) return; @@ -284,8 +285,10 @@ static void conv_opt_walker(ir_node *node, void *data) transformed = conv_transform(pred, mode); if (node != transformed) { + vrp_attr *vrp; + exchange(node, transformed); - vrp_attr *vrp = vrp_get_info(transformed); + vrp = vrp_get_info(transformed); if (vrp && vrp->valid) { vrp->range_type = VRP_VARYING; vrp->bits_set = tarval_convert_to(vrp->bits_set, mode); @@ -312,9 +315,6 @@ int conv_opt(ir_graph *irg) invalidate |= changed; } while (changed); - if (invalidate) { - set_irg_outs_inconsistent(irg); - } return invalidate; }