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:
parent
9adeb64ab9
commit
b8cb3096f7
@ -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.
|
||||
|
150
gcc/dbxout.c
150
gcc/dbxout.c
@ -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.
|
||||
|
13
gcc/final.c
13
gcc/final.c
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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. */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user