[PATCH] Somewhat improve generated code at -O0 (fallout of the -O0 -g debugging patch)

Jakub Jelinek jakub@redhat.com
Thu Oct 9 12:48:00 GMT 2008


Hi!

This is something I've talked about already before in the thread.
Even when locators have different numbers, they might be in fact
equal (same location_t, same block).  As at -O0 we generate worse
code if an edge has goto_locus and the locators are different, IMHO
it is desirable to try harder to compare the locators.
Another thing this patch improves is that it tries harder to find
last or next insn in the src or dest bb, in the src block it can skip
also insns without locator (as those cause no changes to .loc or BB
notes).

This patch e.g. improves
extern void func2 (void);
extern volatile int foo;
int
func (void)
{
  if (foo)
    return 1;
  func2 ();
  return 0;
}
from gdb's testsuite, without this patch we generate an unnecessary
nop in between two bbs.

Ok for trunk if bootstrap/regtest passes?

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/rtl.h.jj	2008-09-11 16:04:26.000000000 +0200
+++ gcc/rtl.h	2008-10-09 11:26:23.000000000 +0200
@@ -1639,6 +1639,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/cfglayout.c.jj	2008-10-08 11:50:40.000000000 +0200
+++ gcc/cfglayout.c	2008-10-09 11:26:23.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.  */
 
@@ -900,24 +917,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/cfgrtl.c.jj	2008-10-08 11:50:40.000000000 +0200
+++ gcc/cfgrtl.c	2008-10-09 11:26:23.000000000 +0200
@@ -2615,19 +2615,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-08 11:50:40.000000000 +0200
+++ gcc/cfgcleanup.c	2008-10-09 11:26:23.000000000 +0200
@@ -483,7 +483,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;
@@ -492,7 +492,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;

	Jakub



More information about the Gcc-patches mailing list