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

*** empty log message ***

[r40]
parent 7fe062ea
......@@ -36,5 +36,6 @@ init_firm (void)
init_cons ();
/* Builds a construct allowing to access all information to be constructed
later. */
init_irprog ();
}
......@@ -9,14 +9,25 @@
# ifndef _FIRM_H_
# define _FIRM_H_
# include "entity.h"
# include "ircons.h"
/* The representations */
# include "irprog.h"
# include "type.h"
# include "entity.h"
/* Functionality */
# include "ircons.h"
# include "irgopt.h"
/* */
# include "xprintf.h"
/** Global flags. Set these by autoconf?? **/
/* If this is defined debuging aids are created, e.g. a field in
ir_node uniquely numbering the nodes. */
/* @@@???? this is also set in irnode.h */
#define DEBUG_libfirm
/* initialize firm */
void init_firm (void);
......
......@@ -41,6 +41,7 @@ new_r_Block (ir_graph *irg, int arity, ir_node **in)
res = new_ir_node (current_ir_graph, NULL, op_Block, mode_R, arity, in);
irn_vrfy (res);
return res;
}
......@@ -710,7 +711,7 @@ new_r_Sync (ir_graph *irg, ir_node *block, int arity, ir_node **in)
}
ir_node *
new_r_Bad (ir_node *block)
new_r_Bad ()
{
return current_ir_graph->bad;
}
......
......@@ -251,10 +251,11 @@
* A less comfortable interface where all predecessors except the block
an operation belongs to need to be specified. SSA must be constructed
by hand. (new_<Node> constructors and switch_block()). This interface
is called "block oriented".
is called "block oriented". It automatically calles the local optimizations
for each new node.
* An even less comfortable interface where the block needs to be specified
explicitly. This is called the "raw" interface. (new_r_<Node>
constructors).
constructors). These nodes are not optimized.
To use the functionality of the comfortable interface correctly the Front
End needs to follow certain protocols. This is explained in the following.
......@@ -1171,7 +1172,7 @@ ir_node *new_r_Tuple (ir_graph *irg, ir_node *block,
int arity, ir_node **in);
ir_node *new_r_Id (ir_graph *irg, ir_node *block,
ir_node *val, ir_mode *mode);
ir_node *new_r_Bad (ir_node *block);
ir_node *new_r_Bad ();
/*************************************************************************/
......
......@@ -33,6 +33,121 @@ static FILE *F;
/* routines to dump information about a single node */
/*******************************************************************/
inline void
dump_node_opcode (ir_node *n)
{
/* Const */
if (n->op->code == iro_Const) {
xfprintf (F, "%v", n->attr.con);
/* SymConst */
} else if (n->op->code == iro_SymConst) {
if (get_SymConst_kind(n) == linkage_ptr_info) {
xfprintf (F, "%I", get_SymConst_ptrinfo(n));
} else {
assert(get_kind(get_SymConst_type(n)) == k_type_class);
assert(get_class_ident((type_class *)get_SymConst_type(n)));
xfprintf (F, "%s ", id_to_str(get_class_ident((type_class *)get_SymConst_type(n))));
if (get_SymConst_kind == type_tag)
xfprintf (F, "tag");
else
xfprintf (F, "size");
}
/* all others */
} else {
xfprintf (F, "%I", n->op->name);
}
}
inline void
dump_node_mode (ir_node *n)
{
switch (n->op->code) {
case iro_Phi:
case iro_Const:
case iro_Id:
case iro_Proj:
case iro_Conv:
case iro_Tuple:
case iro_Add:
case iro_Sub:
case iro_Mul:
case iro_And:
case iro_Or:
case iro_Eor:
case iro_Shl:
case iro_Shr:
case iro_Abs:
case iro_Cmp:
xfprintf (F, "%I", n->mode->name);
break;
default:
}
}
inline void
dump_node_nodeattr (ir_node *n)
{
switch (n->op->code) {
case iro_Proj:
if (n->in[1]->op->code == iro_Cmp) {
xfprintf (F, "%s", get_pnc_string(n->attr.proj));
} else {
xfprintf (F, "%ld", n->attr.proj);
}
break;
case iro_Sel:
assert(n->attr.s.ent->kind == k_entity);
xfprintf (F, "%s", id_to_str(n->attr.s.ent->name));
/* xdoesn't work for some reason.
fprintf (F, "\"%I %I\" ", n->op->name, n->attr.s.ent); */
break;
default:
} /* end switch */
}
inline void
dump_node_vcgattr (ir_node *n)
{
switch (n->op->code) {
case iro_Start:
case iro_End:
xfprintf (F, "color: blue");
break;
case iro_Block:
xfprintf (F, "color: lightyellow");
break;
case iro_Phi:
xfprintf (F, "color: green");
break;
case iro_Const:
case iro_Proj:
case iro_Tuple:
xfprintf (F, "color: yellow");
break;
default:
xfprintf (F, DEFAULT_NODE_ATTR);
}
}
void
dump_node (ir_node *n) {
/* dump this node */
xfprintf (F, "node: {title: \"%p\" label: \"", n);
dump_node_opcode(n);
dump_node_mode (n);
xfprintf (F, " ");
dump_node_nodeattr(n);
#ifdef DEBUG_libfirm
xfprintf (F, " %ld", get_irn_node_nr(n));
#endif
xfprintf (F, "\" ");
dump_node_vcgattr(n);
xfprintf (F, "}\n");
}
void
dump_ir_node (ir_node *n)
{
......@@ -411,15 +526,13 @@ vcg_close () {
fclose (F); /* close vcg file */
}
/************************************************************************/
/* routines to dump a graph, blocks as conventional nodes. */
/************************************************************************/
void
dump_whole_node (ir_node *n, void* env) {
dump_ir_node(n);
dump_node(n);
dump_ir_block_edge(n);
dump_ir_data_edges(n);
}
......@@ -444,20 +557,24 @@ dump_ir_blocks_nodes (ir_node *n, void *env) {
ir_node *block = (ir_node *)env;
if (is_no_Block(n) && get_nodes_Block(n) == block) {
dump_ir_node(n);
dump_node(n);
dump_ir_data_edges(n);
}
}
void
dump_ir_block (ir_node *block, void *env) {
ir_graph *irg = (ir_graph *)env;
if (get_irn_opcode(block) == iro_Block) {
/* This is a block. So dump the vcg information to make a block. */
xfprintf(F, "graph: { title: \"%p\" status:clustered color:lightyellow \n",
block);
xfprintf(F, "graph: { title: \"%p\" label: \"", block);
#ifdef DEBUG_libfirm
xfprintf (F, "%ld", get_irn_node_nr(block));
#elif
xfprintf (F, "%I", block->op->name);
#endif
xfprintf(F, "\" status:clustered color:lightyellow \n");
/* dump the blocks edges */
dump_ir_data_edges(block);
......
......@@ -17,47 +17,49 @@ int optimized = 1;
/* set the flags with set_flagname, get the flag with get_flagname */
void
inline void
set_opt_cse (int value)
{
opt_cse = value;
}
int
inline int
get_opt_cse (void)
{
return opt_cse;
}
void
inline void
set_opt_constant_folding (int value)
{
opt_constant_folding=value;
}
int
inline int
get_opt_constant_folding (void)
{
return opt_constant_folding;
}
void set_opt_dead_node_elimination (int value)
inline void
set_opt_dead_node_elimination (int value)
{
opt_dead_node_elimination=value;
opt_dead_node_elimination = value;
}
int get_opt_dead_node_elimination (void)
inline int
get_opt_dead_node_elimination (void)
{
return opt_dead_node_elimination;
}
void
inline void
set_optimize (int value)
{
optimized = value;
}
int
inline int
get_optimize (void)
{
return optimized;
......
......@@ -3,7 +3,7 @@
**
** Author: Christian Schaefer
**
** dead node elemination
** dead node elimination
** walks one time through the whole graph and copies it into another graph,
** so unreachable nodes will be lost.
*/
......@@ -51,7 +51,9 @@ local_optimize_graph (ir_graph *irg) {
void *
set_new_node (ir_node *old, ir_node *new)
{
old->in[0] = 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. */
return old;
}
......@@ -63,7 +65,7 @@ get_new_node (ir_node * n)
new = n->in[0];
assert(new);
return n->in[0];
return new;
}
......@@ -99,7 +101,7 @@ copy_node (ir_node *n, void *env) {
case iro_End:
res = new_r_End (current_ir_graph, get_new_node(get_nodes_Block(n)));
current_ir_graph -> end = res;
current_ir_graph -> end_block = get_new_node(get_nodes_Block(n));
current_ir_graph -> end_block = get_nodes_Block(res);
break;
case iro_Jmp:
res = new_r_Jmp (current_ir_graph, get_new_node(get_nodes_Block(n)));
......@@ -110,7 +112,7 @@ copy_node (ir_node *n, void *env) {
break;
case iro_Return:
{
ir_node **in ;
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)));
......@@ -151,6 +153,8 @@ copy_node (ir_node *n, void *env) {
case iro_Sel:
{
ir_node **in = get_Sel_index_arr(n);
for (i = 0; i < get_Sel_n_index(n); i++)
set_Sel_index(n, i, get_new_node(get_Sel_index(n, i)));
res = new_r_Sel (current_ir_graph, get_new_node(get_nodes_Block(n)),
get_new_node(get_Sel_mem(n)),
get_new_node(get_Sel_ptr(n)), get_Sel_n_index(n),
......@@ -160,6 +164,8 @@ copy_node (ir_node *n, void *env) {
case iro_Call:
{
ir_node **in = get_Call_param_arr(n);
for (i = 0; i < get_Call_arity(n); i++)
set_Call_param(n, i, get_new_node(get_Call_param(n, i)));
res = new_r_Call (current_ir_graph, get_new_node(get_nodes_Block(n)),
get_new_node(get_Call_mem(n)),
get_new_node(get_Call_ptr(n)), get_Call_arity(n),
......@@ -257,6 +263,8 @@ copy_node (ir_node *n, void *env) {
case iro_Phi:
{
ir_node **in = get_Phi_preds_arr(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));
}
......@@ -288,6 +296,8 @@ copy_node (ir_node *n, void *env) {
case iro_Sync:
{
ir_node **in = get_Sync_preds_arr(n);
for (i = 0; i < get_Sync_n_preds(n); i++)
set_Sync_pred(n, i, get_new_node(get_Sync_pred(n, i)));
res = new_r_Sync (current_ir_graph, get_new_node(get_nodes_Block(n)),
get_Sync_n_preds(n), in);
}
......@@ -300,6 +310,8 @@ copy_node (ir_node *n, void *env) {
case iro_Tuple:
{
ir_node **in = get_Tuple_preds_arr(n);
for (i = 0; i < get_Tuple_n_preds(n); i++)
set_Tuple_pred(n, i, get_new_node(get_Tuple_pred(n, i)));
res = new_r_Tuple (current_ir_graph, get_new_node(get_nodes_Block(n)),
get_Tuple_n_preds(n), in);
}
......@@ -309,9 +321,10 @@ copy_node (ir_node *n, void *env) {
get_new_node(get_Id_pred(n)), get_irn_mode(n));
break;
case iro_Bad:
res = new_r_Bad (get_new_node(get_nodes_Block(n)));
res = new_r_Bad ();
break;
}
/* @@@ Here we could call optimize()!! */
set_new_node(n, res);
}
......@@ -336,21 +349,58 @@ dead_node_elimination(ir_graph *irg) {
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");
/* 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);
irg->start_block = new_node; ;
new_node = new_r_Block (current_ir_graph, 0, NULL); /* new_r_Block calls
no optimization --> save */
irg->start_block = new_node;
set_new_node (old_node, new_node);
set_irn_visited (new_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 (new_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 (new_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;
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! */
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 (new_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 (new_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");
......@@ -358,8 +408,5 @@ dead_node_elimination(ir_graph *irg) {
xfree (graveyard_obst);
}
/* Free memory from old unoptimized obstack */
xfree (graveyard_obst);
current_ir_graph = rem;
}
......@@ -3,7 +3,7 @@
**
** Author: Christian Schaefer
**
** dead node elemination
** dead node elimination
** walks one time through the whole graph and copies it into another graph,
** so unreachable nodes will be lost.
*/
......@@ -17,6 +17,6 @@
void local_optimize_graph (ir_graph *irg);
/* Performs dead node elimination by copying the ir graph to a new obstack. */
void dead_node_elemination(ir_graph *irg);
void dead_node_elimination(ir_graph *irg);
# endif /* _IRGOPT_H_ */
......@@ -76,6 +76,11 @@ new_ir_node (ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mode,
memcpy (&res->in[1], in, sizeof (ir_node *) * arity);
}
res->in[0] = block;
#ifdef DEBUG_libfirm
res->node_nr = get_irp_new_node_nr();
#endif
return res;
}
......@@ -92,7 +97,7 @@ ir_node_print (XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
return printed;
}
XPF1 ("%I", get_irn_op(np)->name);
XPF1 ("%I", get_irn_opname(np));
switch (get_irn_opcode (np)) { /* node label */
case iro_Const:
......@@ -194,6 +199,14 @@ get_irn_modecode (ir_node *node)
return node->mode->code;
}
inline ident *
get_irn_modename (ir_node *node)
{
assert(node);
return node->mode->name;
}
inline ir_op *
get_irn_op (ir_node *node)
{
......@@ -209,11 +222,18 @@ set_irn_op (ir_node *node, ir_op *op)
node->op = op;
}
inline void
set_irn_visited (ir_node *node, unsigned long visited)
inline opcode
get_irn_opcode (ir_node *node)
{
assert (node);
node->visited = visited;
return node->op->code;
}
inline ident *
get_irn_opname (ir_node *node)
{
assert(node);
return node->op->name;
}
inline unsigned long
......@@ -223,13 +243,12 @@ get_irn_visited (ir_node *node)
return node->visited;
}
inline opcode
get_irn_opcode (ir_node *node)
inline void
set_irn_visited (ir_node *node, unsigned long visited)
{
assert (node);
return node->op->code;
node->visited = visited;
}
inline void
set_irn_link (ir_node *node, ir_node *link) {
assert (node);
......@@ -242,6 +261,15 @@ get_irn_link (ir_node *node) {
return node->link;
}
#ifdef DEBUG_libfirm
/* Outputs a unique number for this node */
inline long
get_irn_node_nr(ir_node *node) {
assert(node);
return node->node_nr;
}
#endif
inline tarval *
get_irn_const_attr (ir_node *node)
{
......
......@@ -17,6 +17,16 @@
# include "tv.h"
# include "type.h"
/** Global flags. Set these by autoconf?? **/
/* If this is defined debuging aids are created, e.g. a field in
ir_node uniquely numbering the nodes. */
/* @@@???? this is also set in firm.h */
#define DEBUG_libfirm
#ifdef DEBUG_libfirm
#include "irprog.h"
#endif
/* projection numbers of compare. */
enum {
False, /* false */
......@@ -146,6 +156,10 @@ struct ir_node {
used while construction to link Phi0 nodes and
during optimization to link to nodes that
shall replace a node. */
#ifdef DEBUG_libfirm
int node_nr; /* a unique node number for each node to make output
readable. */
#endif
attr attr; /* attribute of this node. Depends on opcode. */
/* Must be last field of struct ir_node. */
};
......@@ -188,19 +202,31 @@ inline ir_node **get_irn_in (ir_node *node);
To iterate over the operands iterate from 0 to i < get_irn_arity(),
to iterate includind the Block predecessor iterate from i = -1 to
i < get_irn_arity. */
/* Access predecessor n */
inline ir_node *get_irn_n (ir_node *node, int n);
inline void set_irn_n (ir_node *node, int n, ir_node *in);
/* Get the mode struct. */
inline ir_mode *get_irn_mode (ir_node *node);
/* Get the mode-enum modecode */
inline modecode get_irn_modecode (ir_node *node);
inline void set_irn_op (ir_node *node, ir_op *op);
/* Get the ident for a string representation of the mode */
inline ident *get_irn_modename (ir_node *node);
/* Access the opcode struct of the node */
inline ir_op *get_irn_op (ir_node *node);
inline void set_irn_op (ir_node *node, ir_op *op);
/* Get the opcode-enum of the node */
inline opcode get_irn_opcode (ir_node *node);
/* Get the ident for a string representation of the opcode */
inline ident *get_irn_opname (ir_node *node);
inline void set_irn_visited (ir_node *node, unsigned long visited);
inline unsigned long get_irn_visited (ir_node *node);
/* should be private to the library: */