# include "irgwalk.h"
# include "typewalk.h"
+/* Attributes of nodes */
#define DEFAULT_NODE_ATTR ""
+#define DEFAULT_TYPE_ATTRIBUTE ""
+
+/* Attributes of edges between Firm nodes */
#define BLOCK_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
+#define CF_EDGE_ATTR "color: red"
+#define MEM_EDGE_ATTR "color: blue"
+
+/* Attributes of edges between Firm nodes and type/entity nodes */
#define NODE2TYPE_EDGE_ATTR ""
-#define DEFAULT_TYPE_ATTRIBUTE ""
-#define TYPE_EDGE_ATTR ""
+
+/* Attributes of edges in type/entity graphs. */
+#define TYPE_METH_NODE_ATTR "color: lightyellow"
+#define TYPE_CLASS_NODE_ATTR "color: green"
+#define ENTITY_NODE_ATTR "color: yellow"
+#define ENT_TYPE_EDGE_ATTR "label: \"type\" color: red"
+#define ENT_OWN_EDGE_ATTR "label: \"owner\" color: black"
+#define METH_PAR_EDGE_ATTR "label: \"param %d\" color: green"
+#define METH_RES_EDGE_ATTR "label: \"res %d\" color: green"
+#define TYPE_SUPER_EDGE_ATTR "label: \"supertype\" color: blue"
+#define PTR_PTS_TO_EDGE_ATTR "label: \"points to\" color:green"
+#define ARR_ELT_TYPE_EDGE_ATTR "label: \"arr elt\" color:green"
#define PRINT_NODEID(X) fprintf(F, "%p", X)
xfprintf (F, "%ld", n->attr.proj);
}
break;
- case iro_Sel:
- /*assert(n->attr.s.ent->kind == k_entity);*/
+ case iro_Sel: {
assert(get_kind(get_Sel_entity(n)) == k_entity);
xfprintf (F, "%s", id_to_str(get_entity_ident(get_Sel_entity(n))));
-
- /* xdoesn't work for some reason.
- fprintf (F, "\"%I %I\" ", get_irn_opident(n), n->attr.s.ent); */
- break;
+ } break;
default:
} /* end switch */
}
assert(get_kind(get_Sel_entity(n)) == k_entity);
xfprintf (F, "\"%I ", get_irn_opident(n));
xfprintf (F, "%s", id_to_str(get_entity_ident(get_Sel_entity(n))));
- /* xdoesn't work for some reason.
- fprintf (F, "\"%I %I\" ", get_irn_opident(n), get_entity_ident(get_Sel_entity(n))); */
xfprintf (F, DEFAULT_NODE_ATTR);
break;
case iro_SymConst:
BLOCK_EDGE_ATTR "}\n", n, get_nodes_Block(n));
}
+void print_edge_vcgattr(ir_node *from, int to) {
+ assert(from);
+
+ switch (get_irn_opcode(from)) {
+ case iro_Block:
+ xfprintf (F, CF_EDGE_ATTR);
+ break;
+ case iro_Start: break;
+ case iro_End: break;
+ case iro_Jmp: break;
+ case iro_Cond: break;
+ case iro_Return:
+ case iro_Raise:
+ if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
+ break;
+ case iro_Const: break;
+ case iro_SymConst:break;
+ case iro_Sel:
+ case iro_Call:
+ if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
+ break;
+ case iro_Add: break;
+ case iro_Sub: break;
+ case iro_Minus: break;
+ case iro_Mul: break;
+ case iro_Quot:
+ case iro_DivMod:
+ case iro_Div:
+ case iro_Mod:
+ if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
+ break;
+ case iro_Abs: break;
+ case iro_And: break;
+ case iro_Or: break;
+ case iro_Eor: break;
+ case iro_Shl: break;
+ case iro_Shr: break;
+ case iro_Shrs: break;
+ case iro_Rot: break;
+ case iro_Cmp: break;
+ case iro_Conv: break;
+ case iro_Phi:
+ if (get_irn_modecode(from) == irm_M) xfprintf (F, MEM_EDGE_ATTR);
+ break;
+ case iro_Load:
+ case iro_Store:
+ case iro_Alloc:
+ case iro_Free:
+ if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
+ break;
+ case iro_Sync:
+ xfprintf (F, MEM_EDGE_ATTR);
+ break;
+ case iro_Tuple: break;
+ case iro_Proj:
+ switch (get_irn_modecode(from)) {
+ case irm_X:
+ xfprintf (F, CF_EDGE_ATTR);
+ break;
+ case irm_M:
+ xfprintf (F, MEM_EDGE_ATTR);
+ break;
+ default: break;
+ }
+ break;
+ case iro_Bad: break;
+ case iro_Id: break;
+ default:
+ }
+}
/* dump edges to our inputs */
void
assert(get_irn_n(n, i));
xfprintf (F, "edge: {sourcename: \"%p\" targetname: \"%p\"",
n, get_irn_n(n, i));
- fprintf (F, " label: \"%d\"", i+1);
+ fprintf (F, " label: \"%d\" ", i+1);
+ print_edge_vcgattr(n, i);
fprintf (F, "}\n");
}
}
case k_entity:
{
entity *ent = (entity *)tore;
- xfprintf (F, "\"ent %I\"}\n", get_entity_ident(ent));
+ xfprintf (F, "\"ent %I\" " ENTITY_NODE_ATTR "}\n", get_entity_ident(ent));
xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
- " label: \"owner\" "
- TYPE_EDGE_ATTR "}\n", tore, get_entity_owner(ent));
+ ENT_OWN_EDGE_ATTR "}\n", tore, get_entity_owner(ent));
xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
- " label: \"type\" "
- TYPE_EDGE_ATTR "}\n", tore, get_entity_type(ent));
+ ENT_TYPE_EDGE_ATTR "}\n", tore, get_entity_type(ent));
} break;
case k_type_class:
{
type_class *type = (type_class *)tore;
- xfprintf (F, "\"class %I\"}\n", get_class_ident(type));
+ xfprintf (F, "\"class %I\" " TYPE_CLASS_NODE_ATTR "}\n", get_class_ident(type));
for (i=0; i < get_class_n_supertype(type); i++)
xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
- " label: \"supertype\" " TYPE_EDGE_ATTR "}\n",
+ TYPE_SUPER_EDGE_ATTR "}\n",
type, get_class_supertype(type, i));
} break;
case k_type_strct:
{
type_strct *type = (type_strct *)tore;
xfprintf (F, "\"strct %I\"}\n", get_strct_ident(type));
+ /* edges !!!??? */
} break;
case k_type_method:
{
type_method *type = (type_method *)tore;
- xfprintf (F, "\"meth %I\"}\n", get_method_ident(type));
+ xfprintf (F, "\"meth %I\" " TYPE_METH_NODE_ATTR "}\n", get_method_ident(type));
for (i = 0; i < get_method_arity(type); i++)
xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
- " label: \"param %d\" " TYPE_EDGE_ATTR "}\n",
+ METH_PAR_EDGE_ATTR "}\n",
tore, get_method_param_type(type, i), i);
for (i = 0; i < get_method_n_res(type); i++)
xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
- " label: \"res %d\" " TYPE_EDGE_ATTR "}\n",
+ METH_RES_EDGE_ATTR "}\n",
tore, get_method_res_type(type, i), i);
} break;
case k_type_union:
type_array *type = (type_array *)tore;
xfprintf (F, "\"array %I\"}\n", get_array_ident(type));
xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
- TYPE_EDGE_ATTR "}\n", tore, get_array_element_type(type), i);
+ ARR_ELT_TYPE_EDGE_ATTR "}\n", tore, get_array_element_type(type), i);
+ /* edges !!!??? */
} break;
case k_type_enumeration:
{
type_pointer *type = (type_pointer *)tore;
xfprintf (F, "\"ptr %I\"}\n", get_pointer_ident(type));
xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
- TYPE_EDGE_ATTR "}\n", tore,
+ PTR_PTS_TO_EDGE_ATTR "}\n", tore,
get_pointer_points_to_type(type), i);
} break;
case k_type_primitive:
# include "misc.h"
# include "irgmod.h"
+# include "pset.h"
+pset *new_identities (void);
+void del_identities (pset *value_table);
+
/********************************************************************/
/* apply optimizations of iropt to all nodes. */
/********************************************************************/
ir_graph *rem = current_ir_graph;
current_ir_graph = irg;
+ /* Should we clean the value_table in irg for the cse? Better do so... */
+ del_identities(irg->value_table);
+ irg->value_table = new_identities();
+
/* walk over the graph */
irg_walk(irg->end, NULL, optimize_in_place_wrapper, NULL);
/* Copies the node to the new obstack. The Ins of the new node point to
the predecessors on the old obstack. n->link points to the new node.
- For Phi and Block nodes the function allocate in arrays with an arity
+ For Phi and Block nodes the function allocates in-arrays with an arity
only for useful predecessors. The arity is determined by counting
the non-bad predecessors of the block. */
inline void
get_irn_mode(n),
new_arity,
get_irn_in(n));
+ /* Copy the attributes. These might point to additional data. If this
+ was allocated on the old obstack the pointers now are dangling. This
+ frees e.g. the memory of the graph_arr allocated in new_immBlock. */
copy_attrs(n, nn);
set_new_node(n, nn);
}
Spare the Bad predecessors of Phi and Block nodes. */
inline void
copy_preds (ir_node *n, void *env) {
- ir_node *nn, *block/*, *on*/;
+ ir_node *nn, *block, *on;
int i, j;
nn = get_new_node(n);
/* repair the block visited flag from above misuse */
set_Block_block_visited(nn, 0);
/* Local optimization could not merge two subsequent blocks if
- in array contained Bads. Now it's possible. *
+ in array contained Bads. Now it's possible. */
on = optimize_in_place(nn);
- if (nn != on) exchange(nn, on);*/
+ if (nn != on) exchange(nn, on);
} else if (get_irn_opcode(n) == iro_Phi) {
/* Don't copy node if corresponding predecessor in block is Bad.
The Block itself should not be Bad. */
j++;
}
/* Compacting the Phi's ins might generate Phis with only one
- predecessor. *
+ predecessor. */
if (get_irn_arity(n) == 1)
- exchange(n, get_irn_n(n, 0)); */
+ exchange(n, get_irn_n(n, 0));
} else {
for (i = -1; i < get_irn_arity(n); i++)
set_irn_n (nn, i, get_new_node(get_irn_n(n, i)));