From 1e3c1d950e3723c46ef467306bcaea3a4f1a85f2 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 5 Mar 2012 21:17:44 +0100 Subject: 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 --- gcc/function.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 8 deletions(-) (limited to 'gcc/function.c') diff --git a/gcc/function.c b/gcc/function.c index 4508ae2..9add7c1 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -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; + } } } -- cgit v1.1