debug/96383 - emit debug info for used external functions

Message ID nycvar.YFH.7.76.2007311423260.9963@zhemvz.fhfr.qr
State New
Headers show
Series
  • debug/96383 - emit debug info for used external functions
Related show

Commit Message

Richard Biener July 31, 2020, 12:24 p.m.
This makes sure to emit full declaration DIEs including
formal parameters for used external functions.  This helps
debugging when debug information of the external entity is
not available and also helps external tools cross-checking
ABI compatibility which was the bug reporters use case.

For cc1 this affects debug information size as follows:

     VM SIZE                     FILE SIZE
 ++++++++++++++ GROWING       ++++++++++++++
  [ = ]       0 .debug_info   +1.63Mi  +1.3%
  [ = ]       0 .debug_str     +263Ki  +3.4%
  [ = ]       0 .debug_abbrev  +101Ki  +4.9%
  [ = ]       0 .debug_line   +5.71Ki  +0.0%
   +44%     +16 [Unmapped]        +48  +1.2%

 -------------- SHRINKING     --------------
  [ = ]       0 .debug_loc       -213  -0.0%
  -0.0%     -48 .text             -48  -0.0%
  [ = ]       0 .debug_ranges     -16  -0.0%

  -0.0%     -32 TOTAL         +1.99Mi  +0.6%

and DWARF compression via DWZ can only shave off minor bits
here.

Previously we emitted no DIEs for external functions at all
unless they were referenced via DW_TAG_GNU_call_site which
for some GCC revs caused a regular DIE to appear and since
GCC 4.9 only a stub without formal parameters.  This means
at -O0 we did not emit any DIE for external functions
but with optimization we emitted stubs.

Bootstrapped and tested on x86_64-unknown-linux-gnu, OK for trunk?
What about branch(es)?

Thanks,
Richard.

2020-07-30  Richard Biener  <rguenther@suse.de>

	PR debug/96383
	c-family/
	* c-common.h (c_common_finalize_early_debug): Declare.
	* c-common.c: Include debug.h.
	(c_common_finalize_early_debug): finalize_early_debug langhook
	implementation generating debug for extern declarations.

	c/
	* c-objc-common.h (LANG_HOOKS_FINALIZE_EARLY_DEBUG):
	Define to c_common_finalize_early_debug.

	cp/
	* cp-objcp-common.h (LANG_HOOKS_FINALIZE_EARLY_DEBUG):
	Define to c_common_finalize_early_debug.

	* langhooks-def.h (lhd_finalize_early_debug): Declare.
	(LANG_HOOKS_FINALIZE_EARLY_DEBUG): Define.
	(LANG_HOOKS_INITIALIZER): Amend.
	* langhooks.c: Include cgraph.h and debug.h.
	(lhd_finalize_early_debug): Default implementation from
	former code in finalize_compilation_unit.
	* langhooks.h (lang_hooks::finalize_early_debug): Add.

	gcc/
	* cgraphunit.c (symbol_table::finalize_compilation_unit):
	Call the finalize_early_debug langhook.

	* gcc.dg/debug/dwarf2/pr96383-1.c: New testcase.
	* gcc.dg/debug/dwarf2/pr96383-2.c: Likewise.

	libstdc++/
	* testsuite/20_util/assume_aligned/3.cc: Use -g0.
---
 gcc/c-family/c-common.c                         | 17 +++++++++++++++++
 gcc/c-family/c-common.h                         |  2 ++
 gcc/c/c-objc-common.h                           |  2 ++
 gcc/cgraphunit.c                                |  8 +++-----
 gcc/cp/cp-objcp-common.h                        |  2 ++
 gcc/langhooks-def.h                             |  5 ++++-
 gcc/langhooks.c                                 | 14 ++++++++++++++
 gcc/langhooks.h                                 |  3 +++
 gcc/testsuite/gcc.dg/debug/dwarf2/pr96383-1.c   | 17 +++++++++++++++++
 gcc/testsuite/gcc.dg/debug/dwarf2/pr96383-2.c   | 17 +++++++++++++++++
 .../testsuite/20_util/assume_aligned/3.cc       |  2 +-
 11 files changed, 82 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/pr96383-1.c
 create mode 100644 gcc/testsuite/gcc.dg/debug/dwarf2/pr96383-2.c

-- 
2.26.2

Comments

Ian Lance Taylor via Gcc-patches July 31, 2020, 12:32 p.m. | #1
On Fri, Jul 31, 2020 at 02:24:08PM +0200, Richard Biener wrote:
> 2020-07-30  Richard Biener  <rguenther@suse.de>

> 

> 	PR debug/96383

> 	c-family/

> 	* c-common.h (c_common_finalize_early_debug): Declare.

> 	* c-common.c: Include debug.h.

> 	(c_common_finalize_early_debug): finalize_early_debug langhook

> 	implementation generating debug for extern declarations.

> 

> 	c/

> 	* c-objc-common.h (LANG_HOOKS_FINALIZE_EARLY_DEBUG):

> 	Define to c_common_finalize_early_debug.

> 

> 	cp/

> 	* cp-objcp-common.h (LANG_HOOKS_FINALIZE_EARLY_DEBUG):

> 	Define to c_common_finalize_early_debug.

> 

> 	* langhooks-def.h (lhd_finalize_early_debug): Declare.

> 	(LANG_HOOKS_FINALIZE_EARLY_DEBUG): Define.

> 	(LANG_HOOKS_INITIALIZER): Amend.

> 	* langhooks.c: Include cgraph.h and debug.h.

> 	(lhd_finalize_early_debug): Default implementation from

> 	former code in finalize_compilation_unit.

> 	* langhooks.h (lang_hooks::finalize_early_debug): Add.

> 

> 	gcc/

> 	* cgraphunit.c (symbol_table::finalize_compilation_unit):

> 	Call the finalize_early_debug langhook.

> 

> 	* gcc.dg/debug/dwarf2/pr96383-1.c: New testcase.

> 	* gcc.dg/debug/dwarf2/pr96383-2.c: Likewise.

> 

> 	libstdc++/

> 	* testsuite/20_util/assume_aligned/3.cc: Use -g0.


LGTM for trunk right now, for 10.3 perhaps after 2 weeks.  Not sure about
older branches, either not at all, or after much longer settlement period.

	Jakub

Patch

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 116867a4513..b97539c0c2a 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -50,6 +50,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "spellcheck.h"
 #include "c-spellcheck.h"
 #include "selftest.h"
+#include "debug.h"
 
 cpp_reader *parse_in;		/* Declared in c-pragma.h.  */
 
@@ -9086,4 +9087,20 @@  braced_lists_to_strings (tree type, tree ctor)
   return braced_lists_to_strings (type, ctor, false);
 }
 
+
+/* Emit debug for functions before finalizing early debug.  */
+
+void
+c_common_finalize_early_debug (void)
+{
+  /* Emit early debug for reachable functions, and by consequence,
+     locally scoped symbols.  Also emit debug for extern declared
+     functions that are still reachable at this point.  */
+  struct cgraph_node *cnode;
+  FOR_EACH_FUNCTION (cnode)
+    if (!cnode->alias && !cnode->thunk.thunk_p
+	&& (cnode->has_gimple_body_p () || !DECL_IS_BUILTIN (cnode->decl)))
+      (*debug_hooks->early_global_decl) (cnode->decl);
+}
+
 #include "gt-c-family-c-common.h"
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 61627264e1e..4fc64bc4aa6 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -885,6 +885,8 @@  extern bool bool_promoted_to_int_p (tree);
 extern tree fold_for_warn (tree);
 extern tree c_common_get_narrower (tree, int *);
 extern bool get_attribute_operand (tree, unsigned HOST_WIDE_INT *);
+extern void c_common_finalize_early_debug (void);
+
 
 #define c_sizeof(LOC, T)  c_sizeof_or_alignof_type (LOC, T, true, false, 1)
 #define c_alignof(LOC, T) c_sizeof_or_alignof_type (LOC, T, false, false, 1)
diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h
index 5471fc7e355..925795986e7 100644
--- a/gcc/c/c-objc-common.h
+++ b/gcc/c/c-objc-common.h
@@ -65,6 +65,8 @@  along with GCC; see the file COPYING3.  If not see
   c_simulate_builtin_function_decl
 #undef LANG_HOOKS_EMITS_BEGIN_STMT
 #define LANG_HOOKS_EMITS_BEGIN_STMT true
+#undef LANG_HOOKS_FINALIZE_EARLY_DEBUG
+#define LANG_HOOKS_FINALIZE_EARLY_DEBUG c_common_finalize_early_debug
 
 /* Attribute hooks.  */
 #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 0a95eb93ce2..0b1009d0dea 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -2998,11 +2998,9 @@  symbol_table::finalize_compilation_unit (void)
 
   if (!seen_error ())
     {
-      /* Emit early debug for reachable functions, and by consequence,
-	 locally scoped symbols.  */
-      struct cgraph_node *cnode;
-      FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (cnode)
-	(*debug_hooks->early_global_decl) (cnode->decl);
+      /* Give the frontends the chance to emit early debug based on
+	 what is still reachable in the TU.  */
+      (*lang_hooks.finalize_early_debug) ();
 
       /* Clean up anything that needs cleaning up after initial debug
 	 generation.  */
diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
index de8d606fe2c..0936f166d5b 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -115,6 +115,8 @@  extern tree cxx_simulate_enum_decl (location_t, const char *,
 #define LANG_HOOKS_BLOCK_MAY_FALLTHRU cxx_block_may_fallthru
 #undef LANG_HOOKS_EMITS_BEGIN_STMT
 #define LANG_HOOKS_EMITS_BEGIN_STMT true
+#undef LANG_HOOKS_FINALIZE_EARLY_DEBUG
+#define LANG_HOOKS_FINALIZE_EARLY_DEBUG c_common_finalize_early_debug
 
 /* Attribute hooks.  */
 #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index 6e4e2cc9367..67b02107c49 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -92,6 +92,7 @@  extern const char *lhd_get_substring_location (const substring_loc &,
 					       location_t *out_loc);
 extern int lhd_decl_dwarf_attribute (const_tree, int);
 extern int lhd_type_dwarf_attribute (const_tree, int);
+extern void lhd_finalize_early_debug (void);
 
 #define LANG_HOOKS_NAME			"GNU unknown"
 #define LANG_HOOKS_IDENTIFIER_SIZE	sizeof (struct lang_identifier)
@@ -139,6 +140,7 @@  extern int lhd_type_dwarf_attribute (const_tree, int);
 #define LANG_HOOKS_EMITS_BEGIN_STMT	false
 #define LANG_HOOKS_RUN_LANG_SELFTESTS   lhd_do_nothing
 #define LANG_HOOKS_GET_SUBSTRING_LOCATION lhd_get_substring_location
+#define LANG_HOOKS_FINALIZE_EARLY_DEBUG lhd_finalize_early_debug
 
 /* Attribute hooks.  */
 #define LANG_HOOKS_ATTRIBUTE_TABLE		NULL
@@ -364,7 +366,8 @@  extern void lhd_end_section (void);
   LANG_HOOKS_CUSTOM_FUNCTION_DESCRIPTORS, \
   LANG_HOOKS_EMITS_BEGIN_STMT, \
   LANG_HOOKS_RUN_LANG_SELFTESTS, \
-  LANG_HOOKS_GET_SUBSTRING_LOCATION \
+  LANG_HOOKS_GET_SUBSTRING_LOCATION, \
+  LANG_HOOKS_FINALIZE_EARLY_DEBUG \
 }
 
 #endif /* GCC_LANG_HOOKS_DEF_H */
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 1cb7cda5b79..3cbe04c6899 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -36,6 +36,8 @@  along with GCC; see the file COPYING3.  If not see
 #include "output.h"
 #include "timevar.h"
 #include "stor-layout.h"
+#include "cgraph.h"
+#include "debug.h"
 
 /* Do nothing; in many cases the default hook.  */
 
@@ -866,6 +868,18 @@  lhd_unit_size_without_reusable_padding (tree t)
   return TYPE_SIZE_UNIT (t);
 }
 
+/* Default implementation for the finalize_early_debug hook.  */
+
+void
+lhd_finalize_early_debug (void)
+{
+  /* Emit early debug for reachable functions, and by consequence,
+     locally scoped symbols.  */
+  struct cgraph_node *cnode;
+  FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (cnode)
+    (*debug_hooks->early_global_decl) (cnode->decl);
+}
+
 /* Returns true if the current lang_hooks represents the GNU C frontend.  */
 
 bool
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 2bd5a67cd37..6ab6fb682f3 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -580,6 +580,9 @@  struct lang_hooks
   const char *(*get_substring_location) (const substring_loc &,
 					 location_t *out_loc);
 
+  /* Invoked before the early_finish debug hook is invoked.  */
+  void (*finalize_early_debug) (void);
+
   /* Whenever you add entries here, make sure you adjust langhooks-def.h
      and langhooks.c accordingly.  */
 };
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr96383-1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr96383-1.c
new file mode 100644
index 00000000000..a9c0efb3fa8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr96383-1.c
@@ -0,0 +1,17 @@ 
+/* { dg-do compile } */
+/* { dg-options "-g -gdwarf -dA" } */
+
+extern void foo (int);
+extern void unusedbar (int);
+
+int main()
+{
+  foo (1);
+}
+
+/* We want subprogram DIEs for both foo and main and a DIE for
+   the formal parameter of foo.  We do not want a DIE for
+   unusedbar.  */
+/* { dg-final { scan-assembler-times "DW_TAG_subprogram" 4 } } */
+/* { dg-final { scan-assembler-times "DW_TAG_formal_parameter" 2 } } */
+/* { dg-final { scan-assembler-not "unusedbar" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr96383-2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr96383-2.c
new file mode 100644
index 00000000000..c3a710e2f89
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr96383-2.c
@@ -0,0 +1,17 @@ 
+/* { dg-do compile } */
+/* { dg-options "-g -O2 -gdwarf -dA" } */
+
+extern void foo (int);
+extern void unusedbar (int);
+
+int main()
+{
+  foo (1);
+}
+
+/* We want subprogram DIEs for both foo and main and a DIE for
+   the formal parameter of foo.  We do not want a DIE for
+   unusedbar.  */
+/* { dg-final { scan-assembler-times "DW_TAG_subprogram" 4 } } */
+/* { dg-final { scan-assembler-times "DW_TAG_formal_parameter" 2 } } */
+/* { dg-final { scan-assembler-not "unusedbar" } } */
diff --git a/libstdc++-v3/testsuite/20_util/assume_aligned/3.cc b/libstdc++-v3/testsuite/20_util/assume_aligned/3.cc
index d1435b54014..25f64d7aad1 100644
--- a/libstdc++-v3/testsuite/20_util/assume_aligned/3.cc
+++ b/libstdc++-v3/testsuite/20_util/assume_aligned/3.cc
@@ -15,7 +15,7 @@ 
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=gnu++2a -O2" }
+// { dg-options "-std=gnu++2a -O2 -g0" }
 // { dg-do compile { target c++2a } }
 // { dg-final { scan-assembler-not "undefined" } }