2 * graph.c: Helper routines to graph various internal states of the code generator
5 * Dietmar Maurer (dietmar@ximian.com)
7 * (C) 2003 Ximian, Inc.
11 #include <mono/utils/mono-compiler.h>
16 #include <mono/metadata/debug-helpers.h>
21 convert_name (const char *str)
23 int i, j, len = strlen (str);
24 char *res = (char *)g_malloc (len * 2);
27 for (i = 0; i < len; i++) {
45 dtree_emit_one_loop_level (MonoCompile *cfg, FILE *fp, MonoBasicBlock *h)
52 fprintf (fp, "subgraph cluster_%d {\n", h->block_num);
53 fprintf (fp, "label=\"loop_%d\"\n", h->block_num);
56 for (i = 1; i < cfg->num_bblocks; ++i) {
57 bb = cfg->bblocks [i];
59 if (!h || (g_list_find (h->loop_blocks, bb) && bb != h)) {
60 if (bb->nesting == level) {
61 fprintf (fp, "BB%d -> BB%d;\n", bb->idom->block_num, bb->block_num);
64 if (bb->nesting == (level + 1) && bb->loop_blocks) {
65 fprintf (fp, "BB%d -> BB%d;\n", bb->idom->block_num, bb->block_num);
66 dtree_emit_one_loop_level (cfg, fp, bb);
77 cfg_emit_one_loop_level (MonoCompile *cfg, FILE *fp, MonoBasicBlock *h)
84 fprintf (fp, "subgraph cluster_%d {\n", h->block_num);
85 fprintf (fp, "label=\"loop_%d\"\n", h->block_num);
88 for (bb = cfg->bb_entry->next_bb; bb; bb = bb->next_bb) {
89 if (bb->region != -1) {
90 switch (bb->region & (MONO_REGION_FINALLY|MONO_REGION_CATCH|MONO_REGION_FAULT|MONO_REGION_FILTER)) {
91 case MONO_REGION_CATCH:
92 fprintf (fp, "BB%d [color=blue];\n", bb->block_num);;
94 case MONO_REGION_FINALLY:
95 fprintf (fp, "BB%d [color=green];\n", bb->block_num);;
97 case MONO_REGION_FAULT:
98 case MONO_REGION_FILTER:
99 fprintf (fp, "BB%d [color=yellow];\n", bb->block_num);;
106 if (!h || (g_list_find (h->loop_blocks, bb) && bb != h)) {
108 if (bb->nesting == level) {
109 for (j = 0; j < bb->in_count; j++)
110 fprintf (fp, "BB%d -> BB%d;\n", bb->in_bb [j]->block_num, bb->block_num);
113 if (bb->nesting == (level + 1) && bb->loop_blocks) {
114 for (j = 0; j < bb->in_count; j++)
115 fprintf (fp, "BB%d -> BB%d;\n", bb->in_bb [j]->block_num, bb->block_num);
116 cfg_emit_one_loop_level (cfg, fp, bb);
127 mono_draw_dtree (MonoCompile *cfg, FILE *fp)
129 g_assert ((cfg->comp_done & MONO_COMP_IDOM));
131 fprintf (fp, "digraph %s {\n", convert_name (cfg->method->name));
132 fprintf (fp, "node [fontsize=12.0]\nedge [len=1,color=red]\n");
133 fprintf (fp, "label=\"Dominator tree for %s\";\n", mono_method_full_name (cfg->method, TRUE));
135 fprintf (fp, "BB0 [shape=doublecircle];\n");
136 fprintf (fp, "BB1 [color=red];\n");
138 dtree_emit_one_loop_level (cfg, fp, NULL);
144 mono_draw_cfg (MonoCompile *cfg, FILE *fp)
146 fprintf (fp, "digraph %s {\n", convert_name (cfg->method->name));
147 fprintf (fp, "node [fontsize=12.0]\nedge [len=1,color=red]\n");
148 fprintf (fp, "label=\"CFG for %s\";\n", mono_method_full_name (cfg->method, TRUE));
150 fprintf (fp, "BB0 [shape=doublecircle];\n");
151 fprintf (fp, "BB1 [color=red];\n");
153 cfg_emit_one_loop_level (cfg, fp, NULL);
159 mono_draw_code_cfg (MonoCompile *cfg, FILE *fp)
163 fprintf (fp, "digraph %s {\n", convert_name (cfg->method->name));
164 fprintf (fp, "node [fontsize=12.0]\nedge [len=1,color=red]\n");
165 fprintf (fp, "label=\"CFG for %s\";\n", mono_method_full_name (cfg->method, TRUE));
167 fprintf (fp, "BB0 [shape=doublecircle];\n");
168 fprintf (fp, "BB1 [color=red];\n");
170 for (bb = cfg->bb_entry->next_bb; bb; bb = bb->next_bb) {
174 if (bb == cfg->bb_exit)
177 if ((cfg->comp_done & MONO_COMP_REACHABILITY) && (bb->flags & BB_REACHABLE))
178 color = "color=red,";
182 fprintf (fp, "BB%d [%sshape=record,labeljust=l,label=\"{BB%d|", bb->block_num, color, bb->block_num);
184 MONO_BB_FOR_EACH_INS (bb, inst) {
185 //mono_print_label (fp, inst);
189 fprintf (fp, "}\"];\n");
192 cfg_emit_one_loop_level (cfg, fp, NULL);
198 mono_draw_graph (MonoCompile *cfg, MonoGraphOptions draw_options)
203 int _i G_GNUC_UNUSED;
205 fn = "/tmp/minidtree.graph";
206 fp = fopen (fn, "w+");
209 switch (draw_options) {
210 case MONO_GRAPH_DTREE:
211 mono_draw_dtree (cfg, fp);
214 mono_draw_cfg (cfg, fp);
216 case MONO_GRAPH_CFG_CODE:
217 case MONO_GRAPH_CFG_OPTCODE:
218 case MONO_GRAPH_CFG_SSA:
219 mono_draw_code_cfg (cfg, fp);
226 //com = g_strdup_printf ("dot %s -Tpng -o %s.png; eog %s.png", fn, fn, fn);
227 com = g_strdup_printf ("dot %s -Tps -o %s.ps;gv %s.ps", fn, fn, fn);
231 g_assert_not_reached ();
235 #else /* !DISABLE_JIT */
237 MONO_EMPTY_SOURCE_FILE (graph);
239 #endif /* !DISABLE_JIT */