re PR debug/81307 (g++.dg/debug/debug9.C -gstabs FAILs)

PR debug/81307
	* dbxout.c (lastlineno): New variable.
	(dbx_debug_hooks): Use dbxout_switch_text_section as
	switch_text_section debug hook.
	(dbxout_function_end): Switch to current_function_section
	rather than function_section.  If crtl->has_bb_partition,
	output just one N_FUN, depending on in_cold_section_p.
	(dbxout_source_line): Remember last lineno in lastlineno.
	(dbxout_switch_text_section): New function.
	(dbxout_function_decl): Adjust dbxout_block caller.
	(dbx_block_with_cold_children): New function.
	(dbxout_block): Return true if any LBRAC/RBRAC have been
	emitted.  Use dbx_block_with_cold_children at depth == 0
	in second partition.  Add PARENT_BLOCKNUM argument, pass
	it optionally adjusted to children.  Output LBRAC/RBRAC
	around recursive call only if the block is in the current
	partition, if not and anything was output, emit empty
	range LBRAC/RBRAC.
	* final.c (final_scan_insn): Compute cold_function_name
	before calling switch_text_section debug hook.  Call
	that hook even if dwarf2out_do_frame if not emitting
	dwarf debug info.

	* g++.dg/debug/debug9.C: Remove -fno-reorder-blocks-and-partition
	workaround.

From-SVN: r255161
This commit is contained in:
Jakub Jelinek 2017-11-27 09:48:56 +01:00 committed by Jakub Jelinek
parent 9adeb64ab9
commit b8cb3096f7
5 changed files with 170 additions and 25 deletions

View File

@ -1,5 +1,28 @@
2017-11-27 Jakub Jelinek <jakub@redhat.com>
PR debug/81307
* dbxout.c (lastlineno): New variable.
(dbx_debug_hooks): Use dbxout_switch_text_section as
switch_text_section debug hook.
(dbxout_function_end): Switch to current_function_section
rather than function_section. If crtl->has_bb_partition,
output just one N_FUN, depending on in_cold_section_p.
(dbxout_source_line): Remember last lineno in lastlineno.
(dbxout_switch_text_section): New function.
(dbxout_function_decl): Adjust dbxout_block caller.
(dbx_block_with_cold_children): New function.
(dbxout_block): Return true if any LBRAC/RBRAC have been
emitted. Use dbx_block_with_cold_children at depth == 0
in second partition. Add PARENT_BLOCKNUM argument, pass
it optionally adjusted to children. Output LBRAC/RBRAC
around recursive call only if the block is in the current
partition, if not and anything was output, emit empty
range LBRAC/RBRAC.
* final.c (final_scan_insn): Compute cold_function_name
before calling switch_text_section debug hook. Call
that hook even if dwarf2out_do_frame if not emitting
dwarf debug info.
PR target/83100
* varasm.c (bss_initializer_p): Return true for DECL_COMMON
TREE_READONLY decls.

View File

@ -244,6 +244,10 @@ static GTY(()) int source_label_number = 1;
static GTY(()) const char *lastfile;
/* Last line number mentioned in a NOTE insn. */
static GTY(()) unsigned int lastlineno;
/* Used by PCH machinery to detect if 'lastfile' should be reset to
base_input_file. */
static GTY(()) int lastfile_is_base;
@ -334,6 +338,7 @@ static void debug_free_queue (void);
static void dbxout_source_line (unsigned int, unsigned int, const char *,
int, bool);
static void dbxout_switch_text_section (void);
static void dbxout_begin_prologue (unsigned int, unsigned int, const char *);
static void dbxout_source_file (const char *);
static void dbxout_function_end (tree);
@ -380,7 +385,7 @@ const struct gcc_debug_hooks dbx_debug_hooks =
dbxout_handle_pch, /* handle_pch */
debug_nothing_rtx_insn, /* var_location */
debug_nothing_tree, /* size_function */
debug_nothing_void, /* switch_text_section */
dbxout_switch_text_section, /* switch_text_section */
debug_nothing_tree_tree, /* set_name */
0, /* start_end_main_source_file */
TYPE_SYMTAB_IS_ADDRESS /* tree_type_symtab_field */
@ -902,7 +907,7 @@ dbxout_function_end (tree decl ATTRIBUTE_UNUSED)
/* The Lscope label must be emitted even if we aren't doing anything
else; dbxout_block needs it. */
switch_to_section (function_section (current_function_decl));
switch_to_section (current_function_section ());
/* Convert Lscope into the appropriate format for local labels in case
the system doesn't insert underscores in front of user generated
@ -923,11 +928,12 @@ dbxout_function_end (tree decl ATTRIBUTE_UNUSED)
if (crtl->has_bb_partition)
{
dbxout_begin_empty_stabs (N_FUN);
dbxout_stab_value_label_diff (crtl->subsections.hot_section_end_label,
crtl->subsections.hot_section_label);
dbxout_begin_empty_stabs (N_FUN);
dbxout_stab_value_label_diff (crtl->subsections.cold_section_end_label,
crtl->subsections.cold_section_label);
if (in_cold_section_p)
dbxout_stab_value_label_diff (crtl->subsections.cold_section_end_label,
crtl->subsections.cold_section_label);
else
dbxout_stab_value_label_diff (crtl->subsections.hot_section_end_label,
crtl->subsections.hot_section_label);
}
else
{
@ -1215,7 +1221,7 @@ dbxout_handle_pch (unsigned at_end)
#if defined (DBX_DEBUGGING_INFO)
static void dbxout_block (tree, int, tree);
static bool dbxout_block (tree, int, tree, int);
/* Output debugging info to FILE to switch to sourcefile FILENAME. */
@ -1289,6 +1295,60 @@ dbxout_source_line (unsigned int lineno, unsigned int column ATTRIBUTE_UNUSED,
else
dbxout_stabd (N_SLINE, lineno);
#endif
lastlineno = lineno;
}
/* Unfortunately, at least when emitting relative addresses, STABS
has no way to express multiple partitions. Represent a function
as two functions in this case. */
static void
dbxout_switch_text_section (void)
{
/* The N_FUN tag at the end of the function is a GNU extension,
which may be undesirable, and is unnecessary if we do not have
named sections. */
in_cold_section_p = !in_cold_section_p;
switch_to_section (current_function_section ());
dbxout_block (DECL_INITIAL (current_function_decl), 0,
DECL_ARGUMENTS (current_function_decl), -1);
dbxout_function_end (current_function_decl);
in_cold_section_p = !in_cold_section_p;
switch_to_section (current_function_section ());
tree context = decl_function_context (current_function_decl);
extern tree cold_function_name;
dbxout_begin_complex_stabs ();
stabstr_I (cold_function_name);
stabstr_S (":f");
tree type = TREE_TYPE (current_function_decl);
if (TREE_TYPE (type))
dbxout_type (TREE_TYPE (type), 0);
else
dbxout_type (void_type_node, 0);
if (context != 0)
{
stabstr_C (',');
stabstr_I (cold_function_name);
stabstr_C (',');
stabstr_I (DECL_NAME (context));
}
dbxout_finish_complex_stabs (current_function_decl, N_FUN, 0,
crtl->subsections.cold_section_label, 0);
/* pre-increment the scope counter */
scope_labelno++;
dbxout_source_line (lastlineno, 0, lastfile, 0, true);
/* Output function begin block at function scope, referenced
by dbxout_block, dbxout_source_line and dbxout_function_end. */
emit_pending_bincls_if_required ();
targetm.asm_out.internal_label (asm_out_file, "LFBB", scope_labelno);
}
/* Describe the beginning of an internal block within a function. */
@ -1322,7 +1382,7 @@ dbxout_function_decl (tree decl)
#ifndef DBX_FUNCTION_FIRST
dbxout_begin_function (decl);
#endif
dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));
dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl), -1);
dbxout_function_end (decl);
}
@ -3664,6 +3724,26 @@ dbx_output_rbrac (const char *label,
dbxout_stab_value_label (label);
}
/* Return true is at least one block among BLOCK, its children or siblings
which has TREE_USED, TREE_ASM_WRITTEN and BLOCK_IN_COLD_SECTION_P
set. If there is none, clear TREE_USED bit on such blocks. */
static bool
dbx_block_with_cold_children (tree block)
{
bool ret = false;
for (; block; block = BLOCK_CHAIN (block))
if (TREE_USED (block) && TREE_ASM_WRITTEN (block))
{
bool children = dbx_block_with_cold_children (BLOCK_SUBBLOCKS (block));
if (BLOCK_IN_COLD_SECTION_P (block) || children)
ret = true;
else
TREE_USED (block) = false;
}
return ret;
}
/* Output everything about a symbol block (a BLOCK node
that represents a scope level),
including recursive output of contained blocks.
@ -3679,22 +3759,31 @@ dbx_output_rbrac (const char *label,
except for the outermost block.
Actually, BLOCK may be several blocks chained together.
We handle them all in sequence. */
We handle them all in sequence.
static void
dbxout_block (tree block, int depth, tree args)
Return true if we emitted any LBRAC/RBRAC. */
static bool
dbxout_block (tree block, int depth, tree args, int parent_blocknum)
{
bool ret = false;
char begin_label[20];
/* Reference current function start using LFBB. */
ASM_GENERATE_INTERNAL_LABEL (begin_label, "LFBB", scope_labelno);
while (block)
/* If called for the second partition, ignore blocks that don't have
any children in the second partition. */
if (crtl->has_bb_partition && in_cold_section_p && depth == 0)
dbx_block_with_cold_children (block);
for (; block; block = BLOCK_CHAIN (block))
{
/* Ignore blocks never expanded or otherwise marked as real. */
if (TREE_USED (block) && TREE_ASM_WRITTEN (block))
{
int did_output;
int blocknum = BLOCK_NUMBER (block);
int this_parent = parent_blocknum;
/* In dbx format, the syms of a block come before the N_LBRAC.
If nothing is output, we don't need the N_LBRAC, either. */
@ -3708,11 +3797,13 @@ dbxout_block (tree block, int depth, tree args)
the block. Use the block's tree-walk order to generate
the assembler symbols LBBn and LBEn
that final will define around the code in this block. */
if (did_output)
if (did_output
&& BLOCK_IN_COLD_SECTION_P (block) == in_cold_section_p)
{
char buf[20];
const char *scope_start;
ret = true;
if (depth == 0)
/* The outermost block doesn't get LBB labels; use
the LFBB local symbol emitted by dbxout_begin_prologue. */
@ -3721,16 +3812,21 @@ dbxout_block (tree block, int depth, tree args)
{
ASM_GENERATE_INTERNAL_LABEL (buf, "LBB", blocknum);
scope_start = buf;
this_parent = blocknum;
}
dbx_output_lbrac (scope_start, begin_label);
}
/* Output the subblocks. */
dbxout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE);
bool children
= dbxout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE,
this_parent);
ret |= children;
/* Refer to the marker for the end of the block. */
if (did_output)
if (did_output
&& BLOCK_IN_COLD_SECTION_P (block) == in_cold_section_p)
{
char buf[100];
if (depth == 0)
@ -3743,9 +3839,29 @@ dbxout_block (tree block, int depth, tree args)
dbx_output_rbrac (buf, begin_label);
}
else if (did_output && !children)
{
/* If we emitted any vars and didn't output any LBRAC/RBRAC,
either at this level or any lower level, we need to emit
an empty LBRAC/RBRAC pair now. */
char buf[20];
const char *scope_start;
ret = true;
if (parent_blocknum == -1)
scope_start = begin_label;
else
{
ASM_GENERATE_INTERNAL_LABEL (buf, "LBB", parent_blocknum);
scope_start = buf;
}
dbx_output_lbrac (scope_start, begin_label);
dbx_output_rbrac (scope_start, begin_label);
}
}
block = BLOCK_CHAIN (block);
}
return ret;
}
/* Output the information about a function and its arguments and result.

View File

@ -2210,8 +2210,17 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
case NOTE_INSN_SWITCH_TEXT_SECTIONS:
in_cold_section_p = !in_cold_section_p;
if (in_cold_section_p)
cold_function_name
= clone_function_name (current_function_decl, "cold");
if (dwarf2out_do_frame ())
dwarf2out_switch_text_section ();
{
dwarf2out_switch_text_section ();
if (!dwarf2_debug_info_emitted_p (current_function_decl)
&& !DECL_IGNORED_P (current_function_decl))
debug_hooks->switch_text_section ();
}
else if (!DECL_IGNORED_P (current_function_decl))
debug_hooks->switch_text_section ();
@ -2223,8 +2232,6 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
suffixing "cold" to the original function's name. */
if (in_cold_section_p)
{
cold_function_name
= clone_function_name (current_function_decl, "cold");
#ifdef ASM_DECLARE_COLD_FUNCTION_NAME
ASM_DECLARE_COLD_FUNCTION_NAME (asm_out_file,
IDENTIFIER_POINTER

View File

@ -1,5 +1,9 @@
2017-11-27 Jakub Jelinek <jakub@redhat.com>
PR debug/81307
* g++.dg/debug/debug9.C: Remove -fno-reorder-blocks-and-partition
workaround.
PR target/83100
* gcc.dg/pr83100-1.c: New test.
* gcc.dg/pr83100-2.c: New test.

View File

@ -1,9 +1,4 @@
/* { dg-do assemble } */
/* Partitioning causes hot/cold section emission and breaks stabs
debugging. */
/* { dg-additional-options "-fno-reorder-blocks-and-partition" } */
/* This testcase requires entries in the debug_range section in DWARF which
refer to a vague linkage function. */