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.
22 # include "irnode_t.h"
23 # include "irgraph_t.h"
24 # include "entity_t.h"
26 # include "firm_common_t.h"
31 # include "typewalk.h"
34 # include "type_or_entity.h"
46 /* Attributes of nodes */
47 #define PRINT_DEFAULT_NODE_ATTR
48 #define DEFAULT_NODE_ATTR " "
49 #define DEFAULT_TYPE_ATTRIBUTE " "
51 /* Attributes of edges between Firm nodes */
52 #define BLOCK_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
53 #define CF_EDGE_ATTR "color: red"
54 #define MEM_EDGE_ATTR "color: blue"
55 #define DOMINATOR_EDGE_ATTR "color: red"
57 #define BACK_EDGE_ATTR "linestyle: dashed "
59 /* Attributes of edges between Firm nodes and type/entity nodes */
60 #define NODE2TYPE_EDGE_ATTR "class: 2 priority: 2 linestyle: dotted"
62 /* Attributes of edges in type/entity graphs. */
63 #define TYPE_METH_NODE_ATTR "color: lightyellow"
64 #define TYPE_CLASS_NODE_ATTR "color: green"
65 #define TYPE_DESCRIPTION_NODE_ATTR "color: lightgreen"
66 #define ENTITY_NODE_ATTR "color: yellow"
67 #define ENT_TYPE_EDGE_ATTR "class: 3 label: \"type\" color: red"
68 #define ENT_OWN_EDGE_ATTR "class: 4 label: \"owner\" color: black"
69 #define METH_PAR_EDGE_ATTR "class: 5 label: \"param %d\" color: green"
70 #define METH_RES_EDGE_ATTR "class: 6 label: \"res %d\" color: green"
71 #define TYPE_SUPER_EDGE_ATTR "class: 7 label: \"supertype\" color: red"
72 #define UNION_EDGE_ATTR "class: 8 label: \"component\" color: blue"
73 #define PTR_PTS_TO_EDGE_ATTR "class: 9 label: \"points to\" color:green"
74 #define ARR_ELT_TYPE_EDGE_ATTR "class: 10 label: \"arr elt tp\" color:green"
75 #define ARR_ENT_EDGE_ATTR "class: 10 label: \"arr ent\" color: green"
76 #define ENT_OVERWRITES_EDGE_ATTR "class: 11 label: \"overwrites\" color:red"
77 #define ENT_VALUE_EDGE_ATTR "label: \"value %d\""
78 #define ENT_CORR_EDGE_ATTR "label: \"value %d corresponds to \" "
79 #define TYPE_MEMBER_EDGE_ATTR "class: 12 label: \"member\" color:blue"
82 #if DEBUG_libfirm && NODEID_AS_LABEL
83 #define PRINT_NODEID(X) fprintf(F, "n%ld", get_irn_node_nr(X))
84 #define PRINT_TYPEID(X) fprintf(F, "\"t%ld\"", get_type_nr(X))
85 #define PRINT_ENTID(X) fprintf(F, "e%ld", get_entity_nr(X))
86 #define PRINT_IRGID(X) fprintf(F, "g%ld", get_irg_graph_nr(X))
87 #define PRINT_CONSTID(X,Y) fprintf(F, "\"n%ldn%ld\"", get_irn_node_nr(X),get_irn_node_nr(Y))
90 #define PRINT_NODEID(X) fprintf(F, "n%p", (void*) X)
91 #define PRINT_TYPEID(X) fprintf(F, "\"t%p\"", (void *) X)
92 #define PRINT_ENTID(X) fprintf(F, "e%p", (void*) X)
93 #define PRINT_IRGID(X) fprintf(F, "g%p",(void*) X)
94 #define PRINT_CONSTID(X,Y) fprintf(F, "\"n%pn%p\"", (void*) X, (void*) Y)
97 static void print_type_type_edge(FILE *F, type *S, type *T, const char *fmt, ...)
102 fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(S);
103 fprintf(F, " targetname: "); PRINT_TYPEID(T);
104 vfprintf(F, fmt, ap);
109 static void print_type_ent_edge(FILE *F, type *T, entity *E, const char *fmt, ...)
114 fprintf(F, "edge: { sourcename: "); PRINT_TYPEID(T);
115 fprintf(F, " targetname: \""); PRINT_ENTID(E); fprintf(F, "\"");
116 vfprintf(F, fmt, ap);
121 static void print_ent_ent_edge(FILE *F, entity *E, entity *T, const char *fmt, ...)
126 fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
127 fprintf(F, "\" targetname: \""); PRINT_ENTID(T); fprintf(F, "\"");
128 vfprintf(F, fmt, ap);
133 static void print_ent_type_edge(FILE *F, entity *E, type *T, const char *fmt, ...)
138 fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
139 fprintf(F, "\" targetname: "); PRINT_TYPEID(T);
140 vfprintf(F, fmt, ap);
145 static void print_node_type_edge(FILE *F, const ir_node *N, type *T, const char *fmt, ...)
150 fprintf(F, "edge: { sourcename: \""); PRINT_NODEID(N);
151 fprintf(F, "\" targetname: "); PRINT_TYPEID(T);
152 vfprintf(F, fmt, ap);
157 static void print_node_ent_edge(FILE *F, const ir_node *N, entity *E, const char *fmt, ...)
162 fprintf(F, "edge: { sourcename: \""); PRINT_NODEID(N);
163 fprintf(F, "\" targetname: \""); PRINT_ENTID(E);
165 vfprintf(F, fmt, ap);
170 static void print_ent_node_edge(FILE *F, entity *E, const ir_node *N, const char *fmt, ...)
175 fprintf(F, "edge: { sourcename: \""); PRINT_ENTID(E);
176 fprintf(F, "\" targetname: \""); PRINT_NODEID(N); fprintf(F, "\"");
177 vfprintf(F, fmt, ap);
182 /*******************************************************************/
183 /* global and ahead declarations */
184 /*******************************************************************/
186 /* A suffix to manipulate the file name. */
187 char *dump_file_suffix = NULL;
189 /* file to dump to */
192 static void dump_whole_node(ir_node *n, void* env);
193 static INLINE void dump_loop_info(ir_graph *irg);
195 /*******************************************************************/
196 /* Helper functions. */
197 /*******************************************************************/
199 /* Use private link attr to be able to call dumper anywhere without
200 destroying link fields. */
202 static pmap *irdump_link_map = NULL;
204 static void init_irdump(void) {
205 /* We need a new, empty map. */
206 if (irdump_link_map) pmap_destroy(irdump_link_map);
207 irdump_link_map = pmap_create();
211 void *ird_get_irn_link(ir_node *n) {
213 if (!irdump_link_map) return NULL;
215 if (pmap_contains(irdump_link_map, (void *)n))
216 res = pmap_get(irdump_link_map, (void *)n);
220 void ird_set_irn_link(ir_node *n, void *x) {
221 if (!irdump_link_map) init_irdump();
222 pmap_insert(irdump_link_map, (void *)n, x);
225 void *ird_get_irg_link(ir_graph *irg) {
227 if (!irdump_link_map) return NULL;
229 if (pmap_contains(irdump_link_map, (void *)irg))
230 res = pmap_get(irdump_link_map, (void *)irg);
234 void ird_set_irg_link(ir_graph *irg, void *x) {
235 if (!irdump_link_map) init_irdump();
236 pmap_insert(irdump_link_map, (void *)irg, x);
239 static void clear_link(ir_node * node, void * env) {
240 ird_set_irn_link(node, NULL);
244 static int node_floats(ir_node *n) {
245 return ((get_op_pinned(get_irn_op(n)) == floats) &&
246 (get_irg_pinned(current_ir_graph) == floats));
249 static ident *get_irg_dump_name (ir_graph *irg) {
250 /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */
251 entity *ent = get_irg_ent(irg);
252 if (ent->ld_name) return ent->ld_name;
256 static void collect_node(ir_node * node, void *env) {
259 || get_irn_op(node) == op_Bad
260 || get_irn_op(node) == op_Unknown) {
261 ir_node ** arr = (ir_node **) ird_get_irg_link(get_irn_irg(node));
262 if (!arr) arr = NEW_ARR_F(ir_node *, 0);
263 ARR_APP1(ir_node *, arr, node);
264 ird_set_irg_link(get_irn_irg(node), arr); /* arr is an l-value, APP_ARR might change it! */
266 ir_node * block = get_nodes_block(node);
267 ird_set_irn_link(node, ird_get_irn_link(block));
268 ird_set_irn_link(block, node);
272 /** Construct lists to walk ir block-wise.
274 * Collects all blocks, nodes not pinned,
275 * Bad and Unknown into a flexible array in link field of
276 * irg they belong to. Sets the irg link field to NULL in all
277 * graphs not visited.
278 * Free the list with DEL_ARR_F. */
279 static ir_node ** construct_block_lists(ir_graph *irg) {
281 ir_graph *rem = current_ir_graph;
282 current_ir_graph = irg;
284 for (i = 0; i < get_irp_n_irgs(); i++)
285 ird_set_irg_link(get_irp_irg(i), NULL);
287 irg_walk_graph(current_ir_graph, clear_link, collect_node, current_ir_graph);
289 current_ir_graph = rem;
290 return ird_get_irg_link(irg);
293 /*******************************************************************/
294 /* flags to steer output */
295 /*******************************************************************/
297 /* A compiler option to turn off edge labels */
299 /* A compiler option to turn off dumping values of constant entities */
300 int const_entities = 1;
301 /* A compiler option to dump the keep alive edges */
302 int dump_keepalive = 0;
303 /* Compiler options to dump analysis information in dump_ir_graph */
304 int dump_out_edge_flag = 0;
305 int dump_dominator_information_flag = 0;
306 int dump_loop_information_flag = 0;
307 int dump_backedge_information_flag = 1;
308 int dump_const_local = 0;
309 bool opt_dump_analysed_type_info = 1;
310 bool opt_dump_pointer_values_to_info = 0; /* default off: for test compares!! */
312 INLINE bool get_opt_dump_const_local(void) {
313 if (!dump_out_edge_flag && !dump_loop_information_flag)
314 return dump_const_local;
319 /* To turn off display of edge labels. Edge labels offen cause xvcg to
320 abort with a segmentation fault. */
321 void turn_off_edge_labels(void) {
325 void dump_consts_local(bool b) {
326 dump_const_local = b;
329 void turn_off_constant_entity_values(void) {
333 void dump_keepalive_edges(bool b) {
337 bool get_opt_dump_keepalive_edges(void) {
338 return dump_keepalive;
341 void dump_out_edges(void) {
342 dump_out_edge_flag = 1;
345 void dump_dominator_information(void) {
346 dump_dominator_information_flag = 1;
349 void dump_loop_information(void) {
350 dump_loop_information_flag = 1;
353 void dont_dump_loop_information(void) {
354 dump_loop_information_flag = 0;
357 void dump_backedge_information(bool b) {
358 dump_backedge_information_flag = b;
361 /* Dump the information of type field specified in ana/irtypeinfo.h.
362 * If the flag is set, the type name is output in [] in the node label,
363 * else it is output as info.
365 void dump_analysed_type_info(bool b) {
366 opt_dump_analysed_type_info = b;
369 void dump_pointer_values_to_info(bool b) {
370 opt_dump_pointer_values_to_info = b;
373 /*******************************************************************/
374 /* Routines to dump information about a single ir node. */
375 /*******************************************************************/
378 dump_node_opcode (ir_node *n)
381 switch(get_irn_opcode(n)) {
386 res = tarval_snprintf(buf, sizeof(buf), get_Const_tarval(n));
387 assert(res < sizeof(buf) && "buffer to small for tarval_snprintf");
392 if (get_SymConst_kind(n) == linkage_ptr_info) {
393 /* don't use get_SymConst_ptr_info as it mangles the name. */
394 fprintf (F, "SymC %s", get_id_str(get_SymConst_ptrinfo(n)));
396 assert(get_kind(get_SymConst_type(n)) == k_type);
397 assert(get_type_ident(get_SymConst_type(n)));
398 fprintf (F, "SymC %s ", get_type_name(get_SymConst_type(n)));
399 if (get_SymConst_kind(n) == type_tag)
407 if (!interprocedural_view) fprintf(F, "Proj'");
408 else fprintf(F, "%s", get_irn_opname(n));
412 if (interprocedural_view) {
413 fprintf(F, "%s %s", get_irn_opname(n), get_entity_name(get_irg_ent(get_irn_irg(n))));
419 fprintf (F, "%s", get_irn_opname(n));
426 dump_node_mode (ir_node *n)
428 switch (get_irn_opcode(n)) {
447 fprintf (F, "%s", get_mode_name(get_irn_mode(n)));
454 static void dump_node_typeinfo(ir_node *n) {
455 if (!opt_dump_analysed_type_info) return;
456 if (get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_consistent ||
457 get_irg_typeinfo_state(current_ir_graph) == irg_typeinfo_inconsistent ) {
458 type *tp = get_irn_type(n);
460 fprintf (F, " [%s]", get_type_name(tp));
467 dump_node_nodeattr (ir_node *n)
469 switch (get_irn_opcode(n)) {
471 if (false && interprocedural_view) {
472 fprintf (F, "%s", get_entity_name(get_irg_ent(current_ir_graph)));
476 if (get_irn_opcode(get_Proj_pred(n)) == iro_Cmp) {
477 fprintf (F, "%s", get_pnc_string(get_Proj_proj(n)));
479 fprintf (F, "%ld", get_Proj_proj(n));
483 fprintf (F, "%ld", get_Filter_proj(n));
486 fprintf (F, "%s", get_entity_name(get_Sel_entity(n)));
489 fprintf (F, "(%s)", get_type_name(get_Cast_type(n)));
492 fprintf (F, "%s", get_pnc_string(get_Confirm_cmp(n)));
501 dump_node_vcgattr (ir_node *n)
503 switch (get_irn_opcode(n)) {
510 fprintf (F, "color: blue");
513 fprintf (F, "color: lightyellow");
516 fprintf (F, "color: green");
522 fprintf (F, "color: yellow");
525 PRINT_DEFAULT_NODE_ATTR;
530 dump_node_info (ir_node *n) {
533 fprintf (F, " info1: \"");
534 if (opt_dump_pointer_values_to_info)
535 fprintf (F, "addr: %p \n", (void *)n);
536 fprintf (F, "visited: %ld \n", get_irn_visited(n));
537 irg = get_irn_irg(n);
538 if (irg != get_const_code_irg())
539 fprintf (F, "irg: %s\n", get_entity_name(get_irg_entity(irg)));
542 switch (get_irn_opcode(n)) {
544 type *tp = get_entity_type(get_irg_ent(get_irn_irg(n)));
545 fprintf(F, "start of method of type %s \n", get_type_name(tp));
546 for (i = 0; i < get_method_n_params(tp); ++i)
547 fprintf(F, " param %d type: %s \n", i, get_type_name(get_method_param_type(tp, i)));
550 fprintf(F, "allocating entity of type %s \n", get_type_name(get_Alloc_type(n)));
553 fprintf(F, "freeing entity of type %s \n", get_type_name(get_Free_type(n)));
556 fprintf(F, "Selecting entity of type %s \n", get_type_name(get_entity_type(get_Sel_entity(n))));
557 fprintf(F, " from entity of type %s \n", get_type_name(get_entity_owner(get_Sel_entity(n))));
560 type *tp = get_Call_type(n);
561 fprintf(F, "calling method of type %s \n", get_type_name(tp));
562 for (i = 0; i < get_method_n_params(tp); ++i)
563 fprintf(F, " param %d type: %s \n", i, get_type_name(get_method_param_type(tp, i)));
564 for (i = 0; i < get_method_n_ress(tp); ++i)
565 fprintf(F, " resul %d type: %s \n", i, get_type_name(get_method_res_type(tp, i)));
568 if (!interprocedural_view) {
569 type *tp = get_entity_type(get_irg_ent(get_irn_irg(n)));
570 fprintf(F, "return in method of type %s \n", get_type_name(tp));
571 for (i = 0; i < get_method_n_ress(tp); ++i)
572 fprintf(F, " res %d type: %s \n", i, get_type_name(get_method_res_type(tp, i)));
576 type *tp = get_Const_type(n);
577 assert(tp != none_type);
578 fprintf(F, "Const of type %s \n", get_type_name(get_Const_type(n)));
582 if (interprocedural_view) {
583 fprintf(F, "intra predecessor nodes:\n");
584 for (i = 0; i < get_irn_intra_arity(n); i++) {
585 ir_node *pred = get_irn_intra_n(n, i);
586 fprintf(F, " %s%s %ld\n", get_irn_opname(pred), get_irn_modename(pred), get_irn_node_nr(pred));
589 fprintf(F, "inter predecessor nodes:\n");
590 for (i = 0; i < get_irn_inter_arity(n); i++) {
591 ir_node *pred = get_irn_inter_n(n, i);
592 fprintf(F, " %s%s %ld \tin graph %s\n", get_irn_opname(pred), get_irn_modename(pred),
593 get_irn_node_nr(pred), get_entity_name(get_irg_entity(get_irn_irg(pred))));
601 if (get_irg_typeinfo_state(get_irn_irg(n)) == irg_typeinfo_consistent ||
602 get_irg_typeinfo_state(get_irn_irg(n)) == irg_typeinfo_inconsistent )
603 if (get_irn_type(n) != none_type)
604 fprintf (F, "\nAnalysed type: %s", get_type_name(get_irn_type(n)));
611 bool is_constlike_node(ir_node *n) {
612 ir_op *op = get_irn_op(n);
613 return (op == op_Const || op == op_Bad || op == op_SymConst || op == op_Unknown);
617 /* outputs the predecessors of n, that are constants, local. I.e.,
618 generates a copy of the constant predecessors for each node called with. */
619 static void dump_const_node_local(ir_node *n) {
621 if (!get_opt_dump_const_local()) return;
623 /* Use visited flag to avoid outputting nodes twice.
624 initialize it first. */
625 for (i = 0; i < get_irn_arity(n); i++) {
626 ir_node *con = get_irn_n(n, i);
627 if (is_constlike_node(con)) {
628 set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
632 for (i = 0; i < get_irn_arity(n); i++) {
633 ir_node *con = get_irn_n(n, i);
634 if (is_constlike_node(con) && irn_not_visited(con)) {
635 mark_irn_visited(con);
636 /* Generate a new name for the node by appending the names of
638 fprintf (F, "node: {title: "); PRINT_CONSTID(n, con);
639 fprintf(F, " label: \"");
640 dump_node_opcode(con);
641 dump_node_mode (con);
642 dump_node_typeinfo(con);
644 dump_node_nodeattr(con);
645 fprintf (F, " %ld", get_irn_node_nr(con));
647 dump_node_vcgattr(con);
655 dump_node (ir_node *n) {
656 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
658 fprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
662 dump_node_typeinfo(n);
664 dump_node_nodeattr(n);
665 fprintf (F, " %ld", get_irn_node_nr(n));
667 dump_node_vcgattr(n);
670 dump_const_node_local(n);
673 /* dump the edge to the block this node belongs to */
675 dump_ir_block_edge(ir_node *n) {
676 if (get_opt_dump_const_local() && is_constlike_node(n)) return;
677 if (is_no_Block(n)) {
678 fprintf (F, "edge: { sourcename: \"");
680 fprintf (F, "\" targetname: \"");
681 PRINT_NODEID(get_nodes_block(n));
682 fprintf (F, "\" " BLOCK_EDGE_ATTR "}\n");
686 static void print_edge_vcgattr(ir_node *from, int to) {
689 if (dump_backedge_information_flag && is_backedge(from, to))
690 fprintf (F, BACK_EDGE_ATTR);
692 switch (get_irn_opcode(from)) {
694 fprintf (F, CF_EDGE_ATTR);
696 case iro_Start: break;
699 if (get_irn_mode(get_End_keepalive(from, to)) == mode_BB)
700 fprintf (F, CF_EDGE_ATTR);
701 if (get_irn_mode(get_End_keepalive(from, to)) == mode_X)
702 fprintf (F, MEM_EDGE_ATTR);
705 case iro_EndReg: break;
706 case iro_EndExcept: break;
708 case iro_Break: break;
709 case iro_Cond: break;
712 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
714 case iro_Const: break;
715 case iro_SymConst:break;
718 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
720 case iro_CallBegin: break;
723 case iro_Minus: break;
729 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
737 case iro_Shrs: break;
740 case iro_Conv: break;
742 if (get_irn_modecode(from) == irm_M) fprintf (F, MEM_EDGE_ATTR);
748 if (to == 0) fprintf (F, MEM_EDGE_ATTR);
751 fprintf (F, MEM_EDGE_ATTR);
753 case iro_Tuple: break;
756 switch (get_irn_modecode(from)) {
758 fprintf (F, CF_EDGE_ATTR);
761 fprintf (F, MEM_EDGE_ATTR);
767 case iro_Unknown: break;
774 /* dump edges to our inputs */
776 dump_ir_data_edges(ir_node *n) {
777 int i, visited = get_irn_visited(n);
779 if ((get_irn_op(n) == op_End) && (!dump_keepalive))
782 for (i = 0; i < get_irn_arity(n); i++) {
783 ir_node * pred = get_irn_n(n, i);
786 if ((interprocedural_view && get_irn_visited(pred) < visited))
787 continue; /* pred not dumped */
789 if (dump_backedge_information_flag && is_backedge(n, i))
790 fprintf (F, "backedge: {sourcename: \"");
792 fprintf (F, "edge: {sourcename: \"");
794 fprintf (F, "\" targetname: ");
795 if ((get_opt_dump_const_local()) && is_constlike_node(pred)) {
796 PRINT_CONSTID(n, pred);
798 fprintf(F, "\""); PRINT_NODEID(pred); fprintf(F, "\"");
800 fprintf (F, " label: \"%d\" ", i);
801 print_edge_vcgattr(n, i);
806 /** Dumps a node and its edges but not the block edge
809 dump_node_wo_blockedge (ir_node *n, void* env) {
811 dump_ir_data_edges(n);
814 /** Dumps a node and its edges.
817 dump_whole_node (ir_node *n, void* env) {
818 dump_node_wo_blockedge(n, env);
819 if (!node_floats(n)) dump_ir_block_edge(n);
823 dump_const_node(ir_node *n, void *env) {
824 if (is_Block(n)) return;
825 dump_node_wo_blockedge(n, env);
828 /***********************************************************************/
829 /* the following routines dump the nodes/irgs bracketed to graphs. */
830 /***********************************************************************/
832 /** Dumps a constant expression as entity initializer, array bound ...
834 static void dump_const_expression(ir_node *value) {
835 ir_graph *rem = current_ir_graph;
836 int rem_dump_const_local = dump_const_local;
837 dump_const_local = 0;
838 current_ir_graph = get_const_code_irg();
839 irg_walk(value, dump_const_node, NULL, NULL);
840 /* Decrease visited flag so that we walk with the same flag for the next
841 expresssion. This guarantees that we don't dump the same node twice,
842 as for const expressions cse is performed to save memory. */
843 set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1);
844 current_ir_graph = rem;
845 dump_const_local = rem_dump_const_local;
848 /** Dump a block as graph containing its nodes.
850 * Expects to find nodes belonging to the block as list in its
852 * Dumps the edges of all nodes including itself. */
854 dump_whole_block(ir_node *block) {
856 assert(is_Block(block));
858 fprintf(F, "graph: { title: \"");
860 fprintf(F, "\" label: \"");
861 dump_node_opcode(block);
862 fprintf (F, " %ld", get_irn_node_nr(block));
864 fprintf(F, "\" status:clustered color:%s \n",
865 get_Block_matured(block) ? "yellow" : "red");
867 /* dump the blocks edges */
868 dump_ir_data_edges(block);
870 /* dump the nodes that go into the block */
871 for (node = ird_get_irn_link(block); node; node = ird_get_irn_link(node)) {
873 dump_ir_data_edges(node);
876 /* Close the vcg information for the block */
878 dump_const_node_local(block);
882 /** dumps a graph block-wise. Expects all blockless nodes in arr in irgs link.
883 * The outermost nodes: blocks and nodes not pinned, Bad, Unknown. */
885 dump_block_graph (ir_graph *irg) {
887 ir_graph *rem = current_ir_graph;
888 ir_node **arr = ird_get_irg_link(irg);
889 current_ir_graph = irg;
891 for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
892 ir_node * node = arr[i];
893 if (is_Block(node)) {
894 /* Dumps the block and all the nodes in the block, which are to
895 be found in Block->link. */
896 dump_whole_block(node);
898 /* Nodes that are not in a Block. */
900 dump_ir_data_edges(node);
904 if (dump_loop_information_flag) dump_loop_info(irg);
906 current_ir_graph = rem;
909 /** Dumps an irg as a graph.
910 * If interprocedural view edges can point to nodes out of this graph.
912 static void dump_graph(ir_graph *irg) {
914 fprintf(F, "graph: { title: \"");
916 fprintf(F, "\" label: \"%s\" status:clustered color:white \n",
917 get_entity_name(get_irg_ent(irg)));
919 dump_block_graph (irg);
921 /* Close the vcg information for the irg */
925 /*******************************************************************/
926 /* Basic type and entity nodes and edges. */
927 /*******************************************************************/
929 /* dumps the edges between nodes and their type or entity attributes. */
930 static void dump_node2type_edges (ir_node *n, void *env)
934 switch (get_irn_opcode(n)) {
936 /* @@@ some consts have an entity */
939 if ( (get_SymConst_kind(n) == type_tag)
940 || (get_SymConst_kind(n) == size))
942 print_node_type_edge(F,n,get_SymConst_type(n),NODE2TYPE_EDGE_ATTR);
946 print_node_ent_edge(F,n,get_Sel_entity(n),NODE2TYPE_EDGE_ATTR);
949 print_node_type_edge(F,n,get_Call_type(n),NODE2TYPE_EDGE_ATTR);
952 print_node_type_edge(F,n,get_Alloc_type(n),NODE2TYPE_EDGE_ATTR);
955 print_node_type_edge(F,n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
958 print_node_type_edge(F,n,get_Cast_type(n),NODE2TYPE_EDGE_ATTR);
966 static void print_type_info(type *tp) {
967 if (get_type_state(tp) == layout_undefined) {
968 fprintf(F, "state: layout_undefined\n");
970 fprintf(F, "state: layout_fixed,\n");
972 if (get_type_mode(tp))
973 fprintf(F, "mode: %s,\n", get_mode_name(get_type_mode(tp)));
974 fprintf(F, "size: %dB,\n", get_type_size(tp));
977 static void print_typespecific_info(type *tp) {
978 switch (get_type_tpop_code(tp)) {
981 fprintf(F, "peculiarity: %s\n", get_peculiarity_string(get_class_peculiarity(tp)));
995 case tpo_enumeration:
1009 static void print_typespecific_vcgattr(type *tp) {
1010 switch (get_type_tpop_code(tp)) {
1013 if (peculiarity_existent == get_class_peculiarity(tp))
1014 fprintf (F, " " TYPE_CLASS_NODE_ATTR);
1016 fprintf (F, " " TYPE_DESCRIPTION_NODE_ATTR);
1020 fprintf (F, " " TYPE_METH_NODE_ATTR);
1031 case tpo_enumeration:
1044 static void print_type_node(type *tp)
1046 fprintf (F, "node: {title: ");
1048 fprintf (F, " label: \"%s %s\"", get_type_tpop_name(tp), get_type_name(tp));
1049 fprintf (F, " info1: \"");
1050 print_type_info(tp);
1051 print_typespecific_info(tp);
1053 print_typespecific_vcgattr(tp);
1057 #define X(a) case a: fprintf(F, #a); break
1058 void dump_entity_node(entity *ent)
1060 fprintf (F, "node: {title: \"");
1061 PRINT_ENTID(ent); fprintf(F, "\"");
1062 fprintf (F, DEFAULT_TYPE_ATTRIBUTE);
1063 fprintf (F, "label: ");
1064 fprintf (F, "\"ent %s\" " ENTITY_NODE_ATTR , get_entity_name(ent));
1065 fprintf (F, "\n info1: \"\nid: "); PRINT_ENTID(ent);
1067 fprintf (F, "\nallocation: ");
1068 switch (get_entity_allocation(ent)) {
1069 X(allocation_dynamic);
1070 X(allocation_automatic);
1071 X(allocation_static);
1072 X(allocation_parameter);
1075 fprintf (F, "\nvisibility: ");
1076 switch (get_entity_visibility(ent)) {
1077 X(visibility_local);
1078 X(visibility_external_visible);
1079 X(visibility_external_allocated);
1082 fprintf (F, "\nvariability: ");
1083 switch (get_entity_variability(ent)) {
1084 X(variability_uninitialized);
1085 X(variability_initialized);
1086 X(variability_part_constant);
1087 X(variability_constant);
1090 fprintf (F, "\nvolatility: ");
1091 switch (get_entity_volatility(ent)) {
1092 X(volatility_non_volatile);
1093 X(volatility_is_volatile);
1096 fprintf(F, "\npeculiarity: %s", get_peculiarity_string(get_entity_peculiarity(ent)));
1097 fprintf(F, "\nname: %s\nld_name: %s",
1098 get_entity_name(ent), ent->ld_name ? get_entity_ld_name(ent) : "no yet set");
1099 fprintf(F, "\noffset: %d", get_entity_offset(ent));
1100 if (is_method_type(get_entity_type(ent))) {
1101 if (get_entity_irg(ent)) /* can be null */
1102 { fprintf (F, "\nirg = "); PRINT_IRGID(get_entity_irg(ent)); }
1104 { fprintf (F, "\nirg = NULL"); }
1106 fprintf(F, "\"\n}\n");
1110 /* dumps a type or entity and it's edges. */
1112 dump_type_info (type_or_ent *tore, void *env) {
1113 int i = 0; /* to shutup gcc */
1115 /* dump this type or entity */
1117 switch (get_kind(tore)) {
1120 entity *ent = (entity *)tore;
1123 dump_entity_node(ent);
1125 /* skip this to reduce graph. Member edge of type is parallel to this edge. *
1126 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1127 ENT_OWN_EDGE_ATTR "}\n", ent, get_entity_owner(ent));*/
1128 print_ent_type_edge(F,ent, get_entity_type(ent), ENT_TYPE_EDGE_ATTR);
1129 if(is_class_type(get_entity_owner(ent))) {
1130 for(i = 0; i < get_entity_n_overwrites(ent); i++){
1131 print_ent_ent_edge(F,ent, get_entity_overwrites(ent, i), ENT_OVERWRITES_EDGE_ATTR);
1134 /* attached subgraphs */
1135 if (const_entities && (get_entity_variability(ent) != variability_uninitialized)) {
1136 if (is_atomic_entity(ent)) {
1137 value = get_atomic_ent_value(ent);
1139 print_ent_node_edge(F,ent, value, ENT_VALUE_EDGE_ATTR, i);
1140 /* DDMN(value); $$$ */
1141 dump_const_expression(value);
1144 if (is_compound_entity(ent)) {
1145 for (i = 0; i < get_compound_ent_n_values(ent); i++) {
1146 value = get_compound_ent_value(ent, i);
1148 print_ent_node_edge(F,ent,value,ENT_VALUE_EDGE_ATTR,i);
1149 dump_const_expression(value);
1150 print_ent_ent_edge(F,ent, get_compound_ent_value_member(ent, i), ENT_CORR_EDGE_ATTR, i);
1152 fprintf (F, "edge: { sourcename: \"%p\" targetname: \"%p\" "
1153 ENT_CORR_EDGE_ATTR "}\n", GET_ENTID(ent),
1154 get_compound_ent_value_member(ent, i), i);
1163 type *tp = (type *)tore;
1164 print_type_node(tp);
1165 /* and now the edges */
1166 switch (get_type_tpop_code(tp)) {
1169 for (i=0; i < get_class_n_supertypes(tp); i++) {
1170 print_type_type_edge(F, tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1173 for (i=0; i < get_class_n_members(tp); i++) {
1174 print_type_ent_edge(F,tp,get_class_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
1179 for (i=0; i < get_struct_n_members(tp); i++) {
1180 print_type_ent_edge(F,tp,get_struct_member(tp, i),TYPE_MEMBER_EDGE_ATTR);
1185 for (i = 0; i < get_method_n_params(tp); i++)
1187 print_type_type_edge(F,tp,get_method_param_type(tp, i),METH_PAR_EDGE_ATTR,i);
1189 for (i = 0; i < get_method_n_ress(tp); i++)
1191 print_type_type_edge(F,tp,get_method_res_type(tp, i),METH_RES_EDGE_ATTR,i);
1196 for (i = 0; i < get_union_n_members(tp); i++)
1198 print_type_ent_edge(F,tp,get_union_member(tp, i),UNION_EDGE_ATTR);
1203 print_type_type_edge(F,tp,get_array_element_type(tp),ARR_ELT_TYPE_EDGE_ATTR);
1204 print_type_ent_edge(F,tp,get_array_element_entity(tp),ARR_ENT_EDGE_ATTR);
1205 for (i = 0; i < get_array_n_dimensions(tp); i++) {
1206 ir_node *upper = get_array_upper_bound(tp, i);
1207 ir_node *lower = get_array_lower_bound(tp, i);
1208 print_node_type_edge(F,upper, tp, "label: \"upper %d\"", get_array_order(tp, i));
1209 print_node_type_edge(F,lower, tp, "label: \"lower %d\"", get_array_order(tp, i));
1210 dump_const_expression(upper);
1211 dump_const_expression(lower);
1215 case tpo_enumeration:
1220 print_type_type_edge(F,tp,get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
1228 break; /* case k_type */
1231 printf(" *** irdump, dump_type_info(l.%i), faulty type.\n", __LINE__);
1233 } /* switch kind_or_entity */
1236 /** For dumping class hierarchies.
1237 * Dumps a class type node and a superclass edge.
1238 * If env != null dumps entities of classes and overwrites edges.
1241 dump_class_hierarchy_node (type_or_ent *tore, void *env) {
1242 int i = 0; /* to shutup gcc */
1244 /* dump this type or entity */
1245 switch (get_kind(tore)) {
1247 entity *ent = (entity *)tore;
1248 if (get_entity_owner(ent) == get_glob_type()) break;
1249 if ((env) && is_class_type(get_entity_owner(ent))) {
1251 dump_entity_node(ent);
1253 print_type_ent_edge(F,get_entity_owner(ent),ent,TYPE_MEMBER_EDGE_ATTR);
1254 for(i = 0; i < get_entity_n_overwrites(ent); i++)
1256 print_ent_ent_edge(F,get_entity_overwrites(ent, i),ent, ENT_OVERWRITES_EDGE_ATTR);
1259 } break; /* case k_entity */
1262 type *tp = (type *)tore;
1263 if (tp == get_glob_type()) break;
1264 switch (get_type_tpop_code(tp)) {
1266 print_type_node(tp);
1267 /* and now the edges */
1268 for (i=0; i < get_class_n_supertypes(tp); i++)
1270 print_type_type_edge(F,tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
1276 break; /* case k_type */
1279 printf(" *** irdump, dump_class_hierarchy_node(l.%i), faulty type.\n", __LINE__);
1281 } /* switch kind_or_entity */
1284 /*******************************************************************/
1285 /* dump analysis information that is expressed in graph terms. */
1286 /*******************************************************************/
1288 /* dump out edges */
1290 dump_out_edge (ir_node *n, void* env) {
1292 for (i = 0; i < get_irn_n_outs(n); i++) {
1293 assert(get_irn_out(n, i));
1294 fprintf (F, "edge: {sourcename: \"");
1296 fprintf (F, "\" targetname: \"");
1297 PRINT_NODEID(get_irn_out(n, i));
1298 fprintf (F, "\" color: red linestyle: dashed");
1304 dump_loop_node_edge (ir_loop *loop, int i) {
1306 fprintf (F, "edge: {sourcename: \"%p\" targetname: \"", (void*) loop);
1307 PRINT_NODEID(get_loop_node(loop, i));
1308 fprintf (F, "\" color: green");
1313 dump_loop_son_edge (ir_loop *loop, int i) {
1315 fprintf (F, "edge: {sourcename: \"%p\" targetname: \"%p\" color: darkgreen}\n",
1316 (void *)loop, (void *)get_loop_son(loop, i));
1320 void dump_loops (ir_loop *loop) {
1322 /* dump this loop node */
1323 fprintf (F, "node: {title: \"%p\" label: \"loop %d, %d sons, %d nodes\" }\n",
1324 (void*)loop, get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop));
1325 /* dump edges to nodes in loop -- only if it is a real loop */
1326 if (get_loop_depth(loop) != 0) {
1327 for (i = 0; i < get_loop_n_nodes(loop); i++) {
1328 dump_loop_node_edge(loop, i);
1331 for (i = 0; i < get_loop_n_sons(loop); i++) {
1332 dump_loops(get_loop_son(loop, i));
1333 dump_loop_son_edge(loop, i);
1338 void dump_loop_info(ir_graph *irg) {
1339 ir_graph *rem = current_ir_graph;
1340 current_ir_graph = irg;
1342 if (get_irg_loop(irg)) dump_loops(get_irg_loop(irg));
1344 current_ir_graph = rem;
1348 /************************************************************************/
1349 /* open and close vcg file */
1350 /************************************************************************/
1353 dump_vcg_header(const char *name) {
1363 "graph: { title: \"ir graph of %s\"\n"
1364 "display_edge_labels: %s\n"
1365 "layoutalgorithm: mindepth\n"
1366 "manhattan_edges: yes\n"
1367 "port_sharing: no\n"
1368 "orientation: bottom_to_top\n"
1369 "classname 1: \"Data\"\n"
1370 "classname 2: \"Block\"\n"
1371 "classname 3: \"Entity type\"\n"
1372 "classname 4: \"Entity owner\"\n"
1373 "classname 5: \"Method Param\"\n"
1374 "classname 6: \"Method Res\"\n"
1375 "classname 7: \"Super\"\n"
1376 "classname 8: \"Union\"\n"
1377 "classname 9: \"Points-to\"\n"
1378 "classname 10: \"Array Element Type\"\n"
1379 "classname 11: \"Overwrites\"\n"
1380 "classname 12: \"Member\"\n",
1383 fprintf (F, "\n"); /* a separator */
1386 static void vcg_open (ir_graph *irg, char *suffix) {
1387 char *fname; /* filename to put the vcg information in */
1392 /** open file for vcg graph */
1393 id = get_irg_dump_name(irg);
1394 len = get_id_strlen (id);
1395 cp = get_id_str (id);
1396 if (dump_file_suffix)
1397 fname = malloc (len + 5 + strlen(suffix) + strlen(dump_file_suffix));
1399 fname = malloc (len + 5 + strlen(suffix));
1400 strncpy (fname, cp, len); /* copy the filename */
1402 if (dump_file_suffix) strcat (fname, dump_file_suffix); /* append file suffix */
1403 strcat (fname, suffix); /* append file suffix */
1404 strcat (fname, ".vcg"); /* append the .vcg suffix */
1405 F = fopen (fname, "w"); /* open file for writing */
1407 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1409 dump_vcg_header(cp);
1412 static void vcg_open_name (const char *name) {
1413 char *fname; /* filename to put the vcg information in */
1416 /** open file for vcg graph */
1418 fname = malloc (len + 5);
1419 if (dump_file_suffix)
1420 fname = malloc (len + 5 + strlen(dump_file_suffix));
1422 fname = malloc (len + 5);
1423 strcpy (fname, name); /* copy the filename */
1424 if (dump_file_suffix) strcat (fname, dump_file_suffix);
1425 strcat (fname, ".vcg"); /* append the .vcg suffix */
1426 F = fopen (fname, "w"); /* open file for writing */
1428 panic ("cannot open %s for writing (%m)", fname); /* not reached */
1431 dump_vcg_header(name);
1436 fprintf (F, "}\n"); /* print footer */
1437 fclose (F); /* close vcg file */
1440 /************************************************************************/
1441 /************************************************************************/
1442 /* Routines that dump all or parts of the firm representation to a file */
1443 /************************************************************************/
1444 /************************************************************************/
1446 /************************************************************************/
1447 /* Dump ir graphs, differnt formats and additional information. */
1448 /************************************************************************/
1450 /** Routine to dump a graph, blocks as conventional nodes.
1453 dump_ir_graph (ir_graph *irg)
1457 rem = current_ir_graph;
1458 current_ir_graph = irg;
1460 if (interprocedural_view) suffix = "-pure-ip";
1461 else suffix = "-pure";
1462 vcg_open (irg, suffix);
1464 /* walk over the graph */
1465 /* dump_whole_node must be called in post visiting predecessors */
1466 irg_walk(get_irg_end(irg), NULL, dump_whole_node, NULL);
1468 /* dump the out edges in a separate walk */
1469 if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != no_outs)) {
1470 irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, NULL);
1475 current_ir_graph = rem;
1480 dump_ir_block_graph (ir_graph *irg)
1485 if (interprocedural_view) suffix = "-ip";
1487 vcg_open (irg, suffix);
1489 construct_block_lists(irg);
1491 for (i = 0; i < get_irp_n_irgs(); i++) {
1492 ir_node **arr = ird_get_irg_link(get_irp_irg(i));
1494 dump_graph(get_irp_irg(i));
1502 /** dumps a graph with type information
1505 dump_ir_graph_w_types (ir_graph *irg)
1507 ir_graph *rem = current_ir_graph;
1509 current_ir_graph = irg;
1511 if (interprocedural_view) suffix = "-pure-wtypes-ip";
1512 else suffix = "-pure-wtypes";
1513 vcg_open (irg, suffix);
1515 /* dump common ir graph */
1516 irg_walk(get_irg_end(irg), NULL, dump_whole_node, NULL);
1517 /* dump type info */
1518 type_walk_irg(irg, dump_type_info, NULL, NULL);
1519 inc_irg_visited(get_const_code_irg());
1520 /* dump edges from graph to type info */
1521 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1524 current_ir_graph = rem;
1528 dump_ir_block_graph_w_types (ir_graph *irg)
1532 ir_graph *rem = current_ir_graph;
1534 if (interprocedural_view) suffix = "-wtypes-ip";
1535 else suffix = "-wtypes";
1536 vcg_open (irg, suffix);
1538 /* dump common blocked ir graph */
1539 construct_block_lists(irg);
1541 for (i = 0; i < get_irp_n_irgs(); i++) {
1542 ir_node **arr = ird_get_irg_link(get_irp_irg(i));
1544 dump_graph(get_irp_irg(i));
1549 /* dump type info */
1550 current_ir_graph = irg;
1551 type_walk_irg(irg, dump_type_info, NULL, NULL);
1552 inc_irg_visited(get_const_code_irg());
1554 /* dump edges from graph to type info */
1555 irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, NULL);
1557 current_ir_graph = rem;
1561 /***********************************************************************/
1562 /* The following routines dump a control flow graph. */
1563 /***********************************************************************/
1566 dump_block_to_cfg (ir_node *block, void *env) {
1570 if (is_Block(block)) {
1571 /* This is a block. Dump a node for the block. */
1572 fprintf (F, "node: {title: \""); PRINT_NODEID(block);
1573 fprintf (F, "\" label: \"%s ", get_op_name(get_irn_op(block)));
1574 PRINT_NODEID(block);
1576 if (dump_dominator_information_flag)
1577 fprintf(F, "info1:dom depth %d", get_Block_dom_depth(block));
1579 /* Dump the edges */
1580 for ( i = 0; i < get_Block_n_cfgpreds(block); i++)
1581 if (get_irn_op(skip_Proj(get_Block_cfgpred(block, i))) != op_Bad) {
1582 pred = get_nodes_block(skip_Proj(get_Block_cfgpred(block, i)));
1583 fprintf (F, "edge: { sourcename: \"");
1584 PRINT_NODEID(block);
1585 fprintf (F, "\" targetname: \"");
1587 fprintf (F, "\"}\n");
1590 /* Dump dominator edge */
1591 if (dump_dominator_information_flag && get_Block_idom(block)) {
1592 pred = get_Block_idom(block);
1593 fprintf (F, "edge: { sourcename: \"");
1594 PRINT_NODEID(block);
1595 fprintf (F, "\" targetname: \"");
1597 fprintf (F, "\" " DOMINATOR_EDGE_ATTR "}\n");
1603 dump_cfg (ir_graph *irg)
1605 ir_graph *rem = current_ir_graph;
1606 int ddif = dump_dominator_information_flag;
1607 int ipv = interprocedural_view;
1608 current_ir_graph = irg;
1609 vcg_open (irg, "-cfg");
1611 if (interprocedural_view) {
1612 printf("Warning: dumping cfg not in interprocedural view!\n");
1613 interprocedural_view = 0;
1616 if (get_irg_dom_state(irg) != dom_consistent)
1617 dump_dominator_information_flag = 0;
1619 /* walk over the blocks in the graph */
1620 irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, NULL);
1621 dump_node (get_irg_bad(irg));
1623 dump_dominator_information_flag = ddif;
1624 interprocedural_view = ipv;
1626 current_ir_graph = rem;
1631 /* Dump all irgs in interprocedural view to a single file. */
1632 void dump_all_cg_block_graph(void) {
1634 int rem_view = interprocedural_view;
1635 interprocedural_view = 1;
1636 vcg_open_name ("All_graphs");
1638 /* collect nodes in all irgs reachable in call graph*/
1639 for (i = 0; i < get_irp_n_irgs(); i++)
1640 ird_set_irg_link(get_irp_irg(i), NULL);
1642 cg_walk(clear_link, collect_node, NULL);
1644 /* dump all graphs */
1645 for (i = 0; i < get_irp_n_irgs(); i++) {
1646 current_ir_graph = get_irp_irg(i);
1647 assert(ird_get_irg_link(current_ir_graph));
1648 dump_graph(current_ir_graph);
1649 DEL_ARR_F(ird_get_irg_link(current_ir_graph));
1653 interprocedural_view = rem_view;
1656 /***********************************************************************/
1657 /* the following routines dumps type information without any ir nodes. */
1658 /***********************************************************************/
1661 dump_type_graph (ir_graph *irg)
1664 rem = current_ir_graph;
1665 current_ir_graph = irg;
1667 vcg_open (irg, "-type");
1669 /* walk over the blocks in the graph */
1670 type_walk_irg(irg, dump_type_info, NULL, NULL);
1671 /* The walker for the const code can be called several times for the
1672 same (sub) experssion. So that no nodes are dumped several times
1673 we decrease the visited flag of the corresponding graph after each
1674 walk. So now increase it finally. */
1675 inc_irg_visited(get_const_code_irg());
1678 current_ir_graph = rem;
1682 dump_all_types (void)
1684 vcg_open_name ("All_types");
1685 type_walk(dump_type_info, NULL, NULL);
1686 inc_irg_visited(get_const_code_irg());
1691 dump_class_hierarchy (bool entities)
1693 vcg_open_name ("class_hierarchy");
1695 type_walk(dump_class_hierarchy_node, NULL, (void *)1);
1697 type_walk(dump_class_hierarchy_node, NULL, NULL);
1701 /***********************************************************************/
1702 /* dumps all graphs with the graph-dumper passed. Possible dumpers: */
1704 /* dump_ir_block_graph */
1706 /* dump_type_graph */
1707 /* dump_ir_graph_w_types */
1708 /***********************************************************************/
1710 void dump_all_ir_graphs (dump_graph_func *dmp_grph) {
1712 for (i=0; i < get_irp_n_irgs(); i++) {
1713 dmp_grph(get_irp_irg(i));