This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix up sorting of block fragments


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]