1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
4 * Authors: Martin Trapp, Christian Schaefer
6 * irdump.h: dumping of an intermediate representation graph
15 # include "irnode_t.h"
16 # include "irgraph_t.h"
21 # include "entity_t.h"
26 # include "type_or_entity.h"
28 # include "typewalk.h"
31 # include "firm_common_t.h"
38 /* Attributes of nodes */
39 #define DEFAULT_NODE_ATTR ""
40 #define DEFAULT_TYPE_ATTRIBUTE ""
42 /* Attributes of edges between Firm nodes */
43 #define BLOCK_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
44 #define CF_EDGE_ATTR "color: red"
45 #define MEM_EDGE_ATTR "color: blue"
46 #define DOMINATOR_EDGE_ATTR "color: red"
48 #define BACK_EDGE_ATTR "linestyle: dashed "
50 /* Attributes of edges between Firm nodes and type/entity nodes */
51 #define NODE2TYPE_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
53 /* Attributes of edges in type/entity graphs. */
54 #define TYPE_METH_NODE_ATTR "color: lightyellow"
55 #define TYPE_CLASS_NODE_ATTR "color: green"
56 #define TYPE_DESCRIPTION_NODE_ATTR "color: lightgreen"
57 #define ENTITY_NODE_ATTR "color: yellow"
58 #define ENT_TYPE_EDGE_ATTR "class: 3 label: \"type\" color: red"
59 #define ENT_OWN_EDGE_ATTR "class: 4 label: \"owner\" color: black"
60 #define METH_PAR_EDGE_ATTR "class: 5 label: \"param %d\" color: green"
61 #define METH_RES_EDGE_ATTR "class: 6 label: \"res %d\" color: green"
62 #define TYPE_SUPER_EDGE_ATTR "class: 7 label: \"supertype\" color: red"
63 #define UNION_EDGE_ATTR "class: 8 label: \"component\" color: blue"
64 #define PTR_PTS_TO_EDGE_ATTR "class: 9 label: \"points to\" color:green"
65 #define ARR_ELT_TYPE_EDGE_ATTR "class: 10 label: \"arr elt tp\" color:green"
66 #define ARR_ENT_EDGE_ATTR "class: 10 label: \"arr ent\" color: green"
67 #define ENT_OVERWRITES_EDGE_ATTR "class: 11 label: \"overwrites\" color:red"
68 #define ENT_VALUE_EDGE_ATTR "label: \"value "
69 #define ENT_CORR_EDGE_ATTR "label: \"value %d corresponds to \" "
70 #define TYPE_MEMBER_EDGE_ATTR "class: 12 label: \"member\" color:blue"
73 #if DEBUG_libfirm && NODEID_AS_LABEL
74 #define PRINT_NODEID(X) fprintf(F, "%ld", get_irn_node_nr(X))
76 #define PRINT_NODEID(X) fprintf(F, "%p", X)
79 /* A suffix to manipulate the file name. */
80 char *dump_file_suffix = NULL;
85 /* A compiler option to turn off edge labels */
87 /* A compiler option to turn off dumping values of constant entities */
88 int const_entities = 1;
89 /* A compiler option to dump the keep alive edges */
90 int dump_keepalive = 0;
91 /* Compiler options to dump analysis information in dump_ir_graph */
92 int dump_out_edge_flag = 0;
93 int dump_dominator_information_flag = 0;
94 int dump_loop_information_flag = 0;
95 int dump_const_local = 0;
97 static INLINE bool dump_const_local_set(void) {
98 if (!dump_out_edge_flag && !dump_loop_information_flag)
99 return dump_const_local;
104 /* A global variable to record output of the Bad node. */
105 static int Bad_dumped;
107 static void dump_ir_blocks_nodes (ir_node *n, void *env);
108 static void dump_whole_node(ir_node *n, void* env);
110 /*******************************************************************/
111 /* routines to dump information about a single node */
112 /*******************************************************************/
117 dump_node_opcode (ir_node *n)
122 if (n->op->code == iro_Const) {
123 xfprintf (F, "%v", n->attr.con);
126 } else if (n->op->code == iro_SymConst) {
127 if (get_SymConst_kind(n) == linkage_ptr_info) {
128 /* don't use get_SymConst_ptr_info as it mangles the name. */
129 xfprintf (F, "SymC %I", n->attr.i.tori.ptrinfo);
131 assert(get_kind(get_SymConst_type(n)) == k_type);
132 assert(get_type_ident(get_SymConst_type(n)));
133 xfprintf (F, "SymC %I ", get_type_ident(get_SymConst_type(n)));
134 if (get_SymConst_kind(n) == type_tag)
137 xfprintf (F, "size");
141 } else if (n->op->code == iro_Filter && !interprocedural_view) {
146 xfprintf (F, "%I", get_irn_opident(n));
151 dump_node_mode (ir_node *n)
153 switch (n->op->code) {
171 xfprintf (F, "%I", get_mode_ident(n->mode));
179 dump_node_nodeattr (ir_node *n)
181 switch (n->op->code) {
183 if (false && interprocedural_view) {
184 xfprintf (F, "%I", get_entity_ident(get_irg_ent(current_ir_graph)));
188 if (n->in[1]->op->code == iro_Cmp) {
189 xfprintf (F, "%s", get_pnc_string(n->attr.proj));
191 xfprintf (F, "%ld", n->attr.proj);
195 xfprintf (F, "%ld", n->attr.filter.proj);
198 assert(get_kind(get_Sel_entity(n)) == k_entity);
199 xfprintf (F, "%I", get_entity_ident(get_Sel_entity(n)));
207 dump_node_vcgattr (ir_node *n)
209 switch (n->op->code) {
216 xfprintf (F, "color: blue");
219 xfprintf (F, "color: lightyellow");
222 xfprintf (F, "color: green");
228 xfprintf (F, "color: yellow");
231 xfprintf (F, DEFAULT_NODE_ATTR);
235 static bool pred_in_wrong_graph(ir_node *n, int pos, pmap *irgmap) {
236 ir_node *block = (is_Block(n)) ? n : get_nodes_Block(n);
239 ((get_irn_op(n) == op_Filter) || (get_irn_op(n) == op_Block))) {
240 ir_node *pred = skip_Proj(get_Block_cfgpred(block, pos));
241 if (is_ip_cfop(pred)) {
242 ir_graph *irg = get_ip_cfop_irg(pred);
243 if (pmap_find(irgmap, irg) == NULL) return true;
252 bool is_constlike_node(ir_node *n) {
253 ir_op *op = get_irn_op(n);
254 return (op == op_Const || op == op_Bad || op == op_SymConst);
258 static void dump_const_node_local(ir_node *n, pmap *irgmap) {
260 if (!dump_const_local_set()) return;
261 /* Use visited flag to avoid outputting nodes twice.
262 initialize it first. */
263 for (i = 0; i < get_irn_arity(n); i++) {
264 ir_node *con = get_irn_n(n, i);
265 if (is_constlike_node(con)) {
266 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
267 set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
270 for (i = 0; i < get_irn_arity(n); i++) {
271 ir_node *con = get_irn_n(n, i);
272 if (is_constlike_node(con) && irn_not_visited(con)) {
273 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
274 mark_irn_visited(con);
275 /* Generate a new name for the node by appending the names of
277 xfprintf (F, "node: {title: \""); PRINT_NODEID(n); PRINT_NODEID(con);
278 fprintf(F, "\" label: \"");
279 dump_node_opcode(con);
280 dump_node_mode (con);
282 dump_node_nodeattr(con);
284 xfprintf (F, " %ld", get_irn_node_nr(con));
287 dump_node_vcgattr(con);
294 dump_node (ir_node *n, pmap * map) {
295 if (dump_const_local_set() && is_constlike_node(n)) return;
298 xfprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
303 dump_node_nodeattr(n);
305 xfprintf (F, " %ld", get_irn_node_nr(n));
308 dump_node_vcgattr(n);
310 dump_const_node_local(n, map);
314 dump_ir_node (ir_node *n)
317 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: ");
319 switch (n->op->code) { /* node label */
321 xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
322 xfprintf (F, DEFAULT_NODE_ATTR);
329 xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
330 xfprintf (F, DEFAULT_NODE_ATTR);
333 xfprintf (F, "\"%I\" color: lightyellow ", get_irn_opident(n));
334 xfprintf (F, DEFAULT_NODE_ATTR);
337 xfprintf (F, "\"%I%I\" color: green", get_irn_opident(n), get_irn_modeident(n));
338 if (get_irn_modecode(n) == irm_M)
339 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
341 xfprintf (F, DEFAULT_NODE_ATTR);
344 xfprintf (F, "\"%v%I\" color: yellow ", n->attr.con, get_irn_modeident(n));
345 xfprintf (F, DEFAULT_NODE_ATTR);
348 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
349 xfprintf (F, DEFAULT_NODE_ATTR);
352 if (n->in[1]->op->code == iro_Cmp) {
353 xfprintf (F, "\"%I%I %s\" color: yellow", get_irn_opident(n), get_irn_modeident(n),
354 get_pnc_string(n->attr.proj));
356 xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.proj);
358 xfprintf (F, DEFAULT_NODE_ATTR);
361 xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.filter.proj);
362 xfprintf (F, DEFAULT_NODE_ATTR);
365 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
366 xfprintf (F, DEFAULT_NODE_ATTR);
369 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
370 xfprintf (F, DEFAULT_NODE_ATTR);
373 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
374 xfprintf (F, DEFAULT_NODE_ATTR);
377 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
378 xfprintf (F, DEFAULT_NODE_ATTR);
381 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
382 xfprintf (F, DEFAULT_NODE_ATTR);
385 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
386 xfprintf (F, DEFAULT_NODE_ATTR);
389 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
390 xfprintf (F, DEFAULT_NODE_ATTR);
393 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
394 xfprintf (F, DEFAULT_NODE_ATTR);
397 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
398 xfprintf (F, DEFAULT_NODE_ATTR);
401 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
402 xfprintf (F, DEFAULT_NODE_ATTR);
405 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
406 xfprintf (F, DEFAULT_NODE_ATTR);
409 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
410 xfprintf (F, DEFAULT_NODE_ATTR);
413 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
414 xfprintf (F, DEFAULT_NODE_ATTR);
417 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
418 xfprintf (F, DEFAULT_NODE_ATTR);
421 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
422 xfprintf (F, DEFAULT_NODE_ATTR);
425 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
426 xfprintf (F, DEFAULT_NODE_ATTR);
429 xfprintf (F, "\"%I\"", get_irn_opident(n));
430 xfprintf (F, DEFAULT_NODE_ATTR);
433 xfprintf (F, "\"%I\"", get_irn_opident(n));
434 xfprintf (F, DEFAULT_NODE_ATTR);
437 xfprintf (F, "\"%I\"", get_irn_opident(n));
438 xfprintf (F, DEFAULT_NODE_ATTR);
441 xfprintf (F, "\"%I\"", get_irn_opident(n));
442 xfprintf (F, DEFAULT_NODE_ATTR);
445 xfprintf (F, "\"%I\"", get_irn_opident(n));
446 xfprintf (F, DEFAULT_NODE_ATTR);
449 xfprintf (F, "\"%I\"", get_irn_opident(n));
450 xfprintf (F, DEFAULT_NODE_ATTR);
453 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
454 xfprintf (F, DEFAULT_NODE_ATTR);
458 xfprintf (F, "\"%R\"", n);
459 xfprintf (F, DEFAULT_NODE_ATTR);
462 xfprintf (F, "\"%I\" ", get_irn_opident(n));
463 xfprintf (F, DEFAULT_NODE_ATTR);
466 assert(get_kind(get_Sel_entity(n)) == k_entity);
467 xfprintf (F, "\"%I ", get_irn_opident(n));
468 xfprintf (F, "%I", get_entity_ident(get_Sel_entity(n)));
469 xfprintf (F, DEFAULT_NODE_ATTR);
472 assert(get_kind(get_SymConst_type(n)) == k_type);
473 assert(get_type_ident(get_SymConst_type(n)));
474 xfprintf (F, "\"%s ", get_type_name(get_SymConst_type(n)));
475 switch (n->attr.i.num){
477 xfprintf (F, "tag\" ");
480 xfprintf (F, "size\" ");
486 xfprintf (F, DEFAULT_NODE_ATTR);
489 xfprintf (F, "\"%I\" ", get_irn_opident(n));
490 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
493 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
494 xfprintf (F, DEFAULT_NODE_ATTR);
497 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
498 xfprintf (F, DEFAULT_NODE_ATTR);
501 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
503 xfprintf (F, "}\n"); /* footer */
507 /* dump the edge to the block this node belongs to */
509 dump_ir_block_edge(ir_node *n) {
510 if (dump_const_local_set() && is_constlike_node(n)) return;
511 if (is_no_Block(n)) {
512 xfprintf (F, "edge: { sourcename: \"");
514 xfprintf (F, "\" targetname: \"");
515 PRINT_NODEID(get_nodes_Block(n));
516 xfprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
520 static void print_edge_vcgattr(ir_node *from, int to) {
523 if (is_backedge(from, to)) xfprintf (F, BACK_EDGE_ATTR);
525 switch (get_irn_opcode(from)) {
527 xfprintf (F, CF_EDGE_ATTR);
529 case iro_Start: break;
532 if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
533 xfprintf (F, CF_EDGE_ATTR);
534 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
535 xfprintf (F, MEM_EDGE_ATTR);
538 case iro_EndReg: break;
539 case iro_EndExcept: break;
541 case iro_Break: break;
542 case iro_Cond: break;
545 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
547 case iro_Const: break;
548 case iro_SymConst:break;
551 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
553 case iro_CallBegin: break;
556 case iro_Minus: break;
562 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
570 case iro_Shrs: break;
573 case iro_Conv: break;
575 if (get_irn_modecode(from) == irm_M) xfprintf (F, MEM_EDGE_ATTR);
581 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
584 xfprintf (F, MEM_EDGE_ATTR);
586 case iro_Tuple: break;
589 switch (get_irn_modecode(from)) {
591 xfprintf (F, CF_EDGE_ATTR);
594 xfprintf (F, MEM_EDGE_ATTR);
600 case iro_Unknown: break;
607 /* dump edges to our inputs */
609 dump_ir_data_edges(ir_node *n) {
610 int i, visited = get_irn_visited(n);
612 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
615 for (i = 0; i < get_irn_arity(n); i++) {
616 ir_node * pred = get_irn_n(n, i);
618 if ((interprocedural_view && get_irn_visited(pred) < visited))
619 continue; /* pred not dumped */
620 if (is_backedge(n, i))
621 fprintf (F, "backedge: {sourcename: \"");
623 fprintf (F, "edge: {sourcename: \"");
625 fprintf (F, "\" targetname: \"");
626 if ((dump_const_local_set()) && is_constlike_node(pred))
630 fprintf (F, " label: \"%d\" ", i);
631 print_edge_vcgattr(n, i);
638 dump_out_edge (ir_node *n, void* env) {
640 for (i = 0; i < get_irn_n_outs(n); i++) {
641 assert(get_irn_out(n, i));
642 fprintf (F, "edge: {sourcename: \"");
644 fprintf (F, "\" targetname: \"");
645 PRINT_NODEID(get_irn_out(n, i));
646 fprintf (F, "\" color: red linestyle: dashed");
652 dump_loop_node_edge (ir_loop *loop, int i) {
654 fprintf (F, "edge: {sourcename: \"%p\" targetname: \"", loop);
655 PRINT_NODEID(get_loop_node(loop, i));
656 fprintf (F, "\" color: green");
661 void dump_loops (ir_loop *loop) {
663 /* dump this loop node */
664 xfprintf (F, "node: {title: \"%p\" label: \"loop %d, %d sons, %d nodes\" }\n",
665 loop, get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
666 /* dump edges to nodes in loop -- only if it is a real loop */
667 if (get_loop_depth(loop) != 0) {
668 for (i = 0; i < get_loop_n_nodes(loop); i++) {
669 dump_loop_node_edge(loop, i);
672 for (i = 0; i < get_loop_n_sons(loop); i++) {
673 dump_loops(get_loop_son(loop, i));
678 void dump_loop_info(ir_graph *irg) {
679 ir_graph *rem = current_ir_graph;
680 current_ir_graph = irg;
682 if (get_irg_loop(irg))
683 dump_loops(get_irg_loop(irg));
685 current_ir_graph = rem;
689 /* dumps the edges between nodes and their type or entity attributes. */
690 static void dump_node2type_edges (ir_node *n, void *env)
694 switch (get_irn_opcode(n)) {
696 /* @@@ some consts have an entity */
699 if ( (get_SymConst_kind(n) == type_tag)
700 || (get_SymConst_kind(n) == size)) {
701 xfprintf (F, "edge: { sourcename: \"");
703 fprintf (F, "\" targetname: \"%p\" "
704 NODE2TYPE_EDGE_ATTR "}\n", get_SymConst_type(n));
708 xfprintf (F, "edge: { sourcename: \"");
710 fprintf (F, "\" targetname: \"%p\" "
711 NODE2TYPE_EDGE_ATTR "}\n", get_Sel_entity(n));
714 xfprintf (F, "edge: { sourcename: \"");
716 fprintf (F, "\" targetname: \"%p\" "
717 NODE2TYPE_EDGE_ATTR "}\n", get_Call_type(n));
720 xfprintf (F, "edge: { sourcename: \"");
722 fprintf (F, "\" targetname: \"%p\" "
723 NODE2TYPE_EDGE_ATTR "}\n", get_Alloc_type(n));
726 xfprintf (F, "edge: { sourcename: \"");
728 fprintf (F, "\" targetname: \"%p\" "
729 NODE2TYPE_EDGE_ATTR "}\n", get_Free_type(n));
737 static void dump_const_expression(ir_node *value) {
738 ir_graph *rem = current_ir_graph;
739 int rem_dump_const_local = dump_const_local;
740 dump_const_local = 0;
741 current_ir_graph = get_const_code_irg();
742 irg_walk(value, dump_ir_blocks_nodes, NULL, get_nodes_Block(value));
743 /* Decrease visited flag so that we walk with the same flag for the next
744 expresssion. This guarantees that we don't dump the same node twice,
745 as for const expressions cse is performed to save memory. */
746 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
747 current_ir_graph = rem;
748 dump_const_local = rem_dump_const_local;
752 static void print_type_info(type *tp) {
753 if (get_type_state(tp) == layout_undefined) {
754 xfprintf(F, "state: layout_undefined\n");
756 xfprintf(F, "state: layout_fixed,\n");
758 if (get_type_mode(tp))
759 xfprintf(F, "mode: %I,\n", get_mode_ident(get_type_mode(tp)));
760 xfprintf(F, "size: %dB,\n", get_type_size(tp));
764 static void print_typespecific_info(type *tp) {
765 switch (get_type_tpop_code(tp)) {
768 if(existent == get_class_peculiarity(tp))
769 xfprintf (F, " " TYPE_CLASS_NODE_ATTR);
771 xfprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
775 xfprintf (F, " " TYPE_METH_NODE_ATTR);
786 case tpo_enumeration:
799 static void print_type_node(type *tp) {
800 xfprintf (F, "node: {title: \"%p\" ", tp);
801 xfprintf (F, "label: \"%I %I\"", get_type_tpop_nameid(tp), get_type_ident(tp));
802 xfprintf (F, "info1: \"");
805 print_typespecific_info(tp);
809 void dump_entity_node(entity *ent) {
810 xfprintf (F, "node: {title: \"%p\" ", ent);
811 xfprintf (F, DEFAULT_TYPE_ATTRIBUTE);
812 xfprintf (F, "label: ");
813 xfprintf (F, "\"ent %I\" " ENTITY_NODE_ATTR , get_entity_ident(ent));
814 fprintf (F, "\n info1:\"\nallocation: ");
815 switch (get_entity_allocation(ent)) {
816 case dynamic_allocated: fprintf (F, "dynamic allocated"); break;
817 case automatic_allocated: fprintf (F, "automatic allocated"); break;
818 case static_allocated: fprintf (F, "static allocated"); break;
819 case parameter_allocated: fprintf (F, "parameter allocated"); break;
821 fprintf (F, "\nvisibility: ");
822 switch (get_entity_visibility(ent)) {
823 case local: fprintf (F, "local"); break;
824 case external_visible: fprintf (F, "external_visible"); break;
825 case external_allocated: fprintf (F, "external_allocate"); break;
827 fprintf (F, "\nvariability: ");
828 switch (get_entity_variability(ent)) {
829 case uninitialized: fprintf (F, "uninitialized");break;
830 case initialized: fprintf (F, "initialized"); break;
831 case part_constant: fprintf (F, "part_constant");break;
832 case constant: fprintf (F, "constant"); break;
834 fprintf (F, "\nvolatility: ");
835 switch (get_entity_volatility(ent)) {
836 case non_volatile: fprintf (F, "non_volatile"); break;
837 case is_volatile: fprintf (F, "is_volatile"); break;
839 fprintf (F, "\npeculiarity: ");
840 switch (get_entity_peculiarity(ent)) {
841 case description: fprintf (F, "description"); break;
842 case inherited: fprintf (F, "inherited"); break;
843 case existent: fprintf (F, "existent"); break;
845 xfprintf(F, "\nname: %I\nld_name: %I", get_entity_ident(ent), get_entity_ld_ident(ent));
846 fprintf(F, "\noffset: %d", get_entity_offset(ent));
847 if (is_method_type(get_entity_type(ent)))
848 xfprintf (F, "\nirg = %p ", get_entity_irg(ent));
849 xfprintf(F, "\"\n}\n");
852 /* dumps a type or entity and it's edges. */
854 dump_type_info (type_or_ent *tore, void *env) {
855 int i = 0; /* to shutup gcc */
857 /* dump this type or entity */
859 switch (get_kind(tore)) {
862 entity *ent = (entity *)tore;
865 dump_entity_node(ent);
867 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
868 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
869 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
870 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
871 ENT_TYPE_EDGE_ATTR "}\n", ent, get_entity_type(ent));
872 if(is_class_type(get_entity_owner(ent))) {
873 for(i = 0; i < get_entity_n_overwrites(ent); i++)
874 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
875 ENT_OVERWRITES_EDGE_ATTR "}\n",
876 ent, get_entity_overwrites(ent, i));
878 /* attached subgraphs */
879 if (const_entities && (get_entity_variability(ent) != uninitialized)) {
880 if (is_atomic_entity(ent)) {
881 value = get_atomic_ent_value(ent);
883 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"", ent);
885 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR "\"}\n");
886 dump_const_expression(value);
889 if (is_compound_entity(ent)) {
890 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
891 value = get_compound_ent_value(ent, i);
893 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"", ent);
895 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR " %d \"}\n", i);
896 dump_const_expression(value);
897 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
898 ENT_CORR_EDGE_ATTR "}\n", ent,
899 get_compound_ent_value_member(ent, i), i);
907 type *tp = (type *)tore;
909 /* and now the edges */
910 switch (get_type_tpop_code(tp)) {
913 for (i=0; i < get_class_n_supertypes(tp); i++)
914 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
915 TYPE_SUPER_EDGE_ATTR "}\n",
916 tp, get_class_supertype(tp, i));
917 for (i=0; i < get_class_n_members(tp); i++)
918 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
919 TYPE_MEMBER_EDGE_ATTR "}\n",
920 tp, get_class_member(tp, i));
924 for (i=0; i < get_struct_n_members(tp); i++)
925 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
926 TYPE_MEMBER_EDGE_ATTR "}\n",
927 tp, get_struct_member(tp, i));
931 for (i = 0; i < get_method_n_params(tp); i++)
932 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
933 METH_PAR_EDGE_ATTR "}\n",
934 tp, get_method_param_type(tp, i), i);
935 for (i = 0; i < get_method_n_ress(tp); i++)
936 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
937 METH_RES_EDGE_ATTR "}\n",
938 tp, get_method_res_type(tp, i), i);
942 for (i = 0; i < get_union_n_members(tp); i++)
943 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
944 "label: \"\"f" UNION_EDGE_ATTR "}\n",
945 tp, get_union_member(tp, i));
949 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
950 ARR_ELT_TYPE_EDGE_ATTR "}\n", tp, get_array_element_type(tp), i);
951 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
952 ARR_ENT_EDGE_ATTR "}\n", tp, get_array_element_entity(tp), i);
954 case tpo_enumeration:
959 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
960 PTR_PTS_TO_EDGE_ATTR "}\n", tp,
961 get_pointer_points_to_type(tp), i);
969 break; /* case k_type */
972 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
974 } /* switch kind_or_entity */
977 /* dumps a class type node and a superclass edge.
978 If env != null dumps entities of classes and overwrites edges. */
980 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
981 int i = 0; /* to shutup gcc */
983 /* dump this type or entity */
984 switch (get_kind(tore)) {
986 entity *ent = (entity *)tore;
987 if (get_entity_owner(ent) == get_glob_type()) break;
988 if ((env) && is_class_type(get_entity_owner(ent))) {
990 dump_entity_node(ent);
992 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
993 TYPE_MEMBER_EDGE_ATTR "}\n", get_entity_owner(ent), ent);
994 for(i = 0; i < get_entity_n_overwrites(ent); i++)
995 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
996 ENT_OVERWRITES_EDGE_ATTR "}\n",
997 ent, get_entity_overwrites(ent, i));
999 } break; /* case k_entity */
1002 type *tp = (type *)tore;
1003 if (tp == get_glob_type()) break;
1004 switch (get_type_tpop_code(tp)) {
1006 print_type_node(tp);
1007 /* and now the edges */
1008 for (i=0; i < get_class_n_supertypes(tp); i++)
1009 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1010 TYPE_SUPER_EDGE_ATTR "}\n",
1011 tp, get_class_supertype(tp, i));
1016 break; /* case k_type */
1019 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
1021 } /* switch kind_or_entity */
1024 /************************************************************************/
1025 /* open and close vcg file */
1026 /************************************************************************/
1028 static void vcg_open (ir_graph *irg, char *suffix) {
1029 char *fname; /* filename to put the vcg information in */
1036 /** open file for vcg graph */
1037 ent = get_irg_ent(irg);
1038 id = ent->ld_name ? ent->ld_name : ent->name;
1039 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
1040 len = id_to_strlen (id);
1041 cp = id_to_str (id);
1042 if (dump_file_suffix)
1043 fname = malloc (len + 5 + strlen(suffix) + strlen(dump_file_suffix));
1045 fname = malloc (len + 5 + strlen(suffix));
1046 strncpy (fname, cp, len); /* copy the filename */
1048 if (dump_file_suffix) strcat (fname, dump_file_suffix); /* append file suffix */
1049 strcat (fname, suffix); /* append file suffix */
1050 strcat (fname, ".vcg"); /* append the .vcg suffix */
1051 F = fopen (fname, "w"); /* open file for writing */
1053 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1057 strcpy(label, "yes");
1059 strcpy (label, "no");
1064 "graph: { title: \"ir graph of %s\"\n"
1065 "display_edge_labels: %s\n"
1066 "layoutalgorithm: mindepth\n"
1067 "manhattan_edges: yes\n"
1068 "port_sharing: no\n"
1069 "orientation: bottom_to_top\n"
1070 "classname 1: \"Data\"\n"
1071 "classname 2: \"Block\"\n"
1072 "classname 3: \"Entity type\""
1073 "classname 4: \"Entity owner\""
1074 "classname 5: \"Method Param\""
1075 "classname 6: \"Method Res\""
1076 "classname 7: \"Super\""
1077 "classname 8: \"Union\""
1078 "classname 9: \"Points-to\""
1079 "classname 10: \"Array Element Type\""
1080 "classname 11: \"Overwrites\""
1081 "classname 12: \"Member\""
1084 xfprintf (F, "\n"); /* a separator */
1087 static void vcg_open_name (const char *name) {
1088 char *fname; /* filename to put the vcg information in */
1092 /** open file for vcg graph */
1094 fname = malloc (len + 5);
1095 if (dump_file_suffix)
1096 fname = malloc (len + 5 + strlen(dump_file_suffix));
1098 fname = malloc (len + 5);
1099 strcpy (fname, name); /* copy the filename */
1100 if (dump_file_suffix) strcat (fname, dump_file_suffix);
1101 strcat (fname, ".vcg"); /* append the .vcg suffix */
1102 F = fopen (fname, "w"); /* open file for writing */
1104 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1108 strcpy(label, "yes");
1110 strcpy (label, "no");
1115 "graph: { title: \"ir graph of %s\"\n"
1116 "display_edge_labels: %s\n"
1117 "layoutalgorithm: mindepth\n"
1118 "manhattan_edges: yes\n"
1119 "port_sharing: no\n"
1120 "orientation: bottom_to_top\n"
1121 "classname 1: \"Data\"\n"
1122 "classname 2: \"Block\"\n"
1123 "classname 3: \"Entity type\"\n"
1124 "classname 4: \"Entity owner\"\n"
1125 "classname 5: \"Method Param\"\n"
1126 "classname 6: \"Method Res\"\n"
1127 "classname 7: \"Super\"\n"
1128 "classname 8: \"Union\"\n"
1129 "classname 9: \"Points-to\"\n"
1130 "classname 10: \"Array Element Type\"\n"
1131 "classname 11: \"Overwrites\"\n"
1132 "classname 12: \"Member\"\n"
1135 xfprintf (F, "\n"); /* a separator */
1140 xfprintf (F, "}\n"); /* print footer */
1141 fclose (F); /* close vcg file */
1144 /************************************************************************/
1145 /* routines to dump a graph, blocks as conventional nodes. */
1146 /************************************************************************/
1148 static int node_floats(ir_node *n) {
1149 return ((get_op_pinned(get_irn_op(n)) == floats) &&
1150 (get_irg_pinned(current_ir_graph) == floats));
1154 dump_whole_node (ir_node *n, void* env) {
1156 if (!node_floats(n)) dump_ir_block_edge(n);
1157 dump_ir_data_edges(n);
1161 dump_ir_graph (ir_graph *irg)
1164 rem = current_ir_graph;
1165 current_ir_graph = irg;
1169 /* walk over the graph */
1170 /* dump_whole_node must be called in post visiting predecessors */
1171 irg_walk(irg->end, NULL, dump_whole_node, NULL);
1173 /* dump the out edges in a separate walk */
1174 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1175 irg_out_walk(irg->start, dump_out_edge, NULL, NULL);
1180 current_ir_graph = rem;
1183 /***********************************************************************/
1184 /* the following routines dump the nodes as attached to the blocks. */
1185 /***********************************************************************/
1188 dump_ir_blocks_nodes (ir_node *n, void *env) {
1189 ir_node *block = (ir_node *)env;
1191 if (is_no_Block(n) && get_nodes_Block(n) == block && !node_floats(n)) {
1193 dump_ir_data_edges(n);
1195 if (get_irn_op(n) == op_Bad)
1200 dump_ir_block (ir_node *block, void *env) {
1201 ir_graph *irg = (ir_graph *)env;
1203 if (get_irn_opcode(block) == iro_Block) {
1205 /* This is a block. So dump the vcg information to make a block. */
1206 xfprintf(F, "graph: { title: \"");
1207 PRINT_NODEID(block);
1208 fprintf(F, "\" label: \"");
1209 #ifdef DEBUG_libfirm
1210 xfprintf (F, "%ld", get_irn_node_nr(block));
1212 xfprintf (F, "%I", block->op->name);
1214 if (exc_normal != get_Block_exc (block))
1215 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1217 xfprintf(F, "\" status:clustered color:%s \n",
1218 get_Block_matured (block) ? "yellow" : "red");
1219 /* dump the blocks edges */
1220 dump_ir_data_edges(block);
1222 /* dump the nodes that go into the block */
1223 irg_walk(irg->end, dump_ir_blocks_nodes, NULL, block);
1225 /* Close the vcg information for the block */
1226 xfprintf(F, "}\n\n");
1227 dump_const_node_local(block, NULL);
1233 dump_blockless_nodes (ir_node *n, void *env) {
1234 if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
1236 dump_ir_data_edges(n);
1237 dump_ir_block_edge(n);
1238 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1241 if (node_floats(n)) {
1243 dump_ir_data_edges(n);
1244 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1248 static void dump_ir_block_graph_2 (ir_graph *irg)
1251 /* walk over the blocks in the graph */
1252 irg_block_walk(irg->end, dump_ir_block, NULL, irg);
1254 /* dump all nodes that are not in a Block */
1255 irg_walk(irg->end, dump_blockless_nodes, NULL, NULL);
1257 /* dump the Bad node */
1259 dump_node(get_irg_bad(irg), NULL);
1263 dump_ir_block_graph (ir_graph *irg)
1266 rem = current_ir_graph;
1267 current_ir_graph = irg;
1271 dump_ir_block_graph_2 (irg);
1273 if (dump_loop_information_flag) dump_loop_info(irg);
1276 current_ir_graph = rem;
1280 /***********************************************************************/
1281 /* the following routines dump a control flow graph */
1282 /***********************************************************************/
1286 dump_block_to_cfg (ir_node *block, void *env) {
1290 if (get_irn_opcode(block) == iro_Block) {
1291 /* This is a block. Dump a node for the block. */
1292 xfprintf (F, "node: {title:\""); PRINT_NODEID(block);
1293 xfprintf (F, "\" label: \"%I ", block->op->name); PRINT_NODEID(block);
1295 if (exc_normal != get_Block_exc (block))
1296 xfprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1298 xfprintf (F, "\" ");
1299 if (dump_dominator_information_flag)
1300 xfprintf(F, "info1:\"dom depth %d\"", get_Block_dom_depth(block));
1301 xfprintf (F, "}\n");
1302 /* Dump the edges */
1303 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1304 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1305 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
1306 xfprintf (F, "edge: { sourcename: \"");
1307 PRINT_NODEID(block);
1308 fprintf (F, "\" targetname: \"");
1310 fprintf (F, "\" }\n");
1313 /* Dump dominator edge */
1314 if (dump_dominator_information_flag && get_Block_idom(block)) {
1315 pred = get_Block_idom(block);
1316 xfprintf (F, "edge: { sourcename: \"");
1317 PRINT_NODEID(block);
1318 fprintf (F, "\" targetname: \"");
1320 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1326 dump_cfg (ir_graph *irg)
1328 ir_graph *rem = current_ir_graph;
1329 int ddif = dump_dominator_information_flag;
1330 current_ir_graph = irg;
1331 vcg_open (irg, "-cfg");
1333 if (get_irg_dom_state(irg) != dom_consistent)
1334 dump_dominator_information_flag = 0;
1336 /* walk over the blocks in the graph */
1337 irg_block_walk(irg->end, dump_block_to_cfg, NULL, NULL);
1338 dump_ir_node (irg->bad);
1340 dump_dominator_information_flag = ddif;
1342 current_ir_graph = rem;
1346 /***********************************************************************/
1347 /* the following routine dumps all type information reachable from an */
1349 /***********************************************************************/
1353 dump_type_graph (ir_graph *irg)
1356 rem = current_ir_graph;
1357 current_ir_graph = irg;
1359 vcg_open (irg, "-type");
1361 /* walk over the blocks in the graph */
1362 type_walk_irg(irg, dump_type_info, NULL, NULL);
1363 /* The walker for the const code can be called several times for the
1364 same (sub) experssion. So that no nodes are dumped several times
1365 we decrease the visited flag of the corresponding graph after each
1366 walk. So now increase it finally. */
1367 inc_irg_visited(get_const_code_irg());
1370 current_ir_graph = rem;
1373 /***********************************************************************/
1374 /* the following routine dumps all type information */
1375 /***********************************************************************/
1379 dump_all_types (void)
1381 vcg_open_name ("All_types");
1382 type_walk(dump_type_info, NULL, NULL);
1383 inc_irg_visited(get_const_code_irg());
1388 dump_class_hierarchy (bool entities)
1390 vcg_open_name ("class_hierarchy");
1392 type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1394 type_walk(dump_class_hierarchy_node, NULL, NULL);
1398 /***********************************************************************/
1399 /* dumps a graph with type information */
1400 /***********************************************************************/
1404 dump_ir_graph_w_types (ir_graph *irg)
1407 rem = current_ir_graph;
1408 current_ir_graph = irg;
1410 vcg_open (irg, "-all");
1412 /* dump common ir graph */
1413 irg_walk(irg->end, dump_whole_node, NULL, NULL);
1414 /* dump type info */
1415 type_walk_irg(irg, dump_type_info, NULL, NULL);
1416 inc_irg_visited(get_const_code_irg());
1417 /* dump edges from graph to type info */
1418 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1421 current_ir_graph = rem;
1425 dump_ir_block_graph_w_types (ir_graph *irg)
1428 rem = current_ir_graph;
1429 current_ir_graph = irg;
1431 vcg_open (irg, "-all");
1433 /* dump common blocked ir graph */
1434 dump_ir_block_graph_2(irg);
1435 /* dump type info */
1436 type_walk_irg(irg, dump_type_info, NULL, NULL);
1437 inc_irg_visited(get_const_code_irg());
1438 /* dump edges from graph to type info */
1439 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1442 current_ir_graph = rem;
1445 /***********************************************************************/
1446 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1448 /* dump_ir_block_graph */
1450 /* dump_type_graph */
1451 /* dump_ir_graph_w_types */
1452 /***********************************************************************/
1453 void dump_all_ir_graphs (dump_graph_func *dump_graph) {
1455 for (i=0; i < get_irp_n_irgs(); i++) {
1456 dump_graph(get_irp_irg(i));
1461 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1462 abort with a segmentation fault. */
1463 void turn_off_edge_labels(void) {
1468 void dump_consts_local(bool b) {
1469 dump_const_local = b;
1472 void turn_off_constant_entity_values(void) {
1476 void dump_keepalive_edges(bool b) {
1480 void dump_out_edges(void) {
1481 dump_out_edge_flag = 1;
1484 void dump_dominator_information(void) {
1485 dump_dominator_information_flag = 1;
1488 void dump_loop_information(void) {
1489 dump_loop_information_flag = 1;
1492 void dont_dump_loop_information(void) {
1493 dump_loop_information_flag = 0;
1496 static void clear_link(ir_node * node, void * env) {
1497 set_irn_link(node, NULL);
1500 static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
1502 || node_floats(node)
1503 || get_irn_op(node) == op_Bad
1504 || get_irn_op(node) == op_Unknown) {
1505 pmap_entry * entry = pmap_find(map, current_ir_graph);
1507 ARR_APP1(ir_node *, (ir_node **) entry->value, node);
1509 ir_node ** arr = NEW_ARR_F(ir_node *, 1);
1511 pmap_insert(map, current_ir_graph, arr);
1514 ir_node * block = get_nodes_Block(node);
1515 set_irn_link(node, get_irn_link(block));
1516 set_irn_link(block, node);
1521 static void dump_cg_ir_block(ir_node * block, void * env) {
1523 pmap *irgmap = (pmap *)env;
1524 assert(is_Block(block));
1525 xfprintf(F, "graph: { title: \"");
1526 PRINT_NODEID(block);
1527 fprintf(F, "\" label: \"");
1528 #ifdef DEBUG_libfirm
1529 xfprintf (F, "%ld", get_irn_node_nr(block));
1531 xfprintf (F, "%I", block->op->name);
1533 if (exc_normal != get_Block_exc(block)) {
1534 fprintf (F, " (%s)", exc_to_string (get_Block_exc(block)));
1537 xfprintf(F, "\" status:clustered color:%s \n",
1538 get_Block_matured(block) ? "yellow" : "red");
1540 /* dump the blocks edges */
1541 dump_ir_data_edges(block);
1543 /* dump the nodes that go into the block */
1544 for (node = get_irn_link(block); node; node = get_irn_link(node)) {
1545 dump_node(node, irgmap);
1546 dump_ir_data_edges(node);
1549 /* Close the vcg information for the block */
1550 xfprintf(F, "}\n\n");
1553 static void d_cg_block_graph(ir_graph *irg, ir_node **arr, pmap *irgmap) {
1556 xfprintf(F, "graph: { title: \"%p\" label: \"%I\" status:clustered color:white \n",
1557 irg, get_entity_ident(get_irg_ent(irg)));
1559 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1560 ir_node * node = arr[i];
1561 if (is_Block(node)) {
1562 /* Dumps the block and all the nodes in the block , which are to
1563 be found in Block->link. */
1564 dump_cg_ir_block(node, irgmap);
1566 /* Nodes that are not in a Block. */
1567 dump_node(node, NULL);
1568 dump_ir_data_edges(node);
1571 /* Close the vcg information for the irg */
1572 xfprintf(F, "}\n\n");
1575 /* dump interprocedural graph with surrounding methods */
1576 void dump_cg_block_graph(ir_graph * irg) {
1577 pmap * map = pmap_create();
1578 pmap * map2 = pmap_create();
1583 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1584 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1585 pmap_insert(map2, entry->key, entry->value);
1586 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1587 d_cg_block_graph(entry->key, entry->value, map2);
1588 DEL_ARR_F(entry->value);
1594 if (dump_loop_information_flag) dump_loop_info(irg);
1598 static void collect_node(ir_node * node, void *env) {
1600 || node_floats(node)
1601 || get_irn_op(node) == op_Bad
1602 || get_irn_op(node) == op_Unknown) {
1603 ir_node ** arr = (ir_node **) get_irg_link(current_ir_graph);
1604 ARR_APP1(ir_node *, arr, node);
1605 set_irg_link(current_ir_graph, arr); /* arr is an l-value, APP_ARR might change it! */
1607 ir_node * block = get_nodes_Block(node);
1608 set_irn_link(node, get_irn_link(block));
1609 set_irn_link(block, node);
1613 /* Links all nodes that have the block field set in the link field of
1614 the block. Adds all blocks and nodes not associated with a block
1615 in a array in irg->link. */
1616 static void collect_nodes(void) {
1618 for (i = 0; i < get_irp_n_irgs(); i++)
1619 set_irg_link(get_irp_irg(i), NEW_ARR_F(ir_node *, 0));
1620 cg_walk(clear_link, collect_node, NULL);
1623 static void dump_graphs(void) {
1625 for (i = 0; i < get_irp_n_irgs(); i++) {
1626 current_ir_graph = get_irp_irg(i);
1627 d_cg_block_graph(current_ir_graph, get_irg_link(current_ir_graph), NULL);
1631 /* Dump all irgs in interprocedural view to a single file. */
1632 void dump_all_cg_block_graph(void) {
1634 int rem_view = interprocedural_view;
1635 interprocedural_view = 1;
1636 vcg_open_name ("All_graphs");
1641 if (dump_loop_information_flag)
1642 for (i = 0; i < get_irp_n_irgs(); i++)
1643 dump_loop_info(get_irp_irg(i));
1646 interprocedural_view = rem_view;
1649 /* dump interprocedural block graph with surrounding methods */
1650 void dump_cg_graph(ir_graph * irg) {
1651 pmap * map = pmap_create();
1652 pmap * map2 = pmap_create(); /* We can not iterate in the same map twice! */
1656 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1657 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1658 pmap_insert(map2, entry->key, entry->value);
1659 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1660 ir_node ** arr = entry->value;
1662 ident * irg_ident = get_entity_ident(get_irg_ent(entry->key));
1664 xfprintf(F, "graph: { title: \"%I\" label: \"%I\" status:clustered color:white \n",
1665 irg_ident, irg_ident);
1667 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1668 ir_node * node = arr[i];
1669 dump_node(node, map2);
1670 dump_ir_data_edges(node);
1671 if (is_Block(node)) {
1672 for (node = get_irn_link(node); node; node = get_irn_link(node)) {
1673 dump_node(node, map2);
1674 dump_ir_block_edge(node);
1675 dump_ir_data_edges(node);
1682 /* Close the vcg information for the irg */
1683 xfprintf(F, "}\n\n");