Commit b8cb3096 by Jakub Jelinek Committed by Jakub Jelinek

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
parent 9adeb64a
2017-11-27 Jakub Jelinek <jakub@redhat.com> 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 PR target/83100
* varasm.c (bss_initializer_p): Return true for DECL_COMMON * varasm.c (bss_initializer_p): Return true for DECL_COMMON
TREE_READONLY decls. TREE_READONLY decls.
...@@ -244,6 +244,10 @@ static GTY(()) int source_label_number = 1; ...@@ -244,6 +244,10 @@ static GTY(()) int source_label_number = 1;
static GTY(()) const char *lastfile; 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 /* Used by PCH machinery to detect if 'lastfile' should be reset to
base_input_file. */ base_input_file. */
static GTY(()) int lastfile_is_base; static GTY(()) int lastfile_is_base;
...@@ -334,6 +338,7 @@ static void debug_free_queue (void); ...@@ -334,6 +338,7 @@ static void debug_free_queue (void);
static void dbxout_source_line (unsigned int, unsigned int, const char *, static void dbxout_source_line (unsigned int, unsigned int, const char *,
int, bool); int, bool);
static void dbxout_switch_text_section (void);
static void dbxout_begin_prologue (unsigned int, unsigned int, const char *); static void dbxout_begin_prologue (unsigned int, unsigned int, const char *);
static void dbxout_source_file (const char *); static void dbxout_source_file (const char *);
static void dbxout_function_end (tree); static void dbxout_function_end (tree);
...@@ -380,7 +385,7 @@ const struct gcc_debug_hooks dbx_debug_hooks = ...@@ -380,7 +385,7 @@ const struct gcc_debug_hooks dbx_debug_hooks =
dbxout_handle_pch, /* handle_pch */ dbxout_handle_pch, /* handle_pch */
debug_nothing_rtx_insn, /* var_location */ debug_nothing_rtx_insn, /* var_location */
debug_nothing_tree, /* size_function */ debug_nothing_tree, /* size_function */
debug_nothing_void, /* switch_text_section */ dbxout_switch_text_section, /* switch_text_section */
debug_nothing_tree_tree, /* set_name */ debug_nothing_tree_tree, /* set_name */
0, /* start_end_main_source_file */ 0, /* start_end_main_source_file */
TYPE_SYMTAB_IS_ADDRESS /* tree_type_symtab_field */ TYPE_SYMTAB_IS_ADDRESS /* tree_type_symtab_field */
...@@ -902,7 +907,7 @@ dbxout_function_end (tree decl ATTRIBUTE_UNUSED) ...@@ -902,7 +907,7 @@ dbxout_function_end (tree decl ATTRIBUTE_UNUSED)
/* The Lscope label must be emitted even if we aren't doing anything /* The Lscope label must be emitted even if we aren't doing anything
else; dbxout_block needs it. */ 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 /* Convert Lscope into the appropriate format for local labels in case
the system doesn't insert underscores in front of user generated the system doesn't insert underscores in front of user generated
...@@ -923,11 +928,12 @@ dbxout_function_end (tree decl ATTRIBUTE_UNUSED) ...@@ -923,11 +928,12 @@ dbxout_function_end (tree decl ATTRIBUTE_UNUSED)
if (crtl->has_bb_partition) if (crtl->has_bb_partition)
{ {
dbxout_begin_empty_stabs (N_FUN); dbxout_begin_empty_stabs (N_FUN);
dbxout_stab_value_label_diff (crtl->subsections.hot_section_end_label, if (in_cold_section_p)
crtl->subsections.hot_section_label); dbxout_stab_value_label_diff (crtl->subsections.cold_section_end_label,
dbxout_begin_empty_stabs (N_FUN); crtl->subsections.cold_section_label);
dbxout_stab_value_label_diff (crtl->subsections.cold_section_end_label, else
crtl->subsections.cold_section_label); dbxout_stab_value_label_diff (crtl->subsections.hot_section_end_label,
crtl->subsections.hot_section_label);
} }
else else
{ {
...@@ -1215,7 +1221,7 @@ dbxout_handle_pch (unsigned at_end) ...@@ -1215,7 +1221,7 @@ dbxout_handle_pch (unsigned at_end)
#if defined (DBX_DEBUGGING_INFO) #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. */ /* 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, ...@@ -1289,6 +1295,60 @@ dbxout_source_line (unsigned int lineno, unsigned int column ATTRIBUTE_UNUSED,
else else
dbxout_stabd (N_SLINE, lineno); dbxout_stabd (N_SLINE, lineno);
#endif #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. */ /* Describe the beginning of an internal block within a function. */
...@@ -1322,7 +1382,7 @@ dbxout_function_decl (tree decl) ...@@ -1322,7 +1382,7 @@ dbxout_function_decl (tree decl)
#ifndef DBX_FUNCTION_FIRST #ifndef DBX_FUNCTION_FIRST
dbxout_begin_function (decl); dbxout_begin_function (decl);
#endif #endif
dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl)); dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl), -1);
dbxout_function_end (decl); dbxout_function_end (decl);
} }
...@@ -3664,6 +3724,26 @@ dbx_output_rbrac (const char *label, ...@@ -3664,6 +3724,26 @@ dbx_output_rbrac (const char *label,
dbxout_stab_value_label (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 /* Output everything about a symbol block (a BLOCK node
that represents a scope level), that represents a scope level),
including recursive output of contained blocks. including recursive output of contained blocks.
...@@ -3679,22 +3759,31 @@ dbx_output_rbrac (const char *label, ...@@ -3679,22 +3759,31 @@ dbx_output_rbrac (const char *label,
except for the outermost block. except for the outermost block.
Actually, BLOCK may be several blocks chained together. Actually, BLOCK may be several blocks chained together.
We handle them all in sequence. */ We handle them all in sequence.
static void Return true if we emitted any LBRAC/RBRAC. */
dbxout_block (tree block, int depth, tree args)
static bool
dbxout_block (tree block, int depth, tree args, int parent_blocknum)
{ {
bool ret = false;
char begin_label[20]; char begin_label[20];
/* Reference current function start using LFBB. */ /* Reference current function start using LFBB. */
ASM_GENERATE_INTERNAL_LABEL (begin_label, "LFBB", scope_labelno); 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. */ /* Ignore blocks never expanded or otherwise marked as real. */
if (TREE_USED (block) && TREE_ASM_WRITTEN (block)) if (TREE_USED (block) && TREE_ASM_WRITTEN (block))
{ {
int did_output; int did_output;
int blocknum = BLOCK_NUMBER (block); int blocknum = BLOCK_NUMBER (block);
int this_parent = parent_blocknum;
/* In dbx format, the syms of a block come before the N_LBRAC. /* 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. */ If nothing is output, we don't need the N_LBRAC, either. */
...@@ -3708,11 +3797,13 @@ dbxout_block (tree block, int depth, tree args) ...@@ -3708,11 +3797,13 @@ dbxout_block (tree block, int depth, tree args)
the block. Use the block's tree-walk order to generate the block. Use the block's tree-walk order to generate
the assembler symbols LBBn and LBEn the assembler symbols LBBn and LBEn
that final will define around the code in this block. */ 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]; char buf[20];
const char *scope_start; const char *scope_start;
ret = true;
if (depth == 0) if (depth == 0)
/* The outermost block doesn't get LBB labels; use /* The outermost block doesn't get LBB labels; use
the LFBB local symbol emitted by dbxout_begin_prologue. */ the LFBB local symbol emitted by dbxout_begin_prologue. */
...@@ -3721,16 +3812,21 @@ dbxout_block (tree block, int depth, tree args) ...@@ -3721,16 +3812,21 @@ dbxout_block (tree block, int depth, tree args)
{ {
ASM_GENERATE_INTERNAL_LABEL (buf, "LBB", blocknum); ASM_GENERATE_INTERNAL_LABEL (buf, "LBB", blocknum);
scope_start = buf; scope_start = buf;
this_parent = blocknum;
} }
dbx_output_lbrac (scope_start, begin_label); dbx_output_lbrac (scope_start, begin_label);
} }
/* Output the subblocks. */ /* 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. */ /* 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]; char buf[100];
if (depth == 0) if (depth == 0)
...@@ -3743,9 +3839,29 @@ dbxout_block (tree block, int depth, tree args) ...@@ -3743,9 +3839,29 @@ dbxout_block (tree block, int depth, tree args)
dbx_output_rbrac (buf, begin_label); 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. /* Output the information about a function and its arguments and result.
......
...@@ -2210,8 +2210,17 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, ...@@ -2210,8 +2210,17 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
case NOTE_INSN_SWITCH_TEXT_SECTIONS: case NOTE_INSN_SWITCH_TEXT_SECTIONS:
in_cold_section_p = !in_cold_section_p; 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 ()) 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)) else if (!DECL_IGNORED_P (current_function_decl))
debug_hooks->switch_text_section (); debug_hooks->switch_text_section ();
...@@ -2223,8 +2232,6 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, ...@@ -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. */ suffixing "cold" to the original function's name. */
if (in_cold_section_p) if (in_cold_section_p)
{ {
cold_function_name
= clone_function_name (current_function_decl, "cold");
#ifdef ASM_DECLARE_COLD_FUNCTION_NAME #ifdef ASM_DECLARE_COLD_FUNCTION_NAME
ASM_DECLARE_COLD_FUNCTION_NAME (asm_out_file, ASM_DECLARE_COLD_FUNCTION_NAME (asm_out_file,
IDENTIFIER_POINTER IDENTIFIER_POINTER
......
2017-11-27 Jakub Jelinek <jakub@redhat.com> 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 PR target/83100
* gcc.dg/pr83100-1.c: New test. * gcc.dg/pr83100-1.c: New test.
* gcc.dg/pr83100-2.c: New test. * gcc.dg/pr83100-2.c: New test.
......
/* { dg-do assemble } */ /* { 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 /* This testcase requires entries in the debug_range section in DWARF which
refer to a vague linkage function. */ refer to a vague linkage function. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment