3 * File name: ir/ir/irdump.c
4 * Purpose: Write vcg representation of firm to file.
5 * Author: Martin Trapp, Christian Schaefer
6 * Modified by: Goetz Lindenmaier, Hubert Schmidt
9 * Copyright: (c) 1998-2003 Universität Karlsruhe
10 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
21 # include "irnode_t.h"
22 # include "irgraph_t.h"
23 # include "entity_t.h"
25 # include "firm_common_t.h"
30 # include "typewalk.h"
33 # include "type_or_entity.h"
45 /* Attributes of nodes */
46 #define PRINT_DEFAULT_NODE_ATTR
47 #define DEFAULT_NODE_ATTR " "
48 #define DEFAULT_TYPE_ATTRIBUTE " "
50 /* Attributes of edges between Firm nodes */
51 #define BLOCK_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
52 #define CF_EDGE_ATTR "color: red"
53 #define MEM_EDGE_ATTR "color: blue"
54 #define DOMINATOR_EDGE_ATTR "color: red"
56 #define BACK_EDGE_ATTR "linestyle: dashed "
58 /* Attributes of edges between Firm nodes and type/entity nodes */
59 #define NODE2TYPE_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
61 /* Attributes of edges in type/entity graphs. */
62 #define TYPE_METH_NODE_ATTR "color: lightyellow"
63 #define TYPE_CLASS_NODE_ATTR "color: green"
64 #define TYPE_DESCRIPTION_NODE_ATTR "color: lightgreen"
65 #define ENTITY_NODE_ATTR "color: yellow"
66 #define ENT_TYPE_EDGE_ATTR "class: 3 label: \"type\" color: red"
67 #define ENT_OWN_EDGE_ATTR "class: 4 label: \"owner\" color: black"
68 #define METH_PAR_EDGE_ATTR "class: 5 label: \"param %d\" color: green"
69 #define METH_RES_EDGE_ATTR "class: 6 label: \"res %d\" color: green"
70 #define TYPE_SUPER_EDGE_ATTR "class: 7 label: \"supertype\" color: red"
71 #define UNION_EDGE_ATTR "class: 8 label: \"component\" color: blue"
72 #define PTR_PTS_TO_EDGE_ATTR "class: 9 label: \"points to\" color:green"
73 #define ARR_ELT_TYPE_EDGE_ATTR "class: 10 label: \"arr elt tp\" color:green"
74 #define ARR_ENT_EDGE_ATTR "class: 10 label: \"arr ent\" color: green"
75 #define ENT_OVERWRITES_EDGE_ATTR "class: 11 label: \"overwrites\" color:red"
76 #define ENT_VALUE_EDGE_ATTR "label: \"value %d\""
77 #define ENT_CORR_EDGE_ATTR "label: \"value %d corresponds to \" "
78 #define TYPE_MEMBER_EDGE_ATTR "class: 12 label: \"member\" color:blue"
81 #if DEBUG_libfirm && NODEID_AS_LABEL
82 #define PRINT_NODEID(X) fprintf(F, "n%ld", get_irn_node_nr(X))
83 #define PRINT_TYPEID(X) fprintf(F, "\"t%ld\"", get_type_nr(X))
84 #define PRINT_ENTID(X) fprintf(F, "e%ld", get_entity_nr(X))
85 #define PRINT_IRGID(X) fprintf(F, "g%ld", get_irg_graph_nr(X))
86 #define PRINT_CONSTID(X,Y) fprintf(F, "\"n%ldn%ld\"", get_irn_node_nr(X),get_irn_node_nr(Y))
89 #define PRINT_NODEID(X) fprintf(F, "n%p", (void*) X)
90 #define PRINT_TYPEID(X) fprintf(F, "\"t%p\"", (void *) X)
91 #define PRINT_ENTID(X) fprintf(F, "e%p", (void*) X)
92 #define PRINT_IRGID(X) fprintf(F, "g%p",(void*) X)
93 #define PRINT_CONSTID(X,Y) fprintf(F, "\"%p%p\"", (void*) X, (void*) Y)
96 #define PRINT_TYPE_TYPE_EDGE(S,T,...){fprintf (F, "edge: { sourcename: "); PRINT_TYPEID(S); fprintf (F, " targetname: "); PRINT_TYPEID(T); fprintf (F, ##__VA_ARGS__); fprintf(F,"}\n"); }
97 #define PRINT_TYPE_ENT_EDGE(S,T,...) {fprintf (F, "edge: { sourcename: "); PRINT_TYPEID(S); fprintf (F, " targetname: \""); PRINT_ENTID(T); fprintf(F, "\""); fprintf (F, ##__VA_ARGS__); fprintf(F,"}\n"); }
98 #define PRINT_ENT_ENT_EDGE(S,T,...) {fprintf (F, "edge: { sourcename: \""); PRINT_ENTID(S); fprintf (F, "\" targetname: \""); PRINT_ENTID(T); fprintf(F, "\""); fprintf (F, ##__VA_ARGS__); fprintf(F,"}\n"); }
99 #define PRINT_ENT_TYPE_EDGE(S,T,...) {fprintf (F, "edge: { sourcename: \""); PRINT_ENTID(S); fprintf (F, "\" targetname: "); PRINT_TYPEID(T); fprintf (F, ##__VA_ARGS__); fprintf(F,"}\n"); }
100 #define PRINT_NODE_TYPE_EDGE(S,T,...){fprintf (F, "edge: { sourcename: \""); PRINT_NODEID(S); fprintf (F, "\" targetname: "); PRINT_TYPEID(T); fprintf (F, ##__VA_ARGS__); fprintf(F,"}\n"); }
101 #define PRINT_NODE_ENT_EDGE(S,T,...) {fprintf (F, "edge: { sourcename: \""); PRINT_NODEID(S); fprintf (F, "\" targetname: \""); PRINT_ENTID(T); fprintf(F, "\""); fprintf (F, ##__VA_ARGS__); fprintf(F,"}\n"); }
102 #define PRINT_ENT_NODE_EDGE(S,T,...) {fprintf (F, "edge: { sourcename: \""); PRINT_ENTID(S); fprintf (F, "\" targetname: \""); PRINT_NODEID(T); fprintf(F, "\""); fprintf (F, ##__VA_ARGS__); fprintf(F,"}\n"); }
105 /* A suffix to manipulate the file name. */
106 char *dump_file_suffix = NULL;
108 /* file to dump to */
111 /* A compiler option to turn off edge labels */
113 /* A compiler option to turn off dumping values of constant entities */
114 int const_entities = 1;
115 /* A compiler option to dump the keep alive edges */
116 int dump_keepalive = 0;
117 /* Compiler options to dump analysis information in dump_ir_graph */
118 int dump_out_edge_flag = 0;
119 int dump_dominator_information_flag = 0;
120 int dump_loop_information_flag = 0;
121 int dump_const_local = 0;
122 bool opt_dump_analysed_type_info = 1;
124 INLINE bool get_opt_dump_const_local(void) {
125 if (!dump_out_edge_flag && !dump_loop_information_flag)
126 return dump_const_local;
131 /* A global variable to record output of the Bad node. */
132 static int Bad_dumped;
134 static void dump_ir_blocks_nodes (ir_node *n, void *env);
135 static void dump_whole_node(ir_node *n, void* env);
137 /*******************************************************************/
138 /* routines to dump information about a single node */
139 /*******************************************************************/
144 dump_node_opcode (ir_node *n)
149 switch(get_irn_opcode(n)) {
152 res = tarval_snprintf(buf, sizeof(buf), get_Const_tarval(n));
153 assert(res < sizeof(buf) && "buffer to small for tarval_snprintf");
158 if (get_SymConst_kind(n) == linkage_ptr_info) {
159 /* don't use get_SymConst_ptr_info as it mangles the name. */
160 fprintf (F, "SymC %s", get_id_str(get_SymConst_ptrinfo(n)));
162 assert(get_kind(get_SymConst_type(n)) == k_type);
163 assert(get_type_ident(get_SymConst_type(n)));
164 fprintf (F, "SymC %s ", get_type_name(get_SymConst_type(n)));
165 if (get_SymConst_kind(n) == type_tag)
173 if (!interprocedural_view) fprintf(F, "Proj'");
177 fprintf (F, "%s", get_id_str(get_irn_opident(n)));
184 dump_node_mode (ir_node *n)
186 switch (get_irn_opcode(n)) {
205 fprintf (F, "%s", get_mode_name(get_irn_mode(n)));
212 static void dump_node_typeinfo(ir_node *n) {
213 if (!opt_dump_analysed_type_info) return;
214 if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
215 get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent ) {
216 type *tp = get_irn_type(n);
218 fprintf (F, " [%s]", get_type_name(tp));
225 dump_node_nodeattr (ir_node *n)
227 switch (get_irn_opcode(n)) {
229 if (false && interprocedural_view) {
230 fprintf (F, "%s", get_entity_name(get_irg_ent(current_ir_graph)));
234 if (get_irn_opcode(get_Proj_pred(n)) == iro_Cmp) {
235 fprintf (F, "%s", get_pnc_string(get_Proj_proj(n)));
237 fprintf (F, "%ld", get_Proj_proj(n));
241 fprintf (F, "%ld", get_Filter_proj(n));
244 assert(get_kind(get_Sel_entity(n)) == k_entity);
245 fprintf (F, "%s", get_entity_name(get_Sel_entity(n)));
248 fprintf (F, "(%s)", get_type_name(get_Cast_type(n)));
251 fprintf (F, "%s", get_pnc_string(get_Confirm_cmp(n)));
260 dump_node_vcgattr (ir_node *n)
262 switch (get_irn_opcode(n)) {
269 fprintf (F, "color: blue");
272 fprintf (F, "color: lightyellow");
275 fprintf (F, "color: green");
281 fprintf (F, "color: yellow");
284 PRINT_DEFAULT_NODE_ATTR;
289 dump_node_info (ir_node *n) {
291 fprintf (F, " info1: \"");
292 fprintf (F, "visited: %ld \n", get_irn_visited(n));
295 switch(get_irn_opcode(n)) {
297 type *tp = get_entity_type(get_irg_ent(get_Start_irg(n)));
298 fprintf(F, "start of method of type %s \n", get_type_name(tp));
299 for (i = 0; i < get_method_n_params(tp); ++i)
300 fprintf(F, " param %d type: %s \n", i, get_type_name(get_method_param_type(tp, i)));
303 fprintf(F, "allocating entity of type %s \n", get_type_name(get_Alloc_type(n)));
306 fprintf(F, "freeing entity of type %s \n", get_type_name(get_Free_type(n)));
309 fprintf(F, "Selecting entity of type %s \n", get_type_name(get_entity_type(get_Sel_entity(n))));
310 fprintf(F, " from entity of type %s \n", get_type_name(get_entity_owner(get_Sel_entity(n))));
313 type *tp = get_Call_type(n);
314 fprintf(F, "calling method of type %s \n", get_type_name(tp));
315 for (i = 0; i < get_method_n_params(tp); ++i)
316 fprintf(F, " param %d type: %s \n", i, get_type_name(get_method_param_type(tp, i)));
317 for (i = 0; i < get_method_n_ress(tp); ++i)
318 fprintf(F, " resul %d type: %s \n", i, get_type_name(get_method_res_type(tp, i)));
321 if (!interprocedural_view) {
322 type *tp = get_entity_type(get_irg_ent(current_ir_graph));
323 fprintf(F, "return in method of type %s \n", get_type_name(tp));
324 for (i = 0; i < get_method_n_ress(tp); ++i)
325 fprintf(F, " res %d type: %s \n", i, get_type_name(get_method_res_type(tp, i)));
329 type *tp = get_Const_type(n);
330 assert(tp != none_type);
331 fprintf(F, "Const of type %s \n", get_type_name(get_Const_type(n)));
336 if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
337 get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent )
338 if (get_irn_type(n) != none_type)
339 fprintf (F, "\nAnalysed type: %s", get_type_name(get_irn_type(n)));
345 static bool pred_in_wrong_graph(ir_node *n, int pos, pmap *irgmap) {
346 ir_node *block = (is_Block(n)) ? n : get_nodes_Block(n);
349 ((get_irn_op(n) == op_Filter) || (get_irn_op(n) == op_Block))) {
350 ir_node *pred = skip_Proj(get_Block_cfgpred(block, pos));
351 if (is_ip_cfop(pred)) {
352 ir_graph *irg = get_ip_cfop_irg(pred);
353 if (pmap_find(irgmap, irg) == NULL) return true;
362 bool is_constlike_node(ir_node *n) {
363 ir_op *op = get_irn_op(n);
364 return (op == op_Const || op == op_Bad || op == op_SymConst || op == op_Unknown);
368 /* outputs the predecessors of n, that are constants, local. I.e.,
369 generates a copy of the constant for each node called with. */
370 static void dump_const_node_local(ir_node *n, pmap *irgmap) {
372 if (!get_opt_dump_const_local()) return;
373 /* Use visited flag to avoid outputting nodes twice.
374 initialize it first. */
375 for (i = 0; i < get_irn_arity(n); i++) {
376 ir_node *con = get_irn_n(n, i);
377 if (is_constlike_node(con)) {
378 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
379 set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
382 for (i = 0; i < get_irn_arity(n); i++) {
383 ir_node *con = get_irn_n(n, i);
384 if (is_constlike_node(con) && irn_not_visited(con)) {
385 if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
386 mark_irn_visited(con);
387 /* Generate a new name for the node by appending the names of
389 fprintf (F, "node: {title: "); PRINT_CONSTID(n,con);
390 fprintf(F, " label: \"");
391 dump_node_opcode(con);
392 dump_node_mode (con);
393 dump_node_typeinfo(con);
395 dump_node_nodeattr(con);
397 fprintf (F, " %ld", get_irn_node_nr(con));
400 dump_node_vcgattr(con);
408 dump_node (ir_node *n, pmap * map) {
409 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
412 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
416 dump_node_typeinfo(n);
418 dump_node_nodeattr(n);
420 fprintf (F, " %ld", get_irn_node_nr(n));
423 dump_node_vcgattr(n);
426 dump_const_node_local(n, map);
429 /* dump the edge to the block this node belongs to */
431 dump_ir_block_edge(ir_node *n) {
432 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
433 if (is_no_Block(n)) {
434 fprintf (F, "edge: { sourcename: \"");
436 fprintf (F, "\" targetname: \"");
437 PRINT_NODEID(get_nodes_Block(n));
438 fprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
442 static void print_edge_vcgattr(ir_node *from, int to) {
445 if (is_backedge(from, to)) fprintf (F, BACK_EDGE_ATTR);
447 switch (get_irn_opcode(from)) {
449 fprintf (F, CF_EDGE_ATTR);
451 case iro_Start: break;
454 if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
455 fprintf (F, CF_EDGE_ATTR);
456 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
457 fprintf (F, MEM_EDGE_ATTR);
460 case iro_EndReg: break;
461 case iro_EndExcept: break;
463 case iro_Break: break;
464 case iro_Cond: break;
467 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
469 case iro_Const: break;
470 case iro_SymConst:break;
473 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
475 case iro_CallBegin: break;
478 case iro_Minus: break;
484 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
492 case iro_Shrs: break;
495 case iro_Conv: break;
497 if (get_irn_modecode(from) == irm_M) fprintf (F, MEM_EDGE_ATTR);
503 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
506 fprintf (F, MEM_EDGE_ATTR);
508 case iro_Tuple: break;
511 switch (get_irn_modecode(from)) {
513 fprintf (F, CF_EDGE_ATTR);
516 fprintf (F, MEM_EDGE_ATTR);
522 case iro_Unknown: break;
529 /* dump edges to our inputs */
531 dump_ir_data_edges(ir_node *n, pmap *irgmap) {
532 int i, visited = get_irn_visited(n);
534 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
537 for (i = 0; i < get_irn_arity(n); i++) {
538 ir_node * pred = get_irn_n(n, i);
540 if ((interprocedural_view && get_irn_visited(pred) < visited))
541 continue; /* pred not dumped */
542 if (is_backedge(n, i))
543 fprintf (F, "backedge: {sourcename: \"");
545 fprintf (F, "edge: {sourcename: \"");
547 fprintf (F, "\" targetname: ");
548 if ((get_opt_dump_const_local()) && is_constlike_node(pred) &&
549 !pred_in_wrong_graph(n, i, irgmap)) {
550 PRINT_CONSTID(n, pred);
552 fprintf(F, "\""); PRINT_NODEID(pred); fprintf(F, "\"");
554 fprintf (F, " label: \"%d\" ", i);
555 print_edge_vcgattr(n, i);
562 dump_out_edge (ir_node *n, void* env) {
564 for (i = 0; i < get_irn_n_outs(n); i++) {
565 assert(get_irn_out(n, i));
566 fprintf (F, "edge: {sourcename: \"");
568 fprintf (F, "\" targetname: \"");
569 PRINT_NODEID(get_irn_out(n, i));
570 fprintf (F, "\" color: red linestyle: dashed");
576 dump_loop_node_edge (ir_loop *loop, int i) {
578 fprintf (F, "edge: {sourcename: \"%p\" targetname: \"", (void*) loop);
579 PRINT_NODEID(get_loop_node(loop, i));
580 fprintf (F, "\" color: green");
585 dump_loop_son_edge (ir_loop *loop, int i) {
587 fprintf (F, "edge: {sourcename: \"%p\" targetname: \"%p\" color: darkgreen}\n",
588 (void *)loop, (void *)get_loop_son(loop, i));
592 void dump_loops (ir_loop *loop) {
594 /* dump this loop node */
595 fprintf (F, "node: {title: \"%p\" label: \"loop %d, %d sons, %d nodes\" }\n",
596 (void*)loop, get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
597 /* dump edges to nodes in loop -- only if it is a real loop */
598 if (get_loop_depth(loop) != 0) {
599 for (i = 0; i < get_loop_n_nodes(loop); i++) {
600 dump_loop_node_edge(loop, i);
603 for (i = 0; i < get_loop_n_sons(loop); i++) {
604 dump_loops(get_loop_son(loop, i));
605 dump_loop_son_edge(loop, i);
610 void dump_loop_info(ir_graph *irg) {
611 ir_graph *rem = current_ir_graph;
612 current_ir_graph = irg;
614 if (get_irg_loop(irg))
615 dump_loops(get_irg_loop(irg));
617 current_ir_graph = rem;
621 /* dumps the edges between nodes and their type or entity attributes. */
622 static void dump_node2type_edges (ir_node *n, void *env)
626 switch (get_irn_opcode(n)) {
628 /* @@@ some consts have an entity */
631 if ( (get_SymConst_kind(n) == type_tag)
632 || (get_SymConst_kind(n) == size))
634 PRINT_NODE_TYPE_EDGE(n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
638 PRINT_NODE_ENT_EDGE(n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
641 PRINT_NODE_TYPE_EDGE(n,get_Call_type(n),NODE2TYPE_EDGE_ATTR);
644 PRINT_NODE_TYPE_EDGE(n,get_Alloc_type(n),NODE2TYPE_EDGE_ATTR);
647 PRINT_NODE_TYPE_EDGE(n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
650 PRINT_NODE_TYPE_EDGE(n,get_Cast_type(n),NODE2TYPE_EDGE_ATTR);
658 static void dump_const_expression(ir_node *value) {
659 ir_graph *rem = current_ir_graph;
660 int rem_dump_const_local = dump_const_local;
661 dump_const_local = 0;
662 current_ir_graph = get_const_code_irg();
663 irg_walk(value, dump_ir_blocks_nodes, NULL, get_nodes_Block(value));
664 /* Decrease visited flag so that we walk with the same flag for the next
665 expresssion. This guarantees that we don't dump the same node twice,
666 as for const expressions cse is performed to save memory. */
667 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
668 current_ir_graph = rem;
669 dump_const_local = rem_dump_const_local;
673 static void print_type_info(type *tp) {
674 if (get_type_state(tp) == layout_undefined) {
675 fprintf(F, "state: layout_undefined\n");
677 fprintf(F, "state: layout_fixed,\n");
679 if (get_type_mode(tp))
680 fprintf(F, "mode: %s,\n", get_mode_name(get_type_mode(tp)));
681 fprintf(F, "size: %dB,\n", get_type_size(tp));
685 static void print_typespecific_info(type *tp) {
686 switch (get_type_tpop_code(tp)) {
689 if (peculiarity_existent == get_class_peculiarity(tp))
690 fprintf (F, " " TYPE_CLASS_NODE_ATTR);
692 fprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
696 fprintf (F, " " TYPE_METH_NODE_ATTR);
707 case tpo_enumeration:
720 static void print_type_node(type *tp)
722 fprintf (F, "node: {title: ");
724 fprintf (F, " label: \"%s %s\"", get_type_tpop_name(tp), get_type_name(tp));
725 fprintf (F, " info1: \"");
728 print_typespecific_info(tp);
732 #define X(a) case a: fprintf(F, #a); break
733 void dump_entity_node(entity *ent)
735 fprintf (F, "node: {title: \"");
736 PRINT_ENTID(ent); fprintf(F, "\"");
737 fprintf (F, DEFAULT_TYPE_ATTRIBUTE);
738 fprintf (F, "label: ");
739 fprintf (F, "\"ent %s\" " ENTITY_NODE_ATTR , get_entity_name(ent));
740 fprintf (F, "\n info1: \"\nid: "); PRINT_ENTID(ent);
742 fprintf (F, "\nallocation: ");
743 switch (get_entity_allocation(ent)) {
744 X(allocation_dynamic);
745 X(allocation_automatic);
746 X(allocation_static);
747 X(allocation_parameter);
750 fprintf (F, "\nvisibility: ");
751 switch (get_entity_visibility(ent)) {
753 X(visibility_external_visible);
754 X(visibility_external_allocated);
757 fprintf (F, "\nvariability: ");
758 switch (get_entity_variability(ent)) {
759 X(variability_uninitialized);
760 X(variability_initialized);
761 X(variability_part_constant);
762 X(variability_constant);
765 fprintf (F, "\nvolatility: ");
766 switch (get_entity_volatility(ent)) {
767 X(volatility_non_volatile);
768 X(volatility_is_volatile);
771 fprintf (F, "\npeculiarity: ");
772 switch (get_entity_peculiarity(ent)) {
773 X(peculiarity_description);
774 X(peculiarity_inherited);
775 X(peculiarity_existent);
777 fprintf(F, "\nname: %s\nld_name: %s",
778 get_entity_name(ent), get_entity_ld_name(ent));
779 fprintf(F, "\noffset: %d", get_entity_offset(ent));
780 if (is_method_type(get_entity_type(ent))) {
781 if (get_entity_irg(ent)) /* can be null */
782 { fprintf (F, "\nirg = "); PRINT_IRGID(get_entity_irg(ent)); }
784 { fprintf (F, "\nirg = NULL"); }
786 fprintf(F, "\"\n}\n");
790 /* dumps a type or entity and it's edges. */
792 dump_type_info (type_or_ent *tore, void *env) {
793 int i = 0; /* to shutup gcc */
795 /* dump this type or entity */
797 switch (get_kind(tore)) {
800 entity *ent = (entity *)tore;
803 dump_entity_node(ent);
805 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
806 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
807 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
808 PRINT_ENT_TYPE_EDGE(ent, get_entity_type(ent), ENT_TYPE_EDGE_ATTR);
809 if(is_class_type(get_entity_owner(ent))) {
810 for(i = 0; i < get_entity_n_overwrites(ent); i++){
811 PRINT_ENT_ENT_EDGE(ent, get_entity_overwrites(ent, i), ENT_OVERWRITES_EDGE_ATTR);
814 /* attached subgraphs */
815 if (const_entities && (get_entity_variability(ent) != variability_uninitialized)) {
816 if (is_atomic_entity(ent)) {
817 value = get_atomic_ent_value(ent);
819 PRINT_ENT_NODE_EDGE(ent, value, ENT_VALUE_EDGE_ATTR, i);
820 /* DDMN(value); $$$ */
821 dump_const_expression(value);
824 if (is_compound_entity(ent)) {
825 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
826 value = get_compound_ent_value(ent, i);
828 PRINT_ENT_NODE_EDGE(ent,value,ENT_VALUE_EDGE_ATTR,i);
829 dump_const_expression(value);
830 PRINT_ENT_ENT_EDGE(ent, get_compound_ent_value_member(ent, i), ENT_CORR_EDGE_ATTR, i);
832 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
833 ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent),
834 get_compound_ent_value_member(ent, i), i);
843 type *tp = (type *)tore;
845 /* and now the edges */
846 switch (get_type_tpop_code(tp)) {
849 for (i=0; i < get_class_n_supertypes(tp); i++) {
850 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
853 for (i=0; i < get_class_n_members(tp); i++) {
854 PRINT_TYPE_ENT_EDGE(tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
859 for (i=0; i < get_struct_n_members(tp); i++) {
860 PRINT_TYPE_ENT_EDGE(tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
865 for (i = 0; i < get_method_n_params(tp); i++)
867 PRINT_TYPE_TYPE_EDGE(tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
869 for (i = 0; i < get_method_n_ress(tp); i++)
871 PRINT_TYPE_TYPE_EDGE(tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
876 for (i = 0; i < get_union_n_members(tp); i++)
878 PRINT_TYPE_ENT_EDGE(tp,get_union_member(tp, i),UNION_EDGE_ATTR);
883 PRINT_TYPE_TYPE_EDGE(tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
884 PRINT_TYPE_ENT_EDGE(tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
885 for (i = 0; i < get_array_n_dimensions(tp); i++) {
886 ir_node *upper = get_array_upper_bound(tp, i);
887 ir_node *lower = get_array_lower_bound(tp, i);
888 PRINT_NODE_TYPE_EDGE(upper, tp, "label: \"upper %d\"", get_array_order(tp, i));
889 PRINT_NODE_TYPE_EDGE(lower, tp, "label: \"lower %d\"", get_array_order(tp, i));
890 dump_const_expression(upper);
891 dump_const_expression(lower);
895 case tpo_enumeration:
900 PRINT_TYPE_TYPE_EDGE(tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
908 break; /* case k_type */
911 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
913 } /* switch kind_or_entity */
916 /* dumps a class type node and a superclass edge.
917 If env != null dumps entities of classes and overwrites edges. */
919 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
920 int i = 0; /* to shutup gcc */
922 /* dump this type or entity */
923 switch (get_kind(tore)) {
925 entity *ent = (entity *)tore;
926 if (get_entity_owner(ent) == get_glob_type()) break;
927 if ((env) && is_class_type(get_entity_owner(ent))) {
929 dump_entity_node(ent);
931 PRINT_TYPE_ENT_EDGE(get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
932 for(i = 0; i < get_entity_n_overwrites(ent); i++)
934 PRINT_ENT_ENT_EDGE(get_entity_overwrites(ent, i),ent, ENT_OVERWRITES_EDGE_ATTR);
937 } break; /* case k_entity */
940 type *tp = (type *)tore;
941 if (tp == get_glob_type()) break;
942 switch (get_type_tpop_code(tp)) {
945 /* and now the edges */
946 for (i=0; i < get_class_n_supertypes(tp); i++)
948 PRINT_TYPE_TYPE_EDGE(tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
954 break; /* case k_type */
957 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
959 } /* switch kind_or_entity */
962 /************************************************************************/
963 /* open and close vcg file */
964 /************************************************************************/
966 static void vcg_open (ir_graph *irg, char *suffix) {
967 char *fname; /* filename to put the vcg information in */
974 /** open file for vcg graph */
975 ent = get_irg_ent(irg);
976 id = ent->ld_name ? ent->ld_name : ent->name;
977 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
978 len = get_id_strlen (id);
979 cp = get_id_str (id);
980 if (dump_file_suffix)
981 fname = malloc (len + 5 + strlen(suffix) + strlen(dump_file_suffix));
983 fname = malloc (len + 5 + strlen(suffix));
984 strncpy (fname, cp, len); /* copy the filename */
986 if (dump_file_suffix) strcat (fname, dump_file_suffix); /* append file suffix */
987 strcat (fname, suffix); /* append file suffix */
988 strcat (fname, ".vcg"); /* append the .vcg suffix */
989 F = fopen (fname, "w"); /* open file for writing */
991 panic ("cannot open %s for writing (%m)", fname); /* not reached */
995 strcpy(label, "yes");
997 strcpy (label, "no");
1002 "graph: { title: \"ir graph of %s\"\n"
1003 "display_edge_labels: %s\n"
1004 "layoutalgorithm: mindepth\n"
1005 "manhattan_edges: yes\n"
1006 "port_sharing: no\n"
1007 "orientation: bottom_to_top\n"
1008 "classname 1: \"Data\"\n"
1009 "classname 2: \"Block\"\n"
1010 "classname 3: \"Entity type\"\n"
1011 "classname 4: \"Entity owner\"\n"
1012 "classname 5: \"Method Param\"\n"
1013 "classname 6: \"Method Res\"\n"
1014 "classname 7: \"Super\"\n"
1015 "classname 8: \"Union\"\n"
1016 "classname 9: \"Points-to\"\n"
1017 "classname 10: \"Array Element Type\"\n"
1018 "classname 11: \"Overwrites\"\n"
1019 "classname 12: \"Member\"\n"
1022 fprintf (F, "\n"); /* a separator */
1025 static void vcg_open_name (const char *name) {
1026 char *fname; /* filename to put the vcg information in */
1030 /** open file for vcg graph */
1032 fname = malloc (len + 5);
1033 if (dump_file_suffix)
1034 fname = malloc (len + 5 + strlen(dump_file_suffix));
1036 fname = malloc (len + 5);
1037 strcpy (fname, name); /* copy the filename */
1038 if (dump_file_suffix) strcat (fname, dump_file_suffix);
1039 strcat (fname, ".vcg"); /* append the .vcg suffix */
1040 F = fopen (fname, "w"); /* open file for writing */
1042 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1046 strcpy(label, "yes");
1048 strcpy (label, "no");
1053 "graph: { title: \"ir graph of %s\"\n"
1054 "display_edge_labels: %s\n"
1055 "layoutalgorithm: mindepth\n"
1056 "manhattan_edges: yes\n"
1057 "port_sharing: no\n"
1058 "orientation: bottom_to_top\n"
1059 "classname 1: \"Data\"\n"
1060 "classname 2: \"Block\"\n"
1061 "classname 3: \"Entity type\"\n"
1062 "classname 4: \"Entity owner\"\n"
1063 "classname 5: \"Method Param\"\n"
1064 "classname 6: \"Method Res\"\n"
1065 "classname 7: \"Super\"\n"
1066 "classname 8: \"Union\"\n"
1067 "classname 9: \"Points-to\"\n"
1068 "classname 10: \"Array Element Type\"\n"
1069 "classname 11: \"Overwrites\"\n"
1070 "classname 12: \"Member\"\n"
1073 fprintf (F, "\n"); /* a separator */
1078 fprintf (F, "}\n"); /* print footer */
1079 fclose (F); /* close vcg file */
1082 /************************************************************************/
1083 /* routines to dump a graph, blocks as conventional nodes. */
1084 /************************************************************************/
1086 static int node_floats(ir_node *n) {
1087 return ((get_op_pinned(get_irn_op(n)) == floats) &&
1088 (get_irg_pinned(current_ir_graph) == floats));
1092 dump_whole_node (ir_node *n, void* env) {
1094 if (!node_floats(n)) dump_ir_block_edge(n);
1095 dump_ir_data_edges(n, NULL);
1099 dump_ir_graph (ir_graph *irg)
1102 rem = current_ir_graph;
1103 current_ir_graph = irg;
1107 /* walk over the graph */
1108 /* dump_whole_node must be called in post visiting predecessors */
1109 irg_walk(get_irg_end(irg), NULL, dump_whole_node, NULL);
1111 /* dump the out edges in a separate walk */
1112 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1113 irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, NULL);
1118 current_ir_graph = rem;
1121 /***********************************************************************/
1122 /* the following routines dump the nodes as attached to the blocks. */
1123 /***********************************************************************/
1126 dump_ir_blocks_nodes (ir_node *n, void *env) {
1127 ir_node *block = (ir_node *)env;
1129 if (is_no_Block(n) && get_nodes_Block(n) == block && !node_floats(n)) {
1131 dump_ir_data_edges(n, NULL);
1133 if (get_irn_op(n) == op_Bad)
1138 dump_ir_block (ir_node *block, void *env) {
1139 ir_graph *irg = (ir_graph *)env;
1141 if (get_irn_opcode(block) == iro_Block) {
1143 /* This is a block. So dump the vcg information to make a block. */
1144 fprintf(F, "graph: { title: \"");
1145 PRINT_NODEID(block);
1146 fprintf(F, "\" label: \"");
1147 #ifdef DEBUG_libfirm
1148 fprintf (F, "%ld", get_irn_node_nr(block));
1150 fprintf (F, "%s", get_op_name(get_irn_op(block)));
1152 if (exc_normal != get_Block_exc (block))
1153 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1155 fprintf(F, "\" status:clustered color:%s \n",
1156 get_Block_matured (block) ? "yellow" : "red");
1157 /* dump the blocks edges */
1158 dump_ir_data_edges(block, NULL);
1160 /* dump the nodes that go into the block */
1161 irg_walk(get_irg_end(irg), dump_ir_blocks_nodes, NULL, block);
1163 /* Close the vcg information for the block */
1164 fprintf(F, "}\n\n");
1165 dump_const_node_local(block, NULL);
1171 dump_blockless_nodes (ir_node *n, void *env) {
1172 if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
1174 dump_ir_data_edges(n, NULL);
1175 dump_ir_block_edge(n);
1176 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1179 if (node_floats(n)) {
1181 dump_ir_data_edges(n, NULL);
1182 if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
1186 static void dump_ir_block_graph_2 (ir_graph *irg)
1189 /* walk over the blocks in the graph */
1190 irg_block_walk(get_irg_end(irg), dump_ir_block, NULL, irg);
1192 /* dump all nodes that are not in a Block */
1193 irg_walk(get_irg_end(irg), dump_blockless_nodes, NULL, NULL);
1195 /* dump the Bad node */
1197 dump_node(get_irg_bad(irg), NULL);
1201 dump_ir_block_graph (ir_graph *irg)
1204 rem = current_ir_graph;
1205 current_ir_graph = irg;
1209 dump_ir_block_graph_2 (irg);
1211 if (dump_loop_information_flag) dump_loop_info(irg);
1214 current_ir_graph = rem;
1218 /***********************************************************************/
1219 /* the following routines dump a control flow graph */
1220 /***********************************************************************/
1224 dump_block_to_cfg (ir_node *block, void *env) {
1228 if (get_irn_opcode(block) == iro_Block) {
1229 /* This is a block. Dump a node for the block. */
1230 fprintf (F, "node: {title: \""); PRINT_NODEID(block);
1231 fprintf (F, "\" label: \"%s ", get_op_name(get_irn_op(block)));
1232 #ifdef DEBUG_libfirm
1233 fprintf (F, "%ld", get_irn_node_nr(block));
1235 fprintf (F, "%p", (void*) block);
1238 if (exc_normal != get_Block_exc (block))
1239 fprintf (F, " (%s)", exc_to_string (get_Block_exc (block)));
1242 if (dump_dominator_information_flag)
1243 fprintf(F, "info1:dom depth %d", get_Block_dom_depth(block));
1245 /* Dump the edges */
1246 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1247 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1248 pred = get_nodes_Block(skip_Proj(get_Block_cfgpred(block, i)));
1249 fprintf (F, "edge: { sourcename: \"");
1250 PRINT_NODEID(block);
1251 fprintf (F, "\" targetname: \"");
1253 fprintf (F, "\"}\n");
1256 /* Dump dominator edge */
1257 if (dump_dominator_information_flag && get_Block_idom(block)) {
1258 pred = get_Block_idom(block);
1259 fprintf (F, "edge: { sourcename: \"");
1260 PRINT_NODEID(block);
1261 fprintf (F, "\" targetname: \"");
1263 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1269 dump_cfg (ir_graph *irg)
1271 ir_graph *rem = current_ir_graph;
1272 int ddif = dump_dominator_information_flag;
1273 current_ir_graph = irg;
1274 vcg_open (irg, "-cfg");
1276 if (get_irg_dom_state(irg) != dom_consistent)
1277 dump_dominator_information_flag = 0;
1279 /* walk over the blocks in the graph */
1280 irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, NULL);
1281 dump_node (get_irg_bad(irg), NULL);
1283 dump_dominator_information_flag = ddif;
1285 current_ir_graph = rem;
1289 /***********************************************************************/
1290 /* the following routine dumps all type information reachable from an */
1292 /***********************************************************************/
1296 dump_type_graph (ir_graph *irg)
1299 rem = current_ir_graph;
1300 current_ir_graph = irg;
1302 vcg_open (irg, "-type");
1304 /* walk over the blocks in the graph */
1305 type_walk_irg(irg, dump_type_info, NULL, NULL);
1306 /* The walker for the const code can be called several times for the
1307 same (sub) experssion. So that no nodes are dumped several times
1308 we decrease the visited flag of the corresponding graph after each
1309 walk. So now increase it finally. */
1310 inc_irg_visited(get_const_code_irg());
1313 current_ir_graph = rem;
1316 /***********************************************************************/
1317 /* the following routine dumps all type information */
1318 /***********************************************************************/
1322 dump_all_types (void)
1324 vcg_open_name ("All_types");
1325 type_walk(dump_type_info, NULL, NULL);
1326 inc_irg_visited(get_const_code_irg());
1331 dump_class_hierarchy (bool entities)
1333 vcg_open_name ("class_hierarchy");
1335 type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1337 type_walk(dump_class_hierarchy_node, NULL, NULL);
1341 /***********************************************************************/
1342 /* dumps a graph with type information */
1343 /***********************************************************************/
1347 dump_ir_graph_w_types (ir_graph *irg)
1350 rem = current_ir_graph;
1351 current_ir_graph = irg;
1353 vcg_open (irg, "-all");
1355 /* dump common ir graph */
1356 irg_walk(get_irg_end(irg), dump_whole_node, NULL, NULL);
1357 /* dump type info */
1358 type_walk_irg(irg, dump_type_info, NULL, NULL);
1359 inc_irg_visited(get_const_code_irg());
1360 /* dump edges from graph to type info */
1361 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1364 current_ir_graph = rem;
1368 dump_ir_block_graph_w_types (ir_graph *irg)
1371 rem = current_ir_graph;
1372 current_ir_graph = irg;
1374 vcg_open (irg, "-all");
1376 /* dump common blocked ir graph */
1377 dump_ir_block_graph_2(irg);
1378 /* dump type info */
1379 type_walk_irg(irg, dump_type_info, NULL, NULL);
1380 inc_irg_visited(get_const_code_irg());
1381 /* dump edges from graph to type info */
1382 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1385 current_ir_graph = rem;
1388 /***********************************************************************/
1389 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1391 /* dump_ir_block_graph */
1393 /* dump_type_graph */
1394 /* dump_ir_graph_w_types */
1395 /***********************************************************************/
1396 void dump_all_ir_graphs (dump_graph_func *dump_graph) {
1398 for (i=0; i < get_irp_n_irgs(); i++) {
1399 dump_graph(get_irp_irg(i));
1404 /* To turn off display of edge labels. Edge labels offen cause xvcg to
1405 abort with a segmentation fault. */
1406 void turn_off_edge_labels(void) {
1411 void dump_consts_local(bool b) {
1412 dump_const_local = b;
1415 void turn_off_constant_entity_values(void) {
1419 void dump_keepalive_edges(bool b) {
1423 bool get_opt_dump_keepalive_edges(void) {
1424 return dump_keepalive;
1427 void dump_out_edges(void) {
1428 dump_out_edge_flag = 1;
1431 void dump_dominator_information(void) {
1432 dump_dominator_information_flag = 1;
1435 void dump_loop_information(void) {
1436 dump_loop_information_flag = 1;
1439 void dont_dump_loop_information(void) {
1440 dump_loop_information_flag = 0;
1443 static void clear_link(ir_node * node, void * env) {
1444 set_irn_link(node, NULL);
1448 static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
1449 assert(node); assert(map);
1451 || node_floats(node)
1452 || get_irn_op(node) == op_Bad
1453 || get_irn_op(node) == op_Unknown) {
1454 pmap_entry * entry = pmap_find(map, current_ir_graph);
1460 ARR_APP1(ir_node *, arr, node);
1461 entry->value = (void *)arr;
1463 ir_node ** arr = NEW_ARR_F(ir_node *, 1);
1466 pmap_insert(map, current_ir_graph, arr);
1469 ir_node * block = get_nodes_Block(node);
1470 set_irn_link(node, get_irn_link(block));
1471 set_irn_link(block, node);
1476 static void dump_cg_ir_block(ir_node * block, void * env) {
1478 pmap *irgmap = (pmap *)env;
1479 assert(is_Block(block));
1481 fprintf(F, "graph: { title: \"");
1482 PRINT_NODEID(block);
1483 fprintf(F, "\" label: \"");
1484 dump_node_opcode(block);
1485 fprintf (F, " %ld", get_irn_node_nr(block));
1487 if (exc_normal != get_Block_exc(block)) {
1488 fprintf (F, " (%s)", exc_to_string (get_Block_exc(block)));
1491 fprintf(F, "\" status:clustered color:%s \n",
1492 get_Block_matured(block) ? "yellow" : "red");
1494 /* dump the blocks edges */
1495 dump_ir_data_edges(block, irgmap);
1497 /* dump the nodes that go into the block */
1498 for (node = get_irn_link(block); node; node = get_irn_link(node)) {
1499 dump_node(node, irgmap);
1500 dump_ir_data_edges(node, irgmap);
1503 /* Close the vcg information for the block */
1505 dump_const_node_local(block, irgmap);
1509 static void d_cg_block_graph(ir_graph *irg, ir_node **arr, pmap *irgmap) {
1512 fprintf(F, "graph: { title: \"%p\" label: \"%s\" status:clustered color:white \n",
1513 (void*) irg, get_entity_name(get_irg_ent(irg)));
1515 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1516 ir_node * node = arr[i];
1517 if (is_Block(node)) {
1518 /* Dumps the block and all the nodes in the block, which are to
1519 be found in Block->link. */
1520 dump_cg_ir_block(node, irgmap);
1522 /* Nodes that are not in a Block. */
1523 dump_node(node, NULL);
1524 dump_ir_data_edges(node, NULL);
1527 /* Close the vcg information for the irg */
1528 fprintf(F, "}\n\n");
1531 /* dump interprocedural graph with surrounding methods */
1532 void dump_cg_block_graph(ir_graph * irg) {
1533 pmap * map = pmap_create();
1534 pmap * map2 = pmap_create();
1539 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1540 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1541 pmap_insert(map2, entry->key, entry->value);
1542 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1543 d_cg_block_graph(entry->key, entry->value, map2);
1544 DEL_ARR_F(entry->value);
1550 if (dump_loop_information_flag) dump_loop_info(irg);
1554 static void collect_node(ir_node * node, void *env) {
1556 || node_floats(node)
1557 || get_irn_op(node) == op_Bad
1558 || get_irn_op(node) == op_Unknown) {
1559 ir_node ** arr = (ir_node **) get_irg_link(current_ir_graph);
1560 ARR_APP1(ir_node *, arr, node);
1561 set_irg_link(current_ir_graph, arr); /* arr is an l-value, APP_ARR might change it! */
1563 ir_node * block = get_nodes_Block(node);
1564 set_irn_link(node, get_irn_link(block));
1565 set_irn_link(block, node);
1569 /* Links all nodes that have the block field set in the link field of
1570 the block. Adds all blocks and nodes not associated with a block
1571 in a array in irg->link. */
1572 static void collect_nodes(void) {
1574 for (i = 0; i < get_irp_n_irgs(); i++)
1575 set_irg_link(get_irp_irg(i), NEW_ARR_F(ir_node *, 0));
1576 cg_walk(clear_link, collect_node, NULL);
1579 static void dump_graphs(void) {
1581 for (i = 0; i < get_irp_n_irgs(); i++) {
1582 current_ir_graph = get_irp_irg(i);
1583 d_cg_block_graph(current_ir_graph, get_irg_link(current_ir_graph), NULL);
1587 /* Dump all irgs in interprocedural view to a single file. */
1588 void dump_all_cg_block_graph(void) {
1590 int rem_view = interprocedural_view;
1591 interprocedural_view = 1;
1592 vcg_open_name ("All_graphs");
1597 if (dump_loop_information_flag)
1598 for (i = 0; i < get_irp_n_irgs(); i++)
1599 dump_loop_info(get_irp_irg(i));
1602 interprocedural_view = rem_view;
1605 /* dump interprocedural block graph with surrounding methods */
1606 void dump_cg_graph(ir_graph * irg) {
1607 pmap * map = pmap_create();
1608 pmap * map2 = pmap_create(); /* We can not iterate in the same map twice! */
1612 irg_walk_graph(irg, clear_link, (irg_walk_func *) collect_blocks_floats_cg, map);
1613 for (entry = pmap_first(map); entry; entry = pmap_next(map))
1614 pmap_insert(map2, entry->key, entry->value);
1615 for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
1616 ir_node ** arr = entry->value;
1618 ident * irg_ident = get_entity_ident(get_irg_ent(entry->key));
1620 fprintf(F, "graph: { title: %s label: %s status:clustered color:white \n",
1621 get_id_str(irg_ident), get_id_str(irg_ident));
1623 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
1624 ir_node * node = arr[i];
1625 dump_node(node, map2);
1626 dump_ir_data_edges(node, NULL);
1627 if (is_Block(node)) {
1628 for (node = get_irn_link(node); node; node = get_irn_link(node)) {
1629 dump_node(node, map2);
1630 dump_ir_block_edge(node);
1631 dump_ir_data_edges(node, NULL);
1638 /* Close the vcg information for the irg */
1639 fprintf(F, "}\n\n");
1648 /* Dump the information of type field specified in ana/irtypeinfo.h.
1649 * If the flag is set, the type name is output in [] in the node label,
1650 * else it is output as info.
1652 void dump_analysed_type_info(bool b) {
1653 opt_dump_analysed_type_info = b;