]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/lto/lto-dump.c
39b442335f6d784ed5635c1dd1a4ff076c718b6c
[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 char* get_name () const
48 {
49 if (flag_lto_dump_demangle)
50 return xstrdup (node->name ());
51 else
52 return xstrdup (node->asm_name ());
53 }
54
55 virtual size_t get_size () const = 0;
56
57 virtual void dump ()
58 {
59 const char *name = get_name ();
60 const char *type_name = node->get_symtab_type_string ();
61 const char *visibility = node->get_visibility_string ();
62 size_t sz = get_size ();
63 printf ("%s %s %4" PRIu64 " %s ", type_name, visibility, (uint64_t) sz,
64 name);
65 }
66 };
67
68 /* Stores variable specific details of symbols for dumping symbol list. */
69
70 struct variable_entry: public symbol_entry
71 {
72 variable_entry (varpool_node *node_): symbol_entry (node_)
73 {}
74
75 virtual size_t get_size () const
76 {
77 varpool_node *vnode = dyn_cast<varpool_node *> (node);
78 if (DECL_SIZE (vnode->decl) && tree_fits_shwi_p (DECL_SIZE (vnode->decl)))
79 return tree_to_shwi (DECL_SIZE (vnode->decl));
80 return 0;
81 }
82
83 virtual void dump ()
84 {
85 symbol_entry :: dump ();
86 varpool_node *vnode = dyn_cast<varpool_node *> (node);
87 vnode->get_constructor ();
88 tree value_tree = DECL_INITIAL (vnode->decl);
89 if (flag_lto_print_value && value_tree)
90 print_generic_expr (stdout, value_tree, TDF_NONE);
91 printf ("\n");
92 }
93 };
94
95 /* Stores function specific details of symbols for dumping symbol list. */
96
97 struct function_entry: public symbol_entry
98 {
99 function_entry (cgraph_node *node_): symbol_entry (node_)
100 {}
101
102 virtual void dump ()
103 {
104 symbol_entry :: dump ();
105 printf ("\n");
106 }
107
108 virtual size_t get_size () const
109 {
110 cgraph_node *cnode = dyn_cast<cgraph_node *> (node);
111 gcc_assert (cnode);
112
113 return (cnode->definition)
114 ? n_basic_blocks_for_fn (DECL_STRUCT_FUNCTION (cnode->decl))
115 : 0;
116 }
117 };
118
119 /* Comparing symbols based on size. */
120
121 int size_compare (const void *a, const void *b)
122 {
123 const symbol_entry *e1 = *(const symbol_entry * const*) a;
124 const symbol_entry *e2 = *(const symbol_entry * const*) b;
125
126 return e1->get_size () - e2->get_size ();
127 }
128
129 /* Comparing symbols based on name. */
130
131 int name_compare (const void *a, const void *b)
132 {
133 const symbol_entry *e1 = *(const symbol_entry * const*) a;
134 const symbol_entry *e2 = *(const symbol_entry * const*) b;
135
136 return strcmp (e1->get_name (), e2->get_name ());
137 }
138
139 /* Dump list of functions and their details. */
140
141 void dump_list_functions (void)
142 {
143 auto_vec<symbol_entry *> v;
144
145 cgraph_node *cnode;
146 FOR_EACH_FUNCTION (cnode)
147 {
148 if (cnode->definition)
149 cnode->get_untransformed_body ();
150 symbol_entry *e = new function_entry (cnode);
151 if (!flag_lto_dump_defined || cnode->definition)
152 v.safe_push (e);
153 }
154
155 if (flag_lto_size_sort)
156 v.qsort (size_compare);
157 else if (flag_lto_name_sort)
158 v.qsort (name_compare);
159 if (flag_lto_reverse_sort)
160 v.reverse ();
161
162 printf ("Type Visibility Size Name");
163 if (flag_lto_print_value)
164 printf (" Value");
165 printf ("\n");
166 int i=0;
167 symbol_entry* e;
168 FOR_EACH_VEC_ELT (v, i, e)
169 e->dump ();
170 }
171
172 /* Dump list of variables and their details. */
173
174 void dump_list_variables (void)
175 {
176 auto_vec<symbol_entry *> v;
177
178 varpool_node *vnode;
179 FOR_EACH_VARIABLE (vnode)
180 {
181 symbol_entry *e = new variable_entry (vnode);
182 if (!flag_lto_dump_defined || vnode->definition)
183 v.safe_push (e);
184 }
185
186 if (flag_lto_size_sort)
187 v.qsort (size_compare);
188 else if (flag_lto_name_sort)
189 v.qsort (name_compare);
190 if (flag_lto_reverse_sort)
191 v.reverse ();
192
193 printf ("\n");
194 int i=0;
195 symbol_entry* e;
196 FOR_EACH_VEC_ELT (v, i, e)
197 e->dump ();
198 }
199
200 /* Dump symbol list. */
201
202 void dump_list (void)
203 {
204 dump_list_functions ();
205 dump_list_variables ();
206 return;
207 }
208
209 /* Dump specific variables and functions used in IL. */
210 void dump_symbol ()
211 {
212 symtab_node *node;
213 printf ("Symbol: %s\n", flag_lto_dump_symbol);
214 FOR_EACH_SYMBOL (node)
215 {
216 if (!strcmp (flag_lto_dump_symbol, node->name ()))
217 {
218 node->debug ();
219 printf ("\n");
220 }
221 }
222 return;
223 }
224
225 /* Dump specific gimple body of specified function. */
226 void dump_body ()
227 {
228 int flag = 0;
229 dump_flags_t flags = TDF_NONE;
230 if (flag_dump_level)
231 flags = parse_dump_option (flag_dump_level, NULL);
232 if (flags == TDF_ERROR)
233 {
234 error_at (input_location, "Level not found, use none, slim, blocks, vops.");
235 return;
236 }
237 cgraph_node *cnode;
238 FOR_EACH_FUNCTION (cnode)
239 if (cnode->definition && !strcmp (cnode->name (), flag_dump_body))
240 {
241 printf ("Gimple Body of Function: %s\n", cnode->name ());
242 cnode->get_untransformed_body ();
243 debug_function (cnode->decl, flags);
244 flag = 1;
245 }
246 if (!flag)
247 error_at (input_location, "Function not found.");
248 return;
249 }
250
251 /* List of command line options for dumping. */
252 void dump_tool_help ()
253 {
254 printf ("Usage: lto-dump [OPTION]... SUB_COMMAND [OPTION]...\n\n");
255 printf ("LTO dump tool command line options.\n\n");
256 printf (" -list [options] Dump the symbol list.\n");
257 printf (" -demangle Dump the demangled output.\n");
258 printf (" -defined-only Dump only the defined symbols.\n");
259 printf (" -print-value Dump initial values of the "
260 "variables.\n");
261 printf (" -name-sort Sort the symbols alphabetically.\n");
262 printf (" -size-sort Sort the symbols according to size.\n");
263 printf (" -reverse-sort Dump the symbols in reverse order.\n");
264 printf (" -symbol= Dump the details of specific symbol.\n");
265 printf (" -objects Dump the details of LTO objects.\n");
266 printf (" -type-stats Dump statistics of tree types.\n");
267 printf (" -tree-stats Dump statistics of trees.\n");
268 printf (" -gimple-stats Dump statistics of gimple "
269 "statements.\n");
270 printf (" -dump-body= Dump the specific gimple body.\n");
271 printf (" -dump-level= Deciding the optimization level "
272 "of body.\n");
273 printf (" -help Display the dump tool help.\n");
274 return;
275 }
276
277 unsigned int
278 lto_option_lang_mask (void)
279 {
280 return CL_LTODump;
281 }
282
283 /* Functions for dumping various details in LTO dump tool are called
284 in lto_main(). The purpose of this dump tool is to analyze the LTO
285 object files. */
286
287 void
288 lto_main (void)
289 {
290 quiet_flag = true;
291 if (flag_lto_dump_tool_help)
292 dump_tool_help ();
293
294 /* LTO is called as a front end, even though it is not a front end.
295 Because it is called as a front end, TV_PHASE_PARSING and
296 TV_PARSE_GLOBAL are active, and we need to turn them off while
297 doing LTO. Later we turn them back on so they are active up in
298 toplev.c. */
299
300 /* Initialize the LTO front end. */
301 lto_fe_init ();
302 g_timer = NULL;
303 /* Read all the symbols and call graph from all the files in the
304 command line. */
305 read_cgraph_and_symbols (num_in_fnames, in_fnames);
306
307 /* Dump symbol list. */
308 if (flag_lto_dump_list)
309 dump_list ();
310 else if (flag_lto_dump_symbol)
311 {
312 /* Dump specific variables and functions used in IL. */
313 dump_symbol ();
314 }
315 else if (flag_lto_gimple_stats)
316 {
317 /* Dump gimple statement statistics. */
318 cgraph_node *node;
319 FOR_EACH_DEFINED_FUNCTION (node)
320 node->get_untransformed_body ();
321 if (!GATHER_STATISTICS)
322 warning_at (input_location, 0,
323 "Not configured with --enable-gather-detailed-mem-stats.");
324 else
325 dump_gimple_statistics ();
326 }
327 else if (flag_lto_tree_stats)
328 {
329 /* Dump tree statistics. */
330 if (!GATHER_STATISTICS)
331 warning_at (input_location, 0,
332 "Not configured with --enable-gather-detailed-mem-stats.");
333 else
334 {
335 printf ("Tree Statistics\n");
336 dump_tree_statistics ();
337 }
338 }
339 else if (flag_dump_body)
340 {
341 /* Dump specific gimple body of specified function. */
342 dump_body ();
343 return;
344 }
345 }