re PR debug/51902 (lexical_blocks inside inlined_subroutines generate duplicate debug_ranges)
PR debug/51902 * tree.h (BLOCK_SAME_RANGE): Define. * function.c (block_fragments_nreverse): Clear BLOCK_SAME_RANGE if BLOCK_FRAGMENT_CHAIN is non-NULL, but has it cleared. Also clear BLOCK_SAME_RANGE if fragment chain's supercontext fragment isn't equal to supercontext fragment's fragment chain. Adjust BLOCK_SUPERCONTEXT to point to supercontext fragment's fragment origin. (blocks_nreverse_all): Likewise. (reorder_blocks_1): Compute BLOCK_SAME_RANGE bits. Set BLOCK_SUPERCONTEXT to supercontext fragment instead of supercontext fragment's fragment origin. * dwarf2out.c (add_high_low_attributes): If stmt has the same range as its parent (or parents thereof etc.), use the parent's DW_AT_ranges value instead of creating a new .debug_ranges range. From-SVN: r184958
This commit is contained in:
parent
8993fde432
commit
1e3c1d950e
|
@ -1,3 +1,21 @@
|
|||
2012-03-05 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR debug/51902
|
||||
* tree.h (BLOCK_SAME_RANGE): Define.
|
||||
* function.c (block_fragments_nreverse): Clear BLOCK_SAME_RANGE
|
||||
if BLOCK_FRAGMENT_CHAIN is non-NULL, but has it cleared.
|
||||
Also clear BLOCK_SAME_RANGE if fragment chain's supercontext fragment
|
||||
isn't equal to supercontext fragment's fragment chain.
|
||||
Adjust BLOCK_SUPERCONTEXT to point to supercontext fragment's
|
||||
fragment origin.
|
||||
(blocks_nreverse_all): Likewise.
|
||||
(reorder_blocks_1): Compute BLOCK_SAME_RANGE bits. Set
|
||||
BLOCK_SUPERCONTEXT to supercontext fragment instead of
|
||||
supercontext fragment's fragment origin.
|
||||
* dwarf2out.c (add_high_low_attributes): If stmt has the same
|
||||
range as its parent (or parents thereof etc.), use the parent's
|
||||
DW_AT_ranges value instead of creating a new .debug_ranges range.
|
||||
|
||||
2012-03-05 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR tree-opt/52242
|
||||
|
|
|
@ -18134,7 +18134,9 @@ add_high_low_attributes (tree stmt, dw_die_ref die)
|
|||
if (BLOCK_FRAGMENT_CHAIN (stmt)
|
||||
&& (dwarf_version >= 3 || !dwarf_strict))
|
||||
{
|
||||
tree chain;
|
||||
tree chain, superblock = NULL_TREE;
|
||||
dw_die_ref pdie;
|
||||
dw_attr_ref attr = NULL;
|
||||
|
||||
if (inlined_function_outer_scope_p (stmt))
|
||||
{
|
||||
|
@ -18143,6 +18145,56 @@ add_high_low_attributes (tree stmt, dw_die_ref die)
|
|||
add_AT_lbl_id (die, DW_AT_entry_pc, label);
|
||||
}
|
||||
|
||||
/* Optimize duplicate .debug_ranges lists or even tails of
|
||||
lists. If this BLOCK has same ranges as its supercontext,
|
||||
lookup DW_AT_ranges attribute in the supercontext (and
|
||||
recursively so), verify that the ranges_table contains the
|
||||
right values and use it instead of adding a new .debug_range. */
|
||||
for (chain = stmt, pdie = die;
|
||||
BLOCK_SAME_RANGE (chain);
|
||||
chain = BLOCK_SUPERCONTEXT (chain))
|
||||
{
|
||||
dw_attr_ref new_attr;
|
||||
|
||||
pdie = pdie->die_parent;
|
||||
if (pdie == NULL)
|
||||
break;
|
||||
if (BLOCK_SUPERCONTEXT (chain) == NULL_TREE)
|
||||
break;
|
||||
new_attr = get_AT (pdie, DW_AT_ranges);
|
||||
if (new_attr == NULL
|
||||
|| new_attr->dw_attr_val.val_class != dw_val_class_range_list)
|
||||
break;
|
||||
attr = new_attr;
|
||||
superblock = BLOCK_SUPERCONTEXT (chain);
|
||||
}
|
||||
if (attr != NULL
|
||||
&& (ranges_table[attr->dw_attr_val.v.val_offset
|
||||
/ 2 / DWARF2_ADDR_SIZE].num
|
||||
== BLOCK_NUMBER (superblock))
|
||||
&& BLOCK_FRAGMENT_CHAIN (superblock))
|
||||
{
|
||||
unsigned long off = attr->dw_attr_val.v.val_offset
|
||||
/ 2 / DWARF2_ADDR_SIZE;
|
||||
unsigned long supercnt = 0, thiscnt = 0;
|
||||
for (chain = BLOCK_FRAGMENT_CHAIN (superblock);
|
||||
chain; chain = BLOCK_FRAGMENT_CHAIN (chain))
|
||||
{
|
||||
++supercnt;
|
||||
gcc_checking_assert (ranges_table[off + supercnt].num
|
||||
== BLOCK_NUMBER (chain));
|
||||
}
|
||||
gcc_checking_assert (ranges_table[off + supercnt + 1].num == 0);
|
||||
for (chain = BLOCK_FRAGMENT_CHAIN (stmt);
|
||||
chain; chain = BLOCK_FRAGMENT_CHAIN (chain))
|
||||
++thiscnt;
|
||||
gcc_assert (supercnt >= thiscnt);
|
||||
add_AT_range_list (die, DW_AT_ranges,
|
||||
(off + supercnt - thiscnt)
|
||||
* 2 * DWARF2_ADDR_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
add_AT_range_list (die, DW_AT_ranges, add_ranges (stmt));
|
||||
|
||||
chain = BLOCK_FRAGMENT_CHAIN (stmt);
|
||||
|
|
|
@ -3998,18 +3998,35 @@ generate_setjmp_warnings (void)
|
|||
|
||||
|
||||
/* Reverse the order of elements in the fragment chain T of blocks,
|
||||
and return the new head of the chain (old last element). */
|
||||
and return the new head of the chain (old last element).
|
||||
In addition to that clear BLOCK_SAME_RANGE flags when needed
|
||||
and adjust BLOCK_SUPERCONTEXT from the super fragment to
|
||||
its super fragment origin. */
|
||||
|
||||
static tree
|
||||
block_fragments_nreverse (tree t)
|
||||
{
|
||||
tree prev = 0, block, next;
|
||||
tree prev = 0, block, next, prev_super = 0;
|
||||
tree super = BLOCK_SUPERCONTEXT (t);
|
||||
if (BLOCK_FRAGMENT_ORIGIN (super))
|
||||
super = BLOCK_FRAGMENT_ORIGIN (super);
|
||||
for (block = t; block; block = next)
|
||||
{
|
||||
next = BLOCK_FRAGMENT_CHAIN (block);
|
||||
BLOCK_FRAGMENT_CHAIN (block) = prev;
|
||||
if ((prev && !BLOCK_SAME_RANGE (prev))
|
||||
|| (BLOCK_FRAGMENT_CHAIN (BLOCK_SUPERCONTEXT (block))
|
||||
!= prev_super))
|
||||
BLOCK_SAME_RANGE (block) = 0;
|
||||
prev_super = BLOCK_SUPERCONTEXT (block);
|
||||
BLOCK_SUPERCONTEXT (block) = super;
|
||||
prev = block;
|
||||
}
|
||||
t = BLOCK_FRAGMENT_ORIGIN (t);
|
||||
if (BLOCK_FRAGMENT_CHAIN (BLOCK_SUPERCONTEXT (t))
|
||||
!= prev_super)
|
||||
BLOCK_SAME_RANGE (t) = 0;
|
||||
BLOCK_SUPERCONTEXT (t) = super;
|
||||
return prev;
|
||||
}
|
||||
|
||||
|
@ -4026,11 +4043,15 @@ blocks_nreverse_all (tree t)
|
|||
{
|
||||
next = BLOCK_CHAIN (block);
|
||||
BLOCK_CHAIN (block) = prev;
|
||||
BLOCK_SUBBLOCKS (block) = blocks_nreverse_all (BLOCK_SUBBLOCKS (block));
|
||||
if (BLOCK_FRAGMENT_CHAIN (block)
|
||||
&& BLOCK_FRAGMENT_ORIGIN (block) == NULL_TREE)
|
||||
BLOCK_FRAGMENT_CHAIN (block)
|
||||
= block_fragments_nreverse (BLOCK_FRAGMENT_CHAIN (block));
|
||||
{
|
||||
BLOCK_FRAGMENT_CHAIN (block)
|
||||
= block_fragments_nreverse (BLOCK_FRAGMENT_CHAIN (block));
|
||||
if (!BLOCK_SAME_RANGE (BLOCK_FRAGMENT_CHAIN (block)))
|
||||
BLOCK_SAME_RANGE (block) = 0;
|
||||
}
|
||||
BLOCK_SUBBLOCKS (block) = blocks_nreverse_all (BLOCK_SUBBLOCKS (block));
|
||||
prev = block;
|
||||
}
|
||||
return prev;
|
||||
|
@ -4085,6 +4106,7 @@ static void
|
|||
reorder_blocks_1 (rtx insns, tree current_block, VEC(tree,heap) **p_block_stack)
|
||||
{
|
||||
rtx insn;
|
||||
tree prev_beg = NULL_TREE, prev_end = NULL_TREE;
|
||||
|
||||
for (insn = insns; insn; insn = NEXT_INSN (insn))
|
||||
{
|
||||
|
@ -4098,12 +4120,17 @@ reorder_blocks_1 (rtx insns, tree current_block, VEC(tree,heap) **p_block_stack)
|
|||
gcc_assert (BLOCK_FRAGMENT_ORIGIN (block) == NULL_TREE);
|
||||
origin = block;
|
||||
|
||||
if (prev_end)
|
||||
BLOCK_SAME_RANGE (prev_end) = 0;
|
||||
prev_end = NULL_TREE;
|
||||
|
||||
/* If we have seen this block before, that means it now
|
||||
spans multiple address regions. Create a new fragment. */
|
||||
if (TREE_ASM_WRITTEN (block))
|
||||
{
|
||||
tree new_block = copy_node (block);
|
||||
|
||||
BLOCK_SAME_RANGE (new_block) = 0;
|
||||
BLOCK_FRAGMENT_ORIGIN (new_block) = origin;
|
||||
BLOCK_FRAGMENT_CHAIN (new_block)
|
||||
= BLOCK_FRAGMENT_CHAIN (origin);
|
||||
|
@ -4113,6 +4140,11 @@ reorder_blocks_1 (rtx insns, tree current_block, VEC(tree,heap) **p_block_stack)
|
|||
block = new_block;
|
||||
}
|
||||
|
||||
if (prev_beg == current_block && prev_beg)
|
||||
BLOCK_SAME_RANGE (block) = 1;
|
||||
|
||||
prev_beg = origin;
|
||||
|
||||
BLOCK_SUBBLOCKS (block) = 0;
|
||||
TREE_ASM_WRITTEN (block) = 1;
|
||||
/* When there's only one block for the entire function,
|
||||
|
@ -4120,10 +4152,22 @@ reorder_blocks_1 (rtx insns, tree current_block, VEC(tree,heap) **p_block_stack)
|
|||
will cause infinite recursion. */
|
||||
if (block != current_block)
|
||||
{
|
||||
tree super;
|
||||
if (block != origin)
|
||||
gcc_assert (BLOCK_SUPERCONTEXT (origin) == current_block);
|
||||
|
||||
BLOCK_SUPERCONTEXT (block) = current_block;
|
||||
gcc_assert (BLOCK_SUPERCONTEXT (origin) == current_block
|
||||
|| BLOCK_FRAGMENT_ORIGIN (BLOCK_SUPERCONTEXT
|
||||
(origin))
|
||||
== current_block);
|
||||
if (VEC_empty (tree, *p_block_stack))
|
||||
super = current_block;
|
||||
else
|
||||
{
|
||||
super = VEC_last (tree, *p_block_stack);
|
||||
gcc_assert (super == current_block
|
||||
|| BLOCK_FRAGMENT_ORIGIN (super)
|
||||
== current_block);
|
||||
}
|
||||
BLOCK_SUPERCONTEXT (block) = super;
|
||||
BLOCK_CHAIN (block) = BLOCK_SUBBLOCKS (current_block);
|
||||
BLOCK_SUBBLOCKS (current_block) = block;
|
||||
current_block = origin;
|
||||
|
@ -4134,8 +4178,20 @@ reorder_blocks_1 (rtx insns, tree current_block, VEC(tree,heap) **p_block_stack)
|
|||
{
|
||||
NOTE_BLOCK (insn) = VEC_pop (tree, *p_block_stack);
|
||||
current_block = BLOCK_SUPERCONTEXT (current_block);
|
||||
if (BLOCK_FRAGMENT_ORIGIN (current_block))
|
||||
current_block = BLOCK_FRAGMENT_ORIGIN (current_block);
|
||||
prev_beg = NULL_TREE;
|
||||
prev_end = BLOCK_SAME_RANGE (NOTE_BLOCK (insn))
|
||||
? NOTE_BLOCK (insn) : NULL_TREE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_beg = NULL_TREE;
|
||||
if (prev_end)
|
||||
BLOCK_SAME_RANGE (prev_end) = 0;
|
||||
prev_end = NULL_TREE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2088,6 +2088,9 @@ struct GTY(()) tree_omp_clause {
|
|||
#define BLOCK_ABSTRACT_ORIGIN(NODE) (BLOCK_CHECK (NODE)->block.abstract_origin)
|
||||
#define BLOCK_ABSTRACT(NODE) (BLOCK_CHECK (NODE)->block.abstract_flag)
|
||||
|
||||
/* True if BLOCK has the same ranges as its BLOCK_SUPERCONTEXT. */
|
||||
#define BLOCK_SAME_RANGE(NODE) (BLOCK_CHECK (NODE)->base.nameless_flag)
|
||||
|
||||
/* An index number for this block. These values are not guaranteed to
|
||||
be unique across functions -- whether or not they are depends on
|
||||
the debugging output format in use. */
|
||||
|
|
Loading…
Reference in New Issue