aboutsummaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2012-03-05 20:17:44 +0000
committerJakub Jelinek <jakub@redhat.com>2012-03-05 20:17:44 +0000
commitb961e2382ce92b70ea6a6b877bc6772b789e6fec (patch)
tree0a203dfd5709e8e57936d2ab25e4fc15b3529a67 /gcc/function.c
parentb88caef2376c8aa00b2c19969fb1f754a2dbc99e (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@184958 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/function.c')
-rw-r--r--gcc/function.c72
1 files changed, 64 insertions, 8 deletions
diff --git a/gcc/function.c b/gcc/function.c
index 4508ae22de4..9add7c1a007 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;
+ }
}
}