added two more hooks to the ir graph dumper
[libfirm] / ir / ir / irdump.c
index 7c3be78..722b91c 100644 (file)
@@ -41,6 +41,7 @@
 #include "callgraph.h"
 #include "irextbb_t.h"
 #include "dbginfo_t.h"
+#include "irtools.h"
 
 #include "irvrfy.h"
 
@@ -104,13 +105,25 @@ DUMP_NODE_EDGE_FUNC get_dump_node_edge_hook(void)
 }
 
 
-/** 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)
@@ -134,7 +147,7 @@ int is_filtered_dump_name(ident *name) {
   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;
@@ -394,7 +407,8 @@ static void *ird_get_irn_link(ir_node *n) {
  * 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);
 }
 
@@ -426,10 +440,10 @@ static void clear_link(ir_node * node, void * env) {
 }
 
 /**
- * If the entity has a ld_name, returns it if the option dump_ld_name is set,
+ * If the entity has a ld_name, returns it if the dump_ld_name is set,
  * else returns the name of the entity.
  */
-const char *get_ent_dump_name(entity *ent) {
+static const char *_get_ent_dump_name(entity *ent, int dump_ld_name) {
   if (!ent)
     return "<NULL entity>";
   if (dump_ld_name) {
@@ -439,11 +453,18 @@ const char *get_ent_dump_name(entity *ent) {
   return get_id_str(ent->name);
 }
 
+/**
+ * If the entity has a ld_name, returns it if the option dump_ld_name is set,
+ * else returns the name of the entity.
+ */
+const char *get_ent_dump_name(entity *ent) {
+  return _get_ent_dump_name(ent, dump_ld_name);
+}
+
 /* Returns the name of an IRG. */
 const char *get_irg_dump_name(ir_graph *irg) {
   /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
-  entity *ent = get_irg_entity(irg);
-  return get_ent_dump_name(ent);
+  return _get_ent_dump_name(get_irg_entity(irg), 1);
 }
 
 /**
@@ -638,6 +659,9 @@ dump_node_opcode(FILE *F, ir_node *n)
   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:
@@ -867,6 +891,12 @@ handle_lut:
       }
       if (! f)
         fprintf (F, "%ld ", proj_nr);
+      if (code == iro_Cond && get_Cond_jmp_pred(pred) != COND_JMP_PRED_NONE) {
+        if (proj_nr == pn_Cond_false && get_Cond_jmp_pred(pred) == COND_JMP_PRED_FALSE)
+          fprintf(F, "PRED ");
+        if (proj_nr == pn_Cond_true && get_Cond_jmp_pred(pred) == COND_JMP_PRED_TRUE)
+          fprintf(F, "PRED ");
+      }
     }
     break;
   case iro_Filter:
@@ -1055,6 +1085,19 @@ static void dump_const_block_local(FILE *F, ir_node *n) {
     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");
   }
 }
@@ -1133,6 +1176,19 @@ dump_ir_block_edge(FILE *F, ir_node *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");
     }
   }
@@ -1166,6 +1222,10 @@ static void
 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);
 
@@ -1372,6 +1432,8 @@ static void dump_const_expression(FILE *F, ir_node *value) {
 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: \"");
@@ -1382,8 +1444,17 @@ dump_whole_block(FILE *F, ir_node *block) {
   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);
@@ -1462,7 +1533,7 @@ dump_extblock_graph(FILE *F, ir_graph *irg) {
   compute_extbb(irg);
   for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
     ir_extblk *extbb = arr[i];
-    ir_node *leader = extbb->blks[0];
+    ir_node *leader = get_extbb_leader(extbb);
     int j;
 
     fprintf(F, "graph: { title: \"");
@@ -1888,7 +1959,7 @@ static INLINE void dump_loop_info(FILE *F, ir_loop *loop) {
   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, "\"");
 }
@@ -2168,6 +2239,11 @@ dump_ir_graph (ir_graph *irg, const char *suffix )
   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);
@@ -2276,12 +2352,16 @@ dump_ir_graph_w_types (ir_graph *irg, const char *suffix)
   FILE *f;
   ir_graph *rem = current_ir_graph;
   char *suffix1;
+  int rem_dump_const_local;
 
   /* if a filter is set, dump only the irg's that match the filter */
   if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg))))
     return;
 
   current_ir_graph = irg;
+  rem_dump_const_local = dump_const_local;
+  /* dumping types does not work with local nodes */
+  dump_const_local = 0;
 
   if (get_interprocedural_view()) suffix1 = "-pure-wtypes-ip";
   else                            suffix1 = "-pure-wtypes";
@@ -2297,6 +2377,7 @@ dump_ir_graph_w_types (ir_graph *irg, const char *suffix)
   irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, f);
 
   vcg_close(f);
+  dump_const_local = rem_dump_const_local;
   current_ir_graph = rem;
 }
 
@@ -2307,11 +2388,16 @@ dump_ir_block_graph_w_types (ir_graph *irg, const char *suffix)
   int i;
   char *suffix1;
   ir_graph *rem = current_ir_graph;
+  int rem_dump_const_local;
 
   /* if a filter is set, dump only the irg's that match the filter */
   if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg))))
     return;
 
+  rem_dump_const_local = dump_const_local;
+  /* dumping types does not work with local nodes */
+  dump_const_local = 0;
+
   if (get_interprocedural_view()) suffix1 = "-wtypes-ip";
   else                            suffix1 = "-wtypes";
   f = vcg_open(irg, suffix, suffix1);
@@ -2336,8 +2422,9 @@ dump_ir_block_graph_w_types (ir_graph *irg, const char *suffix)
   /* dump edges from graph to type info */
   irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, f);
 
-  current_ir_graph = rem;
   vcg_close(f);
+  dump_const_local = rem_dump_const_local;
+  current_ir_graph = rem;
 }
 
 /*---------------------------------------------------------------------*/
@@ -2347,7 +2434,7 @@ dump_ir_block_graph_w_types (ir_graph *irg, const char *suffix)
 static void
 dump_block_to_cfg(ir_node *block, void *env) {
   FILE *F = env;
-  int i, fl;
+  int i, fl = 0;
   ir_node *pred;
 
   if (is_Block(block)) {