Commit 5b3aff6d authored by Michael Beck's avatar Michael Beck
Browse files

do not use set_irn_in to change End's keep-alives, this changes the in array...

do not use set_irn_in to change End's keep-alives, this changes the in array from a flexible one to a dynamic ...
use new set_end_keepalives() function

[r7658]
parent abfcb763
......@@ -532,14 +532,14 @@ static int init_construction(ir_graph *irg, irg_walk_func *pre) {
/* now visit the unreachable (from End) Blocks and remove unnecessary keep-alives */
end = get_irg_end(irg);
arity = get_irn_arity(end);
arity = get_End_n_keepalives(end);
if (arity) { /* we have keep-alives */
ir_node **in;
int i, j;
NEW_ARR_A(ir_node *, in, arity);
for (i = j = 0; i < arity; i++) {
ir_node *pred = get_irn_n(end, i);
ir_node *pred = get_End_keepalive(end, i);
if (get_irn_op(pred) == op_Block) {
if (Block_not_block_visited(pred)) {
......@@ -554,7 +554,7 @@ static int init_construction(ir_graph *irg, irg_walk_func *pre) {
}
if (j != arity) {
/* we kill some Block keep-alives */
set_irn_in(end, j, in);
set_End_keepalives(end, j, in);
set_irg_outs_inconsistent(irg);
}
}
......
......@@ -242,17 +242,17 @@ set_irn_in (ir_node *node, int arity, ir_node **in) {
arr = &node->in;
}
for (i = 0; i < arity; i++) {
if (i < ARR_LEN(*arr)-1)
edges_notify_edge(node, i, in[i], (*arr)[i+1], irg);
else
edges_notify_edge(node, i, in[i], NULL, irg);
for (i = 0; i < arity; i++) {
if (i < ARR_LEN(*arr)-1)
edges_notify_edge(node, i, in[i], (*arr)[i+1], irg);
else
edges_notify_edge(node, i, in[i], NULL, irg);
}
for(;i < ARR_LEN(*arr)-1; i++) {
edges_notify_edge(node, i, NULL, (*arr)[i+1], irg);
}
for(;i < ARR_LEN(*arr)-1; i++) {
edges_notify_edge(node, i, NULL, (*arr)[i+1], irg);
}
if (arity != ARR_LEN(*arr) - 1) {
if (arity != ARR_LEN(*arr) - 1) {
ir_node * block = (*arr)[0];
*arr = NEW_ARR_D(ir_node *, irg->obst, arity + 1);
(*arr)[0] = block;
......@@ -789,11 +789,28 @@ set_End_keepalive(ir_node *end, int pos, ir_node *ka) {
set_irn_n(end, pos + END_KEEPALIVE_OFFSET, ka);
}
/* Set new keep-alives */
void set_End_keepalives(ir_node *end, int n, ir_node *in[]) {
int i;
ir_graph *irg = get_irn_irg(end);
/* notify that edges are deleted */
for (i = END_KEEPALIVE_OFFSET; i < ARR_LEN(end->in); ++i) {
edges_notify_edge(end, i, in[i], NULL, irg);
}
ARR_RESIZE(ir_node *, end->in, n + END_KEEPALIVE_OFFSET);
for (i = 0; i < n; ++i) {
end->in[END_KEEPALIVE_OFFSET + i] = in[i];
edges_notify_edge(end, END_KEEPALIVE_OFFSET + i, NULL, end->in[END_KEEPALIVE_OFFSET + i], irg);
}
}
void
free_End (ir_node *end) {
assert (end->op == op_End);
end->kind = k_BAD;
DEL_ARR_F(end->in); /* GL @@@ tut nicht ! */
DEL_ARR_F(end->in);
end->in = NULL; /* @@@ make sure we get an error if we use the
in array afterwards ... */
}
......
......@@ -328,6 +328,9 @@ void add_End_keepalive (ir_node *end, ir_node *ka);
/** Set the Keep alive node at position pos. */
void set_End_keepalive(ir_node *end, int pos, ir_node *ka);
/** Set new keep-alives */
void set_End_keepalives(ir_node *end, int n, ir_node *in[]);
/** Some parts of the End node are allocated separately -- their memory
is not recovered by dead_node_elimination if a End node is dead.
free_End() frees these data structures. */
......
......@@ -13,6 +13,13 @@
# include "config.h"
#endif
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif
#include <assert.h>
#include "xmalloc.h"
......@@ -600,7 +607,7 @@ static void optimize_blocks(ir_node *b, void *env) {
* we will lose blocks and thereby generate memory leaks.
*/
void optimize_cf(ir_graph *irg) {
int i, n;
int i, j, n;
ir_node **in;
ir_node *end = get_irg_end(irg);
ir_graph *rem = current_ir_graph;
......@@ -650,12 +657,13 @@ void optimize_cf(ir_graph *irg) {
/* Walk all keep alives, optimize them if block, add to new in-array
for end if useful. */
in = NEW_ARR_F (ir_node *, 1);
in[0] = get_nodes_block(end);
n = get_End_n_keepalives(end);
if (n > 0)
NEW_ARR_A (ir_node *, in, n);
inc_irg_visited(current_ir_graph);
/* fix the keep alive */
for (i = 0, n = get_End_n_keepalives(end); i < n; i++) {
for (i = j = 0; i < n; i++) {
ir_node *ka = get_End_keepalive(end, i);
if (irn_not_visited(ka)) {
......@@ -666,20 +674,20 @@ void optimize_cf(ir_graph *irg) {
get_irg_block_visited(current_ir_graph)-1);
irg_block_walk(ka, optimize_blocks, NULL, NULL);
mark_irn_visited(ka);
ARR_APP1 (ir_node *, in, ka);
in[j++] = ka;
} else if (op == op_Phi) {
mark_irn_visited(ka);
if (! is_Block_dead(get_nodes_block(ka)))
ARR_APP1 (ir_node *, in, ka);
in[j++] = ka;
} else if (is_op_keep(op)) {
mark_irn_visited(ka);
if (! is_Block_dead(get_nodes_block(ka)))
ARR_APP1 (ir_node *, in, ka);
in[j++] = ka;
}
}
}
DEL_ARR_F(end->in);
end->in = in;
if (j != n)
set_End_keepalives(end, j, in);
/* the verifier doesn't work yet with floating nodes */
if (get_irg_pinned(irg) == op_pin_state_pinned) {
......
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