public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: marxin <mliska@suse.cz>
To: gcc-patches@gcc.gnu.org
Cc: hrishikeshparag@gmail.com
Cc: hubicka@ucw.cz
Subject: [PATCH 2/3] Add lto-dump tool.
Date: Thu, 14 Mar 2019 14:00:00 -0000	[thread overview]
Message-ID: <00d68e39b80bb63105d123a2481b218b3b1e66cc.1552571776.git.mliska@suse.cz> (raw)
In-Reply-To: <cover.1552571776.git.mliska@suse.cz>

[-- Attachment #1: Type: text/plain, Size: 1849 bytes --]


gcc/ChangeLog:

2019-03-14  Hrishikesh Kulkarni  <hrishikeshparag@gmail.com>
	    Martin Liska  <mliska@suse.cz>

	* Makefile.in: Add lto-dump.texi.
	* cgraph.h: Add new functions dump_visibility and
	dump_type_name.
	* doc/gcc.texi: Include lto-dump section.
	* doc/lto-dump.texi: New file.
	* dumpfile.c (dump_switch_p_1): Use parse_dump_option.
	(parse_dump_option): Factor out this function.
	* dumpfile.h (enum dump_flag): Add new value TDF_ERROR.
	(parse_dump_option): Export the function.
	* symtab.c (symtab_node::dump_visibility): New function.
	(symtab_node::dump_type_name): Likewise.

gcc/lto/ChangeLog:

2019-03-14  Hrishikesh Kulkarni  <hrishikeshparag@gmail.com>
	    Martin Liska  <mliska@suse.cz>

	* Make-lang.in: Add lto_dump-related definition.
	* config-lang.in: Likewise.
	* lang.opt: Add new language LTODump and options related
	to LTO dump tool.
	* lto-common.c (lto_read_decls): Support type statistics dump.
	(lto_file_read): Likewise for object files.
	* lto-dump.c: New file.
	* lto-lang.c (lto_option_lang_mask): Move from ..
	* lto.c (lto_option_lang_mask): .. here.
	* lto.h (lto_option_lang_mask): New declaration.
---
 gcc/Makefile.in        |   2 +-
 gcc/cgraph.h           |   6 +
 gcc/doc/gcc.texi       |   5 +
 gcc/doc/lto-dump.texi  | 131 ++++++++++++++++
 gcc/dumpfile.c         |  85 ++++++----
 gcc/dumpfile.h         |   5 +
 gcc/lto/Make-lang.in   |  20 ++-
 gcc/lto/config-lang.in |   4 +-
 gcc/lto/lang.opt       |  62 ++++++++
 gcc/lto/lto-common.c   |  40 +++++
 gcc/lto/lto-dump.c     | 344 +++++++++++++++++++++++++++++++++++++++++
 gcc/lto/lto-lang.c     |   6 -
 gcc/lto/lto.c          |   6 +
 gcc/lto/lto.h          |   2 +
 gcc/symtab.c           |  17 ++
 15 files changed, 692 insertions(+), 43 deletions(-)
 create mode 100644 gcc/doc/lto-dump.texi
 create mode 100644 gcc/lto/lto-dump.c


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0002-Add-lto-dump-tool.patch --]
[-- Type: text/x-patch; name="0002-Add-lto-dump-tool.patch", Size: 29328 bytes --]

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 508c674cbdc..c7e4ae94103 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -3158,7 +3158,7 @@ TEXI_GCC_FILES = gcc.texi gcc-common.texi gcc-vers.texi frontends.texi	\
 	 gcov.texi trouble.texi bugreport.texi service.texi		\
 	 contribute.texi compat.texi funding.texi gnu.texi gpl_v3.texi	\
 	 fdl.texi contrib.texi cppenv.texi cppopts.texi avr-mmcu.texi	\
-	 implement-c.texi implement-cxx.texi gcov-tool.texi gcov-dump.texi
+	 implement-c.texi implement-cxx.texi gcov-tool.texi gcov-dump.texi lto-dump.texi
 
 # we explicitly use $(srcdir)/doc/tm.texi here to avoid confusion with
 # the generated tm.texi; the latter might have a more recent timestamp,
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 9a19d83fffb..e2c2c00b5ed 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -119,6 +119,12 @@ public:
   /* Return dump name with assembler name.  */
   const char *dump_asm_name () const;
 
+  /* Return visibility name.  */
+  const char *dump_visibility () const;
+
+  /* Return type_name name.  */
+  const char *dump_type_name () const;
+
   /* Add node into symbol table.  This function is not used directly, but via
      cgraph/varpool node creation routines.  */
   void register_symbol (void);
diff --git a/gcc/doc/gcc.texi b/gcc/doc/gcc.texi
index 5297b9cb5d0..4d03e3a6d96 100644
--- a/gcc/doc/gcc.texi
+++ b/gcc/doc/gcc.texi
@@ -68,6 +68,8 @@ Texts being (a) (see below), and with the Back-Cover Texts being (b)
 * gcov: (gcc) Gcov.            @command{gcov}---a test coverage program.
 * gcov-tool: (gcc) Gcov-tool.  @command{gcov-tool}---an offline gcda profile processing program.
 * gcov-dump: (gcc) Gcov-dump.  @command{gcov-dump}---an offline gcda and gcno profile dump tool.
+* lto-dump: (gcc) lto-dump.    @command{lto-dump}---Tool for
+dumping LTO object files.
 @end direntry
 This file documents the use of the GNU compilers.
 @sp 1
@@ -142,6 +144,8 @@ Introduction, gccint, GNU Compiler Collection (GCC) Internals}.
 * Gcov::            @command{gcov}---a test coverage program.
 * Gcov-tool::       @command{gcov-tool}---an offline gcda profile processing program.
 * Gcov-dump::       @command{gcov-dump}---an offline gcda and gcno profile dump tool.
+* lto-dump::        @command{lto-dump}---Tool for dumping LTO
+object files.
 * Trouble::         If you have trouble using GCC.
 * Bugs::            How, why and where to report bugs.
 * Service::         How To Get Help with GCC
@@ -170,6 +174,7 @@ Introduction, gccint, GNU Compiler Collection (GCC) Internals}.
 @include gcov.texi
 @include gcov-tool.texi
 @include gcov-dump.texi
+@include lto-dump.texi
 @include trouble.texi
 @include bugreport.texi
 @include service.texi
diff --git a/gcc/doc/lto-dump.texi b/gcc/doc/lto-dump.texi
new file mode 100644
index 00000000000..d84397581c0
--- /dev/null
+++ b/gcc/doc/lto-dump.texi
@@ -0,0 +1,131 @@
+@c Copyright (C) 2018-2019 Free Software Foundation, Inc.
+@c This is part of the GCC manual.
+@c For copying conditions, see the file gcc.texi.
+
+@ignore
+@c man begin COPYRIGHT
+Copyright @copyright{} 2017-2018 Free Software Foundation, Inc.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with the
+Invariant Sections being ``GNU General Public License'' and ``Funding
+Free Software'', the Front-Cover texts being (a) (see below), and with
+the Back-Cover Texts being (b) (see below).  A copy of the license is
+included in the gfdl(7) man page.
+
+(a) The FSF's Front-Cover Text is:
+
+     A GNU Manual
+
+(b) The FSF's Back-Cover Text is:
+
+     You have freedom to copy and modify this GNU Manual, like GNU
+     software.  Copies published by the Free Software Foundation raise
+     funds for GNU development.
+@c man end
+@c Set file name and title for the man page.
+@setfilename lto-dump
+@settitle Tool for dumping LTO object files.
+@end ignore
+
+@node lto-dump
+@chapter @command{lto-dump}---Tool for dumping LTO object files.
+
+@menu
+* lto-dump Intro::             Introduction to lto-dump.
+* Invoking lto-dump::          How to use lto-dump.
+@end menu
+
+@node lto-dump Intro
+@section Introduction to @command{lto-dump}
+@c man begin DESCRIPTION
+
+@command{lto-dump} is a tool you can use in conjunction with GCC to
+dump link time optimization object files.
+
+@c man end
+
+@node Invoking lto-dump
+@section Invoking @command{lto-dump}
+
+@smallexample
+Usage: lto-dump @r{[}@var{OPTION}@r{]} ... @var{objfiles}
+@end smallexample
+
+@command{lto-dump} accepts the following options:
+
+@ignore
+@c man begin SYNOPSIS
+lto-dump [@option{-list}]
+     [@option{-demangle}]
+     [@option{-defined-only}]
+     [@option{-print-value}]
+     [@option{-name-sort}]
+     [@option{-size-sort}]
+     [@option{-reverse-sort}]
+     [@option{-no-sort}]
+     [@option{-symbol=}]
+     [@option{-objects}]
+     [@option{-type-stats}]
+     [@option{-tree-stats}]
+     [@option{-gimple-stats}]
+     [@option{-dump-level=}]
+     [@option{-dump-body=}]
+     [@option{-help}] @var{lto-dump}
+@c man end
+@end ignore
+
+@c man begin OPTIONS
+@table @gcctabopt
+@item -list
+Dumps list of details of functions and variables.
+
+@item -demangle
+Dump the demangled output.
+
+@item -defined-only
+Dump only the defined symbols.
+
+@item -print-value
+Dump initial values of the variables.
+
+@item -name-sort
+Sort the symbols alphabetically.
+
+@item -size-sort
+Sort the symbols according to size.
+
+@item -reverse-sort
+Dump the symbols in reverse order.
+
+@item -no-sort
+Dump the symbols in order of occurrence.
+
+@item -symbol=
+Dump the details of specific symbol.
+
+@item -objects
+Dump the details of LTO objects.
+
+@item -type-stats
+Dump the statistics of tree types.
+
+@item -tree-stats
+Dump the statistics of trees.
+
+@item -gimple-stats
+Dump the statistics of gimple statements.
+
+@item -dump-level=
+For deciding the optimization level of body.
+
+@item -dump-body=
+Dump the specific gimple body.
+
+@item -help
+Display the dump tool help.
+
+@end table
+
+@c man end
diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c
index 14b6dfea75e..5263d3a2134 100644
--- a/gcc/dumpfile.c
+++ b/gcc/dumpfile.c
@@ -115,6 +115,7 @@ static struct dump_file_info dump_files[TDI_end] =
    in dumpfile.h and opt_info_options below. */
 static const kv_pair<dump_flags_t> dump_options[] =
 {
+  {"none", TDF_NONE},
   {"address", TDF_ADDRESS},
   {"asmname", TDF_ASMNAME},
   {"slim", TDF_SLIM},
@@ -1770,28 +1771,19 @@ gcc::dump_manager::update_dfi_for_opt_info (dump_file_info *dfi) const
   return true;
 }
 
-/* Parse ARG as a dump switch. Return nonzero if it is, and store the
-   relevant details in the dump_files array.  */
+/* Helper routine to parse -<dump format>[=filename]
+   and return the corresponding dump flag.  If POS_P is non-NULL,
+   assign start of filename into *POS_P.  */
 
-int
-gcc::dump_manager::
-dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob)
+dump_flags_t
+parse_dump_option (const char *option_value, const char **pos_p)
 {
-  const char *option_value;
   const char *ptr;
   dump_flags_t flags;
 
-  if (doglob && !dfi->glob)
-    return 0;
-
-  option_value = skip_leading_substring (arg, doglob ? dfi->glob : dfi->swtch);
-  if (!option_value)
-    return 0;
-
-  if (*option_value && *option_value != '-' && *option_value != '=')
-    return 0;
-
   ptr = option_value;
+  if (pos_p)
+    *pos_p = NULL;
 
   /* Retain "user-facing" and "internals" messages, but filter out
      those from an opt_problem being re-emitted at the top level
@@ -1805,14 +1797,13 @@ dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob)
       const char *end_ptr;
       const char *eq_ptr;
       unsigned length;
-
       while (*ptr == '-')
 	ptr++;
       end_ptr = strchr (ptr, '-');
       eq_ptr = strchr (ptr, '=');
 
       if (eq_ptr && !end_ptr)
-        end_ptr = eq_ptr;
+	end_ptr = eq_ptr;
 
       if (!end_ptr)
 	end_ptr = ptr + strlen (ptr);
@@ -1821,25 +1812,59 @@ dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob)
       for (option_ptr = dump_options; option_ptr->name; option_ptr++)
 	if (strlen (option_ptr->name) == length
 	    && !memcmp (option_ptr->name, ptr, length))
-          {
-            flags |= option_ptr->value;
+	  {
+	    flags |= option_ptr->value;
 	    goto found;
-          }
+	  }
 
       if (*ptr == '=')
-        {
+	{
           /* Interpret rest of the argument as a dump filename.  This
              filename overrides other command line filenames.  */
-          if (dfi->pfilename)
-            free (CONST_CAST (char *, dfi->pfilename));
-          dfi->pfilename = xstrdup (ptr + 1);
-          break;
-        }
+	  if (pos_p)
+	    *pos_p = ptr + 1;
+	  break;
+	}
       else
-        warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
-                 length, ptr, dfi->swtch);
-    found:;
+      {
+	warning (0, "ignoring unknown option %q.*s",
+		 length, ptr);
+	flags = TDF_ERROR;
+      }
+    found:
       ptr = end_ptr;
+  }
+
+  return flags;
+}
+
+/* Parse ARG as a dump switch.  Return nonzero if it is, and store the
+   relevant details in the dump_files array.  */
+
+int
+gcc::dump_manager::
+dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob)
+{
+  const char *option_value;
+  dump_flags_t flags = TDF_NONE;
+
+  if (doglob && !dfi->glob)
+    return 0;
+
+  option_value = skip_leading_substring (arg, doglob ? dfi->glob : dfi->swtch);
+  if (!option_value)
+    return 0;
+
+  if (*option_value && *option_value != '-' && *option_value != '=')
+    return 0;
+
+  const char *filename;
+  flags = parse_dump_option (option_value, &filename);
+  if (filename)
+    {
+      if (dfi->pfilename)
+  free (CONST_CAST (char *, dfi->pfilename));
+      dfi->pfilename = xstrdup (filename);
     }
 
   dfi->pstate = -1;
diff --git a/gcc/dumpfile.h b/gcc/dumpfile.h
index 1f9ac427f75..9bcaa25b0a5 100644
--- a/gcc/dumpfile.h
+++ b/gcc/dumpfile.h
@@ -193,6 +193,9 @@ enum dump_flag
   /* Dumping for -fcompare-debug.  */
   TDF_COMPARE_DEBUG = (1 << 28),
 
+  /* For error.  */
+  TDF_ERROR = (1 << 26),
+
   /* All values.  */
   TDF_ALL_VALUES = (1 << 29) - 1
 };
@@ -501,6 +504,8 @@ extern void dump_end (int, FILE *);
 extern int opt_info_switch_p (const char *);
 extern const char *dump_flag_name (int);
 extern const kv_pair<optgroup_flags_t> optgroup_options[];
+extern dump_flags_t
+parse_dump_option (const char *, const char **);
 
 /* Global variables used to communicate with passes.  */
 extern FILE *dump_file;
diff --git a/gcc/lto/Make-lang.in b/gcc/lto/Make-lang.in
index b7ed96eac29..92487e1f53e 100644
--- a/gcc/lto/Make-lang.in
+++ b/gcc/lto/Make-lang.in
@@ -21,9 +21,12 @@
 
 # The name of the LTO compiler.
 LTO_EXE = lto1$(exeext)
+LTO_DUMP_EXE = lto-dump$(exeext)
 # The LTO-specific object files inclued in $(LTO_EXE).
 LTO_OBJS = lto/lto-lang.o lto/lto.o lto/lto-object.o attribs.o lto/lto-partition.o lto/lto-symtab.o lto/lto-common.o
 lto_OBJS = $(LTO_OBJS)
+LTO_DUMP_OBJS = lto/lto-lang.o lto/lto-object.o attribs.o lto/lto-partition.o lto/lto-symtab.o lto/lto-dump.o lto/lto-common.o
+lto_dump_OBJS = $(LTO_DUMP_OBJS)
 
 # this is only useful in a LTO bootstrap, but this does not work right
 # now. Should reenable after this is fixed, but only when LTO bootstrap
@@ -39,11 +42,14 @@ lto_OBJS = $(LTO_OBJS)
 
 # These hooks are used by the main GCC Makefile.  Consult that
 # Makefile for documentation.
-lto.all.cross: $(LTO_EXE)
-lto.start.encap: $(LTO_EXE)
+lto.all.cross: $(LTO_EXE) $(LTO_DUMP_EXE)
+lto.start.encap: $(LTO_EXE) $(LTO_DUMP_EXE)
 lto.rest.encap:
 lto.tags:
-lto.install-common:
+lto.install-common: installdirs
+	$(INSTALL_PROGRAM) $(LTO_DUMP_EXE) \
+	$(DESTDIR)/$(bindir)/$(LTO_DUMP_EXE)
+
 lto.install-man:
 lto.install-info:
 lto.dvi:
@@ -60,7 +66,7 @@ lto.srcinfo:
 lto.install-plugin:
 
 lto.mostlyclean:
-	rm -f $(LTO_OBJS) $(LTO_EXE) lto1.fda
+	rm -f $(LTO_OBJS) $(LTO_EXE) lto1.fda $(LTO_DUMP_OBJS) $(LTO_DUMP_EXE) lto-dump.fda
 
 lto.clean:
 lto.distclean:
@@ -81,6 +87,12 @@ $(LTO_EXE): $(LTO_OBJS) $(BACKEND) $(LIBDEPS)
 	+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
 		$(LTO_OBJS) $(BACKEND) $(BACKENDLIBS) $(LIBS)
 
+$(LTO_DUMP_EXE): $(LTO_EXE) $(LTO_DUMP_OBJS) $(BACKEND) $(LIBDEPS)
+	+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+		$(LTO_DUMP_OBJS) $(BACKEND) $(BACKENDLIBS) $(LIBS)
+
+lto/lto-dump.o: $(LTO_EXE)
+
 lto1.fda: ../prev-gcc/lto1$(exeext) ../prev-gcc/$(PERF_DATA)
 	$(CREATE_GCOV) -binary ../prev-gcc/lto1$(exeext) -gcov lto1.fda -profile ../prev-gcc/$(PERF_DATA) -gcov_version 1
 
diff --git a/gcc/lto/config-lang.in b/gcc/lto/config-lang.in
index 07214365fd8..37c8f6e12b1 100644
--- a/gcc/lto/config-lang.in
+++ b/gcc/lto/config-lang.in
@@ -18,9 +18,9 @@
 # <http://www.gnu.org/licenses/>.
 
 language="lto"
-compilers="lto1\$(exeext)"
+compilers="lto1\$(exeext) lto-dump\$(exeext)"
 
-gtfiles="\$(srcdir)/lto/lto-tree.h \$(srcdir)/lto/lto-lang.c \$(srcdir)/lto/lto.c \$(srcdir)/lto/lto.h \$(srcdir)/lto/lto-common.h \$(srcdir)/lto/lto-common.c"
+gtfiles="\$(srcdir)/lto/lto-tree.h \$(srcdir)/lto/lto-lang.c \$(srcdir)/lto/lto.c \$(srcdir)/lto/lto.h \$(srcdir)/lto/lto-common.h \$(srcdir)/lto/lto-common.c \$(srcdir)/lto/lto-dump.c"
 
 # LTO is a special front end.  From a user's perspective it is not
 # really a language, but a middle end feature.  However, the GIMPLE
diff --git a/gcc/lto/lang.opt b/gcc/lto/lang.opt
index 4c4c1ced38c..5bacef349e3 100644
--- a/gcc/lto/lang.opt
+++ b/gcc/lto/lang.opt
@@ -24,6 +24,9 @@
 Language
 LTO
 
+Language
+LTODump
+
 Enum
 Name(lto_linker_output) Type(enum lto_linker_output) UnknownError(unknown linker output %qs)
 
@@ -66,6 +69,65 @@ fwpa=
 LTO Driver RejectNegative Joined Var(flag_wpa)
 Whole program analysis (WPA) mode with number of parallel jobs specified.
 
+
+list
+LTODump Var(flag_lto_dump_list)
+Call the dump function for variables and function in IL.
+
+demangle
+LTODump Var(flag_lto_dump_demangle)
+Dump the demangled output.
+
+defined-only
+LTODump Var(flag_lto_dump_defined)
+Dump only the defined symbols.
+
+print-value
+LTODump Var(flag_lto_print_value)
+Print the initial values of the variables.
+
+name-sort
+LTODump Var(flag_lto_name_sort)
+Sort the symbols alphabetically.
+
+size-sort
+LTODump Var(flag_lto_size_sort)
+Sort the symbols according to size.
+
+reverse-sort
+LTODump Var(flag_lto_reverse_sort)
+Display the symbols in reverse order.
+
+symbol=
+LTODump RejectNegative Joined Var(flag_lto_dump_symbol)
+
+objects
+LTODump Var(flag_lto_dump_objects)
+Dump the details of LTO objects.
+
+type-stats
+LTODump Var(flag_lto_dump_type_stats)
+Dump the statistics of tree types.
+
+tree-stats
+LTODump Var(flag_lto_tree_stats)
+Dump the statistics of trees.
+
+gimple-stats
+LTODump Var(flag_lto_gimple_stats)
+Dump the statistics of gimple statements.
+
+dump-level=
+LTODump RejectNegative Joined Var(flag_dump_level)
+
+dump-body=
+LTODump RejectNegative Joined Var(flag_dump_body)
+
+help
+LTODump Var(flag_lto_dump_tool_help)
+Dump the dump tool command line options.
+
+
 fresolution=
 LTO Joined
 The resolution file.
diff --git a/gcc/lto/lto-common.c b/gcc/lto/lto-common.c
index 9d5b034729e..01470c17080 100644
--- a/gcc/lto/lto-common.c
+++ b/gcc/lto/lto-common.c
@@ -1681,6 +1681,10 @@ lto_read_decls (struct lto_file_decl_data *decl_data, const void *data,
   /* We do not uniquify the pre-loaded cache entries, those are middle-end
      internal types that should not be merged.  */
 
+  typedef int_hash<unsigned, 0, UINT_MAX> code_id_hash;
+  hash_map <code_id_hash, unsigned> hm;
+  unsigned total = 0;
+
   /* Read the global declarations and types.  */
   while (ib_main.p < ib_main.len)
     {
@@ -1730,6 +1734,15 @@ lto_read_decls (struct lto_file_decl_data *decl_data, const void *data,
 		 chains.  */
 	      if (TYPE_P (t))
 		{
+		  /* Map the tree types to their frequencies.  */
+		  if (flag_lto_dump_type_stats)
+		    {
+		      unsigned key = (unsigned) TREE_CODE (t);
+		      unsigned *countp = hm.get (key);
+		      hm.put (key, countp ? (*countp) + 1 : 1);
+		      total++;
+		    }
+
 		  seen_type = true;
 		  num_prevailing_types++;
 		  lto_fixup_prevailing_type (t);
@@ -1775,6 +1788,22 @@ lto_read_decls (struct lto_file_decl_data *decl_data, const void *data,
 	  gcc_assert (t && data_in->reader_cache->nodes.length () == from);
 	}
     }
+
+  /* Dump type statistics.  */
+  if (flag_lto_dump_type_stats)
+    {
+      fprintf (stdout, "       Type     Frequency   Percentage\n\n");
+      for (hash_map<code_id_hash, unsigned>::iterator itr = hm.begin ();
+	   itr != hm.end ();
+	   ++itr)
+	{
+	  std::pair<unsigned, unsigned> p = *itr;
+	  enum tree_code code = (enum tree_code) p.first;
+	  fprintf (stdout, "%14s %6d %12.2f\n", get_tree_code_name (code),
+		   p.second, float (p.second)/total*100);
+	}
+    }
+
   data_in->location_cache.apply_location_cache ();
 
   /* Read in lto_in_decl_state objects.  */
@@ -2074,6 +2103,17 @@ lto_file_read (lto_file *file, FILE *resolution_file, int *count)
   memset (&section_list, 0, sizeof (struct lto_section_list)); 
   section_hash_table = lto_obj_build_section_table (file, &section_list);
 
+  /* Dump the details of LTO objects.  */
+  if (flag_lto_dump_objects)
+  {
+    int i=0;
+    fprintf (stdout, "\n    LTO Object Name: %s\n", file->filename);
+    fprintf (stdout, "\nNo.    Offset    Size       Section Name\n\n");
+    for (section = section_list.first; section != NULL; section = section->next)
+      fprintf (stdout, "%2d %8ld %8ld   %s\n",
+	       ++i, section->start, section->len, section->name);
+  }
+
   /* Find all sub modules in the object and put their sections into new hash
      tables in a splay tree. */
   file_ids = lto_splay_tree_new ();
diff --git a/gcc/lto/lto-dump.c b/gcc/lto/lto-dump.c
new file mode 100644
index 00000000000..646b66ed655
--- /dev/null
+++ b/gcc/lto/lto-dump.c
@@ -0,0 +1,344 @@
+/* Functions for LTO dump tool.
+   Copyright (C) 2018-2019 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.  */
+
+struct symbol_entry
+{
+  symtab_node *node;
+  symbol_entry (symtab_node *node_): node (node_)
+  {}
+
+  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->dump_type_name ();
+    const char *visibility = node->dump_visibility ();
+    size_t sz = get_size ();
+    printf ("%s  %s  %4lu  %s  ", type_name, visibility, sz, name);
+  }
+};
+
+/* Stores variable specific details of symbols for dumping symbol list.  */
+
+struct variable_entry: public symbol_entry
+{
+  variable_entry (varpool_node *node_): symbol_entry (node_)
+  {}
+
+  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.  */
+
+struct function_entry: public symbol_entry
+{
+  function_entry (cgraph_node *node_): symbol_entry (node_)
+  {}
+
+  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)
+     ? 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->get_untransformed_body ();
+    symbol_entry *e = new function_entry (cnode);
+    if (!flag_lto_dump_defined || cnode->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 ("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 ();
+}
+
+/* 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 ();
+}
+
+/* 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 && !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 ()
+{
+  printf ("Usage: lto-dump [OPTION]... SUB_COMMAND [OPTION]...\n\n");
+  printf ("LTO dump tool command line options.\n\n");
+  printf ("  -list [options]           Dump the symbol list.\n");
+  printf ("    -demangle               Dump the demangled output.\n");
+  printf ("    -defined-only           Dump only the defined symbols.\n");
+  printf ("    -print-value            Dump initial values of the "
+	  "variables.\n");
+  printf ("    -name-sort              Sort the symbols alphabetically.\n");
+  printf ("    -size-sort              Sort the symbols according to size.\n");
+  printf ("    -reverse-sort           Dump the symbols in reverse order.\n");
+  printf ("  -symbol=                  Dump the details of specific symbol.\n");
+  printf ("  -objects                  Dump the details of LTO objects.\n");
+  printf ("  -type-stats               Dump statistics of tree types.\n");
+  printf ("  -tree-stats               Dump statistics of trees.\n");
+  printf ("  -gimple-stats             Dump statistics of gimple "
+	  "statements.\n");
+  printf ("  -dump-body=               Dump the specific gimple body.\n");
+  printf ("  -dump-level=              Deciding the optimization level "
+	  "of body.\n");
+  printf ("  -help                     Display the dump tool help.\n");
+  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;
+    }
+}
diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
index b88ca09d102..e155ea33d32 100644
--- a/gcc/lto/lto-lang.c
+++ b/gcc/lto/lto-lang.c
@@ -789,12 +789,6 @@ static GTY(()) tree registered_builtin_types;
 
 /* Language hooks.  */
 
-static unsigned int
-lto_option_lang_mask (void)
-{
-  return CL_LTO;
-}
-
 static bool
 lto_complain_wrong_lang_p (const struct cl_option *option ATTRIBUTE_UNUSED)
 {
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 55d5554f18e..26b8c172312 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -535,6 +535,12 @@ offload_handle_link_vars (void)
 #endif
 }
 
+unsigned int
+lto_option_lang_mask (void)
+{
+  return CL_LTO;
+}
+
 /* Main entry point for the GIMPLE front end.  This front end has
    three main personalities:
 
diff --git a/gcc/lto/lto.h b/gcc/lto/lto.h
index a1b39ef8ff0..e67e1e76d40 100644
--- a/gcc/lto/lto.h
+++ b/gcc/lto/lto.h
@@ -69,4 +69,6 @@ struct lto_section_list
   struct lto_section_slot *first, *last;
 };
 
+extern unsigned int lto_option_lang_mask (void);
+
 #endif /* LTO_H */
diff --git a/gcc/symtab.c b/gcc/symtab.c
index c3c057d3283..04fbf762ecd 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -808,6 +808,23 @@ symtab_node::dump_referring (FILE *file)
 
 static const char * const symtab_type_names[] = {"symbol", "function", "variable"};
 
+/* Dump the visibility of the symbol.  */
+
+const char *
+symtab_node::dump_visibility () const
+{
+  static const char * const visibility_types[]
+    = { "default", "protected", "hidden", "internal" };
+  return visibility_types[DECL_VISIBILITY (decl)];
+}
+
+/* Dump the type_name of the symbol.  */
+const char *
+symtab_node::dump_type_name () const
+{
+  return symtab_type_names[type];
+}
+
 /* Dump base fields of symtab nodes to F.  Not to be used directly.  */
 
 void

  parent reply	other threads:[~2019-03-14 14:00 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-14 14:00 [PATCH 0/3][stage1] [PATCH v2] LTO dump tool marxin
2019-03-14 14:00 ` [PATCH 3/3] Fix GNU coding style in lto-common.c marxin
2019-04-29 19:43   ` Jeff Law
2019-03-14 14:00 ` marxin [this message]
2019-04-26 13:14   ` [PATCH 2/3] Add lto-dump tool Richard Biener
2022-10-28 10:14   ` Thomas Schwinge
2022-10-29  3:22     ` Jeff Law
2019-03-14 14:06 ` [PATCH 1/3] Split part of functionality from lto.c to lto-common.c marxin
2019-04-26 12:47   ` Richard Biener

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=00d68e39b80bb63105d123a2481b218b3b1e66cc.1552571776.git.mliska@suse.cz \
    --to=mliska@suse.cz \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=hrishikeshparag@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).