+
+void dump_keepalive_edges(bool b) {
+ dump_keepalive = b;
+}
+
+void dump_out_edges() {
+ dump_out_edge_flag = 1;
+}
+
+void dump_dominator_information() {
+ dump_dominator_information_flag = 1;
+}
+
+void dump_loop_information() {
+ dump_loop_information_flag = 1;
+}
+
+void dont_dump_loop_information() {
+ dump_loop_information_flag = 0;
+}
+
+static void clear_link(ir_node * node, void * env) {
+ set_irn_link(node, NULL);
+}
+
+static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
+ if (is_Block(node)
+ || node_floats(node)
+ || get_irn_op(node) == op_Bad
+ || get_irn_op(node) == op_Unknown) {
+ pmap_entry * entry = pmap_find(map, current_ir_graph);
+ if (entry) {
+ ARR_APP1(ir_node *, (ir_node **) entry->value, node);
+ } else {
+ ir_node ** arr = NEW_ARR_F(ir_node *, 1);
+ arr[0] = node;
+ pmap_insert(map, current_ir_graph, arr);
+ }
+ } else {
+ ir_node * block = get_nodes_Block(node);
+ set_irn_link(node, get_irn_link(block));
+ set_irn_link(block, node);
+ }
+}
+
+
+static void dump_cg_ir_block(ir_node * block, void * env) {
+ ir_node *node;
+ pmap *irgmap = (pmap *)env;
+ assert(is_Block(block));
+ xfprintf(F, "graph: { title: \"");
+ PRINT_NODEID(block);
+ fprintf(F, "\" label: \"");
+#ifdef DEBUG_libfirm
+ xfprintf (F, "%ld", get_irn_node_nr(block));
+#else
+ xfprintf (F, "%I", block->op->name);
+#endif
+ if (exc_normal != get_Block_exc(block)) {
+ fprintf (F, " (%s)", exc_to_string (get_Block_exc(block)));
+ }
+
+ xfprintf(F, "\" status:clustered color:%s \n",
+ get_Block_matured(block) ? "yellow" : "red");
+
+ /* dump the blocks edges */
+ dump_ir_data_edges(block);
+
+ /* dump the nodes that go into the block */
+ for (node = get_irn_link(block); node; node = get_irn_link(node)) {
+ dump_node(node, irgmap);
+ dump_ir_data_edges(node);
+ }
+
+ /* Close the vcg information for the block */
+ xfprintf(F, "}\n\n");
+}
+
+static void d_cg_block_graph(ir_graph *irg, ir_node **arr, pmap *irgmap) {
+ int i;
+
+ xfprintf(F, "graph: { title: \"%p\" label: \"%I\" status:clustered color:white \n",
+ irg, get_entity_ident(get_irg_ent(irg)));
+
+ for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
+ ir_node * node = arr[i];
+ if (is_Block(node)) {
+ /* Dumps the block and all the nodes in the block , which are to
+ be found in Block->link. */
+ dump_cg_ir_block(node, irgmap);
+ } else {
+ /* Nodes that are not in a Block. */
+ dump_node(node, NULL);
+ dump_ir_data_edges(node);
+ }
+ }
+ /* Close the vcg information for the irg */
+ xfprintf(F, "}\n\n");
+}
+
+/* dump interprocedural graph with surrounding methods */
+void dump_cg_block_graph(ir_graph * irg) {
+ pmap * map = pmap_create();
+ pmap * map2 = pmap_create();
+ pmap_entry * entry;
+
+ vcg_open(irg, "");
+
+ irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
+ for (entry = pmap_first(map); entry; entry = pmap_next(map))
+ pmap_insert(map2, entry->key, entry->value);
+ for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
+ d_cg_block_graph(entry->key, entry->value, map2);
+ DEL_ARR_F(entry->value);
+ }
+
+ pmap_destroy(map);
+ pmap_destroy(map2);
+
+ if (dump_loop_information_flag) dump_loop_info(irg);
+ vcg_close();
+}
+
+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 **) get_irg_link(current_ir_graph);
+ ARR_APP1(ir_node *, arr, node);
+ set_irg_link(current_ir_graph, arr); /* arr is an l-value, APP_ARR might change it! */
+ } else {
+ ir_node * block = get_nodes_Block(node);
+ set_irn_link(node, get_irn_link(block));
+ set_irn_link(block, node);
+ }
+}
+
+/* Links all nodes that have the block field set in the link field of
+ the block. Adds all blocks and nodes not associated with a block
+ in a array in irg->link. */
+static void collect_nodes() {
+ int i;
+ for (i = 0; i < get_irp_n_irgs(); i++)
+ set_irg_link(get_irp_irg(i), NEW_ARR_F(ir_node *, 0));
+ cg_walk(clear_link, collect_node, NULL);
+}
+
+static void dump_graphs() {
+ int i;
+ for (i = 0; i < get_irp_n_irgs(); i++) {
+ current_ir_graph = get_irp_irg(i);
+ d_cg_block_graph(current_ir_graph, get_irg_link(current_ir_graph), NULL);
+ }
+}
+
+/* Dump all irgs in interprocedural view to a single file. */
+void dump_all_cg_block_graph() {
+ int i;
+ int rem_view = interprocedural_view;
+ interprocedural_view = 1;
+ vcg_open_name ("All_graphs");
+
+ collect_nodes();
+ dump_graphs();
+
+ if (dump_loop_information_flag)
+ for (i = 0; i < get_irp_n_irgs(); i++)
+ dump_loop_info(get_irp_irg(i));
+
+ vcg_close();
+ interprocedural_view = rem_view;
+}
+
+/* dump interprocedural block graph with surrounding methods */
+void dump_cg_graph(ir_graph * irg) {
+ pmap * map = pmap_create();
+ pmap * map2 = pmap_create(); /* We can not iterate in the same map twice! */
+ pmap_entry * entry;
+ vcg_open(irg, "");
+
+ irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
+ for (entry = pmap_first(map); entry; entry = pmap_next(map))
+ pmap_insert(map2, entry->key, entry->value);
+ for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
+ ir_node ** arr = entry->value;
+ int i;
+ ident * irg_ident = get_entity_ident(get_irg_ent(entry->key));
+
+ xfprintf(F, "graph: { title: \"%I\" label: \"%I\" status:clustered color:white \n",
+ irg_ident, irg_ident);
+
+ for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
+ ir_node * node = arr[i];
+ dump_node(node, map2);
+ dump_ir_data_edges(node);
+ if (is_Block(node)) {
+ for (node = get_irn_link(node); node; node = get_irn_link(node)) {
+ dump_node(node, map2);
+ dump_ir_block_edge(node);
+ dump_ir_data_edges(node);
+ }
+ }
+ }
+
+ DEL_ARR_F(arr);
+
+ /* Close the vcg information for the irg */
+ xfprintf(F, "}\n\n");
+ }
+
+ pmap_destroy(map);
+ pmap_destroy(map2);
+
+ vcg_close();
+}