annotate gcc/graph.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 /* Output routines for graphical representation.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 Copyright (C) 1998-2018 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
111
kono
parents: 67
diff changeset
4 Rewritten for DOT output by Steven Bosscher, 2012.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 GCC is free software; you can redistribute it and/or modify it under
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 the terms of the GNU General Public License as published by the Free
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 Software Foundation; either version 3, or (at your option) any later
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
22 #include "config.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 #include "coretypes.h"
111
kono
parents: 67
diff changeset
25 #include "backend.h"
kono
parents: 67
diff changeset
26 #include "cfghooks.h"
kono
parents: 67
diff changeset
27 #include "pretty-print.h"
kono
parents: 67
diff changeset
28 #include "diagnostic-core.h" /* for fatal_error */
kono
parents: 67
diff changeset
29 #include "cfganal.h"
kono
parents: 67
diff changeset
30 #include "cfgloop.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 #include "graph.h"
111
kono
parents: 67
diff changeset
32 #include "dumpfile.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33
111
kono
parents: 67
diff changeset
34 /* DOT files with the .dot extension are recognized as document templates
kono
parents: 67
diff changeset
35 by a well-known piece of word processing software out of Redmond, WA.
kono
parents: 67
diff changeset
36 Therefore some recommend using the .gv extension instead. Obstinately
kono
parents: 67
diff changeset
37 ignore that recommendation... */
kono
parents: 67
diff changeset
38 static const char *const graph_ext = ".dot";
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39
111
kono
parents: 67
diff changeset
40 /* Open a file with MODE for dumping our graph to.
kono
parents: 67
diff changeset
41 Return the file pointer. */
kono
parents: 67
diff changeset
42 static FILE *
kono
parents: 67
diff changeset
43 open_graph_file (const char *base, const char *mode)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 size_t namelen = strlen (base);
111
kono
parents: 67
diff changeset
46 size_t extlen = strlen (graph_ext) + 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 char *buf = XALLOCAVEC (char, namelen + extlen);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 FILE *fp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 memcpy (buf, base, namelen);
111
kono
parents: 67
diff changeset
51 memcpy (buf + namelen, graph_ext, extlen);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52
111
kono
parents: 67
diff changeset
53 fp = fopen (buf, mode);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 if (fp == NULL)
111
kono
parents: 67
diff changeset
55 fatal_error (input_location, "can%'t open %s: %m", buf);
kono
parents: 67
diff changeset
56
kono
parents: 67
diff changeset
57 return fp;
kono
parents: 67
diff changeset
58 }
kono
parents: 67
diff changeset
59
kono
parents: 67
diff changeset
60 /* Draw a basic block BB belonging to the function with FUNCDEF_NO
kono
parents: 67
diff changeset
61 as its unique number. */
kono
parents: 67
diff changeset
62 static void
kono
parents: 67
diff changeset
63 draw_cfg_node (pretty_printer *pp, int funcdef_no, basic_block bb)
kono
parents: 67
diff changeset
64 {
kono
parents: 67
diff changeset
65 const char *shape;
kono
parents: 67
diff changeset
66 const char *fillcolor;
kono
parents: 67
diff changeset
67
kono
parents: 67
diff changeset
68 if (bb->index == ENTRY_BLOCK || bb->index == EXIT_BLOCK)
kono
parents: 67
diff changeset
69 {
kono
parents: 67
diff changeset
70 shape = "Mdiamond";
kono
parents: 67
diff changeset
71 fillcolor = "white";
kono
parents: 67
diff changeset
72 }
kono
parents: 67
diff changeset
73 else
kono
parents: 67
diff changeset
74 {
kono
parents: 67
diff changeset
75 shape = "record";
kono
parents: 67
diff changeset
76 fillcolor =
kono
parents: 67
diff changeset
77 BB_PARTITION (bb) == BB_HOT_PARTITION ? "lightpink"
kono
parents: 67
diff changeset
78 : BB_PARTITION (bb) == BB_COLD_PARTITION ? "lightblue"
kono
parents: 67
diff changeset
79 : "lightgrey";
kono
parents: 67
diff changeset
80 }
kono
parents: 67
diff changeset
81
kono
parents: 67
diff changeset
82 pp_printf (pp,
kono
parents: 67
diff changeset
83 "\tfn_%d_basic_block_%d "
kono
parents: 67
diff changeset
84 "[shape=%s,style=filled,fillcolor=%s,label=\"",
kono
parents: 67
diff changeset
85 funcdef_no, bb->index, shape, fillcolor);
kono
parents: 67
diff changeset
86
kono
parents: 67
diff changeset
87 if (bb->index == ENTRY_BLOCK)
kono
parents: 67
diff changeset
88 pp_string (pp, "ENTRY");
kono
parents: 67
diff changeset
89 else if (bb->index == EXIT_BLOCK)
kono
parents: 67
diff changeset
90 pp_string (pp, "EXIT");
kono
parents: 67
diff changeset
91 else
kono
parents: 67
diff changeset
92 {
kono
parents: 67
diff changeset
93 pp_left_brace (pp);
kono
parents: 67
diff changeset
94 pp_write_text_to_stream (pp);
kono
parents: 67
diff changeset
95 dump_bb_for_graph (pp, bb);
kono
parents: 67
diff changeset
96 pp_right_brace (pp);
kono
parents: 67
diff changeset
97 }
kono
parents: 67
diff changeset
98
kono
parents: 67
diff changeset
99 pp_string (pp, "\"];\n\n");
kono
parents: 67
diff changeset
100 pp_flush (pp);
kono
parents: 67
diff changeset
101 }
kono
parents: 67
diff changeset
102
kono
parents: 67
diff changeset
103 /* Draw all successor edges of a basic block BB belonging to the function
kono
parents: 67
diff changeset
104 with FUNCDEF_NO as its unique number. */
kono
parents: 67
diff changeset
105 static void
kono
parents: 67
diff changeset
106 draw_cfg_node_succ_edges (pretty_printer *pp, int funcdef_no, basic_block bb)
kono
parents: 67
diff changeset
107 {
kono
parents: 67
diff changeset
108 edge e;
kono
parents: 67
diff changeset
109 edge_iterator ei;
kono
parents: 67
diff changeset
110 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents: 67
diff changeset
111 {
kono
parents: 67
diff changeset
112 const char *style = "\"solid,bold\"";
kono
parents: 67
diff changeset
113 const char *color = "black";
kono
parents: 67
diff changeset
114 int weight = 10;
kono
parents: 67
diff changeset
115
kono
parents: 67
diff changeset
116 if (e->flags & EDGE_FAKE)
kono
parents: 67
diff changeset
117 {
kono
parents: 67
diff changeset
118 style = "dotted";
kono
parents: 67
diff changeset
119 color = "green";
kono
parents: 67
diff changeset
120 weight = 0;
kono
parents: 67
diff changeset
121 }
kono
parents: 67
diff changeset
122 else if (e->flags & EDGE_DFS_BACK)
kono
parents: 67
diff changeset
123 {
kono
parents: 67
diff changeset
124 style = "\"dotted,bold\"";
kono
parents: 67
diff changeset
125 color = "blue";
kono
parents: 67
diff changeset
126 weight = 10;
kono
parents: 67
diff changeset
127 }
kono
parents: 67
diff changeset
128 else if (e->flags & EDGE_FALLTHRU)
kono
parents: 67
diff changeset
129 {
kono
parents: 67
diff changeset
130 color = "blue";
kono
parents: 67
diff changeset
131 weight = 100;
kono
parents: 67
diff changeset
132 }
kono
parents: 67
diff changeset
133
kono
parents: 67
diff changeset
134 if (e->flags & EDGE_ABNORMAL)
kono
parents: 67
diff changeset
135 color = "red";
kono
parents: 67
diff changeset
136
kono
parents: 67
diff changeset
137 pp_printf (pp,
kono
parents: 67
diff changeset
138 "\tfn_%d_basic_block_%d:s -> fn_%d_basic_block_%d:n "
kono
parents: 67
diff changeset
139 "[style=%s,color=%s,weight=%d,constraint=%s",
kono
parents: 67
diff changeset
140 funcdef_no, e->src->index,
kono
parents: 67
diff changeset
141 funcdef_no, e->dest->index,
kono
parents: 67
diff changeset
142 style, color, weight,
kono
parents: 67
diff changeset
143 (e->flags & (EDGE_FAKE | EDGE_DFS_BACK)) ? "false" : "true");
kono
parents: 67
diff changeset
144 if (e->probability.initialized_p ())
kono
parents: 67
diff changeset
145 pp_printf (pp, ",label=\"[%i%%]\"",
kono
parents: 67
diff changeset
146 e->probability.to_reg_br_prob_base ()
kono
parents: 67
diff changeset
147 * 100 / REG_BR_PROB_BASE);
kono
parents: 67
diff changeset
148 pp_printf (pp, "];\n");
kono
parents: 67
diff changeset
149 }
kono
parents: 67
diff changeset
150 pp_flush (pp);
kono
parents: 67
diff changeset
151 }
kono
parents: 67
diff changeset
152
kono
parents: 67
diff changeset
153 /* Draw all the basic blocks in the CFG in case loops are not available.
kono
parents: 67
diff changeset
154 First compute a topological order of the blocks to get a good ranking of
kono
parents: 67
diff changeset
155 the nodes. Then, if any nodes are not reachable from ENTRY, add them at
kono
parents: 67
diff changeset
156 the end. */
kono
parents: 67
diff changeset
157
kono
parents: 67
diff changeset
158 static void
kono
parents: 67
diff changeset
159 draw_cfg_nodes_no_loops (pretty_printer *pp, struct function *fun)
kono
parents: 67
diff changeset
160 {
kono
parents: 67
diff changeset
161 int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun));
kono
parents: 67
diff changeset
162 int i, n;
kono
parents: 67
diff changeset
163
kono
parents: 67
diff changeset
164 auto_sbitmap visited (last_basic_block_for_fn (cfun));
kono
parents: 67
diff changeset
165 bitmap_clear (visited);
kono
parents: 67
diff changeset
166
kono
parents: 67
diff changeset
167 n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, true);
kono
parents: 67
diff changeset
168 for (i = n_basic_blocks_for_fn (fun) - n;
kono
parents: 67
diff changeset
169 i < n_basic_blocks_for_fn (fun); i++)
kono
parents: 67
diff changeset
170 {
kono
parents: 67
diff changeset
171 basic_block bb = BASIC_BLOCK_FOR_FN (cfun, rpo[i]);
kono
parents: 67
diff changeset
172 draw_cfg_node (pp, fun->funcdef_no, bb);
kono
parents: 67
diff changeset
173 bitmap_set_bit (visited, bb->index);
kono
parents: 67
diff changeset
174 }
kono
parents: 67
diff changeset
175 free (rpo);
kono
parents: 67
diff changeset
176
kono
parents: 67
diff changeset
177 if (n != n_basic_blocks_for_fn (fun))
kono
parents: 67
diff changeset
178 {
kono
parents: 67
diff changeset
179 /* Some blocks are unreachable. We still want to dump them. */
kono
parents: 67
diff changeset
180 basic_block bb;
kono
parents: 67
diff changeset
181 FOR_ALL_BB_FN (bb, fun)
kono
parents: 67
diff changeset
182 if (! bitmap_bit_p (visited, bb->index))
kono
parents: 67
diff changeset
183 draw_cfg_node (pp, fun->funcdef_no, bb);
kono
parents: 67
diff changeset
184 }
kono
parents: 67
diff changeset
185 }
kono
parents: 67
diff changeset
186
kono
parents: 67
diff changeset
187 /* Draw all the basic blocks in LOOP. Print the blocks in breath-first
kono
parents: 67
diff changeset
188 order to get a good ranking of the nodes. This function is recursive:
kono
parents: 67
diff changeset
189 It first prints inner loops, then the body of LOOP itself. */
kono
parents: 67
diff changeset
190
kono
parents: 67
diff changeset
191 static void
kono
parents: 67
diff changeset
192 draw_cfg_nodes_for_loop (pretty_printer *pp, int funcdef_no,
kono
parents: 67
diff changeset
193 struct loop *loop)
kono
parents: 67
diff changeset
194 {
kono
parents: 67
diff changeset
195 basic_block *body;
kono
parents: 67
diff changeset
196 unsigned int i;
kono
parents: 67
diff changeset
197 const char *fillcolors[3] = { "grey88", "grey77", "grey66" };
kono
parents: 67
diff changeset
198
kono
parents: 67
diff changeset
199 if (loop->header != NULL
kono
parents: 67
diff changeset
200 && loop->latch != EXIT_BLOCK_PTR_FOR_FN (cfun))
kono
parents: 67
diff changeset
201 pp_printf (pp,
kono
parents: 67
diff changeset
202 "\tsubgraph cluster_%d_%d {\n"
kono
parents: 67
diff changeset
203 "\tstyle=\"filled\";\n"
kono
parents: 67
diff changeset
204 "\tcolor=\"darkgreen\";\n"
kono
parents: 67
diff changeset
205 "\tfillcolor=\"%s\";\n"
kono
parents: 67
diff changeset
206 "\tlabel=\"loop %d\";\n"
kono
parents: 67
diff changeset
207 "\tlabeljust=l;\n"
kono
parents: 67
diff changeset
208 "\tpenwidth=2;\n",
kono
parents: 67
diff changeset
209 funcdef_no, loop->num,
kono
parents: 67
diff changeset
210 fillcolors[(loop_depth (loop) - 1) % 3],
kono
parents: 67
diff changeset
211 loop->num);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
212
111
kono
parents: 67
diff changeset
213 for (struct loop *inner = loop->inner; inner; inner = inner->next)
kono
parents: 67
diff changeset
214 draw_cfg_nodes_for_loop (pp, funcdef_no, inner);
kono
parents: 67
diff changeset
215
kono
parents: 67
diff changeset
216 if (loop->header == NULL)
kono
parents: 67
diff changeset
217 return;
kono
parents: 67
diff changeset
218
kono
parents: 67
diff changeset
219 if (loop->latch == EXIT_BLOCK_PTR_FOR_FN (cfun))
kono
parents: 67
diff changeset
220 body = get_loop_body (loop);
kono
parents: 67
diff changeset
221 else
kono
parents: 67
diff changeset
222 body = get_loop_body_in_bfs_order (loop);
kono
parents: 67
diff changeset
223
kono
parents: 67
diff changeset
224 for (i = 0; i < loop->num_nodes; i++)
kono
parents: 67
diff changeset
225 {
kono
parents: 67
diff changeset
226 basic_block bb = body[i];
kono
parents: 67
diff changeset
227 if (bb->loop_father == loop)
kono
parents: 67
diff changeset
228 draw_cfg_node (pp, funcdef_no, bb);
kono
parents: 67
diff changeset
229 }
kono
parents: 67
diff changeset
230
kono
parents: 67
diff changeset
231 free (body);
kono
parents: 67
diff changeset
232
kono
parents: 67
diff changeset
233 if (loop->latch != EXIT_BLOCK_PTR_FOR_FN (cfun))
kono
parents: 67
diff changeset
234 pp_printf (pp, "\t}\n");
kono
parents: 67
diff changeset
235 }
kono
parents: 67
diff changeset
236
kono
parents: 67
diff changeset
237 /* Draw all the basic blocks in the CFG in case the loop tree is available.
kono
parents: 67
diff changeset
238 All loop bodys are printed in clusters. */
kono
parents: 67
diff changeset
239
kono
parents: 67
diff changeset
240 static void
kono
parents: 67
diff changeset
241 draw_cfg_nodes (pretty_printer *pp, struct function *fun)
kono
parents: 67
diff changeset
242 {
kono
parents: 67
diff changeset
243 if (loops_for_fn (fun))
kono
parents: 67
diff changeset
244 draw_cfg_nodes_for_loop (pp, fun->funcdef_no, get_loop (fun, 0));
kono
parents: 67
diff changeset
245 else
kono
parents: 67
diff changeset
246 draw_cfg_nodes_no_loops (pp, fun);
kono
parents: 67
diff changeset
247 }
kono
parents: 67
diff changeset
248
kono
parents: 67
diff changeset
249 /* Draw all edges in the CFG. Retreating edges are drawin as not
kono
parents: 67
diff changeset
250 constraining, this makes the layout of the graph better. */
kono
parents: 67
diff changeset
251
kono
parents: 67
diff changeset
252 static void
kono
parents: 67
diff changeset
253 draw_cfg_edges (pretty_printer *pp, struct function *fun)
kono
parents: 67
diff changeset
254 {
kono
parents: 67
diff changeset
255 basic_block bb;
kono
parents: 67
diff changeset
256
kono
parents: 67
diff changeset
257 /* Save EDGE_DFS_BACK flag to dfs_back. */
kono
parents: 67
diff changeset
258 auto_bitmap dfs_back;
kono
parents: 67
diff changeset
259 edge e;
kono
parents: 67
diff changeset
260 edge_iterator ei;
kono
parents: 67
diff changeset
261 unsigned int idx = 0;
kono
parents: 67
diff changeset
262 FOR_EACH_BB_FN (bb, cfun)
kono
parents: 67
diff changeset
263 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents: 67
diff changeset
264 {
kono
parents: 67
diff changeset
265 if (e->flags & EDGE_DFS_BACK)
kono
parents: 67
diff changeset
266 bitmap_set_bit (dfs_back, idx);
kono
parents: 67
diff changeset
267 idx++;
kono
parents: 67
diff changeset
268 }
kono
parents: 67
diff changeset
269
kono
parents: 67
diff changeset
270 mark_dfs_back_edges ();
kono
parents: 67
diff changeset
271 FOR_ALL_BB_FN (bb, cfun)
kono
parents: 67
diff changeset
272 draw_cfg_node_succ_edges (pp, fun->funcdef_no, bb);
kono
parents: 67
diff changeset
273
kono
parents: 67
diff changeset
274 /* Restore EDGE_DFS_BACK flag from dfs_back. */
kono
parents: 67
diff changeset
275 idx = 0;
kono
parents: 67
diff changeset
276 FOR_EACH_BB_FN (bb, cfun)
kono
parents: 67
diff changeset
277 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents: 67
diff changeset
278 {
kono
parents: 67
diff changeset
279 if (bitmap_bit_p (dfs_back, idx))
kono
parents: 67
diff changeset
280 e->flags |= EDGE_DFS_BACK;
kono
parents: 67
diff changeset
281 else
kono
parents: 67
diff changeset
282 e->flags &= ~EDGE_DFS_BACK;
kono
parents: 67
diff changeset
283 idx++;
kono
parents: 67
diff changeset
284 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
285
111
kono
parents: 67
diff changeset
286 /* Add an invisible edge from ENTRY to EXIT, to improve the graph layout. */
kono
parents: 67
diff changeset
287 pp_printf (pp,
kono
parents: 67
diff changeset
288 "\tfn_%d_basic_block_%d:s -> fn_%d_basic_block_%d:n "
kono
parents: 67
diff changeset
289 "[style=\"invis\",constraint=true];\n",
kono
parents: 67
diff changeset
290 fun->funcdef_no, ENTRY_BLOCK,
kono
parents: 67
diff changeset
291 fun->funcdef_no, EXIT_BLOCK);
kono
parents: 67
diff changeset
292 pp_flush (pp);
kono
parents: 67
diff changeset
293 }
kono
parents: 67
diff changeset
294
kono
parents: 67
diff changeset
295 /* Print a graphical representation of the CFG of function FUN.
kono
parents: 67
diff changeset
296 First print all basic blocks. Draw all edges at the end to get
kono
parents: 67
diff changeset
297 subgraphs right for GraphViz, which requires nodes to be defined
kono
parents: 67
diff changeset
298 before edges to cluster nodes properly. */
kono
parents: 67
diff changeset
299
kono
parents: 67
diff changeset
300 void DEBUG_FUNCTION
kono
parents: 67
diff changeset
301 print_graph_cfg (FILE *fp, struct function *fun)
kono
parents: 67
diff changeset
302 {
kono
parents: 67
diff changeset
303 pretty_printer graph_slim_pp;
kono
parents: 67
diff changeset
304 graph_slim_pp.buffer->stream = fp;
kono
parents: 67
diff changeset
305 pretty_printer *const pp = &graph_slim_pp;
kono
parents: 67
diff changeset
306 const char *funcname = function_name (fun);
kono
parents: 67
diff changeset
307 pp_printf (pp, "subgraph \"cluster_%s\" {\n"
kono
parents: 67
diff changeset
308 "\tstyle=\"dashed\";\n"
kono
parents: 67
diff changeset
309 "\tcolor=\"black\";\n"
kono
parents: 67
diff changeset
310 "\tlabel=\"%s ()\";\n",
kono
parents: 67
diff changeset
311 funcname, funcname);
kono
parents: 67
diff changeset
312 draw_cfg_nodes (pp, fun);
kono
parents: 67
diff changeset
313 draw_cfg_edges (pp, fun);
kono
parents: 67
diff changeset
314 pp_printf (pp, "}\n");
kono
parents: 67
diff changeset
315 pp_flush (pp);
kono
parents: 67
diff changeset
316 }
kono
parents: 67
diff changeset
317
kono
parents: 67
diff changeset
318 /* Overload with additional flag argument. */
kono
parents: 67
diff changeset
319
kono
parents: 67
diff changeset
320 void DEBUG_FUNCTION
kono
parents: 67
diff changeset
321 print_graph_cfg (FILE *fp, struct function *fun, dump_flags_t flags)
kono
parents: 67
diff changeset
322 {
kono
parents: 67
diff changeset
323 dump_flags_t saved_dump_flags = dump_flags;
kono
parents: 67
diff changeset
324 dump_flags = flags;
kono
parents: 67
diff changeset
325 print_graph_cfg (fp, fun);
kono
parents: 67
diff changeset
326 dump_flags = saved_dump_flags;
kono
parents: 67
diff changeset
327 }
kono
parents: 67
diff changeset
328
kono
parents: 67
diff changeset
329
kono
parents: 67
diff changeset
330 /* Print a graphical representation of the CFG of function FUN.
kono
parents: 67
diff changeset
331 First print all basic blocks. Draw all edges at the end to get
kono
parents: 67
diff changeset
332 subgraphs right for GraphViz, which requires nodes to be defined
kono
parents: 67
diff changeset
333 before edges to cluster nodes properly. */
kono
parents: 67
diff changeset
334
kono
parents: 67
diff changeset
335 void
kono
parents: 67
diff changeset
336 print_graph_cfg (const char *base, struct function *fun)
kono
parents: 67
diff changeset
337 {
kono
parents: 67
diff changeset
338 FILE *fp = open_graph_file (base, "a");
kono
parents: 67
diff changeset
339 print_graph_cfg (fp, fun);
kono
parents: 67
diff changeset
340 fclose (fp);
kono
parents: 67
diff changeset
341 }
kono
parents: 67
diff changeset
342
kono
parents: 67
diff changeset
343 /* Start the dump of a graph. */
kono
parents: 67
diff changeset
344 static void
kono
parents: 67
diff changeset
345 start_graph_dump (FILE *fp, const char *base)
kono
parents: 67
diff changeset
346 {
kono
parents: 67
diff changeset
347 pretty_printer graph_slim_pp;
kono
parents: 67
diff changeset
348 graph_slim_pp.buffer->stream = fp;
kono
parents: 67
diff changeset
349 pretty_printer *const pp = &graph_slim_pp;
kono
parents: 67
diff changeset
350 pp_string (pp, "digraph \"");
kono
parents: 67
diff changeset
351 pp_write_text_to_stream (pp);
kono
parents: 67
diff changeset
352 pp_string (pp, base);
kono
parents: 67
diff changeset
353 pp_write_text_as_dot_label_to_stream (pp, /*for_record=*/false);
kono
parents: 67
diff changeset
354 pp_string (pp, "\" {\n");
kono
parents: 67
diff changeset
355 pp_string (pp, "overlap=false;\n");
kono
parents: 67
diff changeset
356 pp_flush (pp);
kono
parents: 67
diff changeset
357 }
kono
parents: 67
diff changeset
358
kono
parents: 67
diff changeset
359 /* End the dump of a graph. */
kono
parents: 67
diff changeset
360 static void
kono
parents: 67
diff changeset
361 end_graph_dump (FILE *fp)
kono
parents: 67
diff changeset
362 {
kono
parents: 67
diff changeset
363 fputs ("}\n", fp);
kono
parents: 67
diff changeset
364 }
kono
parents: 67
diff changeset
365
kono
parents: 67
diff changeset
366 /* Similar as clean_dump_file, but this time for graph output files. */
kono
parents: 67
diff changeset
367 void
kono
parents: 67
diff changeset
368 clean_graph_dump_file (const char *base)
kono
parents: 67
diff changeset
369 {
kono
parents: 67
diff changeset
370 FILE *fp = open_graph_file (base, "w");
kono
parents: 67
diff changeset
371 start_graph_dump (fp, base);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
372 fclose (fp);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
373 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
374
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
375
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
376 /* Do final work on the graph output file. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
377 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
378 finish_graph_dump_file (const char *base)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
379 {
111
kono
parents: 67
diff changeset
380 FILE *fp = open_graph_file (base, "a");
kono
parents: 67
diff changeset
381 end_graph_dump (fp);
kono
parents: 67
diff changeset
382 fclose (fp);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
383 }