renamed get_type_nameid to get_type_ident
[libfirm] / ir / ir / irdump.c
index baf5464..519b5ca 100644 (file)
@@ -6,6 +6,10 @@
 ** irdump.h: dumping of an intermediate representation graph
 */
 
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
 # include "irnode_t.h"
 # include "irgraph_t.h"
 # include "irprog.h"
 # 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   "class: 3 label: \"type\" color: red"
+#define ENT_OWN_EDGE_ATTR    "class: 4 label: \"owner\" color: black"
+#define METH_PAR_EDGE_ATTR   "class: 5 label: \"param %d\" color: green"
+#define METH_RES_EDGE_ATTR   "class: 6 label: \"res %d\" color: green"
+#define TYPE_SUPER_EDGE_ATTR "class: 7 label: \"supertype\" color: blue"
+#define UNION_EDGE_ATTR      "class: 8 label: \"component\" color: blue"
+#define PTR_PTS_TO_EDGE_ATTR "class: 9 label: \"points to\" color:green"
+#define ARR_ELT_TYPE_EDGE_ATTR "class: 10 label: \"arr elt\" color:green"
+#define ENT_OVERWRITES_EDGE_ATTR "class: 11 label: \"overwrites\" color:red"
+#define TYPE_MEMBER_EDGE_ATTR "class: 12 label: \"member\" color:blue"
 
 #define PRINT_NODEID(X) fprintf(F, "%p", X)
 
 /* file to dump to */
 static FILE *F;
 
+int edge_label = 1;
 
 /*******************************************************************/
 /* routines to dump information about a single node                */
@@ -42,17 +68,19 @@ static FILE *F;
 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))));
+      assert(get_kind(get_SymConst_type(n)) == k_type);
+      assert(get_type_ident(get_SymConst_type(n)));
+      xfprintf (F, "%s ", id_to_str(get_type_ident(get_SymConst_type(n))));
       if (get_SymConst_kind == type_tag)
        xfprintf (F, "tag");
       else
@@ -60,7 +88,7 @@ dump_node_opcode (ir_node *n)
     }
   /* all others */
   } else {
-    xfprintf (F, "%I", n->op->name);
+    xfprintf (F, "%I", get_irn_opident(n));
   }
 }
 
@@ -84,7 +112,7 @@ dump_node_mode (ir_node *n)
   case iro_Shr:
   case iro_Abs:
   case iro_Cmp:
-    xfprintf (F, "%I", n->mode->name);
+    xfprintf (F, "%I", get_mode_ident(n->mode));
     break;
   default:
   }
@@ -101,14 +129,10 @@ dump_node_nodeattr (ir_node *n)
       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\" ", n->op->name, n->attr.s.ent); */
-    break;
+    } break;
   default:
   } /* end switch */
 }
@@ -163,123 +187,123 @@ dump_ir_node (ir_node *n)
 
   switch (n->op->code) {  /* node label */
   case iro_Start:
-    xfprintf (F, "\"%I\" color: blue ", n->op->name);
+    xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
      break;
   case iro_End:
-    xfprintf (F, "\"%I\" color: blue ", n->op->name);
+    xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Block:
-    xfprintf (F, "\"%I\" color: lightyellow ", n->op->name);
+    xfprintf (F, "\"%I\" color: lightyellow ", get_irn_opident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Phi:
-    xfprintf (F, "\"%I%I\" color: green", n->op->name, n->mode->name);
-    if (n->mode->code == irm_M)
+    xfprintf (F, "\"%I%I\" color: green", get_irn_opident(n), get_irn_modeident(n));
+    if (get_irn_modecode(n) == irm_M)
       xfprintf (F, DEFAULT_NODE_ATTR " color: green");
     else
       xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Const:
-    xfprintf (F, "\"%v%I\" color: yellow ", n->attr.con, n->mode->name);
+    xfprintf (F, "\"%v%I\" color: yellow ", n->attr.con, get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Id:
-    xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Proj:
     if (n->in[1]->op->code == iro_Cmp) {
-      xfprintf (F, "\"%I%I %s\" color: yellow", n->op->name, n->mode->name,
+      xfprintf (F, "\"%I%I %s\" color: yellow", get_irn_opident(n), get_irn_modeident(n),
                 get_pnc_string(n->attr.proj));
     } else {
-      xfprintf (F, "\"%I%I %ld\"", n->op->name, n->mode->name, n->attr.proj);
+      xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.proj);
     }
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Conv:
-    xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Tuple:
-    xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Add:
-    xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Sub:
-    xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Mul:
-    xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Quot:
-    xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_DivMod:
-    xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Div:
-    xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Mod:
-    xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_And:
-    xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Or:
-    xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Eor:
-    xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Shl:
-    xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Shr:
-    xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Abs:
-    xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Cmp:
-    xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Jmp:
-    xfprintf (F, "\"%I\"", n->op->name);
+    xfprintf (F, "\"%I\"", get_irn_opident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Cond:
-    xfprintf (F, "\"%I\"", n->op->name);
+    xfprintf (F, "\"%I\"", get_irn_opident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Call:
-    xfprintf (F, "\"%I\"", n->op->name);
+    xfprintf (F, "\"%I\"", get_irn_opident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Return:
-    xfprintf (F, "\"%I\"", n->op->name);
+    xfprintf (F, "\"%I\"", get_irn_opident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Raise:
-    xfprintf (F, "\"%I%I\"", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Load:
@@ -288,22 +312,19 @@ dump_ir_node (ir_node *n)
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Alloc:
-    xfprintf (F, "\"%I\" ", n->op->name);
+    xfprintf (F, "\"%I\" ", get_irn_opident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Sel:
     assert(get_kind(get_Sel_entity(n)) == k_entity);
-    xfprintf (F, "\"%I ", n->op->name);
+    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\" ", n->op->name, get_entity_ident(get_Sel_entity(n))); */
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_SymConst:
-    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))));
+    assert(get_kind(get_SymConst_type(n)) == k_type);
+    assert(get_type_ident(get_SymConst_type(n)));
+    xfprintf (F, "\"%s ", get_type_name(get_SymConst_type(n)));
     switch (n->attr.i.num){
     case type_tag:
       xfprintf (F, "tag\" ");
@@ -318,15 +339,15 @@ dump_ir_node (ir_node *n)
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   case iro_Sync:
-    xfprintf (F, "\"%I\" ", n->op->name);
+    xfprintf (F, "\"%I\" ", get_irn_opident(n));
     xfprintf (F, DEFAULT_NODE_ATTR " color: green");
     break;
   case iro_Bad:
-    xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
     xfprintf (F, DEFAULT_NODE_ATTR);
     break;
   default:
-    xfprintf (F, "\"%I%I\" ", n->op->name, n->mode->name);
+    xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
   }
   xfprintf (F, "}\n");         /* footer */
 }
@@ -340,6 +361,76 @@ dump_ir_block_edge(ir_node *n)  {
                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
@@ -350,7 +441,8 @@ dump_ir_data_edges(ir_node *n)  {
     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");
   }
 }
@@ -403,79 +495,97 @@ dump_type_info (type_or_ent *tore, void *env) {
   case k_entity:
     {
       entity *ent = (entity *)tore;
-      xfprintf (F, "\"ent %I\"}\n", get_entity_ident(ent));
+      xfprintf (F, "\"ent %I\" " ENTITY_NODE_ATTR , get_entity_ident(ent));
+      if(dynamic_allocated == get_entity_allocation(ent))
+       xfprintf (F, " info1:\"dynamic allocated\"}\n");
+      else
+       xfprintf (F, " info1:\"static allocated\"}\n");
       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));
-    } break;
-  case k_type_class:
-    {
-      type_class *type = (type_class *)tore;
-      xfprintf (F, "\"class %I\"}\n", get_class_ident(type));
-      for (i=0; i < get_class_n_supertype(type); i++)
+                ENT_TYPE_EDGE_ATTR "}\n", tore, get_entity_type(ent));
+      for(i = 0; i < get_entity_n_overwrites(ent); i++)
        xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
-                 " label: \"supertype\" " TYPE_EDGE_ATTR "}\n",
-                 type, get_class_supertype(type, i));
+                 ENT_OVERWRITES_EDGE_ATTR "}\n", tore, get_entity_overwrites(ent, i));
     } break;
-  case k_type_strct:
+  case k_type:
     {
-      type_strct *type = (type_strct *)tore;
-      xfprintf (F, "\"strct %I\"}\n", get_strct_ident(type));
-    } break;
-  case k_type_method:
-    {
-      type_method *type = (type_method *)tore;
-      xfprintf (F, "\"meth %I\"}\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",
-                 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",
-                 tore, get_method_res_type(type, i), i);
-    } break;
-  case k_type_union:
-    {
-      type_union *type = (type_union *)tore;
-      xfprintf (F, "\"union %I\"}\n", get_union_ident(type));
-      /* edges !!!??? */
-    } break;
-  case k_type_array:
-    {
-      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);
-    } break;
-  case k_type_enumeration:
-    {
-      type_enumeration *type = (type_enumeration *)tore;
-      xfprintf (F, "\"enum %I\"}\n", get_enumeration_ident(type));
-    } break;
-  case k_type_pointer:
-    {
-      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,
-               get_pointer_points_to_type(type), i);
-    } break;
-  case k_type_primitive:
-    {
-      type_primitive *type = (type_primitive *)tore;
-      xfprintf (F, "\"prim %I, mode %I\"}\n", get_primitive_ident(type),
-               get_mode_ident(get_primitive_mode(type)));
-    } break;
+      /* why can't I cast here??? @@@ */
+      type *type = tore;
+      xfprintf (F, "\"%I %I", get_type_tpop_nameid(type), get_type_ident(type));
+
+      switch (get_type_tpop_code(type)) {
+      case tpo_class:
+       {
+         xfprintf (F, "\" " TYPE_CLASS_NODE_ATTR "}\n");
+         for (i=0; i < get_class_n_supertype(type); i++)
+           xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
+                     TYPE_SUPER_EDGE_ATTR "}\n",
+                     type, get_class_supertype(type, i));
+         for (i=0; i < get_class_n_member(type); i++)
+           xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
+                     TYPE_MEMBER_EDGE_ATTR "}\n",
+                     type, get_class_member(type, i));
+       } break;
+      case tpo_struct:
+       {
+         xfprintf (F, "\"}\n");
+         for (i=0; i < get_struct_n_member(type); i++)
+           xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
+                     TYPE_MEMBER_EDGE_ATTR "}\n",
+                     type, get_struct_member(type, i));
+       } break;
+      case tpo_method:
+       {
+         xfprintf (F, "\" " TYPE_METH_NODE_ATTR "}\n");
+         for (i = 0; i < get_method_n_params(type); i++)
+           xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
+                     METH_PAR_EDGE_ATTR "}\n",
+                     type, get_method_param_type(type, i), i);
+         for (i = 0; i < get_method_n_res(type); i++)
+           xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
+                     METH_RES_EDGE_ATTR "}\n",
+                     type, get_method_res_type(type, i), i);
+       } break;
+      case tpo_union:
+       {
+         xfprintf (F, "\"}\n");
+         for (i = 0; i < get_union_n_members(type); i++)
+           xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
+                     "label: \"\"f" UNION_EDGE_ATTR "}\n",
+                     type, get_union_member(type, i));
+       } break;
+      case tpo_array:
+       {
+         xfprintf (F, "\"}\n");
+         xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
+                   ARR_ELT_TYPE_EDGE_ATTR "}\n", type, get_array_element_type(type), i);
+       } break;
+      case tpo_enumeration:
+       {
+         xfprintf (F, "\"}\n");
+       } break;
+      case tpo_pointer:
+       {
+         xfprintf (F, "\"}\n");
+         xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
+                   PTR_PTS_TO_EDGE_ATTR "}\n", type,
+                   get_pointer_points_to_type(type), i);
+       } break;
+      case tpo_primitive:
+       {
+         xfprintf (F, "mode %I\"}\n", get_mode_ident(get_type_mode(type)));
+       } break;
+      default: break;
+      } /* switch type */
+    }
+    break; /* case k_type */
   default:
     {
       xfprintf (F, "\" faulty type \"}\n");
       printf(" *** irdump,  %s(l.%i), faulty type.\n", __FUNCTION__, __LINE__);
     } break;
-  }
+  } /* switch kind_or_entity */
 }
 
 /************************************************************************/
@@ -487,9 +597,10 @@ void vcg_open (ir_graph *irg, char *suffix) {
   const char *cp;
   ident *id;
   int len;
+  char label[4];
 
   /** open file for vcg graph */
-  id    = get_entity_ld_name (get_irg_ent(irg));
+  id    = get_entity_ld_ident (get_irg_ent(irg));
   len   = id_to_strlen (id);
   cp    = id_to_str (id);
 
@@ -511,16 +622,33 @@ void vcg_open (ir_graph *irg, char *suffix) {
     panic ("cannot open %s for writing (%m)", fname);  /* not reached */
   }
 
+  if (edge_label) {
+    strcpy(label, "yes");
+  } else {
+    strcpy (label, "no");
+  }
+
   /* print header */
   xfprintf (F,
            "graph: { title: \"ir graph of %s\"\n"
-           "display_edge_labels: yes\n"
+           "display_edge_labels: %s\n"
            "layoutalgorithm: mindepth\n"
            "manhattan_edges: yes\n"
            "port_sharing: no\n"
            "orientation: bottom_to_top\n"
            "classname 1: \"Data\"\n"
-           "classname 2: \"Block\"\n", cp);
+           "classname 2: \"Block\"\n"
+           "classname 3: \"Entity type\""
+           "classname 4: \"Entity owner\""
+           "classname 5: \"Method Param\""
+           "classname 6: \"Method Res\""
+           "classname 7: \"Super\""
+           "classname 8: \"Union\""
+           "classname 9: \"Points-to\""
+           "classname 10: \"Array Element Type\""
+           "classname 11: \"Overwrites\""
+           "classname 12: \"Member\""
+           , cp, label);
 
   xfprintf (F, "\n");          /* a separator */
 }
@@ -528,6 +656,7 @@ void vcg_open (ir_graph *irg, char *suffix) {
 void vcg_open_name (const char *name) {
   char *fname;  /* filename to put the vcg information in */
   int len;
+  char label[4];
 
   /** open file for vcg graph */
   len   = strlen(name);
@@ -539,16 +668,33 @@ void vcg_open_name (const char *name) {
     panic ("cannot open %s for writing (%m)", fname);  /* not reached */
   }
 
+  if (edge_label) {
+    strcpy(label, "yes");
+  } else {
+    strcpy (label, "no");
+  }
+
   /* print header */
   xfprintf (F,
            "graph: { title: \"ir graph of %s\"\n"
-           "display_edge_labels: yes\n"
+           "display_edge_labels: %s\n"
            "layoutalgorithm: mindepth\n"
            "manhattan_edges: yes\n"
            "port_sharing: no\n"
            "orientation: bottom_to_top\n"
            "classname 1: \"Data\"\n"
-           "classname 2: \"Block\"\n", name);
+           "classname 2: \"Block\"\n"
+           "classname 3: \"Entity type\"\n"
+           "classname 4: \"Entity owner\"\n"
+           "classname 5: \"Method Param\"\n"
+           "classname 6: \"Method Res\"\n"
+           "classname 7: \"Super\"\n"
+           "classname 8: \"Union\"\n"
+           "classname 9: \"Points-to\"\n"
+           "classname 10: \"Array Element Type\"\n"
+           "classname 11: \"Overwrites\"\n"
+           "classname 12: \"Member\"\n"
+           , name, label);
 
   xfprintf (F, "\n");          /* a separator */
 }
@@ -753,3 +899,10 @@ void dump_all_ir_graphs (void dump_graph(ir_graph*)) {
     dump_graph(get_irp_irg(i));
   }
 }
+
+
+/* To turn off display of edge labels.  Edge labels offen cause xvcg to
+   abort with a segmentation fault. */
+void turn_of_edge_labels() {
+  edge_label = 0;
+}