* [PATCH] Avoid the redundant DW_TAG_lexical_block below DW_TAG_subprogram emitted by C++ FE (PR debug/55541)
@ 2015-02-05 22:53 Jakub Jelinek
2015-02-12 16:58 ` Jason Merrill
0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2015-02-05 22:53 UTC (permalink / raw)
To: Jason Merrill; +Cc: gcc-patches
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
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] Avoid the redundant DW_TAG_lexical_block below DW_TAG_subprogram emitted by C++ FE (PR debug/55541)
2015-02-05 22:53 [PATCH] Avoid the redundant DW_TAG_lexical_block below DW_TAG_subprogram emitted by C++ FE (PR debug/55541) Jakub Jelinek
@ 2015-02-12 16:58 ` Jason Merrill
0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2015-02-12 16:58 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: gcc-patches
OK.
Jason
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-02-12 16:58 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-05 22:53 [PATCH] Avoid the redundant DW_TAG_lexical_block below DW_TAG_subprogram emitted by C++ FE (PR debug/55541) Jakub Jelinek
2015-02-12 16:58 ` Jason Merrill
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).