On 11/13/20 5:47 PM, Sebastian Huber wrote:

Hello.

Sorry for slow response.

Register the profile information in the specified section instead of using a
constructor/destructor.  A pointer to the profile information generated by
-fprofile-arcs or -ftest-coverage is placed in the specified section for each
translation unit.  This option disables the profile information registration
through a constructor and it disables the profile information processing
through a destructor.

The patch is fine.


I am not sure how I can test this option.  One approach would be to assemble a
test file, then scan it and check that a .gcov_info section is present and no
__gcov_init() and __gcov_exit() calls are present.  Is there an example for
this in the test suite?

I'm going to add a test for it. I'm going to test your patch and will install
it after it finishes the tests.

Thanks for working on that. What will be your next steps in order to support
profiling of your embedded target? Something I can help with?

Martin
>From 014962870ff4616d93165bada5f6c507c5e83000 Mon Sep 17 00:00:00 2001
From: Sebastian Huber <sebastian.hu...@embedded-brains.de>
Date: Fri, 13 Nov 2020 17:47:40 +0100
Subject: [PATCH] gcov: Add -fprofile-info-section support

Register the profile information in the specified section instead of using a
constructor/destructor.  A pointer to the profile information generated by
-fprofile-arcs or -ftest-coverage is placed in the specified section for each
translation unit.  This option disables the profile information registration
through a constructor and it disables the profile information processing
through a destructor.

I am not sure how I can test this option.  One approach would be to assemble a
test file, then scan it and check that a .gcov_info section is present and no
__gcov_init() and __gcov_exit() calls are present.  Is there an example for
this in the test suite?

gcc/

	* common.opt (fprofile-info-section): New.
	* coverage.c (build_gcov_info_var_registration): New.
	(coverage_obj_init): Evaluate profile_info_section and use
	build_gcov_info_var_registration().
	* doc/invoke.texi (fprofile-info-section): Document.
	* opts.c (common_handle_option): Process fprofile-info-section
	option.

gcc/testsuite/ChangeLog:

	* gcc.dg/profile-info-section.c: New test.
---
 gcc/common.opt                              |  8 ++++++
 gcc/coverage.c                              | 28 ++++++++++++++++++--
 gcc/doc/invoke.texi                         | 29 +++++++++++++++++++++
 gcc/opts.c                                  |  4 +++
 gcc/testsuite/gcc.dg/profile-info-section.c | 20 ++++++++++++++
 5 files changed, 87 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/profile-info-section.c

diff --git a/gcc/common.opt b/gcc/common.opt
index 9552cebe0d6..fe39b3dee9f 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2272,6 +2272,14 @@ fprofile-generate=
 Common Joined RejectNegative
 Enable common options for generating profile info for profile feedback directed optimizations, and set -fprofile-dir=.
 
+fprofile-info-section
+Common RejectNegative
+Register the profile information in the .gcov_info section instead of using a constructor/destructor.
+
+fprofile-info-section=
+Common Joined RejectNegative Var(profile_info_section)
+Register the profile information in the specified section instead of using a constructor/destructor.
+
 fprofile-partial-training
 Common Report Var(flag_profile_partial_training) Optimization
 Do not assume that functions never executed during the train run are cold.
diff --git a/gcc/coverage.c b/gcc/coverage.c
index 7711412c3be..d299e48d591 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -1097,6 +1097,25 @@ build_gcov_exit_decl (void)
   cgraph_build_static_cdtor ('D', dtor, priority);
 }
 
+/* Generate the pointer to the gcov_info_var in a dedicated section.  */
+
+static void
+build_gcov_info_var_registration (tree gcov_info_type)
+{
+  tree var = build_decl (BUILTINS_LOCATION,
+			 VAR_DECL, NULL_TREE,
+			 build_pointer_type (gcov_info_type));
+  TREE_STATIC (var) = 1;
+  TREE_READONLY (var) = 1;
+  char name_buf[32];
+  ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 2);
+  DECL_NAME (var) = get_identifier (name_buf);
+  get_section (profile_info_section, SECTION_UNNAMED, NULL);
+  set_decl_section_name (var, profile_info_section);
+  DECL_INITIAL (var) = build_fold_addr_expr (gcov_info_var);
+  varpool_node::finalize_decl (var);
+}
+
 /* Create the gcov_info types and object.  Generate the constructor
    function to call __gcov_init.  Does not generate the initializer
    for the object.  Returns TRUE if coverage data is being emitted.  */
@@ -1151,8 +1170,13 @@ coverage_obj_init (void)
   ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
   DECL_NAME (gcov_info_var) = get_identifier (name_buf);
 
-  build_init_ctor (gcov_info_type);
-  build_gcov_exit_decl ();
+  if (profile_info_section)
+    build_gcov_info_var_registration (gcov_info_type);
+  else
+    {
+      build_init_ctor (gcov_info_type);
+      build_gcov_exit_decl ();
+    }
 
   return true;
 }
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 6ce67e6edab..310c3f72a3f 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -566,6 +566,7 @@ Objective-C and Objective-C++ Dialects}.
 @gccoptlist{-p  -pg  -fprofile-arcs  --coverage  -ftest-coverage @gol
 -fprofile-abs-path @gol
 -fprofile-dir=@var{path}  -fprofile-generate  -fprofile-generate=@var{path} @gol
+-fprofile-info-section  -fprofile-info-section=@var{name} @gol
 -fprofile-note=@var{path} -fprofile-prefix-path=@var{path} @gol
 -fprofile-update=@var{method} -fprofile-filter-files=@var{regex} @gol
 -fprofile-exclude-files=@var{regex} @gol
@@ -14237,6 +14238,34 @@ the profile feedback data files. See @option{-fprofile-dir}.
 To optimize the program based on the collected profile information, use
 @option{-fprofile-use}.  @xref{Optimize Options}, for more information.
 
+@item -fprofile-info-section
+@itemx -fprofile-info-section=@var{name}
+@opindex fprofile-info-section
+
+Register the profile information in the specified section instead of using a
+constructor/destructor.  The section name is @var{name} if it is specified,
+otherwise the section name defaults to @code{.gcov_info}.  A pointer to the
+profile information generated by @option{-fprofile-arcs} or
+@option{-ftest-coverage} is placed in the specified section for each
+translation unit.  This option disables the profile information registration
+through a constructor and it disables the profile information processing
+through a destructor.  This option is not intended to be used in hosted
+environments such as GNU/Linux.  It targets systems with limited resources
+which do not support constructors and destructors.  The linker could collect
+the input sections in a continuous memory block and define start and end
+symbols.  The runtime support could dump the profiling information registered
+in this linker set during program termination to a serial line for example.  A
+GNU linker script example which defines a linker output section follows:
+
+@smallexample
+  .gcov_info      :
+  @{
+    PROVIDE (__gcov_info_start = .);
+    KEEP (*(.gcov_info))
+    PROVIDE (__gcov_info_end = .);
+  @}
+@end smallexample
+
 @item -fprofile-note=@var{path}
 @opindex fprofile-note
 
diff --git a/gcc/opts.c b/gcc/opts.c
index ac9972d9c38..57774916a09 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -2596,6 +2596,10 @@ common_handle_option (struct gcc_options *opts,
       SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_bit_cp, value);
       break;
 
+    case OPT_fprofile_info_section:
+      opts->x_profile_info_section = ".gcov_info";
+      break;
+
     case OPT_fpatchable_function_entry_:
       {
 	char *patch_area_arg = xstrdup (arg);
diff --git a/gcc/testsuite/gcc.dg/profile-info-section.c b/gcc/testsuite/gcc.dg/profile-info-section.c
new file mode 100644
index 00000000000..c27fe17084e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/profile-info-section.c
@@ -0,0 +1,20 @@
+/* { dg-options "-fprofile-arcs -fprofile-info-section -fdump-tree-optimized" } */
+
+int foo()
+{
+  return 0;
+}
+
+int bar()
+{
+  return 1;
+}
+
+int main ()
+{
+  return foo ();
+}
+
+/* { dg-final { scan-tree-dump-not "__gcov_init" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "__gcov_exit" "optimized" } } */
+/* { dg-final { scan-assembler "\.gcov_info" } } */
-- 
2.29.2

Reply via email to