From a17babab0fc930abd3cd3fe516015bd64437435a Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Wed, 23 May 2007 13:15:57 +0000 Subject: [PATCH] - changed Phi0 attribute to be a struct - Phi0 attribute is only available onb Phi0 nodes This should now allow CSE on Phi nodes! [r14002] --- ir/ir/ircons.c | 21 ++++++++++----------- ir/ir/irnode.c | 29 +++++++++++++---------------- ir/ir/irnode_t.h | 19 ++++++++++++------- ir/ir/irop.c | 2 +- ir/ir/iropt.c | 27 ++++++++++++++++++++------- 5 files changed, 56 insertions(+), 42 deletions(-) diff --git a/ir/ir/ircons.c b/ir/ir/ircons.c index b30e1a28e..8c2fed5b9 100644 --- a/ir/ir/ircons.c +++ b/ir/ir/ircons.c @@ -250,7 +250,7 @@ new_bd_Phi(dbg_info *db, ir_node *block, int arity, ir_node **in, ir_mode *mode) break; } - if (!has_unknown) res = optimize_node (res); + if (!has_unknown) res = optimize_node(res); IRN_VRFY_IRG(res, irg); /* Memory Phis in endless loops must be kept alive. @@ -2056,8 +2056,7 @@ get_r_value_internal(ir_node *block, int pos, ir_mode *mode) /* Error Message */ printf("Error: no value set. Use of undefined variable. Initializing to zero.\n"); assert(mode->code >= irm_F && mode->code <= irm_P); - res = new_rd_Const(NULL, current_ir_graph, block, mode, - tarval_mode_null[mode->code]); + res = new_rd_Const(NULL, current_ir_graph, block, mode, tarval_mode_null[mode->code]); } /* The local valid value is available now. */ @@ -2251,11 +2250,11 @@ get_r_frag_value_internal(ir_node *block, ir_node *cfOp, int pos, ir_mode *mode) if (block->attr.block.matured) { int ins = get_irn_arity(block); ir_node **nin; - NEW_ARR_A (ir_node *, nin, ins); + NEW_ARR_A(ir_node *, nin, ins); res = phi_merge(block, pos, mode, nin, ins); } else { - res = new_rd_Phi0 (current_ir_graph, block, mode); - res->attr.phi0_pos = pos; + res = new_rd_Phi0(current_ir_graph, block, mode); + res->attr.phi0.pos = pos; res->link = block->link; block->link = res; } @@ -2462,8 +2461,8 @@ get_r_value_internal(ir_node *block, int pos, ir_mode *mode) { The Phi0 has to remember the pos of it's internal value. If the real Phi is computed, pos is used to update the array with the local values. */ - res = new_rd_Phi0 (current_ir_graph, block, mode); - res->attr.phi0_pos = pos; + res = new_rd_Phi0(current_ir_graph, block, mode); + res->attr.phi0.pos = pos; res->link = block->link; block->link = res; } @@ -2502,19 +2501,19 @@ mature_immBlock(ir_node *block) { assert (!get_Block_matured(block) && "Block already matured"); */ if (!get_Block_matured(block)) { - ins = ARR_LEN (block->in)-1; + ins = ARR_LEN(block->in)-1; /* Fix block parameters */ block->attr.block.backedge = new_backedge_arr(current_ir_graph->obst, ins); /* An array for building the Phi nodes. */ - NEW_ARR_A (ir_node *, nin, ins); + NEW_ARR_A(ir_node *, nin, ins); /* Traverse a chain of Phi nodes attached to this block and mature these, too. **/ for (n = block->link; n; n = next) { inc_irg_visited(current_ir_graph); next = n->link; - exchange(n, phi_merge (block, n->attr.phi0_pos, n->mode, nin, ins)); + exchange(n, phi_merge(block, n->attr.phi0.pos, n->mode, nin, ins)); } block->attr.block.matured = 1; diff --git a/ir/ir/irnode.c b/ir/ir/irnode.c index 3c542d9a7..72e2c6806 100644 --- a/ir/ir/irnode.c +++ b/ir/ir/irnode.c @@ -139,9 +139,9 @@ new_ir_node (dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mo int i; assert(irg && op && mode); - p = obstack_alloc (irg->obst, node_size); + p = obstack_alloc(irg->obst, node_size); memset(p, 0, node_size); - res = (ir_node *) (p + firm_add_node_size); + res = (ir_node *)(p + firm_add_node_size); res->kind = k_ir_node; res->op = op; @@ -152,10 +152,10 @@ new_ir_node (dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mo res->deps = NULL; if (arity < 0) { - res->in = NEW_ARR_F (ir_node *, 1); /* 1: space for block */ + res->in = NEW_ARR_F(ir_node *, 1); /* 1: space for block */ } else { - res->in = NEW_ARR_D (ir_node *, irg->obst, (arity+1)); - memcpy (&res->in[1], in, sizeof (ir_node *) * arity); + res->in = NEW_ARR_D(ir_node *, irg->obst, (arity+1)); + memcpy(&res->in[1], in, sizeof(ir_node *) * arity); } res->in[0] = block; @@ -166,10 +166,10 @@ new_ir_node (dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mo res->node_nr = get_irp_new_node_nr(); #endif - for(i = 0; i < EDGE_KIND_LAST; ++i) + for (i = 0; i < EDGE_KIND_LAST; ++i) INIT_LIST_HEAD(&res->edge_info[i].outs_head); - // don't put this into the for loop, arity is -1 for some nodes! + /* don't put this into the for loop, arity is -1 for some nodes! */ edges_notify_edge(res, -1, res->in[0], NULL, irg); for (i = 1; i <= arity; ++i) edges_notify_edge(res, i - 1, res->in[i], NULL, irg); @@ -382,11 +382,10 @@ int add_irn_dep(ir_node *node, ir_node *dep) return res; } -void add_irn_deps(ir_node *tgt, ir_node *src) -{ +void add_irn_deps(ir_node *tgt, ir_node *src) { int i, n; - for(i = 0, n = get_irn_deps(src); i < n; ++i) + for (i = 0, n = get_irn_deps(src); i < n; ++i) add_irn_dep(tgt, get_irn_dep(src, i)); } @@ -439,9 +438,7 @@ ir_opcode const char * get_irn_opname(const ir_node *node) { assert(node); - if ((get_irn_op((ir_node *)node) == op_Phi) && - (get_irg_phase_state(get_irn_irg((ir_node *)node)) == phase_building) && - (get_irn_arity((ir_node *)node) == 0)) return "Phi0"; + if (is_Phi0(node)) return "Phi0"; return get_id_str(node->op->name); } @@ -585,9 +582,9 @@ get_irn_sel_attr(ir_node *node) { } int -get_irn_phi_attr(ir_node *node) { - assert(node->op == op_Phi); - return node->attr.phi0_pos; +get_irn_phi0_attr(ir_node *node) { + assert(is_Phi0(node)); + return node->attr.phi0.pos; } block_attr diff --git a/ir/ir/irnode_t.h b/ir/ir/irnode_t.h index 7d72c62c0..a2d461ff9 100644 --- a/ir/ir/irnode_t.h +++ b/ir/ir/irnode_t.h @@ -169,6 +169,16 @@ typedef struct { ir_volatility volatility; /**< the volatility of a Store operation */ } store_attr; +typedef struct { + int pos; /**< For Phi. Used to remember the value defined by + this Phi node. Needed when the Phi is completed + to call get_r_internal_value to find the + predecessors. If this attribute is set, the Phi + node takes the role of the obsolete Phi0 node, + therefore the name. */ +} phi0_attr; + + typedef pn_Cmp confirm_attr; /**< Attribute to hold compare operation */ /** CopyB attribute. */ @@ -209,12 +219,7 @@ typedef union { cast_attr cast; /**< For Cast. */ load_attr load; /**< For Load. */ store_attr store; /**< For Store. */ - int phi0_pos; /**< For Phi. Used to remember the value defined by - this Phi node. Needed when the Phi is completed - to call get_r_internal_value to find the - predecessors. If this attribute is set, the Phi - node takes the role of the obsolete Phi0 node, - therefore the name. */ + phi0_attr phi0; /**< for Phi0 nodes. */ int *phi_backedge; /**< For Phi after construction. Field n set to true if pred n is backedge. @todo Ev. replace by bitfield! */ @@ -295,7 +300,7 @@ symconst_attr get_irn_symconst_attr (ir_node *node); ir_type *get_irn_call_attr (ir_node *node); ir_type *get_irn_funccall_attr (ir_node *node); sel_attr get_irn_sel_attr (ir_node *node); -int get_irn_phi_attr (ir_node *node); +int get_irn_phi0_attr (ir_node *node); block_attr get_irn_block_attr (ir_node *node); load_attr get_irn_load_attr (ir_node *node); store_attr get_irn_store_attr (ir_node *node); diff --git a/ir/ir/irop.c b/ir/ir/irop.c index 9502bd61b..1971fd382 100644 --- a/ir/ir/irop.c +++ b/ir/ir/irop.c @@ -298,7 +298,7 @@ init_op(void) op_Carry = new_ir_op(iro_Carry, "Carry", op_pin_state_floats, C, oparity_binary, 0, 0, NULL); op_Borrow = new_ir_op(iro_Borrow, "Borrow", op_pin_state_floats, N, oparity_binary, 0, 0, NULL); - op_Phi = new_ir_op(iro_Phi, "Phi", op_pin_state_pinned, N, oparity_variable, -1, sizeof(int), NULL); + op_Phi = new_ir_op(iro_Phi, "Phi", op_pin_state_pinned, N, oparity_variable, -1, sizeof(phi0_attr), NULL); op_Load = new_ir_op(iro_Load, "Load", op_pin_state_exc_pinned, F, oparity_any, -1, sizeof(load_attr), NULL); op_Store = new_ir_op(iro_Store, "Store", op_pin_state_exc_pinned, F, oparity_any, -1, sizeof(store_attr), NULL); diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index 093b1f3f4..38e5f087b 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -3172,17 +3172,24 @@ static ir_node *transform_node_Shl(ir_node *n) { * in keep alive list. We do not generate a new End node. */ static ir_node *transform_node_End(ir_node *n) { - int i, n_keepalives = get_End_n_keepalives(n); + int i, j, n_keepalives = get_End_n_keepalives(n); + ir_node **in; - for (i = 0; i < n_keepalives; ++i) { + NEW_ARR_A(ir_node *, in, n_keepalives); + + for (i = j = 0; i < n_keepalives; ++i) { ir_node *ka = get_End_keepalive(n, i); if (is_Block(ka)) { - if (is_Block_dead(ka)) { - set_End_keepalive(n, i, new_Bad()); + if (! is_Block_dead(ka)) { + in[j++] = ka; } - } else if (is_irn_pinned_in_irg(ka) && is_Block_dead(get_nodes_block(ka))) - set_End_keepalive(n, i, new_Bad()); + } else if (is_irn_pinned_in_irg(ka) && is_Block_dead(get_nodes_block(ka))) { + continue; + } if (is_Phi(ka) || is_irn_keep(ka)) + in[j++] = ka; } + if (j != n_keepalives) + set_End_keepalives(n, j, in); return n; } /* transform_node_End */ @@ -3443,7 +3450,13 @@ static int node_cmp_attr_Sel(ir_node *a, ir_node *b) { /** Compares the attributes of two Phi nodes. */ static int node_cmp_attr_Phi(ir_node *a, ir_node *b) { - return get_irn_phi_attr (a) != get_irn_phi_attr (b); + /* we can only enter this function if both nodes have the same number of inputs, + hence it is enough to check if one of them is a Phi0 */ + if (is_Phi0(a)) { + /* check the Phi0 attribute */ + return get_irn_phi0_attr(a) != get_irn_phi0_attr(b); + } + return 0; } /* node_cmp_attr_Phi */ /** Compares the attributes of two Conv nodes. */ -- 2.20.1