This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Avoid the redundant DW_TAG_lexical_block below DW_TAG_subprogram emitted by C++ FE (PR debug/55541)


Hi!

Long time ago, probably all FEs or most of them emitted an extra BLOCK
around the BLOCK corresponding to user scope of the function, then
the C FE has been changed not to and no_body_blocks langhook has been added
for it (and Java/Ada/Fortran were mishandled), later on r144474
removed the langhook and left C++ broken.

As the testcase shows, this is not only unnecessary increase in debug info
size (0.5% on cc1plus), but also makes it harder to debug programs, because
some variables might appear out of scope on the closing }.

This patch tweaks the C++ FE to do what C FE does for 11+ years already,
emit the variables in the function scope directly in DW_TAG_subprogram
rather than keeping there just the parameters and putting everything else
in an artificial DW_TAG_lexical_block.

I had to tweak outer_curly_brace_block, so that it would still be able to
find the right block with the function scope for FUNCTION_NEEDS_BODY_BLOCK
and other functions, if we could avoid the artificial block or not.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2015-02-05  Jakub Jelinek  <jakub@redhat.com>

	PR debug/55541
	* cp-tree.h (BLOCK_OUTER_CURLY_BRACE_P): Define.
	* decl.c (poplevel): If functionbody, try not to create an extra
	BLOCK for function body and use subblocks as that, if it is non-NULL
	and doesn't have siblings.  Set BLOCK_OUTER_CURLY_BRACE_P flag.
	(outer_curly_brace_block): Use BLOCK_OUTER_CURLY_BRACE_P flag.

	* g++.dg/debug/dwarf2/localclass3.C: Adjust for the extraneous
	DW_TAG_lexical_block removal.
	* g++.dg/debug/dwarf2/redeclaration-1.C: Likewise.
	* g++.dg/guality/pr55541.C: New test.

--- gcc/cp/cp-tree.h.jj	2015-01-15 23:57:07.000000000 +0100
+++ gcc/cp/cp-tree.h	2015-02-05 19:45:35.015905343 +0100
@@ -84,6 +84,7 @@ c-common.h, not after.
       PACK_EXPANSION_LOCAL_P (in *_PACK_EXPANSION)
       TINFO_HAS_ACCESS_ERRORS (in TEMPLATE_INFO)
       SIZEOF_EXPR_TYPE_P (in SIZEOF_EXPR)
+      BLOCK_OUTER_CURLY_BRACE_P (in BLOCK)
    1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE)
       TI_PENDING_TEMPLATE_FLAG.
       TEMPLATE_PARMS_FOR_INLINE.
@@ -326,6 +327,9 @@ typedef struct ptrmem_cst * ptrmem_cst_t
 #define STATEMENT_LIST_TRY_BLOCK(NODE) \
   TREE_LANG_FLAG_2 (STATEMENT_LIST_CHECK (NODE))
 
+/* Mark the outer curly brace BLOCK.  */
+#define BLOCK_OUTER_CURLY_BRACE_P(NODE)	TREE_LANG_FLAG_0 (BLOCK_CHECK (NODE))
+
 /* Nonzero if this statement should be considered a full-expression,
    i.e., if temporaries created during this statement should have
    their destructors run at the end of this statement.  */
--- gcc/cp/decl.c.jj	2015-02-03 10:33:56.000000000 +0100
+++ gcc/cp/decl.c	2015-02-05 21:03:39.851179354 +0100
@@ -610,7 +610,10 @@ poplevel (int keep, int reverse, int fun
      or if this level is a function body,
      create a BLOCK to record them for the life of this function.  */
   block = NULL_TREE;
-  if (keep == 1 || functionbody)
+  /* Avoid function body block if possible.  */
+  if (functionbody && subblocks && BLOCK_CHAIN (subblocks) == NULL_TREE)
+    keep = 0;
+  else if (keep == 1 || functionbody)
     block = make_node (BLOCK);
   if (block != NULL_TREE)
     {
@@ -793,11 +796,16 @@ poplevel (int keep, int reverse, int fun
      check over all the labels.  */
   if (functionbody)
     {
-      /* Since this is the top level block of a function, the vars are
-	 the function's parameters.  Don't leave them in the BLOCK
-	 because they are found in the FUNCTION_DECL instead.  */
-      BLOCK_VARS (block) = 0;
-      pop_labels (block);
+      if (block)
+	{
+	  /* Since this is the top level block of a function, the vars are
+	     the function's parameters.  Don't leave them in the BLOCK
+	     because they are found in the FUNCTION_DECL instead.  */
+	  BLOCK_VARS (block) = 0;
+	  pop_labels (block);
+	}
+      else
+	pop_labels (subblocks);
     }
 
   kind = current_binding_level->kind;
@@ -819,7 +827,17 @@ poplevel (int keep, int reverse, int fun
       /* The current function is being defined, so its DECL_INITIAL
 	 should be error_mark_node.  */
       gcc_assert (DECL_INITIAL (current_function_decl) == error_mark_node);
-      DECL_INITIAL (current_function_decl) = block;
+      DECL_INITIAL (current_function_decl) = block ? block : subblocks;
+      if (subblocks)
+	{
+	  if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
+	    {
+	      if (BLOCK_SUBBLOCKS (subblocks))
+		BLOCK_OUTER_CURLY_BRACE_P (BLOCK_SUBBLOCKS (subblocks)) = 1;
+	    }
+	  else
+	    BLOCK_OUTER_CURLY_BRACE_P (subblocks) = 1;
+	}
     }
   else if (block)
     current_binding_level->blocks
@@ -14053,10 +14071,14 @@ finish_function_body (tree compstmt)
 tree
 outer_curly_brace_block (tree fndecl)
 {
-  tree block = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl));
-  if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
-    /* Skip the artificial function body block.  */
-    block = BLOCK_SUBBLOCKS (block);
+  tree block = DECL_INITIAL (fndecl);
+  if (BLOCK_OUTER_CURLY_BRACE_P (block))
+    return block;
+  block = BLOCK_SUBBLOCKS (block);
+  if (BLOCK_OUTER_CURLY_BRACE_P (block))
+    return block;
+  block = BLOCK_SUBBLOCKS (block);
+  gcc_assert (BLOCK_OUTER_CURLY_BRACE_P (block));
   return block;
 }
 
--- gcc/testsuite/g++.dg/debug/dwarf2/localclass3.C.jj	2012-05-08 14:16:04.000000000 +0200
+++ gcc/testsuite/g++.dg/debug/dwarf2/localclass3.C	2015-02-05 21:49:01.738482422 +0100
@@ -4,8 +4,11 @@
 
 void f()
 {
-  struct A { int i; } *ap;
-  ap->i = 42;
+  int j = 5;
+  {
+    struct A { int i; } *ap;
+    ap->i = 42;
+  }
 }
 
 // { dg-final { scan-assembler "DW_TAG_pointer_type.\[^)\]*. DW_TAG_structure_type" } }
--- gcc/testsuite/g++.dg/debug/dwarf2/redeclaration-1.C.jj	2010-04-07 13:39:52.000000000 +0200
+++ gcc/testsuite/g++.dg/debug/dwarf2/redeclaration-1.C	2015-02-05 21:57:08.348311646 +0100
@@ -9,10 +9,12 @@ namespace S
   int
   f()
   {
-    int i = 42;
     {
-      extern int i;
-      return i;
+      int i = 42;
+      {
+	extern int i;
+	return i;
+      }
     }
   }
 }
--- gcc/testsuite/g++.dg/guality/pr55541.C.jj	2015-02-05 17:13:56.947978046 +0100
+++ gcc/testsuite/g++.dg/guality/pr55541.C	2015-02-05 17:13:34.000000000 +0100
@@ -0,0 +1,11 @@
+// PR debug/55541
+// { dg-do run }
+// { dg-options "-g" }
+
+int
+main ()
+{
+  int vari;
+  vari = 10;
+  vari = vari + 5;
+} // { dg-final { gdb-test 11 "vari" "15" } }


	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]