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]

More flow cleanup


The patch below is a suggestion on how to clean up another bit of flow.c.
Namely, it replaces the code in propagate_block that manages
regs_sometimes_live with code that simply calls EXECUTE_IF_SET_IN_REG_SET
on the bitmap of currently live registers.  The reasoning is that
 - this is not as expensive as it would have been before the bitmap code was
   added.
 - we are currently doing similarly expensive operations on the maxlive
   regset in propagate_block.

Unless someone knows a convincing reason why this patch would make the code
slower nonetheless, I'd like this to be installed.

The patch is tested with c-torture runs on sparc-sun-solaris2.6 and 
i586-linux; I've also verified for some examples that the .flow dumps before
and after are identical.

Actually, looking at the old code, I just noticed one spot that makes me
wonder:

-             EXECUTE_IF_AND_COMPL_IN_REG_SET
-               (live, maxlive, 0, regno,
-                {
-                  regs_sometimes_live[sometimes_max++] = regno;
-                  SET_REGNO_REG_SET (maxlive, regno);
-                });

Is it legal to modify a regset (maxlive in this case) while doing an
EXECUTE_* operation on it?  While working on the reload patch I ran
into some rather ugly bugs with constructs like this.


Bernd

	* flow.c (propagate_block): Replace code that copmutes and uses
	regs_sometimes_live with simpler code that just walks the set of
	currently live registers.

Index: flow.c
===================================================================
RCS file: /usr/local/cvs/gcs/gcc/flow.c,v
retrieving revision 1.1.1.42
diff -u -p -r1.1.1.42 flow.c
--- flow.c	1998/10/08 14:53:00	1.1.1.42
+++ flow.c	1998/10/10 12:30:21
@@ -1624,16 +1624,6 @@ propagate_block (old, first, last, final
   regset live;
   regset dead;
 
-  /* The following variables are used only if FINAL is nonzero.  */
-  /* This vector gets one element for each reg that has been live
-     at any point in the basic block that has been scanned so far.
-     SOMETIMES_MAX says how many elements are in use so far.  */
-  register int *regs_sometimes_live;
-  int sometimes_max = 0;
-  /* This regset has 1 for each reg that we have seen live so far.
-     It and REGS_SOMETIMES_LIVE are updated together.  */
-  regset maxlive;
-
   /* The loop depth may change in the middle of a basic block.  Since we
      scan from end to beginning, we start with the depth at the end of the
      current basic block, and adjust as we pass ends and starts of loops.  */
@@ -1663,18 +1653,12 @@ propagate_block (old, first, last, final
       register int i;
 
       num_scratch = 0;
-      maxlive = ALLOCA_REG_SET ();
-      COPY_REG_SET (maxlive, old);
-      regs_sometimes_live = (int *) alloca (max_regno * sizeof (int));
 
       /* Process the regs live at the end of the block.
-	 Enter them in MAXLIVE and REGS_SOMETIMES_LIVE.
-	 Also mark them as not local to any one basic block. */
+	 Mark them as not local to any one basic block. */
       EXECUTE_IF_SET_IN_REG_SET (old, 0, i,
 				 {
 				   REG_BASIC_BLOCK (i) = REG_BLOCK_GLOBAL;
-				   regs_sometimes_live[sometimes_max] = i;
-				   sometimes_max++;
 				 });
     }
 
@@ -1807,6 +1791,16 @@ propagate_block (old, first, last, final
 	    ;
 	  else
 	    {
+	      /* Any regs live at the time of a call instruction
+		 must not go in a register clobbered by calls.
+		 Find all regs now live and record this for them.  */
+
+	      if (GET_CODE (insn) == CALL_INSN && final)
+		EXECUTE_IF_SET_IN_REG_SET (old, 0, i,
+					   {
+					     REG_N_CALLS_CROSSED (i)++;
+					   });
+
 	      /* LIVE gets the regs used in INSN;
 		 DEAD gets those set by it.  Dead insns don't make anything
 		 live.  */
@@ -1871,44 +1865,13 @@ propagate_block (old, first, last, final
 	      AND_COMPL_REG_SET (old, dead);
 	      IOR_REG_SET (old, live);
 
-	      if (GET_CODE (insn) == CALL_INSN && final)
-		{
-		  /* Any regs live at the time of a call instruction
-		     must not go in a register clobbered by calls.
-		     Find all regs now live and record this for them.  */
-
-		  register int *p = regs_sometimes_live;
-
-		  for (i = 0; i < sometimes_max; i++, p++)
-		    if (REGNO_REG_SET_P (old, *p))
-		      REG_N_CALLS_CROSSED (*p)++;
-		}
 	    }
-
-	  /* On final pass, add any additional sometimes-live regs
-	     into MAXLIVE and REGS_SOMETIMES_LIVE.
-	     Also update counts of how many insns each reg is live at.  */
 
+	  /* On final pass, update counts of how many insns each reg is live
+	     at.  */
 	  if (final)
-	    {
-	      register int regno;
-	      register int *p;
-
-	      EXECUTE_IF_AND_COMPL_IN_REG_SET
-		(live, maxlive, 0, regno,
-		 {
-		   regs_sometimes_live[sometimes_max++] = regno;
-		   SET_REGNO_REG_SET (maxlive, regno);
-		 });
-
-	      p = regs_sometimes_live;
-	      for (i = 0; i < sometimes_max; i++)
-		{
-		  regno = *p++;
-		  if (REGNO_REG_SET_P (old, regno))
-		    REG_LIVE_LENGTH (regno)++;
-		}
-	    }
+	    EXECUTE_IF_SET_IN_REG_SET (old, 0, i,
+				       { REG_LIVE_LENGTH (i)++; });
 	}
     flushed: ;
       if (insn == first)
@@ -1917,8 +1880,6 @@ propagate_block (old, first, last, final
 
   FREE_REG_SET (dead);
   FREE_REG_SET (live);
-  if (final)
-    FREE_REG_SET (maxlive);
 
   if (num_scratch > max_scratch)
     max_scratch = num_scratch;



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