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;
96 static INLINE bool dump_const_local_set() {
97 if (!dump_out_edge_flag && !dump_loop_information_flag)
98 return dump_const_local;
103 /* A global variable to record output of the Bad node. */
104 static int Bad_dumped;
106 static void dump_ir_blocks_nodes (ir_node *n, void *env);
107 static void dump_whole_node(ir_node *n, void* env);
109 /*******************************************************************/
110 /* routines to dump information about a single node */
111 /*******************************************************************/
116 dump_node_opcode (ir_node *n)
121 if (n->op->code == iro_Const) {
122 xfprintf (F, "%v", n->attr.con);
125 } else if (n->op->code == iro_SymConst) {
126 if (get_SymConst_kind(n) == linkage_ptr_info) {
127 /* don't use get_SymConst_ptr_info as it mangles the name. */
128 xfprintf (F, "SymC %I", n->attr.i.tori.ptrinfo);
130 assert(get_kind(get_SymConst_type(n)) == k_type);
131 assert(get_type_ident(get_SymConst_type(n)));
132 xfprintf (F, "SymC %I ", get_type_ident(get_SymConst_type(n)));
133 if (get_SymConst_kind(n) == type_tag)
136 xfprintf (F, "size");
140 } else if (n->op->code == iro_Filter && !interprocedural_view) {
145 xfprintf (F, "%I", get_irn_opident(n));
150 dump_node_mode (ir_node *n)
152 switch (n->op->code) {
170 xfprintf (F, "%I", get_mode_ident(n->mode));
178 dump_node_nodeattr (ir_node *n)
180 switch (n->op->code) {
182 if (false && interprocedural_view) {
183 xfprintf (F, "%I", get_entity_ident(get_irg_ent(current_ir_graph)));
187 if (n->in[1]->op->code == iro_Cmp) {
188 xfprintf (F, "%s", get_pnc_string(n->attr.proj));
190 xfprintf (F, "%ld", n->attr.proj);
194 xfprintf (F, "%ld", n->attr.filter.proj);
197 assert(get_kind(get_Sel_entity(n)) == k_entity);
198 xfprintf (F, "%I", get_entity_ident(get_Sel_entity(n)));
206 dump_node_vcgattr (ir_node *n)
208 switch (n->op->code) {
215 xfprintf (F, "color: blue");
218 xfprintf (F, "color: lightyellow");
221 xfprintf (F, "color: green");
227 xfprintf (F, "color: yellow");
230 xfprintf (F, DEFAULT_NODE_ATTR);
234 static bool pred_in_wrong_graph(ir_node *n, int pos, pmap *irgmap) {
235 ir_node *block = (is_Block(n)) ? n : get_nodes_Block(n);
238 ((get_irn_op(n) == op_Filter) || (get_irn_op(n) == op_Block))) {
239 ir_node *pred = skip_Proj(get_Block_cfgpred(block, pos));
240 if (is_ip_cfop(pred)) {
241 ir_graph *irg = get_ip_cfop_irg(pred);
242 if (pmap_find(irgmap, irg) == NULL) return true;
251 bool is_constlike_node(ir_node *n) {
252 ir_op *op = get_irn_op(n);
253 return (op == op_Const || op == op_Bad || op == op_SymConst);
257 static void dump_const_node_local(ir_node *n, pmap *irgmap) {
259 if (!dump_const_local_set()) return;
260 /* Use visited flag to avoid outputting nodes twice.
261 initialize it first. */
262 for (i = 0; i < get_irn_arity(n); i++) {
263 ir_node *con = get_irn_n(n, i);
264 if (is_constlike_node(con)) {
265 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
266 set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
269 for (i = 0; i < get_irn_arity(n); i++) {
270 ir_node *con = get_irn_n(n, i);
271 if (is_constlike_node(con) && irn_not_visited(con)) {
272 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
273 mark_irn_visited(con);
274 /* Generate a new name for the node by appending the names of
276 xfprintf (F, "node: {title: \""); PRINT_NODEID(n); PRINT_NODEID(con);
277 fprintf(F, "\" label: \"");
278 dump_node_opcode(con);
279 dump_node_mode (con);
281 dump_node_nodeattr(con);
283 xfprintf (F, " %ld", get_irn_node_nr(con));
286 dump_node_vcgattr(con);
293 dump_node (ir_node *n, pmap * map) {
294 if (dump_const_local_set() && is_constlike_node(n)) return;
297 xfprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
302 dump_node_nodeattr(n);
304 xfprintf (F, " %ld", get_irn_node_nr(n));
307 dump_node_vcgattr(n);
309 dump_const_node_local(n, map);
313 dump_ir_node (ir_node *n)
316 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: ");
318 switch (n->op->code) { /* node label */
320 xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
321 xfprintf (F, DEFAULT_NODE_ATTR);
328 xfprintf (F, "\"%I\" color: blue ", get_irn_opident(n));
329 xfprintf (F, DEFAULT_NODE_ATTR);
332 xfprintf (F, "\"%I\" color: lightyellow ", get_irn_opident(n));
333 xfprintf (F, DEFAULT_NODE_ATTR);
336 xfprintf (F, "\"%I%I\" color: green", get_irn_opident(n), get_irn_modeident(n));
337 if (get_irn_modecode(n) == irm_M)
338 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
340 xfprintf (F, DEFAULT_NODE_ATTR);
343 xfprintf (F, "\"%v%I\" color: yellow ", n->attr.con, get_irn_modeident(n));
344 xfprintf (F, DEFAULT_NODE_ATTR);
347 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
348 xfprintf (F, DEFAULT_NODE_ATTR);
351 if (n->in[1]->op->code == iro_Cmp) {
352 xfprintf (F, "\"%I%I %s\" color: yellow", get_irn_opident(n), get_irn_modeident(n),
353 get_pnc_string(n->attr.proj));
355 xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.proj);
357 xfprintf (F, DEFAULT_NODE_ATTR);
360 xfprintf (F, "\"%I%I %ld\"", get_irn_opident(n), get_irn_modeident(n), n->attr.filter.proj);
361 xfprintf (F, DEFAULT_NODE_ATTR);
364 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
365 xfprintf (F, DEFAULT_NODE_ATTR);
368 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
369 xfprintf (F, DEFAULT_NODE_ATTR);
372 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
373 xfprintf (F, DEFAULT_NODE_ATTR);
376 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
377 xfprintf (F, DEFAULT_NODE_ATTR);
380 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
381 xfprintf (F, DEFAULT_NODE_ATTR);
384 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
385 xfprintf (F, DEFAULT_NODE_ATTR);
388 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
389 xfprintf (F, DEFAULT_NODE_ATTR);
392 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
393 xfprintf (F, DEFAULT_NODE_ATTR);
396 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
397 xfprintf (F, DEFAULT_NODE_ATTR);
400 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
401 xfprintf (F, DEFAULT_NODE_ATTR);
404 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
405 xfprintf (F, DEFAULT_NODE_ATTR);
408 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
409 xfprintf (F, DEFAULT_NODE_ATTR);
412 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
413 xfprintf (F, DEFAULT_NODE_ATTR);
416 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
417 xfprintf (F, DEFAULT_NODE_ATTR);
420 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
421 xfprintf (F, DEFAULT_NODE_ATTR);
424 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
425 xfprintf (F, DEFAULT_NODE_ATTR);
428 xfprintf (F, "\"%I\"", get_irn_opident(n));
429 xfprintf (F, DEFAULT_NODE_ATTR);
432 xfprintf (F, "\"%I\"", get_irn_opident(n));
433 xfprintf (F, DEFAULT_NODE_ATTR);
436 xfprintf (F, "\"%I\"", get_irn_opident(n));
437 xfprintf (F, DEFAULT_NODE_ATTR);
440 xfprintf (F, "\"%I\"", get_irn_opident(n));
441 xfprintf (F, DEFAULT_NODE_ATTR);
444 xfprintf (F, "\"%I\"", get_irn_opident(n));
445 xfprintf (F, DEFAULT_NODE_ATTR);
448 xfprintf (F, "\"%I\"", get_irn_opident(n));
449 xfprintf (F, DEFAULT_NODE_ATTR);
452 xfprintf (F, "\"%I%I\"", get_irn_opident(n), get_irn_modeident(n));
453 xfprintf (F, DEFAULT_NODE_ATTR);
457 xfprintf (F, "\"%R\"", n);
458 xfprintf (F, DEFAULT_NODE_ATTR);
461 xfprintf (F, "\"%I\" ", get_irn_opident(n));
462 xfprintf (F, DEFAULT_NODE_ATTR);
465 assert(get_kind(get_Sel_entity(n)) == k_entity);
466 xfprintf (F, "\"%I ", get_irn_opident(n));
467 xfprintf (F, "%I", get_entity_ident(get_Sel_entity(n)));
468 xfprintf (F, DEFAULT_NODE_ATTR);
471 assert(get_kind(get_SymConst_type(n)) == k_type);
472 assert(get_type_ident(get_SymConst_type(n)));
473 xfprintf (F, "\"%s ", get_type_name(get_SymConst_type(n)));
474 switch (n->attr.i.num){
476 xfprintf (F, "tag\" ");
479 xfprintf (F, "size\" ");
485 xfprintf (F, DEFAULT_NODE_ATTR);
488 xfprintf (F, "\"%I\" ", get_irn_opident(n));
489 xfprintf (F, DEFAULT_NODE_ATTR " color: green");
492 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
493 xfprintf (F, DEFAULT_NODE_ATTR);
496 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
497 xfprintf (F, DEFAULT_NODE_ATTR);
500 xfprintf (F, "\"%I%I\" ", get_irn_opident(n), get_irn_modeident(n));
502 xfprintf (F, "}\n"); /* footer */
506 /* dump the edge to the block this node belongs to */
508 dump_ir_block_edge(ir_node *n) {
509 if (dump_const_local_set() && is_constlike_node(n)) return;
510 if (is_no_Block(n)) {
511 xfprintf (F, "edge: { sourcename: \"");
513 xfprintf (F, "\" targetname: \"");
514 PRINT_NODEID(get_nodes_Block(n));
515 xfprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
519 static void print_edge_vcgattr(ir_node *from, int to) {
522 if (is_backedge(from, to)) xfprintf (F, BACK_EDGE_ATTR);
524 switch (get_irn_opcode(from)) {
526 xfprintf (F, CF_EDGE_ATTR);
528 case iro_Start: break;
531 if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
532 xfprintf (F, CF_EDGE_ATTR);
533 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
534 xfprintf (F, MEM_EDGE_ATTR);
537 case iro_EndReg: break;
538 case iro_EndExcept: break;
540 case iro_Break: break;
541 case iro_Cond: break;
544 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
546 case iro_Const: break;
547 case iro_SymConst:break;
550 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
552 case iro_CallBegin: break;
555 case iro_Minus: break;
561 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
569 case iro_Shrs: break;
572 case iro_Conv: break;
574 if (get_irn_modecode(from) == irm_M) xfprintf (F, MEM_EDGE_ATTR);
580 if (to == 0) xfprintf (F, MEM_EDGE_ATTR);
583 xfprintf (F, MEM_EDGE_ATTR);
585 case iro_Tuple: break;
588 switch (get_irn_modecode(from)) {
590 xfprintf (F, CF_EDGE_ATTR);
593 xfprintf (F, MEM_EDGE_ATTR);
599 case iro_Unknown: break;
606 /* dump edges to our inputs */
608 dump_ir_data_edges(ir_node *n) {
609 int i, visited = get_irn_visited(n);
611 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
614 for (i = 0; i < get_irn_arity(n); i++) {
615 ir_node * pred = get_irn_n(n, i);
617 if ((interprocedural_view && get_irn_visited(pred) < visited))
618 continue; /* pred not dumped */
619 if (is_backedge(n, i))
620 fprintf (F, "backedge: {sourcename: \"");
622 fprintf (F, "edge: {sourcename: \"");
624 fprintf (F, "\" targetname: \"");
625 if ((dump_const_local_set()) && is_constlike_node(pred))
629 fprintf (F, " label: \"%d\" ", i);
630 print_edge_vcgattr(n, i);
637 dump_out_edge (ir_node *n, void* env) {
639 for (i = 0; i < get_irn_n_outs(n); i++) {
640 assert(get_irn_out(n, i));
641 fprintf (F, "edge: {sourcename: \"");
643 fprintf (F, "\" targetname: \"");
644 PRINT_NODEID(get_irn_out(n, i));
645 fprintf (F, "\" color: red linestyle: dashed");
651 dump_loop_node_edge (ir_loop *loop, int i) {
653 fprintf (F, "edge: {sourcename: \"%p\" targetname: \"", loop);
654 PRINT_NODEID(get_loop_node(loop, i));
655 fprintf (F, "\" color: green");
660 void dump_loops (ir_loop *loop) {
662 /* dump this loop node */
663 xfprintf (F, "node: {title: \"%p\" label: \"loop %d, %d sons, %d nodes\" }\n",
664 loop, get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
665 /* dump edges to nodes in loop -- only if it is a real loop */
666 if (get_loop_depth(loop) != 0) {
667 for (i = 0; i < get_loop_n_nodes(loop); i++) {
668 dump_loop_node_edge(loop, i);
671 for (i = 0; i < get_loop_n_sons(loop); i++) {
672 dump_loops(get_loop_son(loop, i));
677 void dump_loop_info(ir_graph *irg) {
678 ir_graph *rem = current_ir_graph;
679 current_ir_graph = irg;
681 if (get_irg_loop(irg))
682 dump_loops(get_irg_loop(irg));
684 current_ir_graph = rem;
688 /* dumps the edges between nodes and their type or entity attributes. */
689 static void dump_node2type_edges (ir_node *n, void *env)
693 switch (get_irn_opcode(n)) {
695 /* @@@ some consts have an entity */
698 if ( (get_SymConst_kind(n) == type_tag)
699 || (get_SymConst_kind(n) == size)) {
700 xfprintf (F, "edge: { sourcename: \"");
702 fprintf (F, "\" targetname: \"%p\" "
703 NODE2TYPE_EDGE_ATTR "}\n", get_SymConst_type(n));
707 xfprintf (F, "edge: { sourcename: \"");
709 fprintf (F, "\" targetname: \"%p\" "
710 NODE2TYPE_EDGE_ATTR "}\n", get_Sel_entity(n));
713 xfprintf (F, "edge: { sourcename: \"");
715 fprintf (F, "\" targetname: \"%p\" "
716 NODE2TYPE_EDGE_ATTR "}\n", get_Call_type(n));
719 xfprintf (F, "edge: { sourcename: \"");
721 fprintf (F, "\" targetname: \"%p\" "
722 NODE2TYPE_EDGE_ATTR "}\n", get_Alloc_type(n));
725 xfprintf (F, "edge: { sourcename: \"");
727 fprintf (F, "\" targetname: \"%p\" "
728 NODE2TYPE_EDGE_ATTR "}\n", get_Free_type(n));
736 static void dump_const_expression(ir_node *value) {
737 ir_graph *rem = current_ir_graph;
738 int rem_dump_const_local = dump_const_local;
739 dump_const_local = 0;
740 current_ir_graph = get_const_code_irg();
741 irg_walk(value, dump_ir_blocks_nodes, NULL, get_nodes_Block(value));
742 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
743 current_ir_graph = rem;
744 dump_const_local = rem_dump_const_local;
748 static void print_type_info(type *tp) {
749 if (get_type_state(tp) == layout_undefined) {
750 xfprintf(F, "state: layout_undefined\n");
752 xfprintf(F, "state: layout_fixed,\n");
754 if (get_type_mode(tp))
755 xfprintf(F, "mode: %I,\n", get_mode_ident(get_type_mode(tp)));
756 xfprintf(F, "size: %dB,\n", get_type_size(tp));
760 static void print_typespecific_info(type *tp) {
761 switch (get_type_tpop_code(tp)) {
764 if(existent == get_class_peculiarity(tp))
765 xfprintf (F, " " TYPE_CLASS_NODE_ATTR);
767 xfprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
771 xfprintf (F, " " TYPE_METH_NODE_ATTR);
782 case tpo_enumeration:
795 static void print_type_node(type *tp) {
796 xfprintf (F, "node: {title: \"%p\" ", tp);
797 xfprintf (F, "label: \"%I %I\"", get_type_tpop_nameid(tp), get_type_ident(tp));
798 xfprintf (F, "info1: \"");
801 print_typespecific_info(tp);
805 void dump_entity_node(entity *ent) {
806 xfprintf (F, "node: {title: \"%p\" ", ent);
807 xfprintf (F, DEFAULT_TYPE_ATTRIBUTE);
808 xfprintf (F, "label: ");
809 xfprintf (F, "\"ent %I\" " ENTITY_NODE_ATTR , get_entity_ident(ent));
810 fprintf (F, "\n info1:\"\nallocation: ");
811 switch (get_entity_allocation(ent)) {
812 case dynamic_allocated: fprintf (F, "dynamic allocated"); break;
813 case automatic_allocated: fprintf (F, "automatic allocated"); break;
814 case static_allocated: fprintf (F, "static allocated"); break;
815 case parameter_allocated: fprintf (F, "parameter allocated"); break;
817 fprintf (F, "\nvisibility: ");
818 switch (get_entity_visibility(ent)) {
819 case local: fprintf (F, "local"); break;
820 case external_visible: fprintf (F, "external_visible"); break;
821 case external_allocated: fprintf (F, "external_allocate"); break;
823 fprintf (F, "\nvariability: ");
824 switch (get_entity_variability(ent)) {
825 case uninitialized: fprintf (F, "uninitialized");break;
826 case initialized: fprintf (F, "initialized"); break;
827 case part_constant: fprintf (F, "part_constant");break;
828 case constant: fprintf (F, "constant"); break;
830 fprintf (F, "\nvolatility: ");
831 switch (get_entity_volatility(ent)) {
832 case non_volatile: fprintf (F, "non_volatile"); break;
833 case is_volatile: fprintf (F, "is_volatile"); break;
835 fprintf (F, "\npeculiarity: ");
836 switch (get_entity_peculiarity(ent)) {
837 case description: fprintf (F, "description"); break;
838 case inherited: fprintf (F, "inherited"); break;
839 case existent: fprintf (F, "existent"); break;
841 xfprintf(F, "\nname: %I\nld_name: %I", get_entity_ident(ent), get_entity_ld_ident(ent));
842 fprintf(F, "\noffset: %d", get_entity_offset(ent));
843 if (is_method_type(get_entity_type(ent)))
844 xfprintf (F, "\nirg = %p ", get_entity_irg(ent));
845 xfprintf(F, "\"\n}\n");
848 /* dumps a type or entity and it's edges. */
850 dump_type_info (type_or_ent *tore, void *env) {
851 int i = 0; /* to shutup gcc */
853 /* dump this type or entity */
855 switch (get_kind(tore)) {
858 entity *ent = (entity *)tore;
861 dump_entity_node(ent);
863 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
864 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
865 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
866 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
867 ENT_TYPE_EDGE_ATTR "}\n", ent, get_entity_type(ent));
868 if(is_class_type(get_entity_owner(ent))) {
869 for(i = 0; i < get_entity_n_overwrites(ent); i++)
870 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
871 ENT_OVERWRITES_EDGE_ATTR "}\n",
872 ent, get_entity_overwrites(ent, i));
874 /* attached subgraphs */
875 if (const_entities && (get_entity_variability(ent) != uninitialized)) {
876 if (is_atomic_entity(ent)) {
877 value = get_atomic_ent_value(ent);
878 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"", ent);
880 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR "\"}\n");
881 dump_const_expression(value);
883 if (is_compound_entity(ent)) {
884 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
885 value = get_compound_ent_value(ent, i);
886 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"", ent);
888 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR " %d \"}\n", i);
889 dump_const_expression(value);
890 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
891 ENT_CORR_EDGE_ATTR "}\n", ent,
892 get_compound_ent_value_member(ent, i), i);
899 type *tp = (type *)tore;
901 /* and now the edges */
902 switch (get_type_tpop_code(tp)) {
905 for (i=0; i < get_class_n_supertypes(tp); i++)
906 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
907 TYPE_SUPER_EDGE_ATTR "}\n",
908 tp, get_class_supertype(tp, i));
909 for (i=0; i < get_class_n_members(tp); i++)
910 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
911 TYPE_MEMBER_EDGE_ATTR "}\n",
912 tp, get_class_member(tp, i));
916 for (i=0; i < get_struct_n_members(tp); i++)
917 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
918 TYPE_MEMBER_EDGE_ATTR "}\n",
919 tp, get_struct_member(tp, i));
923 for (i = 0; i < get_method_n_params(tp); i++)
924 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
925 METH_PAR_EDGE_ATTR "}\n",
926 tp, get_method_param_type(tp, i), i);
927 for (i = 0; i < get_method_n_ress(tp); i++)
928 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
929 METH_RES_EDGE_ATTR "}\n",
930 tp, get_method_res_type(tp, i), i);
934 for (i = 0; i < get_union_n_members(tp); i++)
935 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
936 "label: \"\"f" UNION_EDGE_ATTR "}\n",
937 tp, get_union_member(tp, i));
941 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
942 ARR_ELT_TYPE_EDGE_ATTR "}\n", tp, get_array_element_type(tp), i);
943 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
944 ARR_ENT_EDGE_ATTR "}\n", tp, get_array_element_entity(tp), i);
946 case tpo_enumeration:
951 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
952 PTR_PTS_TO_EDGE_ATTR "}\n", tp,
953 get_pointer_points_to_type(tp), i);
961 break; /* case k_type */
964 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
966 } /* switch kind_or_entity */
969 /* dumps a class type node and a superclass edge.
970 If env != null dumps entities of classes and overwrites edges. */
972 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
973 int i = 0; /* to shutup gcc */
975 /* dump this type or entity */
976 switch (get_kind(tore)) {
978 entity *ent = (entity *)tore;
979 if (get_entity_owner(ent) == get_glob_type()) break;
980 if ((env) && is_class_type(get_entity_owner(ent))) {
982 dump_entity_node(ent);
984 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
985 TYPE_MEMBER_EDGE_ATTR "}\n", get_entity_owner(ent), ent);
986 for(i = 0; i < get_entity_n_overwrites(ent); i++)
987 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
988 ENT_OVERWRITES_EDGE_ATTR "}\n",
989 ent, get_entity_overwrites(ent, i));
991 } break; /* case k_entity */
994 type *tp = (type *)tore;
995 if (tp == get_glob_type()) break;
996 switch (get_type_tpop_code(tp)) {
999 /* and now the edges */
1000 for (i=0; i < get_class_n_supertypes(tp); i++)
1001 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1002 TYPE_SUPER_EDGE_ATTR "}\n",
1003 tp, get_class_supertype(tp, i));
1008 break; /* case k_type */
1011 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
1013 } /* switch kind_or_entity */
1016 /************************************************************************/
1017 /* open and close vcg file */
1018 /************************************************************************/
1020 static void vcg_open (ir_graph *irg, char *suffix) {
1021 char *fname; /* filename to put the vcg information in */
1028 /** open file for vcg graph */
1029 ent = get_irg_ent(irg);
1030 id = ent->ld_name ? ent->ld_name : ent->name;
1031 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
1032 len = id_to_strlen (id);
1033 cp = id_to_str (id);
1034 if (dump_file_suffix)
1035 fname = malloc (len + 5 + strlen(suffix) + strlen(dump_file_suffix));
1037 fname = malloc (len + 5 + strlen(suffix));
1038 strncpy (fname, cp, len); /* copy the filename */
1040 if (dump_file_suffix) strcat (fname, dump_file_suffix); /* append file suffix */
1041 strcat (fname, suffix); /* append file suffix */
1042 strcat (fname, ".vcg"); /* append the .vcg suffix */
1043 F = fopen (fname, "w"); /* open file for writing */
1045 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1049 strcpy(label, "yes");
1051 strcpy (label, "no");
1056 "graph: { title: \"ir graph of %s\"\n"
1057 "display_edge_labels: %s\n"
1058 "layoutalgorithm: mindepth\n"
1059 "manhattan_edges: yes\n"
1060 "port_sharing: no\n"
1061 "orientation: bottom_to_top\n"
1062 "classname 1: \"Data\"\n"
1063 "classname 2: \"Block\"\n"
1064 "classname 3: \"Entity type\""
1065 "classname 4: \"Entity owner\""
1066 "classname 5: \"Method Param\""
1067 "classname 6: \"Method Res\""
1068 "classname 7: \"Super\""
1069 "classname 8: \"Union\""
1070 "classname 9: \"Points-to\""
1071 "classname 10: \"Array Element Type\""
1072 "classname 11: \"Overwrites\""
1073 "classname 12: \"Member\""
1076 xfprintf (F, "\n"); /* a separator */
1079 static void vcg_open_name (const char *name) {
1080 char *fname; /* filename to put the vcg information in */
1084 /** open file for vcg graph */
1086 fname = malloc (len + 5);
1087 if (dump_file_suffix)
1088 fname = malloc (len + 5 + strlen(dump_file_suffix));
1090 fname = malloc (len + 5);
1091 strcpy (fname, name); /* copy the filename */
1092 if (dump_file_suffix) strcat (fname, dump_file_suffix);
1093 strcat (fname, ".vcg"); /* append the .vcg suffix */
1094 F = fopen (fname, "w"); /* open file for writing */
1096 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1100 strcpy(label, "yes");
1102 strcpy (label, "no");
1107 "graph: { title: \"ir graph of %s\"\n"
1108 "display_edge_labels: %s\n"
1109 "layoutalgorithm: mindepth\n"
1110 "manhattan_edges: yes\n"
1111 "port_sharing: no\n"
1112 "orientation: bottom_to_top\n"
1113 "classname 1: \"Data\"\n"
1114 "classname 2: \"Block\"\n"
1115 "classname 3: \"Entity type\"\n"
1116 "classname 4: \"Entity owner\"\n"
1117 "classname 5: \"Method Param\"\n"
1118 "classname 6: \"Method Res\"\n"
1119 "classname 7: \"Super\"\n"
1120 "classname 8: \"Union\"\n"
1121 "classname 9: \"Points-to\"\n"
1122 "classname 10: \"Array Element Type\"\n"
1123 "classname 11: \"Overwrites\"\n"
1124 "classname 12: \"Member\"\n"
1127 xfprintf (F, "\n"); /* a separator */
1132 xfprintf (F, "}\n"); /* print footer */
1133 fclose (F); /* close vcg file */
1136 /************************************************************************/
1137 /* routines to dump a graph, blocks as conventional nodes. */
1138 /************************************************************************/
1140 static int node_floats(ir_node *n) {
1141 return ((get_op_pinned(get_irn_op(n)) == floats) &&
1142 (get_irg_pinned(current_ir_graph) == floats));
1146 dump_whole_node (ir_node *n, void* env) {
1148 if (!node_floats(n)) dump_ir_block_edge(n);
1149 dump_ir_data_edges(n);
1153 dump_ir_graph (ir_graph *irg)
1156 rem = current_ir_graph;
1157 current_ir_graph = irg;
1161 /* walk over the graph */
1162 /* dump_whole_node must be called in post visiting predecessors */
1163 irg_walk(irg->end, NULL, dump_whole_node, NULL);
1165 /* dump the out edges in a separate walk */
1166 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1167 irg_out_walk(irg->start, dump_out_edge, NULL, NULL);
1172 current_ir_graph = rem;
1175 /***********************************************************************/
1176 /* the following routines dump the nodes as attached to the blocks. */
1177 /***********************************************************************/
1180 dump_ir_blocks_nodes (ir_node *n, void *env) {
1181 ir_node *block = (ir_node *)env;
1183 if (is_no_Block(n) && get_nodes_Block(n) == block && !node_floats(n)) {
1185 dump_ir_data_edges(n);
1187 if (get_irn_op(n) == op_Bad)
1192 dump_ir_block (ir_node *block, void *env) {
1193 ir_graph *irg = (ir_graph *)env;
1195 if (get_irn_opcode(block) == iro_Block) {
1197 /* This is a block. So dump the vcg information to make a block. */
1198 xfprintf(F, "graph: { title: \"");
1199 PRINT_NODEID(block);
1200 fprintf(F, "\" label: \"");
1201 #ifdef DEBUG_libfirm
1202 xfprintf (F, "%ld", get_irn_node_nr(block));
1204 xfprintf (F, "%I", block->op->name);
1206 if (exc_normal != get_Block_exc (block))
1207 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1209 xfprintf(F, "\" status:clustered color:%s \n",
1210 get_Block_matured (block) ? "yellow" : "red");
1211 /* dump the blocks edges */
1212 dump_ir_data_edges(block);
1214 /* dump the nodes that go into the block */
1215 irg_walk(irg->end, dump_ir_blocks_nodes, NULL, block);
1217 /* Close the vcg information for the block */
1218 xfprintf(F, "}\n\n");
1219 dump_const_node_local(block, NULL);
1225 dump_blockless_nodes (ir_node *n, void *env) {
1226 if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
1228 dump_ir_data_edges(n);
1229 dump_ir_block_edge(n);
1230 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1233 if (node_floats(n)) {
1235 dump_ir_data_edges(n);
1236 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1240 static void dump_ir_block_graph_2 (ir_graph *irg)
1243 /* walk over the blocks in the graph */
1244 irg_block_walk(irg->end, dump_ir_block, NULL, irg);
1246 /* dump all nodes that are not in a Block */
1247 irg_walk(irg->end, dump_blockless_nodes, NULL, NULL);
1249 /* dump the Bad node */
1251 dump_node(get_irg_bad(irg), NULL);
1255 dump_ir_block_graph (ir_graph *irg)
1258 rem = current_ir_graph;
1259 current_ir_graph = irg;
1263 dump_ir_block_graph_2 (irg);
1265 if (dump_loop_information_flag) dump_loop_info(irg);
1268 current_ir_graph = rem;
1272 /***********************************************************************/
1273 /* the following routines dump a control flow graph */
1274 /***********************************************************************/
1278 dump_block_to_cfg (ir_node *block, void *env) {
1282 if (get_irn_opcode(block) == iro_Block) {
1283 /* This is a block. Dump a node for the block. */
1284 xfprintf (F, "node: {title:\""); PRINT_NODEID(block);
1285 xfprintf (F, "\" label: \"%I ", block->op->name); PRINT_NODEID(block);
1287 if (exc_normal != get_Block_exc (block))
1288 xfprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1290 xfprintf (F, "\" ");
1291 if (dump_dominator_information_flag)
1292 xfprintf(F, "info1:\"dom depth %d\"", get_Block_dom_depth(block));
1293 xfprintf (F, "}\n");
1294 /* Dump the edges */
1295 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1296 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1297 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
1298 xfprintf (F, "edge: { sourcename: \"");
1299 PRINT_NODEID(block);
1300 fprintf (F, "\" targetname: \"");
1302 fprintf (F, "\" }\n");
1305 /* Dump dominator edge */
1306 if (dump_dominator_information_flag && get_Block_idom(block)) {
1307 pred = get_Block_idom(block);
1308 xfprintf (F, "edge: { sourcename: \"");
1309 PRINT_NODEID(block);
1310 fprintf (F, "\" targetname: \"");
1312 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1318 dump_cfg (ir_graph *irg)
1320 ir_graph *rem = current_ir_graph;
1321 int ddif = dump_dominator_information_flag;
1322 current_ir_graph = irg;
1323 vcg_open (irg, "-cfg");
1325 if (get_irg_dom_state(irg) != dom_consistent)
1326 dump_dominator_information_flag = 0;
1328 /* walk over the blocks in the graph */
1329 irg_block_walk(irg->end, dump_block_to_cfg, NULL, NULL);
1330 dump_ir_node (irg->bad);
1332 dump_dominator_information_flag = ddif;
1334 current_ir_graph = rem;
1338 /***********************************************************************/
1339 /* the following routine dumps all type information reachable from an */
1341 /***********************************************************************/
1345 dump_type_graph (ir_graph *irg)
1348 rem = current_ir_graph;
1349 current_ir_graph = irg;
1351 vcg_open (irg, "-type");
1353 /* walk over the blocks in the graph */
1354 type_walk_irg(irg, dump_type_info, NULL, NULL);
1355 /* The walker for the const code can be called several times for the
1356 same (sub) experssion. So that no nodes are dumped several times
1357 we decrease the visited flag of the corresponding graph after each
1358 walk. So now increase it finally. */
1359 inc_irg_visited(get_const_code_irg());
1362 current_ir_graph = rem;
1365 /***********************************************************************/
1366 /* the following routine dumps all type information */
1367 /***********************************************************************/
1371 dump_all_types (void)
1373 vcg_open_name ("All_types");
1374 type_walk(dump_type_info, NULL, NULL);
1375 inc_irg_visited(get_const_code_irg());
1380 dump_class_hierarchy (bool entities)
1382 vcg_open_name ("class_hierarchy");
1384 type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1386 type_walk(dump_class_hierarchy_node, NULL, NULL);
1390 /***********************************************************************/
1391 /* dumps a graph with type information */
1392 /***********************************************************************/
1396 dump_ir_graph_w_types (ir_graph *irg)
1399 rem = current_ir_graph;
1400 current_ir_graph = irg;
1402 vcg_open (irg, "-all");
1404 /* dump common ir graph */
1405 irg_walk(irg->end, dump_whole_node, NULL, NULL);
1406 /* dump type info */
1407 type_walk_irg(irg, dump_type_info, NULL, NULL);
1408 inc_irg_visited(get_const_code_irg());
1409 /* dump edges from graph to type info */
1410 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1413 current_ir_graph = rem;
1417 dump_ir_block_graph_w_types (ir_graph *irg)
1420 rem = current_ir_graph;
1421 current_ir_graph = irg;
1423 vcg_open (irg, "-all");
1425 /* dump common blocked ir graph */
1426 dump_ir_block_graph_2(irg);
1427 /* dump type info */
1428 type_walk_irg(irg, dump_type_info, NULL, NULL);
1429 inc_irg_visited(get_const_code_irg());
1430 /* dump edges from graph to type info */
1431 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1434 current_ir_graph = rem;
1437 /***********************************************************************/
1438 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1440 /* dump_ir_block_graph */
1442 /* dump_type_graph */
1443 /* dump_ir_graph_w_types */
1444 /***********************************************************************/
1445 void dump_all_ir_graphs (dump_graph_func *dump_graph) {
1447 for (i=0; i < get_irp_n_irgs(); i++) {
1448 dump_graph(get_irp_irg(i));
1453 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1454 abort with a segmentation fault. */
1455 void turn_off_edge_labels() {
1460 void dump_consts_local(bool b) {
1461 dump_const_local = b;
1464 void turn_off_constant_entity_values() {
1468 void dump_keepalive_edges(bool b) {
1472 void dump_out_edges() {
1473 dump_out_edge_flag = 1;
1476 void dump_dominator_information() {
1477 dump_dominator_information_flag = 1;
1480 void dump_loop_information() {
1481 dump_loop_information_flag = 1;
1484 void dont_dump_loop_information() {
1485 dump_loop_information_flag = 0;
1488 static void clear_link(ir_node * node, void * env) {
1489 set_irn_link(node, NULL);
1492 static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
1494 || node_floats(node)
1495 || get_irn_op(node) == op_Bad
1496 || get_irn_op(node) == op_Unknown) {
1497 pmap_entry * entry = pmap_find(map, current_ir_graph);
1499 ARR_APP1(ir_node *, (ir_node **) entry->value, node);
1501 ir_node ** arr = NEW_ARR_F(ir_node *, 1);
1503 pmap_insert(map, current_ir_graph, arr);
1506 ir_node * block = get_nodes_Block(node);
1507 set_irn_link(node, get_irn_link(block));
1508 set_irn_link(block, node);
1513 static void dump_cg_ir_block(ir_node * block, void * env) {
1515 pmap *irgmap = (pmap *)env;
1516 assert(is_Block(block));
1517 xfprintf(F, "graph: { title: \"");
1518 PRINT_NODEID(block);
1519 fprintf(F, "\" label: \"");
1520 #ifdef DEBUG_libfirm
1521 xfprintf (F, "%ld", get_irn_node_nr(block));
1523 xfprintf (F, "%I", block->op->name);
1525 if (exc_normal != get_Block_exc(block)) {
1526 fprintf (F, " (%s)", exc_to_string (get_Block_exc(block)));
1529 xfprintf(F, "\" status:clustered color:%s \n",
1530 get_Block_matured(block) ? "yellow" : "red");
1532 /* dump the blocks edges */
1533 dump_ir_data_edges(block);
1535 /* dump the nodes that go into the block */
1536 for (node = get_irn_link(block); node; node = get_irn_link(node)) {
1537 dump_node(node, irgmap);
1538 dump_ir_data_edges(node);
1541 /* Close the vcg information for the block */
1542 xfprintf(F, "}\n\n");
1545 static void d_cg_block_graph(ir_graph *irg, ir_node **arr, pmap *irgmap) {
1548 xfprintf(F, "graph: { title: \"%p\" label: \"%I\" status:clustered color:white \n",
1549 irg, get_entity_ident(get_irg_ent(irg)));
1551 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1552 ir_node * node = arr[i];
1553 if (is_Block(node)) {
1554 /* Dumps the block and all the nodes in the block , which are to
1555 be found in Block->link. */
1556 dump_cg_ir_block(node, irgmap);
1558 /* Nodes that are not in a Block. */
1559 dump_node(node, NULL);
1560 dump_ir_data_edges(node);
1563 /* Close the vcg information for the irg */
1564 xfprintf(F, "}\n\n");
1567 /* dump interprocedural graph with surrounding methods */
1568 void dump_cg_block_graph(ir_graph * irg) {
1569 pmap * map = pmap_create();
1570 pmap * map2 = pmap_create();
1575 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1576 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1577 pmap_insert(map2, entry->key, entry->value);
1578 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1579 d_cg_block_graph(entry->key, entry->value, map2);
1580 DEL_ARR_F(entry->value);
1586 if (dump_loop_information_flag) dump_loop_info(irg);
1590 static void collect_node(ir_node * node, void *env) {
1592 || node_floats(node)
1593 || get_irn_op(node) == op_Bad
1594 || get_irn_op(node) == op_Unknown) {
1595 ir_node ** arr = (ir_node **) get_irg_link(current_ir_graph);
1596 ARR_APP1(ir_node *, arr, node);
1597 set_irg_link(current_ir_graph, arr); /* arr is an l-value, APP_ARR might change it! */
1599 ir_node * block = get_nodes_Block(node);
1600 set_irn_link(node, get_irn_link(block));
1601 set_irn_link(block, node);
1605 /* Links all nodes that have the block field set in the link field of
1606 the block. Adds all blocks and nodes not associated with a block
1607 in a array in irg->link. */
1608 static void collect_nodes() {
1610 for (i = 0; i < get_irp_n_irgs(); i++)
1611 set_irg_link(get_irp_irg(i), NEW_ARR_F(ir_node *, 0));
1612 cg_walk(clear_link, collect_node, NULL);
1615 static void dump_graphs() {
1617 for (i = 0; i < get_irp_n_irgs(); i++) {
1618 current_ir_graph = get_irp_irg(i);
1619 d_cg_block_graph(current_ir_graph, get_irg_link(current_ir_graph), NULL);
1623 /* Dump all irgs in interprocedural view to a single file. */
1624 void dump_all_cg_block_graph() {
1626 int rem_view = interprocedural_view;
1627 interprocedural_view = 1;
1628 vcg_open_name ("All_graphs");
1633 if (dump_loop_information_flag)
1634 for (i = 0; i < get_irp_n_irgs(); i++)
1635 dump_loop_info(get_irp_irg(i));
1638 interprocedural_view = rem_view;
1641 /* dump interprocedural block graph with surrounding methods */
1642 void dump_cg_graph(ir_graph * irg) {
1643 pmap * map = pmap_create();
1644 pmap * map2 = pmap_create(); /* We can not iterate in the same map twice! */
1648 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1649 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1650 pmap_insert(map2, entry->key, entry->value);
1651 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1652 ir_node ** arr = entry->value;
1654 ident * irg_ident = get_entity_ident(get_irg_ent(entry->key));
1656 xfprintf(F, "graph: { title: \"%I\" label: \"%I\" status:clustered color:white \n",
1657 irg_ident, irg_ident);
1659 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1660 ir_node * node = arr[i];
1661 dump_node(node, map2);
1662 dump_ir_data_edges(node);
1663 if (is_Block(node)) {
1664 for (node = get_irn_link(node); node; node = get_irn_link(node)) {
1665 dump_node(node, map2);
1666 dump_ir_block_edge(node);
1667 dump_ir_data_edges(node);
1674 /* Close the vcg information for the irg */
1675 xfprintf(F, "}\n\n");