X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fana%2Firconsconfirm.c;h=eb5a3542c3b12fd13b89e91458024d44ea5ba6fc;hb=aaab09380443d3ff37ffac05209ed2446afd1158;hp=8eb0d75824e5c97031544426620aca26e311ab0b;hpb=323a1c9bb3e6ca6b0197f6863679693f65590419;p=libfirm diff --git a/ir/ana/irconsconfirm.c b/ir/ana/irconsconfirm.c index 8eb0d7582..eb5a3542c 100644 --- a/ir/ana/irconsconfirm.c +++ b/ir/ana/irconsconfirm.c @@ -1,22 +1,33 @@ /* - * Project: libFIRM - * File name: ir/ana/irconsconfirm.c - * Purpose: Construction of Confirm nodes - * Author: Michael Beck - * Modified by: - * Created: 6.2005 - * CVS-ID: $Id$ - * Copyright: (C) 2002-2005 Universität Karlsruhe - * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. + * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved. + * + * This file is part of libFirm. + * + * This file may be distributed and/or modified under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation and appearing in the file LICENSE.GPL included in the + * packaging of this file. + * + * Licensees holding valid libFirm Professional Edition licenses may use + * this file in accordance with the libFirm Commercial License. + * Agreement provided with the Software. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. */ /** - * @file irconsconfirm.c - * - * Construction of Confirm nodes - * - * @author Michael Beck + * @file + * @brief Construction of Confirm nodes + * @author Michael Beck + * @date 6.2005 + * @version $Id$ */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include "irgraph_t.h" #include "irnode_t.h" #include "ircons_t.h" @@ -35,6 +46,24 @@ typedef struct _env_t { unsigned num_eq; /**< number of equalities placed */ } env_t; +/** + * Return the effective use block of a node and it's predecessor on + * position pos. + * + * @param node the node + * @param pos the position of the used input + * + * This handles correctly Phi nodes. + */ +static ir_node *get_effective_use_block(ir_node *node, int pos) +{ + /* the effective use of a Phi is in its predecessor block */ + if (is_Phi(node)) + return get_nodes_block(get_irn_n(node, pos)); + else + return get_nodes_block(node); +} + /** * Handle a CASE-branch. * @@ -48,7 +77,6 @@ typedef struct _env_t { */ static void handle_case(ir_node *block, ir_node *irn, long nr, env_t *env) { - int pos; const ir_edge_t *edge, *next; ir_node *c = NULL; @@ -57,7 +85,8 @@ static void handle_case(ir_node *block, ir_node *irn, long nr, env_t *env) 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); + int pos = get_edge_src_pos(edge); + ir_node *blk = get_effective_use_block(succ, pos); next = get_irn_out_edge_next(irn, edge); @@ -76,7 +105,6 @@ static void handle_case(ir_node *block, ir_node *irn, long nr, env_t *env) 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_C(irn, c); // ir_printf("1 Replacing input %d of node %n with %n\n", pos, succ, c); @@ -84,7 +112,7 @@ static void handle_case(ir_node *block, ir_node *irn, long nr, env_t *env) env->num_consts += 1; } } -} +} /* handle_case */ /** * Handle an IF-branch. @@ -124,23 +152,21 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env) /* * First case: both values are identical. - * replace the right one by the left one. + * replace the left one by the right (potentially const) one. */ if (pnc == pn_Cmp_Eq) { - int pos; - for (edge = get_irn_out_edge_first(left); edge; edge = next) { ir_node *succ = get_edge_src_irn(edge); - ir_node *blk = get_nodes_block(succ); + int pos = get_edge_src_pos(edge); + ir_node *blk = get_effective_use_block(succ, pos); next = get_irn_out_edge_next(left, edge); if (block_dominates(block, blk)) { /* - * Ok, we found a user of right that is placed - * in a block dominated by the branch block. + * Ok, we found a usage of left in a block + * dominated by the branch block. * We can replace the input with right. */ - pos = get_edge_src_pos(edge); set_irn_n(succ, pos, right); DBG_OPT_CONFIRM(left, right); @@ -150,19 +176,19 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env) } } } - else { /* not == cases */ - int pos; + else { /* not pn_Cmp_Eq cases */ ir_node *c = NULL; for (edge = get_irn_out_edge_first(left); edge; edge = next) { ir_node *succ = get_edge_src_irn(edge); - ir_node *blk = get_nodes_block(succ); + int pos = get_edge_src_pos(edge); + ir_node *blk = get_effective_use_block(succ, pos); next = get_irn_out_edge_next(left, edge); if (block_dominates(block, blk)) { /* - * Ok, we found a user of right that is placed - * in a block dominated by the branch block. + * Ok, we found a usage of left in a block + * dominated by the branch block. * We can replace the input with a Confirm(left, pnc, right). */ if (! c) @@ -176,7 +202,7 @@ static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env) } } } -} +} /* handle_if */ /** * Pre-walker: Called for every block to insert Confirm nodes @@ -188,7 +214,7 @@ static void insert_Confirm(ir_node *block, void *env) /* * we can only handle blocks with only ONE control flow - * predecessor + * predecessor yet. */ if (get_Block_n_cfgpreds(block) != 1) return; @@ -235,7 +261,7 @@ static void insert_Confirm(ir_node *block, void *env) handle_case(block, get_Cond_selector(cond), proj_nr, env); } -} +} /* insert_Confirm */ /* * Construct Confirm nodes @@ -280,7 +306,7 @@ void construct_confirms(ir_graph *irg) /* deactivate edges if they where off */ if (! edges_active) edges_deactivate(irg); -} +} /* construct_confirms */ /** * Post-walker: Remove Confirm nodes @@ -298,11 +324,11 @@ static void rem_Confirm(ir_node *n, void *env) { exchange(n, new_Bad()); } } -} +} /* rem_Confirm */ /* * Remove all Confirm nodes from a graph. */ void remove_confirms(ir_graph *irg) { irg_walk_graph(irg, NULL, rem_Confirm, NULL); -} +} /* remove_confirms */