# include "exc.h"
+# include "pmap.h"
+
/* Attributes of nodes */
#define DEFAULT_NODE_ATTR ""
#define DEFAULT_TYPE_ATTRIBUTE ""
#if DEBUG_libfirm && NODEID_AS_LABEL
-#define PRINT_NODEID(X) fprintf(F, "%d", get_irn_node_nr(X))
+#define PRINT_NODEID(X) fprintf(F, "%ld", get_irn_node_nr(X))
#else
#define PRINT_NODEID(X) fprintf(F, "%p", X)
#endif
inline void
dump_node_opcode (ir_node *n)
{
+ assert(n && n->op);
/* Const */
if (n->op->code == iro_Const) {
else
xfprintf (F, "size");
}
+
+ /* Filter */
+ } else if (n->op->code == iro_Filter && !interprocedural_view) {
+ fprintf(F, "Proj'");
+
/* all others */
} else {
xfprintf (F, "%I", get_irn_opident(n));
case iro_Const:
case iro_Id:
case iro_Proj:
+ case iro_Filter:
case iro_Conv:
case iro_Tuple:
case iro_Add:
xfprintf (F, "%ld", n->attr.proj);
}
break;
+ case iro_Filter:
+ xfprintf (F, "%ld", n->attr.filter.proj);
+ break;
case iro_Sel: {
assert(get_kind(get_Sel_entity(n)) == k_entity);
xfprintf (F, "%I", get_entity_ident(get_Sel_entity(n)));
{
switch (n->op->code) {
case iro_Start:
+ case iro_EndReg:
+ /* fall through */
+ case iro_EndExcept:
+ /* fall through */
case iro_End:
xfprintf (F, "color: blue");
break;
break;
case iro_Const:
case iro_Proj:
+ case iro_Filter:
case iro_Tuple:
xfprintf (F, "color: yellow");
break;
xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
xfprintf (F, DEFAULT_NODE_ATTR);
break;
+ case iro_EndReg:
+ /* fall through */
+ case iro_EndExcept:
+ /* fall through */
case iro_End:
xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
xfprintf (F, DEFAULT_NODE_ATTR);
}
xfprintf (F, DEFAULT_NODE_ATTR);
break;
+ case iro_Filter:
+ xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.filter.proj);
+ xfprintf (F, DEFAULT_NODE_ATTR);
+ break;
case iro_Conv:
xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
xfprintf (F, DEFAULT_NODE_ATTR);
xfprintf (F, "\"%I\"", get_irn_opident(n));
xfprintf (F, DEFAULT_NODE_ATTR);
break;
+ case iro_Break:
+ xfprintf (F, "\"%I\"", get_irn_opident(n));
+ xfprintf (F, DEFAULT_NODE_ATTR);
+ break;
case iro_Cond:
xfprintf (F, "\"%I\"", get_irn_opident(n));
xfprintf (F, DEFAULT_NODE_ATTR);
xfprintf (F, "\"%I\"", get_irn_opident(n));
xfprintf (F, DEFAULT_NODE_ATTR);
break;
+ case iro_CallBegin:
+ xfprintf (F, "\"%I\"", get_irn_opident(n));
+ xfprintf (F, DEFAULT_NODE_ATTR);
+ break;
case iro_Return:
xfprintf (F, "\"%I\"", get_irn_opident(n));
xfprintf (F, DEFAULT_NODE_ATTR);
xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
xfprintf (F, DEFAULT_NODE_ATTR);
break;
+ case iro_Unknown:
+ xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
+ xfprintf (F, DEFAULT_NODE_ATTR);
+ break;
default:
xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
}
xfprintf (F, MEM_EDGE_ATTR);
}
break;
+ case iro_EndReg: break;
+ case iro_EndExcept: break;
case iro_Jmp: break;
+ case iro_Break: break;
case iro_Cond: break;
case iro_Return:
case iro_Raise:
case iro_Call:
if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
break;
+ case iro_CallBegin: break;
case iro_Add: break;
case iro_Sub: break;
case iro_Minus: break;
break;
case iro_Tuple: break;
case iro_Proj:
+ case iro_Filter:
switch (get_irn_modecode(from)) {
case irm_X:
xfprintf (F, CF_EDGE_ATTR);
}
break;
case iro_Bad: break;
+ case iro_Unknown: break;
case iro_Id: break;
default:
}
/* dump edges to our inputs */
void
dump_ir_data_edges(ir_node *n) {
- int i, max;
+ int i, visited = get_irn_visited(n);
if ((get_irn_op(n) == op_End) && (!dump_keepalive))
return;
for (i = 0; i < get_irn_arity(n); i++) {
- assert(get_irn_n(n, i));
+ ir_node * pred = get_irn_n(n, i);
+ assert(pred);
+ if (interprocedural_view && get_irn_visited(pred) < visited) continue; /* pred not dumped */
fprintf (F, "edge: {sourcename: \"");
PRINT_NODEID(n);
fprintf (F, "\" targetname: \"");
- PRINT_NODEID(get_irn_n(n, i));
+ PRINT_NODEID(pred);
fprintf (F, "\"");
fprintf (F, " label: \"%d\" ", i);
print_edge_vcgattr(n, i);
/* routines to dump a graph, blocks as conventional nodes. */
/************************************************************************/
+int node_floats(ir_node *n) {
+
+ return ((get_op_pinned(get_irn_op(n)) == floats) &&
+ (get_irg_pinned(current_ir_graph) == floats));
+}
+
void
dump_whole_node (ir_node *n, void* env) {
dump_node(n);
vcg_open (irg, "");
/* walk over the graph */
- irg_walk(irg->end, dump_whole_node, NULL, NULL);
+ /* dump_whole_node must be called in post visiting predecessors */
+ irg_walk(irg->end, NULL, dump_whole_node, NULL);
/* dump the out edges in a separate walk */
if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
/* the following routines dump the nodes as attached to the blocks. */
/***********************************************************************/
-int node_floats(ir_node *n) {
-
- return ((get_op_pinned(get_irn_op(n)) == floats) &&
- (get_irg_pinned(current_ir_graph) == floats));
-}
-
void
dump_ir_blocks_nodes (ir_node *n, void *env) {
ir_node *block = (ir_node *)env;
#else
xfprintf (F, "%I", block->op->name);
#endif
- if (exc_normal != get_Block_exc (block))
- fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
+ if (exc_normal != get_Block_exc (block))
+ fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
xfprintf(F, "\" status:clustered color:%s \n",
- get_Block_matured (block) ? "yellow" : "red");
+ get_Block_matured (block) ? "yellow" : "red");
/* dump the blocks edges */
dump_ir_data_edges(block);
void dump_dominator_information() {
dump_dominator_information_flag = 1;
}
+
+
+static void clear_link(ir_node * node, void * env) {
+ set_irn_link(node, NULL);
+}
+
+
+static inline bool is_Block(ir_node * node) {
+ return !is_no_Block(node);
+}
+
+
+static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
+ if (is_Block(node)
+ || node_floats(node)
+ || get_irn_op(node) == op_Bad
+ || get_irn_op(node) == op_Unknown) {
+ pmap_entry * entry = pmap_find(map, current_ir_graph);
+ if (entry) {
+ ARR_APP1(ir_node *, (ir_node **) entry->value, node);
+ } else {
+ ir_node ** arr = NEW_ARR_F(ir_node *, 1);
+ arr[0] = node;
+ pmap_insert(map, current_ir_graph, arr);
+ }
+ } else {
+ ir_node * block = get_nodes_Block(node);
+ set_irn_link(node, get_irn_link(block));
+ set_irn_link(block, node);
+ }
+}
+
+
+static void dump_cg_ir_block(ir_node * node, void * env) {
+ assert(is_Block(node));
+ xfprintf(F, "graph: { title: \"");
+ PRINT_NODEID(node);
+ fprintf(F, "\" label: \"");
+#ifdef DEBUG_libfirm
+ xfprintf (F, "%ld", get_irn_node_nr(node));
+#else
+ xfprintf (F, "%I", node->op->name);
+#endif
+ if (exc_normal != get_Block_exc(node)) {
+ fprintf (F, " (%s)", exc_to_string (get_Block_exc(node)));
+ }
+
+ xfprintf(F, "\" status:clustered color:%s \n",
+ get_Block_matured(node) ? "yellow" : "red");
+
+ /* dump the blocks edges */
+ dump_ir_data_edges(node);
+
+ /* dump the nodes that go into the block */
+ for (node = get_irn_link(node); node; node = get_irn_link(node)) {
+ dump_node(node);
+ dump_ir_data_edges(node);
+ }
+
+ /* Close the vcg information for the block */
+ xfprintf(F, "}\n\n");
+}
+
+
+/* dump interprocedural graph with surrounding methods */
+void dump_cg_block_graph(ir_graph * irg) {
+ pmap * map = pmap_create();
+ pmap_entry * entry;
+ vcg_open(irg, "");
+
+ irg_walk_graph(irg, clear_link, (irg_walk_func) collect_blocks_floats_cg, map);
+ for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
+ ir_node ** arr = entry->value;
+ int i;
+
+ xfprintf(F, "graph: { title: \"%I\" label: \"%I\" status:clustered color:white \n",
+ get_entity_ident(get_irg_ent(entry->key)),
+ get_entity_ident(get_irg_ent(entry->key)));
+
+ for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
+ ir_node * node = arr[i];
+ if (is_Block(node)) {
+ dump_cg_ir_block(node, NULL);
+ } else {
+ dump_node(node);
+ dump_ir_data_edges(node);
+ }
+ }
+
+ DEL_ARR_F(arr);
+
+ /* Close the vcg information for the irg */
+ xfprintf(F, "}\n\n");
+ }
+
+ pmap_destroy(map);
+
+ vcg_close();
+}
+
+
+/* dump interprocedural block graph with surrounding methods */
+void dump_cg_graph(ir_graph * irg) {
+ pmap * map = pmap_create();
+ pmap_entry * entry;
+ vcg_open(irg, "");
+
+ irg_walk_graph(irg, clear_link, (irg_walk_func) collect_blocks_floats_cg, map);
+ for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
+ ir_node ** arr = entry->value;
+ int i;
+ ident * irg_ident = get_entity_ident(get_irg_ent(entry->key));
+
+ xfprintf(F, "graph: { title: \"%I\" label: \"%I\" status:clustered color:white \n",
+ irg_ident, irg_ident);
+
+ for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
+ ir_node * node = arr[i];
+ dump_node(node);
+ dump_ir_data_edges(node);
+ if (is_Block(node)) {
+ for (node = get_irn_link(node); node; node = get_irn_link(node)) {
+ dump_node(node);
+ dump_ir_block_edge(node);
+ dump_ir_data_edges(node);
+ }
+ }
+ }
+
+ DEL_ARR_F(arr);
+
+ /* Close the vcg information for the irg */
+ xfprintf(F, "}\n\n");
+ }
+
+ pmap_destroy(map);
+
+ vcg_close();
+}