Commit 55fadbd9 authored by Christian Schäfer's avatar Christian Schäfer
Browse files

implemented dead node elimination. Doesnt run yet.

[r28]
parent df8c328a
......@@ -22,7 +22,7 @@ MAKE = /usr/bin/make -k
SHELL = /bin/sh
CXX = gcc
CFLAGS = -pipe -Wall #-ansi -pedantic # -g
CFLAGS = -pipe -Wall # -ansi -pedantic # -g
COPTFLAGS = -O3 -ffast-math # -fno-caller-saves
TARGET = libfirm.a
......@@ -31,7 +31,7 @@ TARGET = libfirm.a
$(TARGET):
# mkdir objects
for i in $(SUBDIRS); do $(MAKE) "INCLUDES=$(INCLUDES)" -C $$i; done
for i in $(SUBDIRS); do $(MAKE) "INCLUDES=$(INCLUDES)" "CXXFLAGS=-g" -C $$i; done
$(AR) $(TARGET) objects/*.o
mv $(TARGET) ..
......
......@@ -18,6 +18,7 @@
# include "array.h"
/* memset belongs to string.h */
# include "string.h"
# include "irnode.h"
#if USE_EXPICIT_PHI_IN_STACK
/* A stack needed for the automatic Phi node construction in constructor
......@@ -31,13 +32,14 @@ struct Phi_in_stack {
/*********************************************** */
/** privat interfaces, for professional use only */
/* Constructs a Block with a fixed number of predecessors.*/
inline ir_node *
new_r_Block (ir_graph *irg, int arity, ir_node **in)
{
ir_node *res;
res = new_ir_node (current_ir_graph, NULL, op_Block, mode_R, -1, NULL);
res = new_ir_node (current_ir_graph, NULL, op_Block, mode_R, arity, in);
return res;
}
......@@ -142,7 +144,7 @@ alloc_or_pop_from_Phi_in_stack(ir_graph *irg, ir_node *block, ir_mode *mode,
assert (res->kind == k_ir_node);
assert (res->op == op_Phi);
res->mode = mode;
res->visit = 0;
res->visited = 0;
res->link = NULL;
assert (arity >= 0);
/* ???!!! How to free the old in array?? */
......@@ -261,13 +263,20 @@ new_r_Id (ir_graph *irg, ir_node *block, ir_node *val, ir_mode *mode)
}
ir_node *
new_r_Proj (ir_graph *irg, ir_node *block, ir_node *arg, ir_mode *mode, long proj)
new_r_Proj (ir_graph *irg, ir_node *block, ir_node *arg, ir_mode *mode,
long proj)
{
ir_node *in[1] = {arg};
ir_node *res;
res = new_ir_node (irg, block, op_Proj, mode, 1, in);
res->attr.proj = proj;
assert(res);
assert(get_Proj_pred(res));
assert(get_nodes_Block(get_Proj_pred(res)));
res = optimize (res);
ir_vrfy (res);
return res;
......@@ -565,17 +574,11 @@ new_r_Return (ir_graph *irg, ir_node *block,
int r_arity;
r_arity = arity+1;
NEW_ARR_A (ir_node *, r_in, r_arity);
r_in[0] = store;
memcpy (&r_in[1], in, sizeof (ir_node *) * arity);
res = new_ir_node (irg, block, op_Return, mode_X, r_arity, r_in);
res = optimize (res);
ir_vrfy (res);
return res;
}
......@@ -868,10 +871,10 @@ get_r_value_internal (ir_node *block, int pos, ir_mode *mode)
*/
/* case 4 -- already visited. */
if (block->visit == ir_visited) return NULL;
if (get_irn_visited(block) == get_irg_visited(current_ir_graph)) return NULL;
/* visited the first time */
block->visit = ir_visited;
set_irn_visited(block, get_irg_visited(current_ir_graph));
/* Get the local valid value */
res = block->attr.block.graph_arr[pos];
......@@ -941,7 +944,7 @@ mature_block (ir_node *block)
/* Traverse a chain of Phi nodes attached to this block and mature
these, too. **/
for (n = block->link; n; n=next) {
ir_visited++;
inc_irg_visited(current_ir_graph);
next = n->link;
exchange (n, phi_merge (block, n->attr.phi0_pos, n->mode, nin, ins));
}
......@@ -1253,7 +1256,7 @@ switch_block (ir_node *target)
ir_node *
get_value (int pos, ir_mode *mode)
{
++ir_visited;
inc_irg_visited(current_ir_graph);
return get_r_value_internal (current_ir_graph->current_block, pos + 1, mode);
}
......@@ -1269,7 +1272,7 @@ inline ir_node *
get_store (void)
{
/* GL: one could call get_value instead */
++ir_visited;
inc_irg_visited(current_ir_graph);
return get_r_value_internal (current_ir_graph->current_block, 0, mode_M);
}
......
......@@ -101,6 +101,9 @@
*Phi_in_stack; a stack needed for automatic Phi construction, needed only
during ir construction.
visited A int used as flag to traverse the ir_graph.
block_visited A int used as a flag to traverse block nodes in the graph.
Three kinds of nodes
--------------------
......@@ -203,7 +206,6 @@
CONSTRUCTOR FOR IR_GRAPH
========================
......@@ -1267,7 +1269,6 @@ ir_node *get_store (void);
/* Write a store. */
void set_store (ir_node *store);
/* This function is for internal use only. It is visible as it is needed
in irgraph.c to create the stack that is needed for automatic Phi
construction. */
......
......@@ -8,8 +8,11 @@
# include "irflag.h"
/* 0 - don't do this optimization
1 - lets see, if there is a better graph */
int opt_cse = 0;
int opt_constant_folding = 1;
int opt_dead_node_elimination = 0;
int optimized = 1;
/* set the flags with set_flagname, get the flag with get_flagname */
......@@ -38,6 +41,16 @@ get_opt_constant_folding (void)
return opt_constant_folding;
}
void set_opt_dead_node_elimination (int value)
{
opt_dead_node_elimination=value;
}
int get_opt_dead_node_elimination (void)
{
return opt_dead_node_elimination;
}
void
set_optimize (int value)
{
......
......@@ -18,6 +18,8 @@ void set_opt_cse (int value);
int get_opt_cse (void);
void set_opt_constant_folding (int value);
int get_opt_constant_folding (void);
void set_opt_dead_node_elimination (int value);
int get_opt_dead_node_elimination (void);
void set_optimize (int value);
int get_optimize (void);
......
......@@ -9,13 +9,6 @@
# include "irgmod.h"
# include "array.h"
/* ir_node * */
/* arg_access (ir_mode *mode, long proj) */
/* { */
/* return new_r_Proj (current_ir_graph, current_ir_graph->start, */
/* current_ir_graph->args, mode, proj); */
/* } */
/* Turns a node into a "useless" Tuple. The Tuple just forms a tuple
from several inputs.
This is useful if a node returning a tuple is removed, but the Projs
......
......@@ -59,17 +59,23 @@ set_new_node (ir_node *old, ir_node *new)
ir_node *
get_new_node (ir_node * n)
{
ir_node *new;
new = n->in[0];
assert(new);
return n->in[0];
}
/* Create this node on a new obstack. */
void
copy_node (ir_node *n, void *env) {
ir_node *res = NULL;
ir_node *a = NULL;
ir_node *b = NULL;
int i;
ir_node *res, *a, *b;
res = (ir_node *) malloc (sizeof (ir_node));
a = (ir_node *) malloc (sizeof (ir_node));
b = (ir_node *) malloc (sizeof (ir_node));
assert (n);
if (is_binop(n)) {
a = get_binop_left(n);
......@@ -81,61 +87,52 @@ copy_node (ir_node *n, void *env) {
switch (get_irn_opcode(n)) {
case iro_Block:
{
/*CS malloc*/
ir_node *in [get_Block_n_cfgpreds(n)];
for (i=0; i <(get_Block_n_cfgpreds(n)); i++) {
in[i] = get_Block_cfgpred (n, i);
}
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);
set_new_node(n, res);
}
break;
case iro_Start:
res = new_r_Start (current_ir_graph, get_new_node(n));
set_new_node(n, res);
res = new_r_Start (current_ir_graph, get_new_node(get_nodes_Block(n)));
break;
case iro_End:
res = new_r_End (current_ir_graph, get_new_node(n));
set_new_node(n, res);
current_ir_graph -> end = res;
current_ir_graph -> end_block = get_new_node(get_nodes_Block(n));
break;
case iro_Jmp:
res = new_r_Jmp (current_ir_graph, get_new_node(n));
set_new_node(n, res);
break;
case iro_Cond:
res = new_r_Cond (current_ir_graph, get_new_node(n),
get_Cond_selector(n));
set_new_node(n, res);
break;
case iro_Return:
{
/*CS malloc*/
ir_node *in [get_Return_n_res(n)];
for (i=0; i <(get_Return_n_res(n)); i++) {
in[i] = get_Return_res (n, i);
}
ir_node **in ;
in = get_Return_res_arr(n);
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(n),
get_Return_mem (n), get_Return_n_res(n), in);
set_new_node(n, res);
}
break;
case iro_Raise:
res = new_r_Raise (current_ir_graph, get_new_node(n),
get_Raise_mem(n), get_Raise_exoptr(n));
set_new_node(n, res);
get_Raise_mem(n), get_Raise_exo_ptr(n));
break;
case iro_Const:
res = new_r_Const (current_ir_graph, get_new_node(n),
get_irn_mode(n), get_Const_tarval(n));
set_new_node(n, res);
break;
case iro_SymConst:
{
type_or_id *value;
value = (type_or_id *) malloc (sizeof (type_or_id));
type_or_id *value = NULL;
if ((get_SymConst_kind(n)==type_tag) || (get_SymConst_kind(n)==size))
{
value = (type_or_id *) get_SymConst_type(n);
}
else
......@@ -147,39 +144,27 @@ copy_node (ir_node *n, void *env) {
}
res = new_r_SymConst (current_ir_graph, get_new_node(n), value,
get_SymConst_kind (n));
set_new_node(n, res);
}
break;
case iro_Sel:
{
/*CS*/
ir_node *in [get_Sel_n_index(n)];
for (i=0; i <(get_Sel_n_index(n)); i++) {
in[i] = get_Sel_index (n, i);
}
ir_node **in = get_Sel_index_arr(n);
res = new_r_Sel (current_ir_graph, get_new_node(n),
get_Sel_mem(n), get_Sel_ptr(n), get_Sel_n_index(n),
in, get_Sel_entity(n));
set_new_node(n, res);
}
break;
case iro_Call:
{
/*CS*/
ir_node *in [get_Call_arity(n)];
for (i=0; i <(get_Call_arity(n)); i++) {
in[i] = get_Call_param (n, i);
}
ir_node **in = get_Call_param_arr(n);
res = new_r_Call (current_ir_graph, get_new_node(n), get_Call_mem(n),
get_Call_ptr(n), get_Call_arity(n),
in, get_Call_type (n));
set_new_node(n, res);
}
break;
case iro_Add:
res = new_r_Add (current_ir_graph, get_new_node(n),
get_new_node(a), get_new_node(b), get_irn_mode(n));
set_new_node(n, res);
break;
case iro_Sub:
{
......@@ -187,13 +172,11 @@ copy_node (ir_node *n, void *env) {
temp_node = get_nodes_Block(n);
res = new_r_Sub (current_ir_graph, get_new_node(temp_node),
get_new_node(a), get_new_node(b), get_irn_mode(n));
set_new_node(n, res);
}
break;
case iro_Minus:
res = new_r_Minus (current_ir_graph, get_new_node(n), get_new_node(a),
get_irn_mode(n));
set_new_node(n, res);
break;
case iro_Mul:
res = new_r_Mul (current_ir_graph, get_new_node(n), get_new_node(a),
......@@ -260,15 +243,10 @@ copy_node (ir_node *n, void *env) {
get_irn_mode(n));
break;
case iro_Phi:
/*CS malloc*/
{
ir_node *in [get_Phi_n_preds(n)];
for (i=0; i <(get_Phi_n_preds(n)); i++) {
in[i] = get_Phi_pred (n, i);
}
ir_node **in = get_Phi_preds_arr(n);
res = new_r_Phi (current_ir_graph, get_new_node(n),
get_Phi_n_preds(n), in, get_irn_mode(n));
set_new_node(n, res);
}
break;
case iro_Load:
......@@ -291,32 +269,22 @@ copy_node (ir_node *n, void *env) {
get_Free_size(n), get_Free_type(n));
break;
case iro_Sync:
/*CS malloc*/
{
ir_node *in [get_Sync_n_preds(n)];
for (i=0; i <(get_Sync_n_preds(n)); i++) {
in[i] = get_Sync_pred (n, i);
}
ir_node **in = get_Sync_preds_arr(n);
res = new_r_Sync (current_ir_graph, get_new_node(n),
get_Sync_n_preds(n), in);
set_new_node(n, res);
}
break;
case iro_Proj:
res = new_r_Proj (current_ir_graph, get_new_node(n),
get_Proj_pred(n), get_irn_mode(n),
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:
/*CS malloc*/
{
ir_node *in [get_Tuple_n_preds(n)];
for (i=0; i <(get_Tuple_n_preds(n)); i++) {
in[i] = get_Tuple_pred (n, i);
}
ir_node **in = get_Tuple_preds_arr(n);
res = new_r_Tuple (current_ir_graph, get_new_node(n),
get_Tuple_n_preds(n), in);
set_new_node(n, res);
}
break;
case iro_Id:
......@@ -327,28 +295,51 @@ copy_node (ir_node *n, void *env) {
res = new_r_Bad (get_new_node(n));
break;
}
set_new_node(n, res);
}
void
dead_node_elemination(ir_graph *irg) {
struct obstack *graveyard_obst;
dead_node_elimination(ir_graph *irg) {
struct obstack *graveyard_obst=NULL;
struct obstack *rebirth_obst;
ir_node *old_node, *new_node;
ir_graph *rem = current_ir_graph;
current_ir_graph = irg;
/* A quiet place, where the old obstack can rest in peace,
until it will be cremated. */
graveyard_obst = irg->obst;
if (get_opt_dead_node_elimination()) {
/* A new obstack, where the reachable nodes will be copied to. */
rebirth_obst = (struct obstack *) xmalloc (sizeof (struct obstack));
current_ir_graph->obst = rebirth_obst;
obstack_init (current_ir_graph->obst);
/* A quiet place, where the old obstack can rest in peace,
until it will be cremated. */
graveyard_obst = irg->obst;
/* 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);
/* A new obstack, where the reachable nodes will be copied to. */
rebirth_obst = (struct obstack *) xmalloc (sizeof (struct obstack));
current_ir_graph->obst = rebirth_obst;
obstack_init (current_ir_graph->obst);
/* Walks the graph once, and at the recursive way do the copy thing.
all reachable nodes will be copied to a new obstack. */
/*CS*/
printf("Before starting the DEAD NODE ELIMINATION !\n");
old_node = irg->start_block;
new_node = new_r_Block (current_ir_graph, 0, NULL);
irg->start_block = new_node; ;
set_new_node (old_node, new_node);
set_irn_visited (new_node, get_irg_visited(current_ir_graph)+1);
/*CS Start node und alle Proj nodes muessen hier per hand eingetragen
werden! */
irg_walk(irg->end, NULL, copy_node, NULL);
/*CS*/
printf("After the DEAD NODE ELIMINATION !\n");
/* Free memory from old unoptimized obstack */
xfree (graveyard_obst);
}
/* Free memory from old unoptimized obstack */
xfree (graveyard_obst);
......
......@@ -15,10 +15,6 @@
ir_graph *current_ir_graph;
unsigned long ir_visited = 0;
unsigned long block_visited = 0;
/* Allocates a list of nodes:
- The start block containing a start node and Proj nodes for it's four
results (X, M, P, Tuple).
......@@ -45,14 +41,17 @@ new_ir_graph (entity *ent, int params)
dereferenced in this graph plus one for
the store. This is not the number of parameters
to the procedure! */
res->visited = 0; /* visited flag, for the ir walker */
res->block_visited=0; /* visited flag, for the 'block'-walker */
#if USE_EXPICIT_PHI_IN_STACK
res->Phi_in_stack = new_Phi_in_stack(); /* A stack needed for automatic Phi
generation */
#endif
res->obst = (struct obstack *) xmalloc (sizeof (struct obstack));
obstack_init (res->obst);
res->value_table = new_identities (); /* Symbol table for local variables
of this procedure */
res->value_table = new_identities (); /* value table for global value numbering
for optimizing use in iropt.c */
/** Type inforamtion for the procedure of the graph **/
res->ent = ent;
......@@ -86,81 +85,83 @@ new_ir_graph (entity *ent, int params)
return res;
}
/* access routines for all ir_graph attributes */
/* access routines for all ir_graph attributes:
templates:
{attr type} get_irg_{attribute name} (ir_graph *irg);
void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
ir_node *
get_start_block_of_irgraph (ir_graph *irg)
get_irg_start_block (ir_graph *irg)
{
return irg->start_block;
}
void
set_start_block_of_irgraph (ir_graph *irg, ir_node *node)
set_irg_start_block (ir_graph *irg, ir_node *node)
{
irg->start_block = node;
}
ir_node *
get_start_of_irgraph (ir_graph *irg)
get_irg_start (ir_graph *irg)
{
return irg->start;
}
void
set_start_of_irgraph(ir_graph *irg, ir_node *node)
set_irg_start(ir_graph *irg, ir_node *node)
{
irg->start = node;
}
ir_node *
get_end_block_of_irgraph (ir_graph *irg)
get_irg_end_block (ir_graph *irg)
{
return irg->end_block;
}
void
set_end_block_of_irgraph (ir_graph *irg, ir_node *node)
set_irg_end_block (ir_graph *irg, ir_node *node)
{
irg->end_block = node;
}
ir_node *
get_end_of_irgraph (ir_graph *irg)
get_irg_end (ir_graph *irg)
{
return irg->end;
}
void
set_end_of_irgraph (ir_graph *irg, ir_node *node)
set_irg_end (ir_graph *irg, ir_node *node)
{
irg->end = node;
}
ir_node *
get_cstore_of_irgraph (ir_graph *irg)
get_irg_cstore (ir_graph *irg)
{
return irg->cstore;
}
void
set_cstore_of_irgraph (ir_graph *irg, ir_node *node)
set_irg_cstore (ir_graph *irg, ir_node *node)
{
irg->cstore = node;
}
ir_node *
get_frame_of_irgraph (ir_graph *irg)
get_irg_frame (ir_graph *irg)
{
return irg->frame;
}
void
set_frame_of_irgraph(ir_graph *irg, ir_node *node)
set_irg_frame (ir_graph *irg, ir_node *node)
{
irg->frame = node;
}
ir_node *
get_irg_globals (ir_graph *irg)
{
......@@ -173,64 +174,98 @@ set_irg_globals (ir_graph *irg, ir_node *node)
irg->globals = node;
}
ir_node *
get_args_of_irgraph (ir_graph *irg)
get_irg_args (ir_graph *irg)
{
return irg->args;
}
void
set_args_of_irgraph(ir_graph *irg, ir_node *node)
set_irg_args (ir_graph *irg, ir_node *node)
{
irg->args = node;
}
ir_node *
get_bad_of_irgraph (ir_graph *irg)