#include "callgraph.h"
#include "irextbb_t.h"
#include "dbginfo_t.h"
+#include "irtools.h"
#include "irvrfy.h"
}
-/** The vcg attribute hook. */
+/** The vcg node attribute hook. */
+static DUMP_IR_GRAPH_FUNC dump_ir_graph_hook = NULL;
+/** The vcg node attribute hook. */
static DUMP_NODE_VCGATTR_FUNC dump_node_vcgattr_hook = NULL;
+/** The vcg edge attribute hook. */
+static DUMP_EDGE_VCGATTR_FUNC dump_edge_vcgattr_hook = NULL;
-/* set the hook */
+/* set the ir graph hook */
+void set_dump_ir_graph_hook(DUMP_IR_GRAPH_FUNC hook) {
+ dump_ir_graph_hook = hook;
+}
+/* set the node attribute hook */
void set_dump_node_vcgattr_hook(DUMP_NODE_VCGATTR_FUNC hook) {
dump_node_vcgattr_hook = hook;
}
+/* set the edge attribute hook */
+void set_dump_edge_vcgattr_hook(DUMP_EDGE_VCGATTR_FUNC hook) {
+ dump_edge_vcgattr_hook = hook;
+}
INLINE bool get_opt_dump_const_local(void) {
if (!dump_out_edge_flag && !dump_loop_information_flag)
return id_is_prefix(dump_file_filter_id, name);
}
-/* To turn off display of edge labels. Edge labels offen cause xvcg to
+/* To turn off display of edge labels. Edge labels often cause xvcg to
abort with a segmentation fault. */
void turn_off_edge_labels(void) {
edge_label = 0;
* Sets the private link field.
*/
static void ird_set_irn_link(ir_node *n, void *x) {
- if (!irdump_link_map) init_irdump();
+ if (!irdump_link_map)
+ init_irdump();
pmap_insert(irdump_link_map, (void *)n, x);
}
case iro_Load:
fprintf (F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_Load_mode(n), &bad));
break;
+ case iro_Block:
+ fprintf (F, "%s%s", is_Block_dead(n) ? "Dead " : "", get_irn_opname(n));
+ break;
default: {
default_case:
fprintf (F, "edge: { sourcename: \"");
PRINT_NODEID(n);
fprintf (F, "\" targetname: \""); PRINT_CONSTBLKID(n,blk);
+
+ if (dump_edge_vcgattr_hook) {
+ fprintf (F, "\" ");
+ if (dump_edge_vcgattr_hook(F, n, -1)) {
+ fprintf (F, "}\n");
+ return;
+ }
+ else {
+ fprintf (F, " " BLOCK_EDGE_ATTR "}\n");
+ return;
+ }
+ }
+
fprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
}
}
PRINT_NODEID(n);
fprintf (F, "\" targetname: ");
fprintf(F, "\""); PRINT_NODEID(block); fprintf(F, "\"");
+
+ if (dump_edge_vcgattr_hook) {
+ fprintf (F, " ");
+ if (dump_edge_vcgattr_hook(F, n, -1)) {
+ fprintf (F, "}\n");
+ return;
+ }
+ else {
+ fprintf (F, " " BLOCK_EDGE_ATTR "}\n");
+ return;
+ }
+ }
+
fprintf (F, " " BLOCK_EDGE_ATTR "}\n");
}
}
print_edge_vcgattr(FILE *F, ir_node *from, int to) {
assert(from);
+ if (dump_edge_vcgattr_hook)
+ if (dump_edge_vcgattr_hook(F, from, to))
+ return;
+
if (dump_backedge_information_flag && is_backedge(from, to))
fprintf (F, BACK_EDGE_ATTR);
static void
dump_whole_block(FILE *F, ir_node *block) {
ir_node *node;
+ const char *color = "yellow";
+
assert(is_Block(block));
fprintf(F, "graph: { title: \"");
if (get_opt_dump_abstvals())
fprintf (F, " seqno: %d", (int)get_Block_seqno(block));
#endif
- fprintf(F, "\" status:clustered color:%s \n",
- get_Block_matured(block) ? "yellow" : "red");
+
+ /* colorize blocks */
+ if (! get_Block_matured(block))
+ color = "red";
+ if (is_Block_dead(block))
+ color = "orange";
+
+ fprintf(F, "\" status:clustered color:%s \n", color);
+
+ /* ycomp can show attributs for blocks, VCG parses but ignores them */
+ dump_node_info(F, block);
/* dump the blocks edges */
dump_ir_data_edges(F, block);
fprintf (F, " info1: \"");
fprintf (F, " loop nr: %d", get_loop_loop_nr(loop));
#if DEBUG_libfirm /* GL @@@ debug analyses */
- fprintf (F, "\n The loop was analyzed %d times.", (int)get_loop_link(loop));
+ fprintf (F, "\n The loop was analyzed %d times.", PTR_TO_INT(get_loop_link(loop)));
#endif
fprintf (F, "\"");
}
f = vcg_open(irg, suffix, suffix1);
dump_vcg_header(f, get_irg_dump_name(irg), NULL);
+ /* call the dump graph hook */
+ if (dump_ir_graph_hook)
+ if (dump_ir_graph_hook(f, irg))
+ return;
+
/* walk over the graph */
/* dump_whole_node must be called in post visiting predecessors */
irg_walk(get_irg_end(irg), NULL, dump_whole_node, f);