Mercurial > hg > CbC > CbC_gcc
diff gcc/lto/lto-dump.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/lto/lto-dump.c Thu Feb 13 11:34:05 2020 +0900 @@ -0,0 +1,379 @@ +/* Functions for LTO dump tool. + Copyright (C) 2018-2020 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "function.h" +#include "basic-block.h" +#include "tree.h" +#include "gimple.h" +#include "cfg.h" +#include "tree-cfg.h" +#include "tree-pass.h" +#include "tree-streamer.h" +#include "cgraph.h" +#include "opts.h" +#include "debug.h" +#include "lto-partition.h" +#include "tree-pretty-print.h" +#include "lto-common.h" + +/* Stores details of symbols for dumping symbol list. */ + +class symbol_entry +{ +public: + symtab_node *node; + symbol_entry (symtab_node *node_): node (node_) + {} + + virtual ~symbol_entry () + {} + + char* get_name () const + { + if (flag_lto_dump_demangle) + return xstrdup (node->name ()); + else + return xstrdup (node->asm_name ()); + } + + virtual size_t get_size () const = 0; + + virtual void dump () + { + const char *name = get_name (); + const char *type_name = node->get_symtab_type_string (); + const char *visibility = node->get_visibility_string (); + size_t sz = get_size (); + printf ("%s %s %4" PRIu64 " %s ", type_name, visibility, (uint64_t) sz, + name); + } +}; + +/* Stores variable specific details of symbols for dumping symbol list. */ + +class variable_entry: public symbol_entry +{ +public: + variable_entry (varpool_node *node_): symbol_entry (node_) + {} + + virtual ~variable_entry () + {} + + virtual size_t get_size () const + { + varpool_node *vnode = dyn_cast<varpool_node *> (node); + if (DECL_SIZE (vnode->decl) && tree_fits_shwi_p (DECL_SIZE (vnode->decl))) + return tree_to_shwi (DECL_SIZE (vnode->decl)); + return 0; + } + + virtual void dump () + { + symbol_entry :: dump (); + varpool_node *vnode = dyn_cast<varpool_node *> (node); + vnode->get_constructor (); + tree value_tree = DECL_INITIAL (vnode->decl); + if (flag_lto_print_value && value_tree) + print_generic_expr (stdout, value_tree, TDF_NONE); + printf ("\n"); + } +}; + +/* Stores function specific details of symbols for dumping symbol list. */ + +class function_entry: public symbol_entry +{ +public: + function_entry (cgraph_node *node_): symbol_entry (node_) + {} + + virtual ~function_entry () + {} + + virtual void dump () + { + symbol_entry :: dump (); + printf ("\n"); + } + + virtual size_t get_size () const + { + cgraph_node *cnode = dyn_cast<cgraph_node *> (node); + gcc_assert (cnode); + + return (cnode->definition && !cnode->alias) + ? n_basic_blocks_for_fn (DECL_STRUCT_FUNCTION (cnode->decl)) + : 0; + } +}; + +/* Comparing symbols based on size. */ + +int size_compare (const void *a, const void *b) +{ + const symbol_entry *e1 = *(const symbol_entry * const*) a; + const symbol_entry *e2 = *(const symbol_entry * const*) b; + + return e1->get_size () - e2->get_size (); +} + +/* Comparing symbols based on name. */ + +int name_compare (const void *a, const void *b) +{ + const symbol_entry *e1 = *(const symbol_entry * const*) a; + const symbol_entry *e2 = *(const symbol_entry * const*) b; + + return strcmp (e1->get_name (), e2->get_name ()); +} + +/* Dump list of functions and their details. */ + +void dump_list_functions (void) +{ + auto_vec<symbol_entry *> v; + + cgraph_node *cnode; + FOR_EACH_FUNCTION (cnode) + { + if (cnode->definition && !cnode->alias) + cnode->get_untransformed_body (); + symbol_entry *e = new function_entry (cnode); + if (!flag_lto_dump_defined || (cnode->definition && !cnode->alias)) + v.safe_push (e); + } + + if (flag_lto_size_sort) + v.qsort (size_compare); + else if (flag_lto_name_sort) + v.qsort (name_compare); + if (flag_lto_reverse_sort) + v.reverse (); + + printf ("Type Visibility Size Name"); + if (flag_lto_print_value) + printf (" Value"); + printf ("\n"); + int i=0; + symbol_entry* e; + FOR_EACH_VEC_ELT (v, i, e) + { + e->dump (); + delete e; + } +} + +/* Dump list of variables and their details. */ + +void dump_list_variables (void) +{ + auto_vec<symbol_entry *> v; + + varpool_node *vnode; + FOR_EACH_VARIABLE (vnode) + { + symbol_entry *e = new variable_entry (vnode); + if (!flag_lto_dump_defined || vnode->definition) + v.safe_push (e); + } + + if (flag_lto_size_sort) + v.qsort (size_compare); + else if (flag_lto_name_sort) + v.qsort (name_compare); + if (flag_lto_reverse_sort) + v.reverse (); + + printf ("\n"); + int i=0; + symbol_entry* e; + FOR_EACH_VEC_ELT (v, i, e) + { + e->dump (); + delete e; + } +} + +/* Dump symbol table in graphviz format. */ +void dump_symtab_graphviz (void) +{ + symtab->dump_graphviz (stdout); +} + +/* Dump symbol list. */ + +void dump_list (void) +{ + dump_list_functions (); + dump_list_variables (); + return; +} + +/* Dump specific variables and functions used in IL. */ +void dump_symbol () +{ + symtab_node *node; + printf ("Symbol: %s\n", flag_lto_dump_symbol); + FOR_EACH_SYMBOL (node) + { + if (!strcmp (flag_lto_dump_symbol, node->name ())) + { + node->debug (); + printf ("\n"); + } + } + return; +} + +/* Dump specific gimple body of specified function. */ +void dump_body () +{ + int flag = 0; + dump_flags_t flags = TDF_NONE; + if (flag_dump_level) + flags = parse_dump_option (flag_dump_level, NULL); + if (flags == TDF_ERROR) + { + error_at (input_location, "Level not found, use none, slim, blocks, vops."); + return; + } + cgraph_node *cnode; + FOR_EACH_FUNCTION (cnode) + if (cnode->definition + && !cnode->alias + && !strcmp (cnode->name (), flag_dump_body)) + { + printf ("Gimple Body of Function: %s\n", cnode->name ()); + cnode->get_untransformed_body (); + debug_function (cnode->decl, flags); + flag = 1; + } + if (!flag) + error_at (input_location, "Function not found."); + return; +} + +/* List of command line options for dumping. */ +void dump_tool_help () +{ + const char *msg = + "Usage: lto-dump [OPTION]... SUB_COMMAND [OPTION]...\n\n" + "LTO dump tool command line options.\n\n" + " -list [options] Dump the symbol list.\n" + " -demangle Dump the demangled output.\n" + " -defined-only Dump only the defined symbols.\n" + " -print-value Dump initial values of the variables.\n" + " -name-sort Sort the symbols alphabetically.\n" + " -size-sort Sort the symbols according to size.\n" + " -reverse-sort Dump the symbols in reverse order.\n" + " -symbol= Dump the details of specific symbol.\n" + " -objects Dump the details of LTO objects.\n" + " -callgraph Dump the callgraph in graphviz format.\n" + " -type-stats Dump statistics of tree types.\n" + " -tree-stats Dump statistics of trees.\n" + " -gimple-stats Dump statistics of gimple statements.\n" + " -dump-body= Dump the specific gimple body.\n" + " -dump-level= Deciding the optimization level of body.\n" + " -help Display the dump tool help.\n"; + + fputs (msg, stdout); + return; +} + +unsigned int +lto_option_lang_mask (void) +{ + return CL_LTODump; +} + +/* Functions for dumping various details in LTO dump tool are called + in lto_main(). The purpose of this dump tool is to analyze the LTO + object files. */ + +void +lto_main (void) +{ + quiet_flag = true; + if (flag_lto_dump_tool_help) + dump_tool_help (); + + /* LTO is called as a front end, even though it is not a front end. + Because it is called as a front end, TV_PHASE_PARSING and + TV_PARSE_GLOBAL are active, and we need to turn them off while + doing LTO. Later we turn them back on so they are active up in + toplev.c. */ + + /* Initialize the LTO front end. */ + lto_fe_init (); + g_timer = NULL; + /* Read all the symbols and call graph from all the files in the + command line. */ + read_cgraph_and_symbols (num_in_fnames, in_fnames); + + /* Dump symbol list. */ + if (flag_lto_dump_list) + dump_list (); + else if (flag_lto_dump_symbol) + { + /* Dump specific variables and functions used in IL. */ + dump_symbol (); + } + else if (flag_lto_gimple_stats) + { + /* Dump gimple statement statistics. */ + cgraph_node *node; + FOR_EACH_DEFINED_FUNCTION (node) + node->get_untransformed_body (); + if (!GATHER_STATISTICS) + warning_at (input_location, 0, + "Not configured with " + "%<--enable-gather-detailed-mem-stats%>."); + else + dump_gimple_statistics (); + } + else if (flag_lto_tree_stats) + { + /* Dump tree statistics. */ + if (!GATHER_STATISTICS) + warning_at (input_location, 0, + "Not configured with " + "%<--enable-gather-detailed-mem-stats%>."); + else + { + printf ("Tree Statistics\n"); + dump_tree_statistics (); + } + } + else if (flag_dump_body) + { + /* Dump specific gimple body of specified function. */ + dump_body (); + return; + } + else if (flag_dump_callgraph) + { + dump_symtab_graphviz (); + return; + } +}