-# include <string.h>
-# include <stdlib.h>
-
-# include "irnode_t.h"
-# include "irgraph_t.h"
-# include "entity_t.h"
-# include "irop_t.h"
-# include "firm_common_t.h"
-
-# include "irdump.h"
-
-# include "irgwalk.h"
-# include "typewalk.h"
-# include "irprog.h"
-# include "tv_t.h"
-# include "type_or_entity.h"
-# include "irouts.h"
-# include "irdom.h"
-# include "irloop.h"
-
-# include "panic.h"
-# include "array.h"
-# include "pmap.h"
-
-# include "exc.h"
-
-
-/* Attributes of nodes */
-#define PRINT_DEFAULT_NODE_ATTR
-#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"
-#define DOMINATOR_EDGE_ATTR "color: red"
-
-#define BACK_EDGE_ATTR "linestyle: dashed "
-
-/* Attributes of edges between Firm nodes and type/entity nodes */
-#define NODE2TYPE_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
-
-/* Attributes of edges in type/entity graphs. */
-#define TYPE_METH_NODE_ATTR "color: lightyellow"
-#define TYPE_CLASS_NODE_ATTR "color: green"
-#define TYPE_DESCRIPTION_NODE_ATTR "color: lightgreen"
-#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: red"
-#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 tp\" color:green"
-#define ARR_ENT_EDGE_ATTR "class: 10 label: \"arr ent\" color: green"
-#define ENT_OVERWRITES_EDGE_ATTR "class: 11 label: \"overwrites\" color:red"
-#define ENT_VALUE_EDGE_ATTR "label: \"value %d\""
-#define ENT_CORR_EDGE_ATTR "label: \"value %d corresponds to \" "
-#define TYPE_MEMBER_EDGE_ATTR "class: 12 label: \"member\" color:blue"
-
-
-#if DEBUG_libfirm && NODEID_AS_LABEL
-#define PRINT_NODEID(X) fprintf(F, "n%ld", get_irn_node_nr(X))
-#define PRINT_TYPEID(X) fprintf(F, "\"t%ld\"", get_type_nr(X))
-#define PRINT_ENTID(X) fprintf(F, "e%ld", get_entity_nr(X))
-#define PRINT_IRGID(X) fprintf(F, "g%ld", get_irg_graph_nr(X))
-#define PRINT_CONSTID(X,Y) fprintf(F, "\"n%ldn%ld\"", get_irn_node_nr(X),get_irn_node_nr(Y))
-
-#else
-#define PRINT_NODEID(X) fprintf(F, "n%p", (void*) X)
-#define PRINT_TYPEID(X) fprintf(F, "\"t%p\"", (void *) X)
-#define PRINT_ENTID(X) fprintf(F, "e%p", (void*) X)
-#define PRINT_IRGID(X) fprintf(F, "g%p",(void*) X)
-#define PRINT_CONSTID(X,Y) fprintf(F, "\"n%pn%p\"", (void*) X, (void*) Y)
-#endif
+/* basis for a color range for vcg */
+static int n_colors = 0;
+static int base_color = 0;
+
+#define ERROR_TXT "<ERROR>"
+
+/**
+ * returns the name of a mode or <ERROR> if mode is NOT a mode object.
+ * in the later case, sets bad
+ */
+static const char *get_mode_name_ex(ir_mode *mode, int *bad)
+{
+ if (is_mode(mode))
+ return get_mode_name(mode);
+ *bad |= 1;
+ return ERROR_TXT;
+}
+
+/**
+ * returns the name of a type or <ERROR> if mode is NOT a mode object.
+ * in the later case, sets bad
+ */
+static const char *get_type_name_ex(type *tp, int *bad)
+{
+ if (is_type(tp))
+ return get_type_name(tp);
+ *bad |= 1;
+ return ERROR_TXT;
+}
+
+/**
+ * prints the edge from a type S to a type T with additional info fmt, ...
+ * to the file F
+ */
+static void print_type_type_edge(FILE *F, type *S, type *T, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(S);
+ fprintf(F, " targetname: "); PRINT_TYPEID(T);
+ vfprintf(F, fmt, ap);
+ fprintf(F,"}\n");
+ va_end(ap);
+}
+
+/**
+ * prints the edge from a type T to an entity E with additional info fmt, ...
+ * to the file F
+ */
+static void print_type_ent_edge(FILE *F, type *T, entity *E, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(T);
+ fprintf(F, " targetname: \""); PRINT_ENTID(E); fprintf(F, "\"");
+ vfprintf(F, fmt, ap);
+ fprintf(F, "}\n");
+ va_end(ap);
+}
+
+/**
+ * prints the edge from an entity E to an entity T with additional info fmt, ...
+ * to the file F
+ */
+static void print_ent_ent_edge(FILE *F, entity *E, entity *T, int backedge, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ if (backedge)
+ fprintf(F, "backedge: { sourcename: \"");
+ else
+ fprintf(F, "edge: { sourcename: \"");
+ PRINT_ENTID(E);
+ fprintf(F, "\" targetname: \""); PRINT_ENTID(T); fprintf(F, "\"");
+ vfprintf(F, fmt, ap);
+ fprintf(F, "}\n");
+ va_end(ap);
+}
+
+/**
+ * prints the edge from an entity E to a type T with additional info fmt, ...
+ * to the file F
+ */
+static void print_ent_type_edge(FILE *F, entity *E, type *T, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
+ fprintf(F, "\" targetname: "); PRINT_TYPEID(T);
+ vfprintf(F, fmt, ap);
+ fprintf(F,"}\n");
+ va_end(ap);
+}
+
+/**
+ * prints the edge from a node N to a type T with additional info fmt, ...
+ * to the file F
+ */
+static void print_node_type_edge(FILE *F, const ir_node *N, type *T, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ fprintf(F, "edge: { sourcename: \""); PRINT_NODEID(N);
+ fprintf(F, "\" targetname: "); PRINT_TYPEID(T);
+ vfprintf(F, fmt, ap);
+ fprintf(F,"}\n");
+ va_end(ap);
+}
+
+/**
+ * prints the edge from a node N to an entity E with additional info fmt, ...
+ * to the file F
+ */
+static void print_node_ent_edge(FILE *F, const ir_node *N, entity *E, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ fprintf(F, "edge: { sourcename: \""); PRINT_NODEID(N);
+ fprintf(F, "\" targetname: \""); PRINT_ENTID(E);
+ fprintf(F, "\"");
+ vfprintf(F, fmt, ap);
+ fprintf(F,"}\n");
+ va_end(ap);
+}
+
+/**
+ * prints the edge from an entity E to a node N with additional info fmt, ...
+ * to the file F
+ */
+static void print_ent_node_edge(FILE *F, entity *E, const ir_node *N, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
+ fprintf(F, "\" targetname: \""); PRINT_NODEID(N); fprintf(F, "\"");
+ vfprintf(F, fmt, ap);
+ fprintf(F,"}\n");
+ va_end(ap);
+}
+
+/**
+ * prints the edge from a type E to an enumeration item item with additional info fmt, ...
+ * to the file F
+ */
+static void print_enum_item_edge(FILE *F, type *E, int item, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(E);
+ fprintf(F, " targetname: \""); PRINT_ITEMID(E, item); fprintf(F, "\" ");
+ vfprintf(F, fmt, ap);
+ fprintf(F,"}\n");
+ va_end(ap);
+}
+
+/*-----------------------------------------------------------------*/
+/* global and ahead declarations */
+/*-----------------------------------------------------------------*/
+
+static void dump_whole_node(ir_node *n, void *env);
+static INLINE void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg);
+
+/*-----------------------------------------------------------------*/
+/* Helper functions. */
+/*-----------------------------------------------------------------*/
+
+/**
+ * This map is used as a private link attr to be able to call dumper
+ * anywhere without destroying link fields.
+ */
+static pmap *irdump_link_map = NULL;
+
+/** Creates the link attribut map. */
+static void init_irdump(void) {
+ /* We need a new, empty map. */
+ if (irdump_link_map) pmap_destroy(irdump_link_map);
+ irdump_link_map = pmap_create();
+}
+
+/**
+ * Returns the private link field.
+ */
+static void *ird_get_irn_link(ir_node *n) {
+ void *res = NULL;
+ if (!irdump_link_map) return NULL;
+
+ if (pmap_contains(irdump_link_map, (void *)n))
+ res = pmap_get(irdump_link_map, (void *)n);
+ return res;
+}
+
+/**
+ * Sets the private link field.
+ */
+static void ird_set_irn_link(ir_node *n, void *x) {
+ if (!irdump_link_map) init_irdump();
+ pmap_insert(irdump_link_map, (void *)n, x);
+}
+
+/**
+ * Gets the private link field of an irg.
+ */
+static void *ird_get_irg_link(ir_graph *irg) {
+ void *res = NULL;
+ if (!irdump_link_map) return NULL;
+
+ if (pmap_contains(irdump_link_map, (void *)irg))
+ res = pmap_get(irdump_link_map, (void *)irg);
+ return res;
+}
+
+/**
+ * Sets the private link field of an irg.
+ */
+static void ird_set_irg_link(ir_graph *irg, void *x) {
+ if (!irdump_link_map) init_irdump();
+ pmap_insert(irdump_link_map, (void *)irg, x);
+}
+
+/**
+ * Walker, clears tzhe private link field
+ */
+static void clear_link(ir_node * node, void * env) {
+ ird_set_irn_link(node, NULL);
+}
+
+/**
+ * Returns non-zero if a node is in floating state.
+ */
+static int node_floats(ir_node *n) {
+ return ((get_irn_pinned(n) == op_pin_state_floats) &&
+ (get_irg_pinned(current_ir_graph) == op_pin_state_floats));
+}
+
+/**
+ * If the entity has a ld_name, returns it, else returns the name of the entity.
+ */
+static const char *get_ent_dump_name(entity *ent) {
+ if (!ent)
+ return "<NULL entity>";
+ /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
+ if (ent->ld_name) return get_id_str(ent->ld_name);
+ return get_id_str(ent->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);
+}
+
+/**
+ * Walker, allocates an array for all blocks and puts it's nodes non-floating nodes into this array.
+ */
+static void collect_node(ir_node * node, void *env) {
+ if (is_Block(node)
+ || node_floats(node)
+ || get_irn_op(node) == op_Bad
+ || get_irn_op(node) == op_Unknown
+ || get_irn_op(node) == op_NoMem) {
+ ir_node ** arr = (ir_node **) ird_get_irg_link(get_irn_irg(node));
+ if (!arr) arr = NEW_ARR_F(ir_node *, 0);
+ ARR_APP1(ir_node *, arr, node);
+ ird_set_irg_link(get_irn_irg(node), arr); /* arr is an l-value, APP_ARR might change it! */
+ } else {
+ ir_node * block = get_nodes_block(node);
+ ird_set_irn_link(node, ird_get_irn_link(block));
+ ird_set_irn_link(block, node);
+ }
+}
+
+/** Construct lists to walk ir block-wise.
+ *
+ * Collects all blocks, nodes not op_pin_state_pinned,
+ * Bad, NoMem and Unknown into a flexible array in link field of
+ * irg they belong to. Sets the irg link field to NULL in all
+ * graphs not visited.
+ * Free the list with DEL_ARR_F().
+ */
+static ir_node ** construct_block_lists(ir_graph *irg) {
+ int i, rem_view = get_interprocedural_view();
+ ir_graph *rem = current_ir_graph;
+ current_ir_graph = irg;
+
+ for (i = 0; i < get_irp_n_irgs(); i++)
+ ird_set_irg_link(get_irp_irg(i), NULL);
+
+ irg_walk_graph(current_ir_graph, clear_link, collect_node, current_ir_graph);