3 * Helper routines to graph various internal states of the code generator
6 * Dietmar Maurer (dietmar@ximian.com)
8 * (C) 2003 Ximian, Inc.
12 #include <mono/utils/mono-compiler.h>
17 #include <mono/metadata/debug-helpers.h>
22 convert_name (const char *str)
24 int i, j, len = strlen (str);
25 char *res = (char *)g_malloc (len * 2);
28 for (i = 0; i < len; i++) {
46 dtree_emit_one_loop_level (MonoCompile *cfg, FILE *fp, MonoBasicBlock *h)
53 fprintf (fp, "subgraph cluster_%d {\n", h->block_num);
54 fprintf (fp, "label=\"loop_%d\"\n", h->block_num);
57 for (i = 1; i < cfg->num_bblocks; ++i) {
58 bb = cfg->bblocks [i];
60 if (!h || (g_list_find (h->loop_blocks, bb) && bb != h)) {
61 if (bb->nesting == level) {
62 fprintf (fp, "BB%d -> BB%d;\n", bb->idom->block_num, bb->block_num);
65 if (bb->nesting == (level + 1) && bb->loop_blocks) {
66 fprintf (fp, "BB%d -> BB%d;\n", bb->idom->block_num, bb->block_num);
67 dtree_emit_one_loop_level (cfg, fp, bb);
78 cfg_emit_one_loop_level (MonoCompile *cfg, FILE *fp, MonoBasicBlock *h)
85 fprintf (fp, "subgraph cluster_%d {\n", h->block_num);
86 fprintf (fp, "label=\"loop_%d\"\n", h->block_num);
89 for (bb = cfg->bb_entry->next_bb; bb; bb = bb->next_bb) {
90 if (bb->region != -1) {
91 switch (bb->region & (MONO_REGION_FINALLY|MONO_REGION_CATCH|MONO_REGION_FAULT|MONO_REGION_FILTER)) {
92 case MONO_REGION_CATCH:
93 fprintf (fp, "BB%d [color=blue];\n", bb->block_num);;
95 case MONO_REGION_FINALLY:
96 fprintf (fp, "BB%d [color=green];\n", bb->block_num);;
98 case MONO_REGION_FAULT:
99 case MONO_REGION_FILTER:
100 fprintf (fp, "BB%d [color=yellow];\n", bb->block_num);;
107 if (!h || (g_list_find (h->loop_blocks, bb) && bb != h)) {
109 if (bb->nesting == level) {
110 for (j = 0; j < bb->in_count; j++)
111 fprintf (fp, "BB%d -> BB%d;\n", bb->in_bb [j]->block_num, bb->block_num);
114 if (bb->nesting == (level + 1) && bb->loop_blocks) {
115 for (j = 0; j < bb->in_count; j++)
116 fprintf (fp, "BB%d -> BB%d;\n", bb->in_bb [j]->block_num, bb->block_num);
117 cfg_emit_one_loop_level (cfg, fp, bb);
128 mono_draw_dtree (MonoCompile *cfg, FILE *fp)
130 g_assert ((cfg->comp_done & MONO_COMP_IDOM));
132 fprintf (fp, "digraph %s {\n", convert_name (cfg->method->name));
133 fprintf (fp, "node [fontsize=12.0]\nedge [len=1,color=red]\n");
134 fprintf (fp, "label=\"Dominator tree for %s\";\n", mono_method_full_name (cfg->method, TRUE));
136 fprintf (fp, "BB0 [shape=doublecircle];\n");
137 fprintf (fp, "BB1 [color=red];\n");
139 dtree_emit_one_loop_level (cfg, fp, NULL);
145 mono_draw_cfg (MonoCompile *cfg, FILE *fp)
147 fprintf (fp, "digraph %s {\n", convert_name (cfg->method->name));
148 fprintf (fp, "node [fontsize=12.0]\nedge [len=1,color=red]\n");
149 fprintf (fp, "label=\"CFG for %s\";\n", mono_method_full_name (cfg->method, TRUE));
151 fprintf (fp, "BB0 [shape=doublecircle];\n");
152 fprintf (fp, "BB1 [color=red];\n");
154 cfg_emit_one_loop_level (cfg, fp, NULL);
160 mono_draw_code_cfg (MonoCompile *cfg, FILE *fp)
164 fprintf (fp, "digraph %s {\n", convert_name (cfg->method->name));
165 fprintf (fp, "node [fontsize=12.0]\nedge [len=1,color=red]\n");
166 fprintf (fp, "label=\"CFG for %s\";\n", mono_method_full_name (cfg->method, TRUE));
168 fprintf (fp, "BB0 [shape=doublecircle];\n");
169 fprintf (fp, "BB1 [color=red];\n");
171 for (bb = cfg->bb_entry->next_bb; bb; bb = bb->next_bb) {
175 if (bb == cfg->bb_exit)
178 if ((cfg->comp_done & MONO_COMP_REACHABILITY) && (bb->flags & BB_REACHABLE))
179 color = "color=red,";
183 fprintf (fp, "BB%d [%sshape=record,labeljust=l,label=\"{BB%d|", bb->block_num, color, bb->block_num);
185 MONO_BB_FOR_EACH_INS (bb, inst) {
186 //mono_print_label (fp, inst);
190 fprintf (fp, "}\"];\n");
193 cfg_emit_one_loop_level (cfg, fp, NULL);
199 mono_draw_graph (MonoCompile *cfg, MonoGraphOptions draw_options)
204 int _i G_GNUC_UNUSED;
206 fn = "/tmp/minidtree.graph";
207 fp = fopen (fn, "w+");
210 switch (draw_options) {
211 case MONO_GRAPH_DTREE:
212 mono_draw_dtree (cfg, fp);
215 mono_draw_cfg (cfg, fp);
217 case MONO_GRAPH_CFG_CODE:
218 case MONO_GRAPH_CFG_OPTCODE:
219 case MONO_GRAPH_CFG_SSA:
220 mono_draw_code_cfg (cfg, fp);
227 //com = g_strdup_printf ("dot %s -Tpng -o %s.png; eog %s.png", fn, fn, fn);
228 com = g_strdup_printf ("dot %s -Tps -o %s.ps;gv %s.ps", fn, fn, fn);
232 g_assert_not_reached ();
236 #else /* !DISABLE_JIT */
238 MONO_EMPTY_SOURCE_FILE (graph);
240 #endif /* !DISABLE_JIT */