[PATCH] Fix a couple of performance issues in the PR rtl-optimization/36419 fix

Jakub Jelinek jakub@redhat.com
Fri Aug 1 18:56:00 GMT 2008


Hi!

While looking at PR36998, I've discovered that there are a few performance
issues with compute_barrier_args_size.  One is that it is called completely
unnecessary when the only BARRIER in a function is at the end of the
function.  The more important is that while I meant to write the algorithm
so that it scans every insn at most once, the implmentation I've committed
can actually scan some insns many times.  Fixed thusly,
bootstrapped/regtested on i686-linux, ok for trunk/4.3?

OT: For PR36998, we could temporarily remove the two asserts (one in
compute_barrier_args_size, one in compute_barrier_args_size_1) and reenable
them only when the args_size computation in PR36998 is fixed.  We will be
generating incorrect unwind info in that case, but we've always done that
before as well.

2008-08-01  Jakub Jelinek  <jakub@redhat.com>

	* dwarf2out.c (compute_barrier_args_size): Set barrier_args_size
	for labels for which it hasn't been set yet.  If it has been set,
	stop walking insns and continue with next worklist item.
	(dwarf2out_stack_adjust): Don't call compute_barrier_args_size
	if the only BARRIER is at the very end of a function.

--- gcc/dwarf2out.c.jj	2008-07-31 21:03:01.000000000 +0200
+++ gcc/dwarf2out.c	2008-08-01 19:30:19.000000000 +0200
@@ -1206,10 +1206,10 @@ compute_barrier_args_size (void)
     {
       while (!VEC_empty (rtx, worklist))
 	{
-	  rtx prev, body;
+	  rtx prev, body, first_insn;
 	  HOST_WIDE_INT cur_args_size;
 
-	  insn = VEC_pop (rtx, worklist);
+	  first_insn = insn = VEC_pop (rtx, worklist);
 	  cur_args_size = barrier_args_size[INSN_UID (insn)];
 	  prev = prev_nonnote_insn (insn);
 	  if (prev && BARRIER_P (prev))
@@ -1224,10 +1224,21 @@ compute_barrier_args_size (void)
 
 	      if (LABEL_P (insn))
 		{
-		  gcc_assert (barrier_args_size[INSN_UID (insn)] < 0
-			      || barrier_args_size[INSN_UID (insn)]
+		  if (insn == first_insn)
+		    continue;
+		  else if (barrier_args_size[INSN_UID (insn)] < 0)
+		    {
+		      barrier_args_size[INSN_UID (insn)] = cur_args_size;
+		      continue;
+		    }
+		  else
+		    {
+		      /* The insns starting with this label have been
+			 already scanned or are in the worklist.  */
+		      gcc_assert (barrier_args_size[INSN_UID (insn)]
 				  == cur_args_size);
-		  continue;
+		      break;
+		    }
 		}
 
 	      body = PATTERN (insn);
@@ -1306,11 +1317,18 @@ dwarf2out_stack_adjust (rtx insn, bool a
     }
   else if (BARRIER_P (insn))
     {
-      if (barrier_args_size == NULL)
+      /* Don't call compute_barrier_args_size () if the only
+	 BARRIER is at the end of function.  */
+      if (barrier_args_size == NULL && next_nonnote_insn (insn))
 	compute_barrier_args_size ();
-      offset = barrier_args_size[INSN_UID (insn)];
-      if (offset < 0)
+      if (barrier_args_size == NULL)
 	offset = 0;
+      else
+	{
+	  offset = barrier_args_size[INSN_UID (insn)];
+	  if (offset < 0)
+	    offset = 0;
+	}
 
       offset -= args_size;
 #ifndef STACK_GROWS_DOWNWARD

	Jakub



More information about the Gcc-patches mailing list