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 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
744 current_ir_graph = rem;
745 dump_const_local = rem_dump_const_local;
749 static void print_type_info(type *tp) {
750 if (get_type_state(tp) == layout_undefined) {
751 xfprintf(F, "state: layout_undefined\n");
753 xfprintf(F, "state: layout_fixed,\n");
755 if (get_type_mode(tp))
756 xfprintf(F, "mode: %I,\n", get_mode_ident(get_type_mode(tp)));
757 xfprintf(F, "size: %dB,\n", get_type_size(tp));
761 static void print_typespecific_info(type *tp) {
762 switch (get_type_tpop_code(tp)) {
765 if(existent == get_class_peculiarity(tp))
766 xfprintf (F, " " TYPE_CLASS_NODE_ATTR);
768 xfprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
772 xfprintf (F, " " TYPE_METH_NODE_ATTR);
783 case tpo_enumeration:
796 static void print_type_node(type *tp) {
797 xfprintf (F, "node: {title: \"%p\" ", tp);
798 xfprintf (F, "label: \"%I %I\"", get_type_tpop_nameid(tp), get_type_ident(tp));
799 xfprintf (F, "info1: \"");
802 print_typespecific_info(tp);
806 void dump_entity_node(entity *ent) {
807 xfprintf (F, "node: {title: \"%p\" ", ent);
808 xfprintf (F, DEFAULT_TYPE_ATTRIBUTE);
809 xfprintf (F, "label: ");
810 xfprintf (F, "\"ent %I\" " ENTITY_NODE_ATTR , get_entity_ident(ent));
811 fprintf (F, "\n info1:\"\nallocation: ");
812 switch (get_entity_allocation(ent)) {
813 case dynamic_allocated: fprintf (F, "dynamic allocated"); break;
814 case automatic_allocated: fprintf (F, "automatic allocated"); break;
815 case static_allocated: fprintf (F, "static allocated"); break;
816 case parameter_allocated: fprintf (F, "parameter allocated"); break;
818 fprintf (F, "\nvisibility: ");
819 switch (get_entity_visibility(ent)) {
820 case local: fprintf (F, "local"); break;
821 case external_visible: fprintf (F, "external_visible"); break;
822 case external_allocated: fprintf (F, "external_allocate"); break;
824 fprintf (F, "\nvariability: ");
825 switch (get_entity_variability(ent)) {
826 case uninitialized: fprintf (F, "uninitialized");break;
827 case initialized: fprintf (F, "initialized"); break;
828 case part_constant: fprintf (F, "part_constant");break;
829 case constant: fprintf (F, "constant"); break;
831 fprintf (F, "\nvolatility: ");
832 switch (get_entity_volatility(ent)) {
833 case non_volatile: fprintf (F, "non_volatile"); break;
834 case is_volatile: fprintf (F, "is_volatile"); break;
836 fprintf (F, "\npeculiarity: ");
837 switch (get_entity_peculiarity(ent)) {
838 case description: fprintf (F, "description"); break;
839 case inherited: fprintf (F, "inherited"); break;
840 case existent: fprintf (F, "existent"); break;
842 xfprintf(F, "\nname: %I\nld_name: %I", get_entity_ident(ent), get_entity_ld_ident(ent));
843 fprintf(F, "\noffset: %d", get_entity_offset(ent));
844 if (is_method_type(get_entity_type(ent)))
845 xfprintf (F, "\nirg = %p ", get_entity_irg(ent));
846 xfprintf(F, "\"\n}\n");
849 /* dumps a type or entity and it's edges. */
851 dump_type_info (type_or_ent *tore, void *env) {
852 int i = 0; /* to shutup gcc */
854 /* dump this type or entity */
856 switch (get_kind(tore)) {
859 entity *ent = (entity *)tore;
862 dump_entity_node(ent);
864 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
865 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
866 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
867 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
868 ENT_TYPE_EDGE_ATTR "}\n", ent, get_entity_type(ent));
869 if(is_class_type(get_entity_owner(ent))) {
870 for(i = 0; i < get_entity_n_overwrites(ent); i++)
871 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
872 ENT_OVERWRITES_EDGE_ATTR "}\n",
873 ent, get_entity_overwrites(ent, i));
875 /* attached subgraphs */
876 if (const_entities && (get_entity_variability(ent) != uninitialized)) {
877 if (is_atomic_entity(ent)) {
878 value = get_atomic_ent_value(ent);
879 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"", ent);
881 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR "\"}\n");
882 dump_const_expression(value);
884 if (is_compound_entity(ent)) {
885 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
886 value = get_compound_ent_value(ent, i);
887 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"", ent);
889 fprintf(F, "\" " ENT_VALUE_EDGE_ATTR " %d \"}\n", i);
890 dump_const_expression(value);
891 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
892 ENT_CORR_EDGE_ATTR "}\n", ent,
893 get_compound_ent_value_member(ent, i), i);
900 type *tp = (type *)tore;
902 /* and now the edges */
903 switch (get_type_tpop_code(tp)) {
906 for (i=0; i < get_class_n_supertypes(tp); i++)
907 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
908 TYPE_SUPER_EDGE_ATTR "}\n",
909 tp, get_class_supertype(tp, i));
910 for (i=0; i < get_class_n_members(tp); i++)
911 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
912 TYPE_MEMBER_EDGE_ATTR "}\n",
913 tp, get_class_member(tp, i));
917 for (i=0; i < get_struct_n_members(tp); i++)
918 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
919 TYPE_MEMBER_EDGE_ATTR "}\n",
920 tp, get_struct_member(tp, i));
924 for (i = 0; i < get_method_n_params(tp); i++)
925 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
926 METH_PAR_EDGE_ATTR "}\n",
927 tp, get_method_param_type(tp, i), i);
928 for (i = 0; i < get_method_n_ress(tp); i++)
929 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
930 METH_RES_EDGE_ATTR "}\n",
931 tp, get_method_res_type(tp, i), i);
935 for (i = 0; i < get_union_n_members(tp); i++)
936 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
937 "label: \"\"f" UNION_EDGE_ATTR "}\n",
938 tp, get_union_member(tp, i));
942 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
943 ARR_ELT_TYPE_EDGE_ATTR "}\n", tp, get_array_element_type(tp), i);
944 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
945 ARR_ENT_EDGE_ATTR "}\n", tp, get_array_element_entity(tp), i);
947 case tpo_enumeration:
952 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
953 PTR_PTS_TO_EDGE_ATTR "}\n", tp,
954 get_pointer_points_to_type(tp), i);
962 break; /* case k_type */
965 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
967 } /* switch kind_or_entity */
970 /* dumps a class type node and a superclass edge.
971 If env != null dumps entities of classes and overwrites edges. */
973 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
974 int i = 0; /* to shutup gcc */
976 /* dump this type or entity */
977 switch (get_kind(tore)) {
979 entity *ent = (entity *)tore;
980 if (get_entity_owner(ent) == get_glob_type()) break;
981 if ((env) && is_class_type(get_entity_owner(ent))) {
983 dump_entity_node(ent);
985 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
986 TYPE_MEMBER_EDGE_ATTR "}\n", get_entity_owner(ent), ent);
987 for(i = 0; i < get_entity_n_overwrites(ent); i++)
988 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
989 ENT_OVERWRITES_EDGE_ATTR "}\n",
990 ent, get_entity_overwrites(ent, i));
992 } break; /* case k_entity */
995 type *tp = (type *)tore;
996 if (tp == get_glob_type()) break;
997 switch (get_type_tpop_code(tp)) {
1000 /* and now the edges */
1001 for (i=0; i < get_class_n_supertypes(tp); i++)
1002 xfprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1003 TYPE_SUPER_EDGE_ATTR "}\n",
1004 tp, get_class_supertype(tp, i));
1009 break; /* case k_type */
1012 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
1014 } /* switch kind_or_entity */
1017 /************************************************************************/
1018 /* open and close vcg file */
1019 /************************************************************************/
1021 static void vcg_open (ir_graph *irg, char *suffix) {
1022 char *fname; /* filename to put the vcg information in */
1029 /** open file for vcg graph */
1030 ent = get_irg_ent(irg);
1031 id = ent->ld_name ? ent->ld_name : ent->name;
1032 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
1033 len = id_to_strlen (id);
1034 cp = id_to_str (id);
1035 if (dump_file_suffix)
1036 fname = malloc (len + 5 + strlen(suffix) + strlen(dump_file_suffix));
1038 fname = malloc (len + 5 + strlen(suffix));
1039 strncpy (fname, cp, len); /* copy the filename */
1041 if (dump_file_suffix) strcat (fname, dump_file_suffix); /* append file suffix */
1042 strcat (fname, suffix); /* append file suffix */
1043 strcat (fname, ".vcg"); /* append the .vcg suffix */
1044 F = fopen (fname, "w"); /* open file for writing */
1046 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1050 strcpy(label, "yes");
1052 strcpy (label, "no");
1057 "graph: { title: \"ir graph of %s\"\n"
1058 "display_edge_labels: %s\n"
1059 "layoutalgorithm: mindepth\n"
1060 "manhattan_edges: yes\n"
1061 "port_sharing: no\n"
1062 "orientation: bottom_to_top\n"
1063 "classname 1: \"Data\"\n"
1064 "classname 2: \"Block\"\n"
1065 "classname 3: \"Entity type\""
1066 "classname 4: \"Entity owner\""
1067 "classname 5: \"Method Param\""
1068 "classname 6: \"Method Res\""
1069 "classname 7: \"Super\""
1070 "classname 8: \"Union\""
1071 "classname 9: \"Points-to\""
1072 "classname 10: \"Array Element Type\""
1073 "classname 11: \"Overwrites\""
1074 "classname 12: \"Member\""
1077 xfprintf (F, "\n"); /* a separator */
1080 static void vcg_open_name (const char *name) {
1081 char *fname; /* filename to put the vcg information in */
1085 /** open file for vcg graph */
1087 fname = malloc (len + 5);
1088 if (dump_file_suffix)
1089 fname = malloc (len + 5 + strlen(dump_file_suffix));
1091 fname = malloc (len + 5);
1092 strcpy (fname, name); /* copy the filename */
1093 if (dump_file_suffix) strcat (fname, dump_file_suffix);
1094 strcat (fname, ".vcg"); /* append the .vcg suffix */
1095 F = fopen (fname, "w"); /* open file for writing */
1097 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1101 strcpy(label, "yes");
1103 strcpy (label, "no");
1108 "graph: { title: \"ir graph of %s\"\n"
1109 "display_edge_labels: %s\n"
1110 "layoutalgorithm: mindepth\n"
1111 "manhattan_edges: yes\n"
1112 "port_sharing: no\n"
1113 "orientation: bottom_to_top\n"
1114 "classname 1: \"Data\"\n"
1115 "classname 2: \"Block\"\n"
1116 "classname 3: \"Entity type\"\n"
1117 "classname 4: \"Entity owner\"\n"
1118 "classname 5: \"Method Param\"\n"
1119 "classname 6: \"Method Res\"\n"
1120 "classname 7: \"Super\"\n"
1121 "classname 8: \"Union\"\n"
1122 "classname 9: \"Points-to\"\n"
1123 "classname 10: \"Array Element Type\"\n"
1124 "classname 11: \"Overwrites\"\n"
1125 "classname 12: \"Member\"\n"
1128 xfprintf (F, "\n"); /* a separator */
1133 xfprintf (F, "}\n"); /* print footer */
1134 fclose (F); /* close vcg file */
1137 /************************************************************************/
1138 /* routines to dump a graph, blocks as conventional nodes. */
1139 /************************************************************************/
1141 static int node_floats(ir_node *n) {
1142 return ((get_op_pinned(get_irn_op(n)) == floats) &&
1143 (get_irg_pinned(current_ir_graph) == floats));
1147 dump_whole_node (ir_node *n, void* env) {
1149 if (!node_floats(n)) dump_ir_block_edge(n);
1150 dump_ir_data_edges(n);
1154 dump_ir_graph (ir_graph *irg)
1157 rem = current_ir_graph;
1158 current_ir_graph = irg;
1162 /* walk over the graph */
1163 /* dump_whole_node must be called in post visiting predecessors */
1164 irg_walk(irg->end, NULL, dump_whole_node, NULL);
1166 /* dump the out edges in a separate walk */
1167 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1168 irg_out_walk(irg->start, dump_out_edge, NULL, NULL);
1173 current_ir_graph = rem;
1176 /***********************************************************************/
1177 /* the following routines dump the nodes as attached to the blocks. */
1178 /***********************************************************************/
1181 dump_ir_blocks_nodes (ir_node *n, void *env) {
1182 ir_node *block = (ir_node *)env;
1184 if (is_no_Block(n) && get_nodes_Block(n) == block && !node_floats(n)) {
1186 dump_ir_data_edges(n);
1188 if (get_irn_op(n) == op_Bad)
1193 dump_ir_block (ir_node *block, void *env) {
1194 ir_graph *irg = (ir_graph *)env;
1196 if (get_irn_opcode(block) == iro_Block) {
1198 /* This is a block. So dump the vcg information to make a block. */
1199 xfprintf(F, "graph: { title: \"");
1200 PRINT_NODEID(block);
1201 fprintf(F, "\" label: \"");
1202 #ifdef DEBUG_libfirm
1203 xfprintf (F, "%ld", get_irn_node_nr(block));
1205 xfprintf (F, "%I", block->op->name);
1207 if (exc_normal != get_Block_exc (block))
1208 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1210 xfprintf(F, "\" status:clustered color:%s \n",
1211 get_Block_matured (block) ? "yellow" : "red");
1212 /* dump the blocks edges */
1213 dump_ir_data_edges(block);
1215 /* dump the nodes that go into the block */
1216 irg_walk(irg->end, dump_ir_blocks_nodes, NULL, block);
1218 /* Close the vcg information for the block */
1219 xfprintf(F, "}\n\n");
1220 dump_const_node_local(block, NULL);
1226 dump_blockless_nodes (ir_node *n, void *env) {
1227 if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
1229 dump_ir_data_edges(n);
1230 dump_ir_block_edge(n);
1231 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1234 if (node_floats(n)) {
1236 dump_ir_data_edges(n);
1237 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1241 static void dump_ir_block_graph_2 (ir_graph *irg)
1244 /* walk over the blocks in the graph */
1245 irg_block_walk(irg->end, dump_ir_block, NULL, irg);
1247 /* dump all nodes that are not in a Block */
1248 irg_walk(irg->end, dump_blockless_nodes, NULL, NULL);
1250 /* dump the Bad node */
1252 dump_node(get_irg_bad(irg), NULL);
1256 dump_ir_block_graph (ir_graph *irg)
1259 rem = current_ir_graph;
1260 current_ir_graph = irg;
1264 dump_ir_block_graph_2 (irg);
1266 if (dump_loop_information_flag) dump_loop_info(irg);
1269 current_ir_graph = rem;
1273 /***********************************************************************/
1274 /* the following routines dump a control flow graph */
1275 /***********************************************************************/
1279 dump_block_to_cfg (ir_node *block, void *env) {
1283 if (get_irn_opcode(block) == iro_Block) {
1284 /* This is a block. Dump a node for the block. */
1285 xfprintf (F, "node: {title:\""); PRINT_NODEID(block);
1286 xfprintf (F, "\" label: \"%I ", block->op->name); PRINT_NODEID(block);
1288 if (exc_normal != get_Block_exc (block))
1289 xfprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1291 xfprintf (F, "\" ");
1292 if (dump_dominator_information_flag)
1293 xfprintf(F, "info1:\"dom depth %d\"", get_Block_dom_depth(block));
1294 xfprintf (F, "}\n");
1295 /* Dump the edges */
1296 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1297 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1298 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
1299 xfprintf (F, "edge: { sourcename: \"");
1300 PRINT_NODEID(block);
1301 fprintf (F, "\" targetname: \"");
1303 fprintf (F, "\" }\n");
1306 /* Dump dominator edge */
1307 if (dump_dominator_information_flag && get_Block_idom(block)) {
1308 pred = get_Block_idom(block);
1309 xfprintf (F, "edge: { sourcename: \"");
1310 PRINT_NODEID(block);
1311 fprintf (F, "\" targetname: \"");
1313 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1319 dump_cfg (ir_graph *irg)
1321 ir_graph *rem = current_ir_graph;
1322 int ddif = dump_dominator_information_flag;
1323 current_ir_graph = irg;
1324 vcg_open (irg, "-cfg");
1326 if (get_irg_dom_state(irg) != dom_consistent)
1327 dump_dominator_information_flag = 0;
1329 /* walk over the blocks in the graph */
1330 irg_block_walk(irg->end, dump_block_to_cfg, NULL, NULL);
1331 dump_ir_node (irg->bad);
1333 dump_dominator_information_flag = ddif;
1335 current_ir_graph = rem;
1339 /***********************************************************************/
1340 /* the following routine dumps all type information reachable from an */
1342 /***********************************************************************/
1346 dump_type_graph (ir_graph *irg)
1349 rem = current_ir_graph;
1350 current_ir_graph = irg;
1352 vcg_open (irg, "-type");
1354 /* walk over the blocks in the graph */
1355 type_walk_irg(irg, dump_type_info, NULL, NULL);
1356 /* The walker for the const code can be called several times for the
1357 same (sub) experssion. So that no nodes are dumped several times
1358 we decrease the visited flag of the corresponding graph after each
1359 walk. So now increase it finally. */
1360 inc_irg_visited(get_const_code_irg());
1363 current_ir_graph = rem;
1366 /***********************************************************************/
1367 /* the following routine dumps all type information */
1368 /***********************************************************************/
1372 dump_all_types (void)
1374 vcg_open_name ("All_types");
1375 type_walk(dump_type_info, NULL, NULL);
1376 inc_irg_visited(get_const_code_irg());
1381 dump_class_hierarchy (bool entities)
1383 vcg_open_name ("class_hierarchy");
1385 type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1387 type_walk(dump_class_hierarchy_node, NULL, NULL);
1391 /***********************************************************************/
1392 /* dumps a graph with type information */
1393 /***********************************************************************/
1397 dump_ir_graph_w_types (ir_graph *irg)
1400 rem = current_ir_graph;
1401 current_ir_graph = irg;
1403 vcg_open (irg, "-all");
1405 /* dump common ir graph */
1406 irg_walk(irg->end, dump_whole_node, NULL, NULL);
1407 /* dump type info */
1408 type_walk_irg(irg, dump_type_info, NULL, NULL);
1409 inc_irg_visited(get_const_code_irg());
1410 /* dump edges from graph to type info */
1411 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1414 current_ir_graph = rem;
1418 dump_ir_block_graph_w_types (ir_graph *irg)
1421 rem = current_ir_graph;
1422 current_ir_graph = irg;
1424 vcg_open (irg, "-all");
1426 /* dump common blocked ir graph */
1427 dump_ir_block_graph_2(irg);
1428 /* dump type info */
1429 type_walk_irg(irg, dump_type_info, NULL, NULL);
1430 inc_irg_visited(get_const_code_irg());
1431 /* dump edges from graph to type info */
1432 irg_walk(irg->end, dump_node2type_edges, NULL, NULL);
1435 current_ir_graph = rem;
1438 /***********************************************************************/
1439 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1441 /* dump_ir_block_graph */
1443 /* dump_type_graph */
1444 /* dump_ir_graph_w_types */
1445 /***********************************************************************/
1446 void dump_all_ir_graphs (dump_graph_func *dump_graph) {
1448 for (i=0; i < get_irp_n_irgs(); i++) {
1449 dump_graph(get_irp_irg(i));
1454 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1455 abort with a segmentation fault. */
1456 void turn_off_edge_labels(void) {
1461 void dump_consts_local(bool b) {
1462 dump_const_local = b;
1465 void turn_off_constant_entity_values(void) {
1469 void dump_keepalive_edges(bool b) {
1473 void dump_out_edges(void) {
1474 dump_out_edge_flag = 1;
1477 void dump_dominator_information(void) {
1478 dump_dominator_information_flag = 1;
1481 void dump_loop_information(void) {
1482 dump_loop_information_flag = 1;
1485 void dont_dump_loop_information(void) {
1486 dump_loop_information_flag = 0;
1489 static void clear_link(ir_node * node, void * env) {
1490 set_irn_link(node, NULL);
1493 static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
1495 || node_floats(node)
1496 || get_irn_op(node) == op_Bad
1497 || get_irn_op(node) == op_Unknown) {
1498 pmap_entry * entry = pmap_find(map, current_ir_graph);
1500 ARR_APP1(ir_node *, (ir_node **) entry->value, node);
1502 ir_node ** arr = NEW_ARR_F(ir_node *, 1);
1504 pmap_insert(map, current_ir_graph, arr);
1507 ir_node * block = get_nodes_Block(node);
1508 set_irn_link(node, get_irn_link(block));
1509 set_irn_link(block, node);
1514 static void dump_cg_ir_block(ir_node * block, void * env) {
1516 pmap *irgmap = (pmap *)env;
1517 assert(is_Block(block));
1518 xfprintf(F, "graph: { title: \"");
1519 PRINT_NODEID(block);
1520 fprintf(F, "\" label: \"");
1521 #ifdef DEBUG_libfirm
1522 xfprintf (F, "%ld", get_irn_node_nr(block));
1524 xfprintf (F, "%I", block->op->name);
1526 if (exc_normal != get_Block_exc(block)) {
1527 fprintf (F, " (%s)", exc_to_string (get_Block_exc(block)));
1530 xfprintf(F, "\" status:clustered color:%s \n",
1531 get_Block_matured(block) ? "yellow" : "red");
1533 /* dump the blocks edges */
1534 dump_ir_data_edges(block);
1536 /* dump the nodes that go into the block */
1537 for (node = get_irn_link(block); node; node = get_irn_link(node)) {
1538 dump_node(node, irgmap);
1539 dump_ir_data_edges(node);
1542 /* Close the vcg information for the block */
1543 xfprintf(F, "}\n\n");
1546 static void d_cg_block_graph(ir_graph *irg, ir_node **arr, pmap *irgmap) {
1549 xfprintf(F, "graph: { title: \"%p\" label: \"%I\" status:clustered color:white \n",
1550 irg, get_entity_ident(get_irg_ent(irg)));
1552 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1553 ir_node * node = arr[i];
1554 if (is_Block(node)) {
1555 /* Dumps the block and all the nodes in the block , which are to
1556 be found in Block->link. */
1557 dump_cg_ir_block(node, irgmap);
1559 /* Nodes that are not in a Block. */
1560 dump_node(node, NULL);
1561 dump_ir_data_edges(node);
1564 /* Close the vcg information for the irg */
1565 xfprintf(F, "}\n\n");
1568 /* dump interprocedural graph with surrounding methods */
1569 void dump_cg_block_graph(ir_graph * irg) {
1570 pmap * map = pmap_create();
1571 pmap * map2 = pmap_create();
1576 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1577 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1578 pmap_insert(map2, entry->key, entry->value);
1579 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1580 d_cg_block_graph(entry->key, entry->value, map2);
1581 DEL_ARR_F(entry->value);
1587 if (dump_loop_information_flag) dump_loop_info(irg);
1591 static void collect_node(ir_node * node, void *env) {
1593 || node_floats(node)
1594 || get_irn_op(node) == op_Bad
1595 || get_irn_op(node) == op_Unknown) {
1596 ir_node ** arr = (ir_node **) get_irg_link(current_ir_graph);
1597 ARR_APP1(ir_node *, arr, node);
1598 set_irg_link(current_ir_graph, arr); /* arr is an l-value, APP_ARR might change it! */
1600 ir_node * block = get_nodes_Block(node);
1601 set_irn_link(node, get_irn_link(block));
1602 set_irn_link(block, node);
1606 /* Links all nodes that have the block field set in the link field of
1607 the block. Adds all blocks and nodes not associated with a block
1608 in a array in irg->link. */
1609 static void collect_nodes(void) {
1611 for (i = 0; i < get_irp_n_irgs(); i++)
1612 set_irg_link(get_irp_irg(i), NEW_ARR_F(ir_node *, 0));
1613 cg_walk(clear_link, collect_node, NULL);
1616 static void dump_graphs(void) {
1618 for (i = 0; i < get_irp_n_irgs(); i++) {
1619 current_ir_graph = get_irp_irg(i);
1620 d_cg_block_graph(current_ir_graph, get_irg_link(current_ir_graph), NULL);
1624 /* Dump all irgs in interprocedural view to a single file. */
1625 void dump_all_cg_block_graph(void) {
1627 int rem_view = interprocedural_view;
1628 interprocedural_view = 1;
1629 vcg_open_name ("All_graphs");
1634 if (dump_loop_information_flag)
1635 for (i = 0; i < get_irp_n_irgs(); i++)
1636 dump_loop_info(get_irp_irg(i));
1639 interprocedural_view = rem_view;
1642 /* dump interprocedural block graph with surrounding methods */
1643 void dump_cg_graph(ir_graph * irg) {
1644 pmap * map = pmap_create();
1645 pmap * map2 = pmap_create(); /* We can not iterate in the same map twice! */
1649 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1650 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1651 pmap_insert(map2, entry->key, entry->value);
1652 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1653 ir_node ** arr = entry->value;
1655 ident * irg_ident = get_entity_ident(get_irg_ent(entry->key));
1657 xfprintf(F, "graph: { title: \"%I\" label: \"%I\" status:clustered color:white \n",
1658 irg_ident, irg_ident);
1660 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1661 ir_node * node = arr[i];
1662 dump_node(node, map2);
1663 dump_ir_data_edges(node);
1664 if (is_Block(node)) {
1665 for (node = get_irn_link(node); node; node = get_irn_link(node)) {
1666 dump_node(node, map2);
1667 dump_ir_block_edge(node);
1668 dump_ir_data_edges(node);
1675 /* Close the vcg information for the irg */
1676 xfprintf(F, "}\n\n");