Commit 4433514e authored by Götz Lindenmaier's avatar Götz Lindenmaier
Browse files

*** empty log message ***

[r59]
parent 2fa17934
16.8.2000 Goetz
irgopt: Correct copy of self pointer in start block.
irgopt: Correct treatment of loops: pre function in walker
breaks all possible loops in Phi and Block nodes.
irr_loop_example: wrong Return statement
Now I fixed all but one error: in memory_example.
This error showed a conceptual problem, so I wrote
a slightly different algorithm. This now runs for
all testprograms.
dead_node_example: cse is buggy!! merges start and the
following block!
15.8.2000 Goetz
looking at bug in dead_node_elimination.
Following fixes:
......
......@@ -11,7 +11,7 @@
1 - lets see, if there is a better graph */
int opt_cse = 1;
int opt_constant_folding = 1;
int opt_dead_node_elimination = 0;
int opt_dead_node_elimination = 1;
int optimized = 1;
/* set the flags with set_flagname, get the flag with get_flagname */
......
......@@ -44,34 +44,91 @@ local_optimize_graph (ir_graph *irg) {
/* Routines for dead node elimination / copying garbage collection */
/* of the obstack. */
/* Remeber the new node in the old node,
by using a field that all nodes have. */
void *
/* Remeber the new node in the old node by using a field all nodes have. */
inline void
set_new_node (ir_node *old, ir_node *new)
{
assert(old != new);
/* old->in[0] = new; Hi Chris: Benutze old->link, ich hab mich vergewissert dass
das hier ueberschrieben werden kann, das erspaart eine
indirektion --> schneller. */
old->link = new;
return old;
}
/* Get this new node, before the old node is forgotton.*/
ir_node *
inline ir_node *
get_new_node (ir_node * n)
{
ir_node *new;
new = n->link;
assert(new);
assert(new != n);
return n->link;
}
/* Copies the node to the new obstack. In's point to the predecessors
on the old obstack. n->link points to the new node. */
inline void
copy_node (ir_node *n, void *env) {
ir_node *nn, *block;
return new;
if (get_irn_opcode(n) == iro_Block) {
block = NULL;
} else {
block = get_nodes_Block(n);
}
nn = new_ir_node(current_ir_graph,
block,
get_irn_op(n),
get_irn_mode(n),
get_irn_arity(n),
get_irn_in(n));
copy_attrs(n, nn);
set_new_node(n, nn);
}
/* Create this node on a new obstack. */
/* Copies new predecessors of old node to new node remembered in link. */
inline void
copy_preds (ir_node *n, void *env) {
ir_node *nn;
int start, i;
nn = get_new_node(n);
if (get_irn_opcode(n) == iro_Block) start = 0; else start = -1;
for (i = start; i < get_irn_arity(n); i++)
set_irn_n (nn, i, get_new_node(get_irn_n(n, i)));
}
/* To break the recursion of the graph walk if there are loops in
the graph we have to allocate new nodes for Phis and blocks
before descending. Here we use the old predecessors for the
new nodes. These are replaced by the proper predecessors in
copy_node.
It turned out that it is not sufficient to just break loops
for Phi and Block nodes, as the walker can hit visited but
not copied nodes at any point in the graph.
A simple fix would be allocating Id's for every node and then
exchanging them, but this will cause new dead nodes on the new
obstack.
So now there is a different implementation more based on the
view on the graph as a graph than as a represented program. */
void
copy_node (ir_node *n, void *env) {
create_dummy (ir_node *n, void *env) {
assert (n);
/* Assure link is set to NULL so we can test whether there is a
new node by checking link.
set_irn_link(n, NULL); */
switch (get_irn_opcode(n)) {
case iro_Block:
set_new_node(n, new_ir_node(current_ir_graph, NULL, op_Block, mode_R,
get_irn_arity(n), get_irn_in(n)));
break;
case iro_Phi:
set_new_node(n, new_ir_node(current_ir_graph, NULL, op_Phi,
get_irn_mode(n),
get_irn_arity(n), get_irn_in(n)));
break;
default: {}
} /* end switch (get_irn_opcode(n)) */
}
/* Create a copy of this node on a new obstack. */
void
copy_node2 (ir_node *n, void *env) {
ir_node *res = NULL;
ir_node *a = NULL;
ir_node *b = NULL;
......@@ -89,11 +146,12 @@ copy_node (ir_node *n, void *env) {
switch (get_irn_opcode(n)) {
case iro_Block:
{ ir_node **in = get_Block_cfgpred_arr(n);
for (i = 0; i < get_Block_n_cfgpreds(n); i++) {
set_Block_cfgpred(n, i, get_new_node(get_Block_cfgpred(n, i)));
}
res = new_r_Block (current_ir_graph, get_Block_n_cfgpreds(n), in);
{
res = get_new_node(n);
assert(res);
for (i = 0; i < get_Block_n_cfgpreds(n); i++)
set_Block_cfgpred(res, i, get_new_node(get_Block_cfgpred(n, i)));
set_Block_matured(res, 1);
}
break;
case iro_Start:
......@@ -115,15 +173,8 @@ copy_node (ir_node *n, void *env) {
{
ir_node **in;
in = get_Return_res_arr(n);
/* printf("1. n: %p, in: %p, in[0]: %p, in[1]: %p, in[2]: %p in[3] %p \n", */
/* n, in, in[0], in[1], in[2], in[3]); */
for (i = 0; i < get_Return_n_res(n); i++) {
/* printf(" old: %p, new: %p \n", get_Return_res(n, i), get_new_node(get_Return_res(n, i))); */
for (i = 0; i < get_Return_n_res(n); i++)
set_Return_res(n, i, get_new_node(get_Return_res(n, i)));
}
res = new_r_Return (current_ir_graph,
get_new_node(get_nodes_Block(n)),
get_new_node(get_Return_mem(n)),
......@@ -244,16 +295,11 @@ copy_node (ir_node *n, void *env) {
res = new_r_Not (current_ir_graph, get_new_node(get_nodes_Block(n)),
get_new_node(get_Not_op(n)), get_irn_mode(n));
break;
case iro_Cmp: {
DDMSG2(get_new_node(get_Cmp_left(n)));
DDMSG2(get_new_node(get_Cmp_right(n)));
DDMSG2(get_new_node(get_nodes_Block(n)));
DDMSG;
case iro_Cmp:
res = new_r_Cmp (current_ir_graph,
get_new_node(get_nodes_Block(n)),
get_new_node(get_Cmp_left(n)),
get_new_node(get_Cmp_right(n)));
}
break;
case iro_Shl:
res = new_r_Shl (current_ir_graph, get_new_node(get_nodes_Block(n)),
......@@ -282,11 +328,10 @@ copy_node (ir_node *n, void *env) {
break;
case iro_Phi:
{
ir_node **in = get_Phi_preds_arr(n);
res = get_new_node(n);
for (i = 0; i < get_Phi_n_preds(n); i++)
set_Phi_pred(n, i, get_new_node(get_Phi_pred(n, i)));
res = new_r_Phi (current_ir_graph, get_new_node(get_nodes_Block(n)),
get_Phi_n_preds(n), in, get_irn_mode(n));
set_Phi_pred(res, i, get_new_node(get_Phi_pred(n, i)));
set_nodes_Block(res, get_new_node(get_nodes_Block(n)));
}
break;
case iro_Load:
......@@ -322,10 +367,11 @@ copy_node (ir_node *n, void *env) {
get_Sync_n_preds(n), in);
}
break;
case iro_Proj:
case iro_Proj: {
res = new_r_Proj (current_ir_graph, get_new_node(get_nodes_Block(n)),
get_new_node(get_Proj_pred(n)), get_irn_mode(n),
get_Proj_proj(n));
}
break;
case iro_Tuple:
{
......@@ -337,8 +383,7 @@ copy_node (ir_node *n, void *env) {
}
break;
case iro_Id:
res = new_r_Id (current_ir_graph, get_new_node(get_nodes_Block(n)),
get_new_node(get_Id_pred(n)), get_irn_mode(n));
res = get_new_node(get_Id_pred(n));
break;
case iro_Bad:
res = new_r_Bad ();
......@@ -346,18 +391,130 @@ copy_node (ir_node *n, void *env) {
}
/* @@@ Here we could call optimize()!! Not necessary, called in constructor anyways. */
set_new_node(n, res);
printf(" "); DDMSG2(res);
}
/* Copies the graph reachable from current_ir_graph->end to the obstack
in current_ir_graph.
Then fixes the fields in current_ir_graph containing nodes of the
graph. */
void
copy_graph () {
DDMSG;
/* Not all nodes remembered in current_ir_graph might be reachable
from the end node. Assure their link is set to NULL so that
we can test whether new nodes have been computed. */
set_irn_link(get_irg_frame (current_ir_graph), NULL);
set_irn_link(get_irg_globals(current_ir_graph), NULL);
set_irn_link(get_irg_args (current_ir_graph), NULL);
/* copy the graph */
irg_walk(get_irg_end(current_ir_graph), copy_node, copy_preds, NULL);
/* fix the fields in current_ir_graph */
set_irg_end (current_ir_graph, get_new_node(get_irg_end(current_ir_graph)));
set_irg_end_block (current_ir_graph, get_new_node(get_irg_end_block(current_ir_graph)));
if (get_irn_link(get_irg_frame(current_ir_graph)) == NULL)
irg_walk(get_irg_frame(current_ir_graph), copy_node, copy_preds, NULL);
if (get_irn_link(get_irg_globals(current_ir_graph)) == NULL)
irg_walk(get_irg_globals(current_ir_graph), copy_node, copy_preds, NULL);
if (get_irn_link(get_irg_args(current_ir_graph)) == NULL)
irg_walk(get_irg_args(current_ir_graph), copy_node, copy_preds, NULL);
set_irg_start (current_ir_graph, get_new_node(get_irg_start(current_ir_graph)));
set_irg_start_block(current_ir_graph,
get_new_node(get_irg_start_block(current_ir_graph)));
set_irg_frame (current_ir_graph, get_new_node(get_irg_frame(current_ir_graph)));
set_irg_globals(current_ir_graph, get_new_node(get_irg_globals(current_ir_graph)));
set_irg_args (current_ir_graph, get_new_node(get_irg_args(current_ir_graph)));
if (get_irn_link(get_irg_bad(current_ir_graph)) == NULL) {
copy_node(get_irg_bad(current_ir_graph), NULL);
copy_preds(get_irg_bad(current_ir_graph), NULL);
}
set_irg_bad(current_ir_graph, get_new_node(get_irg_bad(current_ir_graph)));
DDMSG;
}
void
copy_graph2 () {
ir_node *old_node, *new_node, *projX;
ir_graph *irg = current_ir_graph;
/*CS*/
printf("Before starting the DEAD NODE ELIMINATION !\n");
/* Copy nodes remembered in irg fields first.
The optimization contains tests against these fields, e.g., not
to optimize the start block away. Therefore these fields have to
be fixed first.
Further setting these fields in copy_node would impose additional
tests for all nodes of a kind.
Predict the visited flag the walker will use! */
/* Copy the start Block node. Get the ProjX of the Start node, that is
predecessor of the start Block. We have to break the cycle and fix it
later. We use the old in array as placeholder. */
old_node = irg->start_block;
new_node = new_r_Block (current_ir_graph, get_Block_n_cfgpreds(old_node),
get_Block_cfgpred_arr(old_node));
/* new_r_Block calls no optimization --> save */
projX = get_Block_cfgpred(old_node, 0);
irg->start_block = new_node;
set_new_node (old_node, new_node);
set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
/* Copy the Start node */
old_node = irg->start;
new_node = new_r_Start (current_ir_graph, irg->start_block);
irg->start = new_node;
set_new_node (old_node, new_node);
set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
/* Copy the Bad node */
old_node = irg->bad;
new_node = new_ir_node (irg, irg->start_block, op_Bad, mode_T, 0, NULL);
irg->bad = new_node;
set_new_node (old_node, new_node);
set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
/* Copy the Projs for the Start's results. */
old_node = projX;
new_node = new_r_Proj (irg, irg->start_block, irg->start, mode_X, pns_initial_exec);
set_Block_cfgpred(irg->start_block, 0, new_node);
set_new_node (old_node, new_node);
set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
old_node = irg->frame;
new_node = new_r_Proj (irg, irg->start_block, irg->start, mode_p, pns_frame_base);
irg->frame = new_node;
set_new_node (old_node, new_node);
set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
old_node = irg->globals;
new_node = new_r_Proj (irg, irg->start_block, irg->start, mode_p, pns_globals);
irg->globals = new_node;
set_new_node (old_node, new_node);
set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
old_node = irg->args;
new_node = new_r_Proj (irg, irg->start_block, irg->start, mode_T, pns_args);
irg->args = new_node;
set_new_node (old_node, new_node);
set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
/* Walks the graph once, and at the recursive way do the copy thing.
all reachable nodes will be copied to a new obstack. */
irg_walk(irg->end, create_dummy, copy_node2, NULL);
/*CS*/
printf("After DEAD NODE ELIMINATION !\n");
}
/* Amroq call this emigrate() */
void
dead_node_elimination(ir_graph *irg) {
struct obstack *graveyard_obst=NULL;
struct obstack *rebirth_obst;
ir_graph *rem;
struct obstack *graveyard_obst = NULL;
struct obstack *rebirth_obst = NULL;
ir_node *old_node, *new_node;
ir_graph *rem = current_ir_graph;
/* Remember external state of current_ir_graph. */
rem = current_ir_graph;
current_ir_graph = irg;
if (get_optimize() && get_opt_dead_node_elimination()) {
......@@ -371,73 +528,12 @@ dead_node_elimination(ir_graph *irg) {
current_ir_graph->obst = rebirth_obst;
obstack_init (current_ir_graph->obst);
/* @@@@@ Do we need to do something about cse? */
set_opt_cse(0);
/*CS*/
printf("Before starting the DEAD NODE ELIMINATION !\n");
/* Copy nodes remembered in irg fields first.
The optimization contains tests against these fields, e.g., not
to optimize the start block away. Therefore these fields have to
be fixed first.
Further setting these fields in copy_node would impose additional
tests for all nodes of a kind.
Predict the visited flag the walker will use! */
/* Copy the start Block node */
old_node = irg->start_block;
new_node = new_r_Block (current_ir_graph, 0, NULL); /* new_r_Block calls
no optimization --> save */
irg->start_block = new_node;
DDMSG2(new_node);
set_new_node (old_node, new_node);
set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
/* Copy the Start node */
old_node = irg->start;
new_node = new_r_Start (current_ir_graph, irg->start_block);
irg->start = new_node;
DDMSG2(new_node);
set_new_node (old_node, new_node);
set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
/* Copy the Bad node */
old_node = irg->bad;
new_node = new_ir_node (irg, irg->start_block, op_Bad, mode_T, 0, NULL);
irg->bad = new_node;
DDMSG2(new_node);
set_new_node (old_node, new_node);
set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
/* Copy the Projs for the Start's results. */
old_node = irg->frame;
new_node = new_r_Proj (irg, irg->start_block, irg->start, mode_p, pns_frame_base);
irg->frame = new_node;
DDMSG2(new_node);
set_new_node (old_node, new_node);
set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
old_node = irg->globals;
new_node = new_r_Proj (irg, irg->start_block, irg->start, mode_p, pns_globals);
irg->globals = new_node;
DDMSG2(new_node);
set_new_node (old_node, new_node);
set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
old_node = irg->args;
new_node = new_r_Proj (irg, irg->start_block, irg->start, mode_T, pns_args);
irg->args = new_node;
DDMSG2(new_node);
set_new_node (old_node, new_node);
set_irn_visited (old_node, get_irg_visited(current_ir_graph)+1);
/* Walks the graph once, and at the recursive way do the copy thing.
all reachable nodes will be copied to a new obstack. */
irg_walk(irg->end, NULL, copy_node, NULL);
/*CS*/
printf("After the DEAD NODE ELIMINATION !\n");
/* Copy the graph from the old to the new obstack */
copy_graph();
/* Free memory from old unoptimized obstack */
obstack_free(graveyard_obst, 0); /* First empty the obstack ... */
xfree (graveyard_obst); /* ... then free it. */
// obstack_free(graveyard_obst, 0); /* First empty the obstack ... */
//xfree (graveyard_obst); /* ... then free it. */
}
current_ir_graph = rem;
......
......@@ -28,7 +28,7 @@ struct ir_graph {
struct ir_node *start; /* start node of this ir_graph */
struct ir_node *end_block; /* block the end node will belong to */
struct ir_node *end; /* end node of this ir_graph */
struct ir_node *cstore; /* constant store */
struct ir_node *cstore; /* constant store -- no more needed!! */
struct ir_node *frame; /* method's frame */
struct ir_node *globals; /* pointer to the data segment containing all
globals as well as global procedures. */
......
......@@ -19,20 +19,29 @@ void irg_walk_2(ir_node *node,
int i;
assert(node);
if(get_irn_visited(node) < get_irg_visited(current_ir_graph)) {
/* printf(" - "); DDMSG2(node); */
if (get_irn_visited(node) < get_irg_visited(current_ir_graph)) {
/* printf(" -> "); DDMSG2(node); */
set_irn_visited(node, get_irg_visited(current_ir_graph));
if(pre) {
if (pre) {
pre(node, env);
}
if (is_no_Block(node)) {
irg_walk_2(get_nodes_Block(node), pre, post, env);
}
for(i = get_irn_arity(node) - 1; i >= 0; --i) {
for (i = get_irn_arity(node) - 1; i >= 0; --i) {
/* printf(" "); DDMSG2(node); */
/* printf(" "); DDMSG2(get_irn_n(node, i)); */
irg_walk_2(get_irn_n(node, i), pre, post, env);
}
if(post)
/* printf(" <- "); DDMSG2(node); */
if (post)
post(node, env);
}
return;
......
......@@ -90,6 +90,13 @@ new_ir_node (ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mode,
return res;
}
/* Copies all attributes stored in the old node to the new node.
Assumes both have the same opcode and sufficient size. */
void
copy_attrs (ir_node *old, ir_node *new) {
assert (get_irn_opcode(old) == get_irn_opcode(new));
memcpy (&new->attr, &old->attr, get_op_attr_size(get_irn_op(old)));
}
/* IR-Nodes with attributes */
int
......
......@@ -185,6 +185,11 @@ new_ir_node (ir_graph *irg,
int arity,
ir_node **in);
/* Copies all attributes stored in the old node to the new node.
Assumes both have the same opcode and sufficient size. */
void
copy_attrs (ir_node *old, ir_node *new);
/* Print IR-Nodes with attributes */
/* @@@@ brauchen wir dienoch? dann fliegt ev. das xprint raus?*/
......
......@@ -80,10 +80,10 @@ init_op(void)
op_Start = new_ir_op (iro_Start, id_from_str ("Start", 5), sizeof (block_attr), 1);
op_End = new_ir_op (iro_End, id_from_str ("End", 3), sizeof (block_attr), 1);
op_Jmp = new_ir_op (iro_Jmp, id_from_str ("Jmp", 3), 0, 0);
op_Cond = new_ir_op (iro_Cond, id_from_str ("Cond", 4), 0, 1);
op_Jmp = new_ir_op (iro_Jmp, id_from_str ("Jmp", 3), 0, 0);
op_Cond = new_ir_op (iro_Cond, id_from_str ("Cond", 4), 0, 1);
op_Return = new_ir_op (iro_Return, id_from_str ("Return", 6), 0, 1);
op_Raise = new_ir_op (iro_Raise, id_from_str ("Raise", 5), 0, 1);
op_Raise = new_ir_op (iro_Raise, id_from_str ("Raise", 5), 0, 1);
op_Const = new_ir_op (iro_Const, id_from_str ("Const", 5), sizeof (struct tarval *), 0);
op_SymConst = new_ir_op (iro_SymConst, id_from_str ("SymConst", 8),
......@@ -93,7 +93,7 @@ init_op(void)
op_Call = new_ir_op (iro_Call, id_from_str ("Call", 4), sizeof (type_method *), 1);
op_Add = new_ir_op (iro_Add, id_from_str ("Add", 3), 0, 0);
op_Minus = new_ir_op (iro_Minus, id_from_str ("Minus", 3), 0, 0);
op_Minus = new_ir_op (iro_Minus, id_from_str ("Minus", 5), 0, 0);
op_Sub = new_ir_op (iro_Sub, id_from_str ("Sub", 3), 0, 1);
op_Mul = new_ir_op (iro_Mul, id_from_str ("Mul", 3), 0, 0);
op_Quot = new_ir_op (iro_Quot, id_from_str ("Quot", 4), 0, 1);
......@@ -102,26 +102,31 @@ init_op(void)
op_Mod = new_ir_op (iro_Mod, id_from_str ("Mod", 3), 0, 1);
op_Abs = new_ir_op (iro_Abs, id_from_str ("Abs", 3), 0, 0);
op_And = new_ir_op (iro_And, id_from_str ("And", 3), 0, 0);
op_Or = new_ir_op (iro_Or, id_from_str ("Or", 2), 0, 0);
op_Or = new_ir_op (iro_Or, id_from_str ("Or", 2), 0, 0);
op_Eor = new_ir_op (iro_Eor, id_from_str ("Eor", 3), 0, 0);
op_Not = new_ir_op (iro_Not, id_from_str ("Not", 3), 0, 0);
op_Cmp = new_ir_op (iro_Cmp, id_from_str ("Cmp", 3), 0, 1);
op_Shl = new_ir_op (iro_Shl, id_from_str ("Shl", 3), 0, 1);
op_Shr = new_ir_op (iro_Shr, id_from_str ("Shr", 3), 0, 1);
op_Shrs = new_ir_op (iro_Shrs, id_from_str ("Shrs", 3), 0, 0);
op_Rot = new_ir_op (iro_Rot, id_from_str ("Rot", 3), 0, 0);
op_Conv = new_ir_op (iro_Conv, id_from_str ("Conv", 4), 0, 1);
op_Shrs = new_ir_op (iro_Shrs, id_from_str ("Shrs", 3), 0, 0);
op_Rot = new_ir_op (iro_Rot, id_from_str ("Rot", 3), 0, 0);
op_Conv = new_ir_op (iro_Conv, id_from_str ("Conv", 4), 0, 1);
op_Phi = new_ir_op (iro_Phi, id_from_str ("Phi", 3), sizeof (int), 1);
op_Phi = new_ir_op (iro_Phi, id_from_str ("Phi", 3), sizeof (int), 1);
op_Load = new_ir_op (iro_Load, id_from_str ("Load", 4), 0, 1);
op_Load = new_ir_op (iro_Load, id_from_str ("Load", 4), 0, 1);
op_Store = new_ir_op (iro_Store, id_from_str ("Store", 5), 0, 1);
op_Alloc = new_ir_op (iro_Alloc, id_from_str ("Alloc", 5), sizeof (alloc_attr), 1);
op_Free = new_ir_op (iro_Free, id_from_str ("Free", 5), sizeof (type *), 1);
op_Sync = new_ir_op (iro_Sync, id_from_str ("Sync", 4), 0, 0);
op_Free = new_ir_op (iro_Free, id_from_str ("Free", 4), sizeof (type *), 1);
op_Sync = new_ir_op (iro_Sync, id_from_str ("Sync", 4), 0, 0);
op_Proj = new_ir_op (iro_Proj, id_from_str ("Proj", 4), sizeof (long), 1);
op_Proj = new_ir_op (iro_Proj, id_from_str ("Proj", 4), sizeof (long), 1);
op_Tuple = new_ir_op (iro_Tuple, id_from_str ("Tuple", 5), 0, 1);
op_Id = new_ir_op (iro_Id, id_from_str ("Id", 2), 0, 0);
op_Bad = new_ir_op (iro_Bad, id_from_str ("Bad", 3), 0, 0);
op_Id = new_ir_op (iro_Id, id_from_str ("Id", 2), 0, 0);
op_Bad = new_ir_op (iro_Bad, id_from_str ("Bad", 3), 0, 0);
}
/* returns the attribute size of the operator. */
int get_op_attr_size (ir_op *op) {
return op->attr_size;
}
......@@ -91,4 +91,8 @@ ir_op * new_ir_op (opcode code, ident *name, size_t attr_size, int labeled);
/* initialize the irop module */
void init_op (void);
/* returns the attribute size of the operator. */
int get_op_attr_size (ir_op *op);
# endif /* _IROP_H_ */
......@@ -253,7 +253,8 @@ equivalent_node (ir_node *n)
calls the optimization. */
assert(get_Block_matured(n));
/* a single entry Block following a single exit Block can be merged */
/* A single entry Block following a single exit Block can be merged,
if it is not the Start block. */
/* !!! Beware, all Phi-nodes of n must have been optimized away.
This is true, as the block is matured before optimize is called. */
if (get_Block_n_cfgpreds(n) == 1
......
......@@ -31,13 +31,13 @@ realclean: clean
run:
./empty; \
const_eval_example \
const_eval_example; \
if_example; \
if_else_example \
if_else_example; \
if_while_example; \
cond_example \
cond_example; \
call_str_example; \
memory_example \
memory_example; \
array-stack_example; \
array-heap_example; \