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