Commit a17babab authored by Michael Beck's avatar Michael Beck
Browse files

- changed Phi0 attribute to be a struct

- Phi0 attribute is only available onb Phi0 nodes

This should now allow CSE on Phi nodes!

[r14002]
parent 24632339
......@@ -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;
......
......@@ -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
......
......@@ -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);
......
......@@ -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);
......
......@@ -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. */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment