+/* basis for a color range for vcg */
+static int n_colors = 0;
+static int base_color = 0;
+
+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>";
+}
+
+static const char *get_type_name_ex(type *tp, int *bad)
+{
+ if (is_type(tp))
+ return get_type_name(tp);
+ *bad |= 1;
+ return "<ERROR>";
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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. */
+/*******************************************************************/
+
+/* Use private link attr to be able to call dumper anywhere without
+ destroying link fields. */
+
+static pmap *irdump_link_map = NULL;
+
+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();
+}
+
+
+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;
+}
+
+void ird_set_irn_link(ir_node *n, void *x) {
+ if (!irdump_link_map) init_irdump();
+ pmap_insert(irdump_link_map, (void *)n, x);
+}
+
+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;
+}
+
+void ird_set_irg_link(ir_graph *irg, void *x) {
+ if (!irdump_link_map) init_irdump();
+ pmap_insert(irdump_link_map, (void *)irg, x);
+}
+
+static void clear_link(ir_node * node, void * env) {
+ ird_set_irn_link(node, NULL);
+}
+
+
+static int node_floats(ir_node *n) {
+ return ((get_op_pinned(get_irn_op(n)) == op_pin_state_floats) &&
+ (get_irg_pinned(current_ir_graph) == op_pin_state_floats));
+}
+
+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);
+}
+
+static 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);
+}
+
+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) {
+ 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 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 = 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);
+
+ /* Collect also EndReg and EndExcept. We do not want to change the walker. */
+ interprocedural_view = 0;
+ set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
+ irg_walk(get_irg_end_reg(current_ir_graph), clear_link, collect_node, current_ir_graph);
+ set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph)-1);
+ irg_walk(get_irg_end_except(current_ir_graph), clear_link, collect_node, current_ir_graph);
+ interprocedural_view = rem_view;
+
+ current_ir_graph = rem;
+ return ird_get_irg_link(irg);
+}