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]

[vta] retain debug insns "between" merged rtl blocks


When merging two rtl blocks A and B, if there's a note at the end of
A, it won't actually be part of A, but rather it will stand between A
and B, after the end of A, and it will be deleted in the process of
merging the blocks.

If debug insns were emitted in A after the note, then the note will be
part of block A, and the note would have been retained during merging.
This caused (harmless AFAICT) compare-debug regressions.

This patch arranges for debug insns at the end of the block to be
moved to the following block, so that notes before them can be deleted
as they would have been in the absence of the debug insns.

I'm installing the fix in the vta branch.

for  gcc/ChangeLog.vta
from  Alexandre Oliva  <aoliva@redhat.com>

	* cfgrtl.c (rtl_merge_blocks): Drop notes before debug insns at
	the end of the first block.

Index: gcc/cfgrtl.c
===================================================================
--- gcc/cfgrtl.c.orig	2008-09-09 22:25:21.000000000 -0300
+++ gcc/cfgrtl.c	2008-09-20 22:06:49.000000000 -0300
@@ -564,11 +564,15 @@ rtl_merge_blocks (basic_block a, basic_b
 {
   rtx b_head = BB_HEAD (b), b_end = BB_END (b), a_end = BB_END (a);
   rtx del_first = NULL_RTX, del_last = NULL_RTX;
+  rtx b_debug_start = b_end, b_debug_end = b_end;
   int b_empty = 0;
 
   if (dump_file)
     fprintf (dump_file, "merging block %d into block %d\n", b->index, a->index);
 
+  while (DEBUG_INSN_P (b_end))
+    b_end = PREV_INSN (b_debug_start = b_end);
+
   /* If there was a CODE_LABEL beginning B, delete it.  */
   if (LABEL_P (b_head))
     {
@@ -638,9 +642,21 @@ rtl_merge_blocks (basic_block a, basic_b
   /* Reassociate the insns of B with A.  */
   if (!b_empty)
     {
-      update_bb_for_insn_chain (a_end, b_end, a);
+      update_bb_for_insn_chain (a_end, b_debug_end, a);
 
-      a_end = b_end;
+      a_end = b_debug_end;
+    }
+  else if (b_end != b_debug_end)
+    {
+      /* Move any deleted labels and other notes between the end of A
+	 and the debug insns that make up B after the debug insns,
+	 bringing the debug insns into A while keeping the notes after
+	 the end of A.  */
+      if (NEXT_INSN (a_end) != b_debug_start)
+	reorder_insns_nobb (NEXT_INSN (a_end), PREV_INSN (b_debug_start),
+			    b_debug_end);
+      update_bb_for_insn_chain (b_debug_start, b_debug_end, a);
+      a_end = b_debug_end;
     }
 
   df_bb_delete (b->index);
-- 
Alexandre Oliva         http://www.lsd.ic.unicamp.br/~oliva/
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}
FSFLA Board Member       ÂSÃ Libre! => http://www.fsfla.org/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}

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