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]

Re: big slowdown in egcs-1.1.2->gcc-2.95 on alpha


> and the top functions were
> 
>  19.82     67.88    67.88 1599926669     0.00     0.00  bitmap_bit_p
>  15.83    122.07    54.19        3 18063.15 41030.16  build_insn_chain
>  14.52    171.77    49.71     2789    17.82    17.82  find_reg
>  13.64    218.49    46.72   194464     0.24     0.24  record_one_conflict
>   3.14    229.26    10.76    26627     0.40     0.40  record_conflicts
>   2.94    239.32    10.06    30909     0.33     0.33  delete_from_jump_chain
> ...
>   0.51    277.15     1.74        2   869.63   870.11  prune_preferences
> 
> So, even though global-alloc is still the biggest time sink, your patch
> makes a *big* difference.  (I don't believe the times reported in each
> pass of the compiler are reliable when it is profiled with -pg.)

Well, since it worked for one place that looks for set bits in allocno sets,
let's see if it works in the two other ones:

Fri Nov  5 18:33:39 1999  J"orn Rennecke <amylaar@cygnus.co.uk>

	* global.c (EXECUTE_IF_SET_IN_ALLOCNO_SET): New macro.
	(EXECUTE_IF_CONFLICT): Likewise.
	(ALLOCNO_LIVE_P): Avoid signed division.
	(SET_ALLOCNO_LIVE, CLEAR_ALLOCNO_LIVE): Likewise.
	(prune_preferences, find_reg): Use EXECUTE_IF_CONFLICT.
	(record_one_conflict): Use EXECUTE_IF_SET_IN_ALLOCNO_SET.

Index: global.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/global.c,v
retrieving revision 1.40
diff -p -r1.40 global.c
*** global.c	1999/11/05 08:31:48	1.40
--- global.c	1999/11/05 18:31:06
*************** static int allocno_row_words;
*** 139,144 ****
--- 139,172 ----
    &= ~ ((INT_TYPE) 1 << ((J) % INT_BITS)))
  /* END CYGNUS LOCAL */
  
+ /* For any allocno set in ALLOCNO_SET, set OUT_ALLOCNO to that allocno,
+    and execute CODE.  */
+ #define EXECUTE_IF_SET_IN_ALLOCNO_SET(ALLOCNO_SET, ALLOCNO, CODE)	\
+ do {									\
+   int i_;								\
+   int allocno_;								\
+   INT_TYPE *p_ = (ALLOCNO_SET);		\
+ 									\
+   for (i_ = allocno_row_words - 1, allocno_ = 0; i_ >= 0;		\
+        i_--, allocno_ += INT_BITS)					\
+     {									\
+       unsigned INT_TYPE word_ = (unsigned INT_TYPE) *p_++;		\
+ 									\
+       for ((ALLOCNO) = allocno_; word_; word_ >>= 1, (ALLOCNO)++)	\
+ 	{								\
+ 	  if (word_ & 1)						\
+ 	    CODE;							\
+ 	}								\
+     }									\
+ } while (0)
+ 
+ /* For any allocno that conflicts with IN_ALLOCNO, set OUT_ALLOCNO to
+    the conflicting allocno, and execute CODE.  This macro assumes that
+    mirror_conflicts has been run.  */
+ #define EXECUTE_IF_CONFLICT(IN_ALLOCNO, OUT_ALLOCNO, CODE)\
+   EXECUTE_IF_SET_IN_ALLOCNO_SET (conflicts + (IN_ALLOCNO) * allocno_row_words,\
+ 				 OUT_ALLOCNO, CODE)
+ 
  /* Set of hard regs currently live (during scan of all insns).  */
  
  static HARD_REG_SET hard_regs_live;
*************** static INT_TYPE *allocnos_live;
*** 217,231 ****
  
  /* Test, set or clear bit number I in allocnos_live,
     a bit vector indexed by allocno.  */
- 
- #define ALLOCNO_LIVE_P(I) \
-   (allocnos_live[(I) / INT_BITS] & ((INT_TYPE) 1 << ((I) % INT_BITS)))
- 
- #define SET_ALLOCNO_LIVE(I) \
-   (allocnos_live[(I) / INT_BITS] |= ((INT_TYPE) 1 << ((I) % INT_BITS)))
  
! #define CLEAR_ALLOCNO_LIVE(I) \
!   (allocnos_live[(I) / INT_BITS] &= ~((INT_TYPE) 1 << ((I) % INT_BITS)))
  
  /* This is turned off because it doesn't work right for DImode.
     (And it is only used for DImode, so the other cases are worthless.)
--- 245,262 ----
  
  /* Test, set or clear bit number I in allocnos_live,
     a bit vector indexed by allocno.  */
  
! #define ALLOCNO_LIVE_P(I)				\
!   (allocnos_live[(unsigned)(I) / INT_BITS]		\
!    & ((INT_TYPE) 1 << ((unsigned)(I) % INT_BITS)))
! 
! #define SET_ALLOCNO_LIVE(I)				\
!   (allocnos_live[(unsigned)(I) / INT_BITS]		\
!      |= ((INT_TYPE) 1 << ((unsigned)(I) % INT_BITS)))
! 
! #define CLEAR_ALLOCNO_LIVE(I)				\
!   (allocnos_live[(unsigned)(I) / INT_BITS]		\
!      &= ~((INT_TYPE) 1 << ((unsigned)(I) % INT_BITS)))
  
  /* This is turned off because it doesn't work right for DImode.
     (And it is only used for DImode, so the other cases are worthless.)
*************** expand_preferences ()
*** 860,866 ****
  static void
  prune_preferences ()
  {
!   int i, j;
    int allocno;
    int *allocno_to_order = (int *) xmalloc (max_allocno * sizeof (int));
    
--- 891,897 ----
  static void
  prune_preferences ()
  {
!   int i;
    int allocno;
    int *allocno_to_order = (int *) xmalloc (max_allocno * sizeof (int));
    
*************** prune_preferences ()
*** 899,931 ****
  	 we want to give the lower-priority allocno the first chance for
  	 these registers).  */
        HARD_REG_SET temp, temp2;
!       INT_TYPE *p;
!       int allocno2, allocno3;
  
        allocno = allocno_order[i];
-       p = conflicts + allocno * allocno_row_words;
  
        CLEAR_HARD_REG_SET (temp);
        CLEAR_HARD_REG_SET (temp2);
  
!       for (j = allocno_row_words - 1, allocno2 = 0; j >= 0;
! 	   j--, allocno2 += INT_BITS)
  	{
! 	  unsigned INT_TYPE word = (unsigned INT_TYPE) *p++;
! 
! 	  for (allocno3 = allocno2; word; word >>= 1, allocno3++)
  	    {
! 	      if ((word & 1) && allocno_to_order[allocno3] > i)
! 		{
! 		  if (allocno_size[allocno3] <= allocno_size[allocno])
! 		    IOR_HARD_REG_SET (temp,
! 				      hard_reg_full_preferences[allocno3]);
! 		  else
! 		    IOR_HARD_REG_SET (temp2,
! 				      hard_reg_full_preferences[allocno3]);
! 		}
  	    }
! 	}
  
        AND_COMPL_HARD_REG_SET (temp, hard_reg_full_preferences[allocno]);
        IOR_HARD_REG_SET (temp, temp2);
--- 930,952 ----
  	 we want to give the lower-priority allocno the first chance for
  	 these registers).  */
        HARD_REG_SET temp, temp2;
!       int allocno2;
  
        allocno = allocno_order[i];
  
        CLEAR_HARD_REG_SET (temp);
        CLEAR_HARD_REG_SET (temp2);
  
!       EXECUTE_IF_CONFLICT (allocno, allocno2,
  	{
! 	  if (allocno_to_order[allocno2] > i)
  	    {
! 	      if (allocno_size[allocno2] <= allocno_size[allocno])
! 		IOR_HARD_REG_SET (temp, hard_reg_full_preferences[allocno2]);
! 	      else
! 		IOR_HARD_REG_SET (temp2, hard_reg_full_preferences[allocno2]);
  	    }
! 	});
  
        AND_COMPL_HARD_REG_SET (temp, hard_reg_full_preferences[allocno]);
        IOR_HARD_REG_SET (temp, temp2);
*************** find_reg (allocno, losers, alt_regs_p, a
*** 1246,1256 ****
        /* For each other pseudo-reg conflicting with this one,
  	 mark it as conflicting with the hard regs this one occupies.  */
        lim = allocno;
!       for (j = 0; j < max_allocno; j++)
! 	if (CONFLICTP (j, lim))
! 	  {
! 	    IOR_HARD_REG_SET (hard_reg_conflicts[j], this_reg);
! 	  }
      }
  }
  
--- 1267,1276 ----
        /* For each other pseudo-reg conflicting with this one,
  	 mark it as conflicting with the hard regs this one occupies.  */
        lim = allocno;
!       EXECUTE_IF_CONFLICT (lim, j,
! 	{
! 	  IOR_HARD_REG_SET (hard_reg_conflicts[j], this_reg);
! 	});
      }
  }
  
*************** record_one_conflict (regno)
*** 1303,1313 ****
    if (regno < FIRST_PSEUDO_REGISTER)
      /* When a hard register becomes live,
         record conflicts with live pseudo regs.  */
!     for (j = 0; j < max_allocno; j++)
        {
! 	if (ALLOCNO_LIVE_P (j))
! 	  SET_HARD_REG_BIT (hard_reg_conflicts[j], regno);
!       }
    else
      /* When a pseudo-register becomes live,
         record conflicts first with hard regs,
--- 1323,1332 ----
    if (regno < FIRST_PSEUDO_REGISTER)
      /* When a hard register becomes live,
         record conflicts with live pseudo regs.  */
!     EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, j,
        {
! 	SET_HARD_REG_BIT (hard_reg_conflicts[j], regno);
!       });
    else
      /* When a pseudo-register becomes live,
         record conflicts first with hard regs,


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