diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-11-27 09:48:56 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-11-27 09:48:56 +0100 |
commit | b8cb3096f78581c16d87469706e49b1a4ec345f0 (patch) | |
tree | e81f0e0046a42d208b6c8cc59980e1aafa2275bb /gcc/dbxout.c | |
parent | 9adeb64ab940db8fe484e6344dc28ec86f1a83bc (diff) | |
download | gcc-b8cb3096f78581c16d87469706e49b1a4ec345f0.zip gcc-b8cb3096f78581c16d87469706e49b1a4ec345f0.tar.gz gcc-b8cb3096f78581c16d87469706e49b1a4ec345f0.tar.bz2 |
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
Diffstat (limited to 'gcc/dbxout.c')
-rw-r--r-- | gcc/dbxout.c | 150 |
1 files changed, 133 insertions, 17 deletions
diff --git a/gcc/dbxout.c b/gcc/dbxout.c index 49a8583..89f2d1f 100644 --- a/gcc/dbxout.c +++ b/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. |