Blob Blame History Raw
2008-10-09  Jakub Jelinek  <jakub@redhat.com>

	* rtl.h (locator_eq): New decl.
	* cfglayout.c (locator_scope): New function.
	(insn_scope): Use it.
	(locator_eq): New function.
	(fixup_reorder_chain): Search for last insn in src bb
	that has locator set or first insn in dest bb.  Use
	locator_eq instead of == to compare locators.
	* cfgrtl.c (cfg_layout_merge_blocks): Likewise.
	* cfgcleanup.c (try_forward_edges): Use locator_eq instead of
	== to compare locators.

--- gcc/cfglayout.c.jj	2008-10-07 21:35:33.000000000 +0200
+++ gcc/cfglayout.c	2008-10-09 11:18:51.000000000 +0200
@@ -448,13 +448,12 @@ change_scope (rtx orig_insn, tree s1, tr
     }
 }
 
-/* Return lexical scope block insn belong to.  */
+/* Return lexical scope block locator belongs to.  */
 static tree
-insn_scope (const_rtx insn)
+locator_scope (int loc)
 {
   int max = VEC_length (int, block_locators_locs);
   int min = 0;
-  int loc = INSN_LOCATOR (insn);
 
   /* When block_locators_locs was initialized, the pro- and epilogue
      insns didn't exist yet and can therefore not be found this way.
@@ -488,6 +487,13 @@ insn_scope (const_rtx insn)
   return VEC_index (tree, block_locators_blocks, min);
 }
 
+/* Return lexical scope block insn belongs to.  */
+static tree
+insn_scope (const_rtx insn)
+{
+  return locator_scope (INSN_LOCATOR (insn));
+}
+
 /* Return line number of the statement specified by the locator.  */
 static location_t
 locator_location (int loc)
@@ -551,6 +557,17 @@ insn_file (const_rtx insn)
   return locator_file (INSN_LOCATOR (insn));
 }
 
+/* Return true if LOC1 and LOC2 locators have the same location and scope.  */
+bool
+locator_eq (int loc1, int loc2)
+{
+  if (loc1 == loc2)
+    return true;
+  if (locator_location (loc1) != locator_location (loc2))
+    return false;
+  return locator_scope (loc1) == locator_scope (loc2);
+}
+
 /* Rebuild all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes based
    on the scope tree and the newly reordered instructions.  */
 
@@ -901,24 +918,30 @@ fixup_reorder_chain (void)
 	  if (e->goto_locus && !(e->flags & EDGE_ABNORMAL))
 	    {
 	      basic_block nb;
+	      rtx end;
 
-	      if (simplejump_p (BB_END (e->src)))
+	      insn = BB_END (e->src);
+	      end = PREV_INSN (BB_HEAD (e->src));
+	      while (insn != end
+		     && (!INSN_P (insn) || INSN_LOCATOR (insn) == 0))
+		insn = PREV_INSN (insn);
+	      if (insn != end
+		  && locator_eq (INSN_LOCATOR (insn), (int) e->goto_locus))
+		continue;
+	      if (simplejump_p (BB_END (e->src))
+		  && INSN_LOCATOR (BB_END (e->src)) == 0)
 		{
-		  if (INSN_LOCATOR (BB_END (e->src)) == (int) e->goto_locus)
-		    continue;
-		  if (INSN_LOCATOR (BB_END (e->src)) == 0)
-		    {
-		      INSN_LOCATOR (BB_END (e->src)) = e->goto_locus;
-		      continue;
-		    }
+		  INSN_LOCATOR (BB_END (e->src)) = e->goto_locus;
+		  continue;
 		}
 	      if (e->dest != EXIT_BLOCK_PTR)
 		{
 		  insn = BB_HEAD (e->dest);
-		  if (!INSN_P (insn))
-		    insn = next_insn (insn);
-		  if (insn && INSN_P (insn)
-		      && INSN_LOCATOR (insn) == (int) e->goto_locus)
+		  end = NEXT_INSN (BB_END (e->dest));
+		  while (insn != end && !INSN_P (insn))
+		    insn = NEXT_INSN (insn);
+		  if (insn != end && INSN_LOCATOR (insn)
+		      && locator_eq (INSN_LOCATOR (insn), (int) e->goto_locus))
 		    continue;
 		}
 	      nb = split_edge (e);
--- gcc/rtl.h.jj	2008-10-07 21:25:44.000000000 +0200
+++ gcc/rtl.h	2008-10-09 11:15:57.000000000 +0200
@@ -1622,6 +1622,7 @@ extern int insn_line (const_rtx);
 extern const char * insn_file (const_rtx);
 extern int locator_line (int);
 extern const char * locator_file (int);
+extern bool locator_eq (int, int);
 extern int prologue_locator, epilogue_locator;
 
 /* In jump.c */
--- gcc/cfgrtl.c.jj	2008-10-07 21:35:33.000000000 +0200
+++ gcc/cfgrtl.c	2008-10-09 10:37:03.000000000 +0200
@@ -2623,19 +2623,21 @@ cfg_layout_merge_blocks (basic_block a, 
      some unique locus, emit a nop with that locus in between.  */
   if (!optimize && EDGE_SUCC (a, 0)->goto_locus)
     {
-      rtx insn = BB_END (a);
+      rtx insn = BB_END (a), end = PREV_INSN (BB_HEAD (a));
       int goto_locus = EDGE_SUCC (a, 0)->goto_locus;
 
-      if (NOTE_P (insn))
-	insn = prev_nonnote_insn (insn);
-      if (insn && INSN_P (insn) && INSN_LOCATOR (insn) == goto_locus)
+      while (insn != end && (!INSN_P (insn) || INSN_LOCATOR (insn) == 0))
+	insn = PREV_INSN (insn);
+      if (insn != end && locator_eq (INSN_LOCATOR (insn), goto_locus))
 	goto_locus = 0;
       else
 	{
 	  insn = BB_HEAD (b);
-	  if (!INSN_P (insn))
-	    insn = next_insn (insn);
-	  if (insn && INSN_P (insn) && INSN_LOCATOR (insn) == goto_locus)
+	  end = NEXT_INSN (BB_END (b));
+	  while (insn != end && !INSN_P (insn))
+	    insn = NEXT_INSN (insn);
+	  if (insn != end && INSN_LOCATOR (insn) != 0
+	      && locator_eq (INSN_LOCATOR (insn), goto_locus))
 	    goto_locus = 0;
 	}
       if (goto_locus)
--- gcc/cfgcleanup.c.jj	2008-10-07 21:35:33.000000000 +0200
+++ gcc/cfgcleanup.c	2008-10-09 11:07:40.000000000 +0200
@@ -482,7 +482,7 @@ try_forward_edges (int mode, basic_block
 		     blocks with different locus are not optimized out.  */
 		  int locus = single_succ_edge (target)->goto_locus;
 
-		  if (locus && goto_locus && locus != goto_locus)
+		  if (locus && goto_locus && !locator_eq (locus, goto_locus))
 		    counter = n_basic_blocks;
 		  else if (locus)
 		    goto_locus = locus;
@@ -491,7 +491,8 @@ try_forward_edges (int mode, basic_block
 		    {
 		      locus = INSN_LOCATOR (BB_END (target));
 
-		      if (locus && goto_locus && locus != goto_locus)
+		      if (locus && goto_locus
+			  && !locator_eq (locus, goto_locus))
 			counter = n_basic_blocks;
 		      else if (locus)
 			goto_locus = locus;