This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix up sorting of block fragments
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 16 Aug 2010 22:42:27 +0200
- Subject: [PATCH] Fix up sorting of block fragments
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
This is just a small snippet from the "make .debug_loc smaller" patch
which was deferred because of questions whether it doesn't make debug info
quality worse.
This snippet makes sure that block fragments in DW_AT_ranges go, at least
within the same section, with ascending PCs, compared to weirdo order
GCC has been emitting up to now (lowest PC fragment first, then highest PC
fragment and following fragments with decreasing PC).
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2010-08-16 Jakub Jelinek <jakub@redhat.com>
* function.c (block_fragments_nreverse, blocks_nreverse_all): New
functions.
(reorder_blocks): Use blocks_nreverse_all instead of blocks_nreverse.
(reorder_blocks_1): Assert BLOCK_FRAGMENT_ORIGIN is NULL. Don't
call block_nreverse here.
--- gcc/function.c.jj 2010-02-26 16:58:08.000000000 +0100
+++ gcc/function.c 2010-03-21 17:41:29.000000000 +0100
@@ -3808,6 +3808,46 @@ 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). */
+
+static tree
+block_fragments_nreverse (tree t)
+{
+ tree prev = 0, decl, next;
+ for (decl = t; decl; decl = next)
+ {
+ next = BLOCK_FRAGMENT_CHAIN (decl);
+ BLOCK_FRAGMENT_CHAIN (decl) = prev;
+ prev = decl;
+ }
+ return prev;
+}
+
+/* Reverse the order of elements in the chain T of blocks,
+ and return the new head of the chain (old last element).
+ Also do the same on subblocks and reverse the order of elements
+ in BLOCK_FRAGMENT_CHAIN as well. */
+
+static tree
+blocks_nreverse_all (tree t)
+{
+ tree prev = 0, decl, next;
+ for (decl = t; decl; decl = next)
+ {
+ next = BLOCK_CHAIN (decl);
+ BLOCK_CHAIN (decl) = prev;
+ BLOCK_SUBBLOCKS (decl) = blocks_nreverse_all (BLOCK_SUBBLOCKS (decl));
+ if (BLOCK_FRAGMENT_CHAIN (decl)
+ && BLOCK_FRAGMENT_ORIGIN (decl) == NULL_TREE)
+ BLOCK_FRAGMENT_CHAIN (decl)
+ = block_fragments_nreverse (BLOCK_FRAGMENT_CHAIN (decl));
+ prev = decl;
+ }
+ return prev;
+}
+
+
/* Identify BLOCKs referenced by more than one NOTE_INSN_BLOCK_{BEG,END},
and create duplicate blocks. */
/* ??? Need an option to either create block fragments or to create
@@ -3834,7 +3874,7 @@ reorder_blocks (void)
/* Recreate the block tree from the note nesting. */
reorder_blocks_1 (get_insns (), block, &block_stack);
- BLOCK_SUBBLOCKS (block) = blocks_nreverse (BLOCK_SUBBLOCKS (block));
+ BLOCK_SUBBLOCKS (block) = blocks_nreverse_all (BLOCK_SUBBLOCKS (block));
VEC_free (tree, heap, block_stack);
}
@@ -3866,9 +3906,8 @@ reorder_blocks_1 (rtx insns, tree curren
tree block = NOTE_BLOCK (insn);
tree origin;
- origin = (BLOCK_FRAGMENT_ORIGIN (block)
- ? BLOCK_FRAGMENT_ORIGIN (block)
- : block);
+ gcc_assert (BLOCK_FRAGMENT_ORIGIN (block) == NULL_TREE);
+ origin = block;
/* If we have seen this block before, that means it now
spans multiple address regions. Create a new fragment. */
@@ -3905,8 +3944,6 @@ reorder_blocks_1 (rtx insns, tree curren
else if (NOTE_KIND (insn) == NOTE_INSN_BLOCK_END)
{
NOTE_BLOCK (insn) = VEC_pop (tree, *p_block_stack);
- BLOCK_SUBBLOCKS (current_block)
- = blocks_nreverse (BLOCK_SUBBLOCKS (current_block));
current_block = BLOCK_SUPERCONTEXT (current_block);
}
}
Jakub