Patchwork Tweaks to RTL locus preservation code

login
register
mail settings
Submitter Eric Botcazou
Date Oct. 21, 2010, 9:39 p.m.
Message ID <201010212339.15469.ebotcazou@adacore.com>
Download mbox | patch
Permalink /patch/68780/
State New
Headers show

Comments

Eric Botcazou - Oct. 21, 2010, 9:39 p.m.
In http://gcc.gnu.org/ml/gcc-patches/2008-10/msg00017.html, Jakub introduced 
code to preserve location info on control-flow altering constructs at -O0.
The attached patch makes a couple of changes to the RTL part of this code:

 1. In try_forward_edges, instead of throwing away previous steps when running 
into a different locus on an edge or an insn, the modified code only throws 
away the last step and forwards edges up to this point; this in the process 
gets rid of the bogus "Infinite loop" messages present in the RTL dumps when 
the condition triggers.

 2. try_optimize_cfg can also be bypass certain forwarder blocks by merging 
them with their single predecessor; in this case, a locus on the single edge 
in-between will be lost if it is already present on an previous instruction.
The modified code propagates it onto the outgoing edge if possible.  It also 
arranges to have the same messages in the dumps for CFG RTL or layout modes.

Tested (GCC + GDB) on x86_64-suse-linux, applied on the mainline.


2010-10-21  Eric Botcazou  <ebotcazou@adacore.com>

	* cfgcleanup.c (try_forward_edges): Do not throw away previous steps
	when stopping because of a different locus on edge or insn.
	(try_optimize_cfg): Add comment.
	* cfgrtl.c (rtl_merge_blocks): Tweak log message.  If the destination
	block is a forwarder block, propagate locus on the edge.
	(cfg_layout_merge_blocks): Likewise.

Patch

Index: cfgcleanup.c
===================================================================
--- cfgcleanup.c	(revision 165750)
+++ cfgcleanup.c	(working copy)
@@ -485,22 +485,28 @@  try_forward_edges (int mode, basic_block
 		{
 		  /* When not optimizing, ensure that edges or forwarder
 		     blocks with different locus are not optimized out.  */
-		  int locus = single_succ_edge (target)->goto_locus;
+		  int new_locus = single_succ_edge (target)->goto_locus;
+		  int locus = goto_locus;
 
-		  if (locus && goto_locus && !locator_eq (locus, goto_locus))
-		    counter = n_basic_blocks;
-		  else if (locus)
-		    goto_locus = locus;
-
-		  if (INSN_P (BB_END (target)))
+		  if (new_locus && locus && !locator_eq (new_locus, locus))
+		    new_target = NULL;
+		  else
 		    {
-		      locus = INSN_LOCATOR (BB_END (target));
+		      if (new_locus)
+			locus = new_locus;
 
-		      if (locus && goto_locus
-			  && !locator_eq (locus, goto_locus))
-			counter = n_basic_blocks;
-		      else if (locus)
-			goto_locus = locus;
+		      new_locus = INSN_P (BB_END (target))
+				  ? INSN_LOCATOR (BB_END (target)) : 0;
+
+		      if (new_locus && locus && !locator_eq (new_locus, locus))
+			new_target = NULL;
+		      else
+			{
+			  if (new_locus)
+			    locus = new_locus;
+
+			  goto_locus = locus;
+			}
 		    }
 		}
 	    }
@@ -2379,6 +2385,7 @@  try_optimize_cfg (int mode)
 		  continue;
 		}
 
+	      /* Merge B with its single successor, if any.  */
 	      if (single_succ_p (b)
 		  && (s = single_succ_edge (b))
 		  && !(s->flags & EDGE_COMPLEX)
Index: cfgrtl.c
===================================================================
--- cfgrtl.c	(revision 165788)
+++ cfgrtl.c	(working copy)
@@ -588,10 +588,12 @@  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;
+  bool forwarder_p = (b->flags & BB_FORWARDER_BLOCK) != 0;
   int b_empty = 0;
 
   if (dump_file)
-    fprintf (dump_file, "merging block %d into block %d\n", b->index, a->index);
+    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);
@@ -680,6 +682,13 @@  rtl_merge_blocks (basic_block a, basic_b
 
   df_bb_delete (b->index);
   BB_END (a) = a_end;
+
+  /* If B was a forwarder block, propagate the locus on the edge.  */
+  if (forwarder_p && !EDGE_SUCC (b, 0)->goto_locus)
+    EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus;
+
+  if (dump_file)
+    fprintf (dump_file, "Merged blocks %d and %d.\n", a->index, b->index);
 }
 
 
@@ -2692,10 +2701,13 @@  cfg_layout_can_merge_blocks_p (basic_blo
 static void
 cfg_layout_merge_blocks (basic_block a, basic_block b)
 {
+  bool forwarder_p = (b->flags & BB_FORWARDER_BLOCK) != 0;
+
   gcc_checking_assert (cfg_layout_can_merge_blocks_p (a, b));
 
   if (dump_file)
-    fprintf (dump_file, "merging block %d into block %d\n", b->index, a->index);
+    fprintf (dump_file, "Merging block %d into block %d...\n", b->index,
+			 a->index);
 
   /* If there was a CODE_LABEL beginning B, delete it.  */
   if (LABEL_P (BB_HEAD (b)))
@@ -2803,9 +2815,12 @@  cfg_layout_merge_blocks (basic_block a,
       b->il.rtl->footer = NULL;
     }
 
+  /* If B was a forwarder block, propagate the locus on the edge.  */
+  if (forwarder_p && !EDGE_SUCC (b, 0)->goto_locus)
+    EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus;
+
   if (dump_file)
-    fprintf (dump_file, "Merged blocks %d and %d.\n",
-	     a->index, b->index);
+    fprintf (dump_file, "Merged blocks %d and %d.\n", a->index, b->index);
 }
 
 /* Split edge E.  */