]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/lto/lto-dump.c
e9de33cf5d81227a3d5f08dd215150c1bd1fcaf1
[thirdparty/gcc.git] / gcc / lto / lto-dump.c
1 /* Functions for LTO dump tool.
2 Copyright (C) 2018-2019 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "function.h"
25 #include "basic-block.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "cfg.h"
29 #include "tree-cfg.h"
30 #include "tree-pass.h"
31 #include "tree-streamer.h"
32 #include "cgraph.h"
33 #include "opts.h"
34 #include "debug.h"
35 #include "lto-partition.h"
36 #include "tree-pretty-print.h"
37 #include "lto-common.h"
38
39 /* Stores details of symbols for dumping symbol list. */
40
41 struct symbol_entry
42 {
43 symtab_node *node;
44 symbol_entry (symtab_node *node_): node (node_)
45 {}
46
47 virtual ~symbol_entry ()
48 {}
49
50 char* get_name () const
51 {
52 if (flag_lto_dump_demangle)
53 return xstrdup (node->name ());
54 else
55 return xstrdup (node->asm_name ());
56 }
57
58 virtual size_t get_size () const = 0;
59
60 virtual void dump ()
61 {
62 const char *name = get_name ();
63 const char *type_name = node->get_symtab_type_string ();
64 const char *visibility = node->get_visibility_string ();
65 size_t sz = get_size ();
66 printf ("%s %s %4" PRIu64 " %s ", type_name, visibility, (uint64_t) sz,
67 name);
68 }
69 };
70
71 /* Stores variable specific details of symbols for dumping symbol list. */
72
73 struct variable_entry: public symbol_entry
74 {
75 variable_entry (varpool_node *node_): symbol_entry (node_)
76 {}
77
78 virtual ~variable_entry ()
79 {}
80
81 virtual size_t get_size () const
82 {
83 varpool_node *vnode = dyn_cast<varpool_node *> (node);
84 if (DECL_SIZE (vnode->decl) && tree_fits_shwi_p (DECL_SIZE (vnode->decl)))
85 return tree_to_shwi (DECL_SIZE (vnode->decl));
86 return 0;
87 }
88
89 virtual void dump ()
90 {
91 symbol_entry :: dump ();
92 varpool_node *vnode = dyn_cast<varpool_node *> (node);
93 vnode->get_constructor ();
94 tree value_tree = DECL_INITIAL (vnode->decl);
95 if (flag_lto_print_value && value_tree)
96 print_generic_expr (stdout, value_tree, TDF_NONE);
97 printf ("\n");
98 }
99 };
100
101 /* Stores function specific details of symbols for dumping symbol list. */
102
103 struct function_entry: public symbol_entry
104 {
105 function_entry (cgraph_node *node_): symbol_entry (node_)
106 {}
107
108 virtual ~function_entry ()
109 {}
110
111 virtual void dump ()
112 {
113 symbol_entry :: dump ();
114 printf ("\n");
115 }
116
117 virtual size_t get_size () const
118 {
119 cgraph_node *cnode = dyn_cast<cgraph_node *> (node);
120 gcc_assert (cnode);
121
122 return (cnode->definition)
123 ? n_basic_blocks_for_fn (DECL_STRUCT_FUNCTION (cnode->decl))
124 : 0;
125 }
126 };
127
128 /* Comparing symbols based on size. */
129
130 int size_compare (const void *a, const void *b)
131 {
132 const symbol_entry *e1 = *(const symbol_entry * const*) a;
133 const symbol_entry *e2 = *(const symbol_entry * const*) b;
134
135 return e1->get_size () - e2->get_size ();
136 }
137
138 /* Comparing symbols based on name. */
139
140 int name_compare (const void *a, const void *b)
141 {
142 const symbol_entry *e1 = *(const symbol_entry * const*) a;
143 const symbol_entry *e2 = *(const symbol_entry * const*) b;
144
145 return strcmp (e1->get_name (), e2->get_name ());
146 }
147
148 /* Dump list of functions and their details. */
149
150 void dump_list_functions (void)
151 {
152 auto_vec<symbol_entry *> v;
153
154 cgraph_node *cnode;
155 FOR_EACH_FUNCTION (cnode)
156 {
157 if (cnode->definition)
158 cnode->get_untransformed_body ();
159 symbol_entry *e = new function_entry (cnode);
160 if (!flag_lto_dump_defined || cnode->definition)
161 v.safe_push (e);
162 }
163
164 if (flag_lto_size_sort)
165 v.qsort (size_compare);
166 else if (flag_lto_name_sort)
167 v.qsort (name_compare);
168 if (flag_lto_reverse_sort)
169 v.reverse ();
170
171 printf ("Type Visibility Size Name");
172 if (flag_lto_print_value)
173 printf (" Value");
174 printf ("\n");
175 int i=0;
176 symbol_entry* e;
177 FOR_EACH_VEC_ELT (v, i, e)
178 {
179 e->dump ();
180 delete e;
181 }
182 }
183
184 /* Dump list of variables and their details. */
185
186 void dump_list_variables (void)
187 {
188 auto_vec<symbol_entry *> v;
189
190 varpool_node *vnode;
191 FOR_EACH_VARIABLE (vnode)
192 {
193 symbol_entry *e = new variable_entry (vnode);
194 if (!flag_lto_dump_defined || vnode->definition)
195 v.safe_push (e);
196 }
197
198 if (flag_lto_size_sort)
199 v.qsort (size_compare);
200 else if (flag_lto_name_sort)
201 v.qsort (name_compare);
202 if (flag_lto_reverse_sort)
203 v.reverse ();
204
205 printf ("\n");
206 int i=0;
207 symbol_entry* e;
208 FOR_EACH_VEC_ELT (v, i, e)
209 {
210 e->dump ();
211 delete e;
212 }
213 }
214
215 /* Dump symbol list. */
216
217 void dump_list (void)
218 {
219 dump_list_functions ();
220 dump_list_variables ();
221 return;
222 }
223
224 /* Dump specific variables and functions used in IL. */
225 void dump_symbol ()
226 {
227 symtab_node *node;
228 printf ("Symbol: %s\n", flag_lto_dump_symbol);
229 FOR_EACH_SYMBOL (node)
230 {
231 if (!strcmp (flag_lto_dump_symbol, node->name ()))
232 {
233 node->debug ();
234 printf ("\n");
235 }
236 }
237 return;
238 }
239
240 /* Dump specific gimple body of specified function. */
241 void dump_body ()
242 {
243 int flag = 0;
244 dump_flags_t flags = TDF_NONE;
245 if (flag_dump_level)
246 flags = parse_dump_option (flag_dump_level, NULL);
247 if (flags == TDF_ERROR)
248 {
249 error_at (input_location, "Level not found, use none, slim, blocks, vops.");
250 return;
251 }
252 cgraph_node *cnode;
253 FOR_EACH_FUNCTION (cnode)
254 if (cnode->definition && !strcmp (cnode->name (), flag_dump_body))
255 {
256 printf ("Gimple Body of Function: %s\n", cnode->name ());
257 cnode->get_untransformed_body ();
258 debug_function (cnode->decl, flags);
259 flag = 1;
260 }
261 if (!flag)
262 error_at (input_location, "Function not found.");
263 return;
264 }
265
266 /* List of command line options for dumping. */
267 void dump_tool_help ()
268 {
269 printf ("Usage: lto-dump [OPTION]... SUB_COMMAND [OPTION]...\n\n");
270 printf ("LTO dump tool command line options.\n\n");
271 printf (" -list [options] Dump the symbol list.\n");
272 printf (" -demangle Dump the demangled output.\n");
273 printf (" -defined-only Dump only the defined symbols.\n");
274 printf (" -print-value Dump initial values of the "
275 "variables.\n");
276 printf (" -name-sort Sort the symbols alphabetically.\n");
277 printf (" -size-sort Sort the symbols according to size.\n");
278 printf (" -reverse-sort Dump the symbols in reverse order.\n");
279 printf (" -symbol= Dump the details of specific symbol.\n");
280 printf (" -objects Dump the details of LTO objects.\n");
281 printf (" -type-stats Dump statistics of tree types.\n");
282 printf (" -tree-stats Dump statistics of trees.\n");
283 printf (" -gimple-stats Dump statistics of gimple "
284 "statements.\n");
285 printf (" -dump-body= Dump the specific gimple body.\n");
286 printf (" -dump-level= Deciding the optimization level "
287 "of body.\n");
288 printf (" -help Display the dump tool help.\n");
289 return;
290 }
291
292 unsigned int
293 lto_option_lang_mask (void)
294 {
295 return CL_LTODump;
296 }
297
298 /* Functions for dumping various details in LTO dump tool are called
299 in lto_main(). The purpose of this dump tool is to analyze the LTO
300 object files. */
301
302 void
303 lto_main (void)
304 {
305 quiet_flag = true;
306 if (flag_lto_dump_tool_help)
307 dump_tool_help ();
308
309 /* LTO is called as a front end, even though it is not a front end.
310 Because it is called as a front end, TV_PHASE_PARSING and
311 TV_PARSE_GLOBAL are active, and we need to turn them off while
312 doing LTO. Later we turn them back on so they are active up in
313 toplev.c. */
314
315 /* Initialize the LTO front end. */
316 lto_fe_init ();
317 g_timer = NULL;
318 /* Read all the symbols and call graph from all the files in the
319 command line. */
320 read_cgraph_and_symbols (num_in_fnames, in_fnames);
321
322 /* Dump symbol list. */
323 if (flag_lto_dump_list)
324 dump_list ();
325 else if (flag_lto_dump_symbol)
326 {
327 /* Dump specific variables and functions used in IL. */
328 dump_symbol ();
329 }
330 else if (flag_lto_gimple_stats)
331 {
332 /* Dump gimple statement statistics. */
333 cgraph_node *node;
334 FOR_EACH_DEFINED_FUNCTION (node)
335 node->get_untransformed_body ();
336 if (!GATHER_STATISTICS)
337 warning_at (input_location, 0,
338 "Not configured with "
339 "%<--enable-gather-detailed-mem-stats%>.");
340 else
341 dump_gimple_statistics ();
342 }
343 else if (flag_lto_tree_stats)
344 {
345 /* Dump tree statistics. */
346 if (!GATHER_STATISTICS)
347 warning_at (input_location, 0,
348 "Not configured with "
349 "%<--enable-gather-detailed-mem-stats%>.");
350 else
351 {
352 printf ("Tree Statistics\n");
353 dump_tree_statistics ();
354 }
355 }
356 else if (flag_dump_body)
357 {
358 /* Dump specific gimple body of specified function. */
359 dump_body ();
360 return;
361 }
362 }