annotate gcc/graph.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
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.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 1998-2020 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)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
55 fatal_error (input_location, "cannot open %s: %m", buf);
111
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
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
60 /* Disable warnings about quoting issues in the pp_xxx calls below
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
61 that (intentionally) don't follow GCC diagnostic conventions. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
62 #if __GNUC__ >= 10
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
63 # pragma GCC diagnostic push
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
64 # pragma GCC diagnostic ignored "-Wformat-diag"
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
65 #endif
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
66
111
kono
parents: 67
diff changeset
67 /* Draw a basic block BB belonging to the function with FUNCDEF_NO
kono
parents: 67
diff changeset
68 as its unique number. */
kono
parents: 67
diff changeset
69 static void
kono
parents: 67
diff changeset
70 draw_cfg_node (pretty_printer *pp, int funcdef_no, basic_block bb)
kono
parents: 67
diff changeset
71 {
kono
parents: 67
diff changeset
72 const char *shape;
kono
parents: 67
diff changeset
73 const char *fillcolor;
kono
parents: 67
diff changeset
74
kono
parents: 67
diff changeset
75 if (bb->index == ENTRY_BLOCK || bb->index == EXIT_BLOCK)
kono
parents: 67
diff changeset
76 {
kono
parents: 67
diff changeset
77 shape = "Mdiamond";
kono
parents: 67
diff changeset
78 fillcolor = "white";
kono
parents: 67
diff changeset
79 }
kono
parents: 67
diff changeset
80 else
kono
parents: 67
diff changeset
81 {
kono
parents: 67
diff changeset
82 shape = "record";
kono
parents: 67
diff changeset
83 fillcolor =
kono
parents: 67
diff changeset
84 BB_PARTITION (bb) == BB_HOT_PARTITION ? "lightpink"
kono
parents: 67
diff changeset
85 : BB_PARTITION (bb) == BB_COLD_PARTITION ? "lightblue"
kono
parents: 67
diff changeset
86 : "lightgrey";
kono
parents: 67
diff changeset
87 }
kono
parents: 67
diff changeset
88
kono
parents: 67
diff changeset
89 pp_printf (pp,
kono
parents: 67
diff changeset
90 "\tfn_%d_basic_block_%d "
kono
parents: 67
diff changeset
91 "[shape=%s,style=filled,fillcolor=%s,label=\"",
kono
parents: 67
diff changeset
92 funcdef_no, bb->index, shape, fillcolor);
kono
parents: 67
diff changeset
93
kono
parents: 67
diff changeset
94 if (bb->index == ENTRY_BLOCK)
kono
parents: 67
diff changeset
95 pp_string (pp, "ENTRY");
kono
parents: 67
diff changeset
96 else if (bb->index == EXIT_BLOCK)
kono
parents: 67
diff changeset
97 pp_string (pp, "EXIT");
kono
parents: 67
diff changeset
98 else
kono
parents: 67
diff changeset
99 {
kono
parents: 67
diff changeset
100 pp_left_brace (pp);
kono
parents: 67
diff changeset
101 pp_write_text_to_stream (pp);
kono
parents: 67
diff changeset
102 dump_bb_for_graph (pp, bb);
kono
parents: 67
diff changeset
103 pp_right_brace (pp);
kono
parents: 67
diff changeset
104 }
kono
parents: 67
diff changeset
105
kono
parents: 67
diff changeset
106 pp_string (pp, "\"];\n\n");
kono
parents: 67
diff changeset
107 pp_flush (pp);
kono
parents: 67
diff changeset
108 }
kono
parents: 67
diff changeset
109
kono
parents: 67
diff changeset
110 /* Draw all successor edges of a basic block BB belonging to the function
kono
parents: 67
diff changeset
111 with FUNCDEF_NO as its unique number. */
kono
parents: 67
diff changeset
112 static void
kono
parents: 67
diff changeset
113 draw_cfg_node_succ_edges (pretty_printer *pp, int funcdef_no, basic_block bb)
kono
parents: 67
diff changeset
114 {
kono
parents: 67
diff changeset
115 edge e;
kono
parents: 67
diff changeset
116 edge_iterator ei;
kono
parents: 67
diff changeset
117 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents: 67
diff changeset
118 {
kono
parents: 67
diff changeset
119 const char *style = "\"solid,bold\"";
kono
parents: 67
diff changeset
120 const char *color = "black";
kono
parents: 67
diff changeset
121 int weight = 10;
kono
parents: 67
diff changeset
122
kono
parents: 67
diff changeset
123 if (e->flags & EDGE_FAKE)
kono
parents: 67
diff changeset
124 {
kono
parents: 67
diff changeset
125 style = "dotted";
kono
parents: 67
diff changeset
126 color = "green";
kono
parents: 67
diff changeset
127 weight = 0;
kono
parents: 67
diff changeset
128 }
kono
parents: 67
diff changeset
129 else if (e->flags & EDGE_DFS_BACK)
kono
parents: 67
diff changeset
130 {
kono
parents: 67
diff changeset
131 style = "\"dotted,bold\"";
kono
parents: 67
diff changeset
132 color = "blue";
kono
parents: 67
diff changeset
133 weight = 10;
kono
parents: 67
diff changeset
134 }
kono
parents: 67
diff changeset
135 else if (e->flags & EDGE_FALLTHRU)
kono
parents: 67
diff changeset
136 {
kono
parents: 67
diff changeset
137 color = "blue";
kono
parents: 67
diff changeset
138 weight = 100;
kono
parents: 67
diff changeset
139 }
kono
parents: 67
diff changeset
140
kono
parents: 67
diff changeset
141 if (e->flags & EDGE_ABNORMAL)
kono
parents: 67
diff changeset
142 color = "red";
kono
parents: 67
diff changeset
143
kono
parents: 67
diff changeset
144 pp_printf (pp,
kono
parents: 67
diff changeset
145 "\tfn_%d_basic_block_%d:s -> fn_%d_basic_block_%d:n "
kono
parents: 67
diff changeset
146 "[style=%s,color=%s,weight=%d,constraint=%s",
kono
parents: 67
diff changeset
147 funcdef_no, e->src->index,
kono
parents: 67
diff changeset
148 funcdef_no, e->dest->index,
kono
parents: 67
diff changeset
149 style, color, weight,
kono
parents: 67
diff changeset
150 (e->flags & (EDGE_FAKE | EDGE_DFS_BACK)) ? "false" : "true");
kono
parents: 67
diff changeset
151 if (e->probability.initialized_p ())
kono
parents: 67
diff changeset
152 pp_printf (pp, ",label=\"[%i%%]\"",
kono
parents: 67
diff changeset
153 e->probability.to_reg_br_prob_base ()
kono
parents: 67
diff changeset
154 * 100 / REG_BR_PROB_BASE);
kono
parents: 67
diff changeset
155 pp_printf (pp, "];\n");
kono
parents: 67
diff changeset
156 }
kono
parents: 67
diff changeset
157 pp_flush (pp);
kono
parents: 67
diff changeset
158 }
kono
parents: 67
diff changeset
159
kono
parents: 67
diff changeset
160 /* Draw all the basic blocks in the CFG in case loops are not available.
kono
parents: 67
diff changeset
161 First compute a topological order of the blocks to get a good ranking of
kono
parents: 67
diff changeset
162 the nodes. Then, if any nodes are not reachable from ENTRY, add them at
kono
parents: 67
diff changeset
163 the end. */
kono
parents: 67
diff changeset
164
kono
parents: 67
diff changeset
165 static void
kono
parents: 67
diff changeset
166 draw_cfg_nodes_no_loops (pretty_printer *pp, struct function *fun)
kono
parents: 67
diff changeset
167 {
kono
parents: 67
diff changeset
168 int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun));
kono
parents: 67
diff changeset
169 int i, n;
kono
parents: 67
diff changeset
170
kono
parents: 67
diff changeset
171 auto_sbitmap visited (last_basic_block_for_fn (cfun));
kono
parents: 67
diff changeset
172 bitmap_clear (visited);
kono
parents: 67
diff changeset
173
kono
parents: 67
diff changeset
174 n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, true);
kono
parents: 67
diff changeset
175 for (i = n_basic_blocks_for_fn (fun) - n;
kono
parents: 67
diff changeset
176 i < n_basic_blocks_for_fn (fun); i++)
kono
parents: 67
diff changeset
177 {
kono
parents: 67
diff changeset
178 basic_block bb = BASIC_BLOCK_FOR_FN (cfun, rpo[i]);
kono
parents: 67
diff changeset
179 draw_cfg_node (pp, fun->funcdef_no, bb);
kono
parents: 67
diff changeset
180 bitmap_set_bit (visited, bb->index);
kono
parents: 67
diff changeset
181 }
kono
parents: 67
diff changeset
182 free (rpo);
kono
parents: 67
diff changeset
183
kono
parents: 67
diff changeset
184 if (n != n_basic_blocks_for_fn (fun))
kono
parents: 67
diff changeset
185 {
kono
parents: 67
diff changeset
186 /* Some blocks are unreachable. We still want to dump them. */
kono
parents: 67
diff changeset
187 basic_block bb;
kono
parents: 67
diff changeset
188 FOR_ALL_BB_FN (bb, fun)
kono
parents: 67
diff changeset
189 if (! bitmap_bit_p (visited, bb->index))
kono
parents: 67
diff changeset
190 draw_cfg_node (pp, fun->funcdef_no, bb);
kono
parents: 67
diff changeset
191 }
kono
parents: 67
diff changeset
192 }
kono
parents: 67
diff changeset
193
kono
parents: 67
diff changeset
194 /* Draw all the basic blocks in LOOP. Print the blocks in breath-first
kono
parents: 67
diff changeset
195 order to get a good ranking of the nodes. This function is recursive:
kono
parents: 67
diff changeset
196 It first prints inner loops, then the body of LOOP itself. */
kono
parents: 67
diff changeset
197
kono
parents: 67
diff changeset
198 static void
kono
parents: 67
diff changeset
199 draw_cfg_nodes_for_loop (pretty_printer *pp, int funcdef_no,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
200 class loop *loop)
111
kono
parents: 67
diff changeset
201 {
kono
parents: 67
diff changeset
202 basic_block *body;
kono
parents: 67
diff changeset
203 unsigned int i;
kono
parents: 67
diff changeset
204 const char *fillcolors[3] = { "grey88", "grey77", "grey66" };
kono
parents: 67
diff changeset
205
kono
parents: 67
diff changeset
206 if (loop->header != NULL
kono
parents: 67
diff changeset
207 && loop->latch != EXIT_BLOCK_PTR_FOR_FN (cfun))
kono
parents: 67
diff changeset
208 pp_printf (pp,
kono
parents: 67
diff changeset
209 "\tsubgraph cluster_%d_%d {\n"
kono
parents: 67
diff changeset
210 "\tstyle=\"filled\";\n"
kono
parents: 67
diff changeset
211 "\tcolor=\"darkgreen\";\n"
kono
parents: 67
diff changeset
212 "\tfillcolor=\"%s\";\n"
kono
parents: 67
diff changeset
213 "\tlabel=\"loop %d\";\n"
kono
parents: 67
diff changeset
214 "\tlabeljust=l;\n"
kono
parents: 67
diff changeset
215 "\tpenwidth=2;\n",
kono
parents: 67
diff changeset
216 funcdef_no, loop->num,
kono
parents: 67
diff changeset
217 fillcolors[(loop_depth (loop) - 1) % 3],
kono
parents: 67
diff changeset
218 loop->num);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
219
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
220 for (class loop *inner = loop->inner; inner; inner = inner->next)
111
kono
parents: 67
diff changeset
221 draw_cfg_nodes_for_loop (pp, funcdef_no, inner);
kono
parents: 67
diff changeset
222
kono
parents: 67
diff changeset
223 if (loop->header == NULL)
kono
parents: 67
diff changeset
224 return;
kono
parents: 67
diff changeset
225
kono
parents: 67
diff changeset
226 if (loop->latch == EXIT_BLOCK_PTR_FOR_FN (cfun))
kono
parents: 67
diff changeset
227 body = get_loop_body (loop);
kono
parents: 67
diff changeset
228 else
kono
parents: 67
diff changeset
229 body = get_loop_body_in_bfs_order (loop);
kono
parents: 67
diff changeset
230
kono
parents: 67
diff changeset
231 for (i = 0; i < loop->num_nodes; i++)
kono
parents: 67
diff changeset
232 {
kono
parents: 67
diff changeset
233 basic_block bb = body[i];
kono
parents: 67
diff changeset
234 if (bb->loop_father == loop)
kono
parents: 67
diff changeset
235 draw_cfg_node (pp, funcdef_no, bb);
kono
parents: 67
diff changeset
236 }
kono
parents: 67
diff changeset
237
kono
parents: 67
diff changeset
238 free (body);
kono
parents: 67
diff changeset
239
kono
parents: 67
diff changeset
240 if (loop->latch != EXIT_BLOCK_PTR_FOR_FN (cfun))
kono
parents: 67
diff changeset
241 pp_printf (pp, "\t}\n");
kono
parents: 67
diff changeset
242 }
kono
parents: 67
diff changeset
243
kono
parents: 67
diff changeset
244 /* Draw all the basic blocks in the CFG in case the loop tree is available.
kono
parents: 67
diff changeset
245 All loop bodys are printed in clusters. */
kono
parents: 67
diff changeset
246
kono
parents: 67
diff changeset
247 static void
kono
parents: 67
diff changeset
248 draw_cfg_nodes (pretty_printer *pp, struct function *fun)
kono
parents: 67
diff changeset
249 {
kono
parents: 67
diff changeset
250 if (loops_for_fn (fun))
kono
parents: 67
diff changeset
251 draw_cfg_nodes_for_loop (pp, fun->funcdef_no, get_loop (fun, 0));
kono
parents: 67
diff changeset
252 else
kono
parents: 67
diff changeset
253 draw_cfg_nodes_no_loops (pp, fun);
kono
parents: 67
diff changeset
254 }
kono
parents: 67
diff changeset
255
kono
parents: 67
diff changeset
256 /* Draw all edges in the CFG. Retreating edges are drawin as not
kono
parents: 67
diff changeset
257 constraining, this makes the layout of the graph better. */
kono
parents: 67
diff changeset
258
kono
parents: 67
diff changeset
259 static void
kono
parents: 67
diff changeset
260 draw_cfg_edges (pretty_printer *pp, struct function *fun)
kono
parents: 67
diff changeset
261 {
kono
parents: 67
diff changeset
262 basic_block bb;
kono
parents: 67
diff changeset
263
kono
parents: 67
diff changeset
264 /* Save EDGE_DFS_BACK flag to dfs_back. */
kono
parents: 67
diff changeset
265 auto_bitmap dfs_back;
kono
parents: 67
diff changeset
266 edge e;
kono
parents: 67
diff changeset
267 edge_iterator ei;
kono
parents: 67
diff changeset
268 unsigned int idx = 0;
kono
parents: 67
diff changeset
269 FOR_EACH_BB_FN (bb, cfun)
kono
parents: 67
diff changeset
270 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents: 67
diff changeset
271 {
kono
parents: 67
diff changeset
272 if (e->flags & EDGE_DFS_BACK)
kono
parents: 67
diff changeset
273 bitmap_set_bit (dfs_back, idx);
kono
parents: 67
diff changeset
274 idx++;
kono
parents: 67
diff changeset
275 }
kono
parents: 67
diff changeset
276
kono
parents: 67
diff changeset
277 mark_dfs_back_edges ();
kono
parents: 67
diff changeset
278 FOR_ALL_BB_FN (bb, cfun)
kono
parents: 67
diff changeset
279 draw_cfg_node_succ_edges (pp, fun->funcdef_no, bb);
kono
parents: 67
diff changeset
280
kono
parents: 67
diff changeset
281 /* Restore EDGE_DFS_BACK flag from dfs_back. */
kono
parents: 67
diff changeset
282 idx = 0;
kono
parents: 67
diff changeset
283 FOR_EACH_BB_FN (bb, cfun)
kono
parents: 67
diff changeset
284 FOR_EACH_EDGE (e, ei, bb->succs)
kono
parents: 67
diff changeset
285 {
kono
parents: 67
diff changeset
286 if (bitmap_bit_p (dfs_back, idx))
kono
parents: 67
diff changeset
287 e->flags |= EDGE_DFS_BACK;
kono
parents: 67
diff changeset
288 else
kono
parents: 67
diff changeset
289 e->flags &= ~EDGE_DFS_BACK;
kono
parents: 67
diff changeset
290 idx++;
kono
parents: 67
diff changeset
291 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
292
111
kono
parents: 67
diff changeset
293 /* Add an invisible edge from ENTRY to EXIT, to improve the graph layout. */
kono
parents: 67
diff changeset
294 pp_printf (pp,
kono
parents: 67
diff changeset
295 "\tfn_%d_basic_block_%d:s -> fn_%d_basic_block_%d:n "
kono
parents: 67
diff changeset
296 "[style=\"invis\",constraint=true];\n",
kono
parents: 67
diff changeset
297 fun->funcdef_no, ENTRY_BLOCK,
kono
parents: 67
diff changeset
298 fun->funcdef_no, EXIT_BLOCK);
kono
parents: 67
diff changeset
299 pp_flush (pp);
kono
parents: 67
diff changeset
300 }
kono
parents: 67
diff changeset
301
kono
parents: 67
diff changeset
302 /* Print a graphical representation of the CFG of function FUN.
kono
parents: 67
diff changeset
303 First print all basic blocks. Draw all edges at the end to get
kono
parents: 67
diff changeset
304 subgraphs right for GraphViz, which requires nodes to be defined
kono
parents: 67
diff changeset
305 before edges to cluster nodes properly. */
kono
parents: 67
diff changeset
306
kono
parents: 67
diff changeset
307 void DEBUG_FUNCTION
kono
parents: 67
diff changeset
308 print_graph_cfg (FILE *fp, struct function *fun)
kono
parents: 67
diff changeset
309 {
kono
parents: 67
diff changeset
310 pretty_printer graph_slim_pp;
kono
parents: 67
diff changeset
311 graph_slim_pp.buffer->stream = fp;
kono
parents: 67
diff changeset
312 pretty_printer *const pp = &graph_slim_pp;
kono
parents: 67
diff changeset
313 const char *funcname = function_name (fun);
kono
parents: 67
diff changeset
314 pp_printf (pp, "subgraph \"cluster_%s\" {\n"
kono
parents: 67
diff changeset
315 "\tstyle=\"dashed\";\n"
kono
parents: 67
diff changeset
316 "\tcolor=\"black\";\n"
kono
parents: 67
diff changeset
317 "\tlabel=\"%s ()\";\n",
kono
parents: 67
diff changeset
318 funcname, funcname);
kono
parents: 67
diff changeset
319 draw_cfg_nodes (pp, fun);
kono
parents: 67
diff changeset
320 draw_cfg_edges (pp, fun);
kono
parents: 67
diff changeset
321 pp_printf (pp, "}\n");
kono
parents: 67
diff changeset
322 pp_flush (pp);
kono
parents: 67
diff changeset
323 }
kono
parents: 67
diff changeset
324
kono
parents: 67
diff changeset
325 /* Overload with additional flag argument. */
kono
parents: 67
diff changeset
326
kono
parents: 67
diff changeset
327 void DEBUG_FUNCTION
kono
parents: 67
diff changeset
328 print_graph_cfg (FILE *fp, struct function *fun, dump_flags_t flags)
kono
parents: 67
diff changeset
329 {
kono
parents: 67
diff changeset
330 dump_flags_t saved_dump_flags = dump_flags;
kono
parents: 67
diff changeset
331 dump_flags = flags;
kono
parents: 67
diff changeset
332 print_graph_cfg (fp, fun);
kono
parents: 67
diff changeset
333 dump_flags = saved_dump_flags;
kono
parents: 67
diff changeset
334 }
kono
parents: 67
diff changeset
335
kono
parents: 67
diff changeset
336
kono
parents: 67
diff changeset
337 /* Print a graphical representation of the CFG of function FUN.
kono
parents: 67
diff changeset
338 First print all basic blocks. Draw all edges at the end to get
kono
parents: 67
diff changeset
339 subgraphs right for GraphViz, which requires nodes to be defined
kono
parents: 67
diff changeset
340 before edges to cluster nodes properly. */
kono
parents: 67
diff changeset
341
kono
parents: 67
diff changeset
342 void
kono
parents: 67
diff changeset
343 print_graph_cfg (const char *base, struct function *fun)
kono
parents: 67
diff changeset
344 {
kono
parents: 67
diff changeset
345 FILE *fp = open_graph_file (base, "a");
kono
parents: 67
diff changeset
346 print_graph_cfg (fp, fun);
kono
parents: 67
diff changeset
347 fclose (fp);
kono
parents: 67
diff changeset
348 }
kono
parents: 67
diff changeset
349
kono
parents: 67
diff changeset
350 /* Start the dump of a graph. */
kono
parents: 67
diff changeset
351 static void
kono
parents: 67
diff changeset
352 start_graph_dump (FILE *fp, const char *base)
kono
parents: 67
diff changeset
353 {
kono
parents: 67
diff changeset
354 pretty_printer graph_slim_pp;
kono
parents: 67
diff changeset
355 graph_slim_pp.buffer->stream = fp;
kono
parents: 67
diff changeset
356 pretty_printer *const pp = &graph_slim_pp;
kono
parents: 67
diff changeset
357 pp_string (pp, "digraph \"");
kono
parents: 67
diff changeset
358 pp_write_text_to_stream (pp);
kono
parents: 67
diff changeset
359 pp_string (pp, base);
kono
parents: 67
diff changeset
360 pp_write_text_as_dot_label_to_stream (pp, /*for_record=*/false);
kono
parents: 67
diff changeset
361 pp_string (pp, "\" {\n");
kono
parents: 67
diff changeset
362 pp_string (pp, "overlap=false;\n");
kono
parents: 67
diff changeset
363 pp_flush (pp);
kono
parents: 67
diff changeset
364 }
kono
parents: 67
diff changeset
365
kono
parents: 67
diff changeset
366 /* End the dump of a graph. */
kono
parents: 67
diff changeset
367 static void
kono
parents: 67
diff changeset
368 end_graph_dump (FILE *fp)
kono
parents: 67
diff changeset
369 {
kono
parents: 67
diff changeset
370 fputs ("}\n", fp);
kono
parents: 67
diff changeset
371 }
kono
parents: 67
diff changeset
372
kono
parents: 67
diff changeset
373 /* Similar as clean_dump_file, but this time for graph output files. */
kono
parents: 67
diff changeset
374 void
kono
parents: 67
diff changeset
375 clean_graph_dump_file (const char *base)
kono
parents: 67
diff changeset
376 {
kono
parents: 67
diff changeset
377 FILE *fp = open_graph_file (base, "w");
kono
parents: 67
diff changeset
378 start_graph_dump (fp, base);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
379 fclose (fp);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
380 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
381
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
382
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
383 /* Do final work on the graph output file. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
384 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
385 finish_graph_dump_file (const char *base)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
386 {
111
kono
parents: 67
diff changeset
387 FILE *fp = open_graph_file (base, "a");
kono
parents: 67
diff changeset
388 end_graph_dump (fp);
kono
parents: 67
diff changeset
389 fclose (fp);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
390 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
391
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
392 #if __GNUC__ >= 10
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
393 # pragma GCC diagnostic pop
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
394 #endif