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]

scheduler speedup


Hi,
Interestingly enought the disable_checking compiler spends about 20%
of it's time in count_or_remove_dead_notes while compiling the largest
gcc.c-torture compile testcase.

This is because we observe kind of quadratical behaviour in sanity checking on
schedule_insns that is unconditional.

This patch reorganizes the code somewhat to do the checking just conditioanlly
and it also optimizes same problem in updating liveness information by
splitting both beasts to separate passes, so the sanity checking always counts
the notes when all are present and thus we can update the life information at
once, instead of having multiple passes.

Bootstrapped/regtested i386

Honza

Tue Oct 23 15:53:15 CEST 2001  Jan Hubicka  <jh@suse.cz>
	* sched-rgn.c (CHECK_DEAD_NOTES): New constant.
	(init_regions): Reorganize the DEAD notes clearing; compute
	the number of dead notes before clearing them.
	(schedule_insns): Likewise.

Index: sched-rgn.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/sched-rgn.c,v
retrieving revision 1.20
diff -c -3 -p -r1.20 sched-rgn.c
*** sched-rgn.c	2001/10/11 03:16:09	1.20
--- sched-rgn.c	2001/10/23 13:58:23
*************** Software Foundation, 59 Temple Place - S
*** 62,67 ****
--- 62,73 ----
  #include "recog.h"
  #include "sched-int.h"
  
+ #if defined (ENABLE_CHECKING) && !defined (HAVE_conditional_execution)
+ #define CHECK_DEAD_NOTES 1
+ #else
+ #define CHECK_DEAD_NOTES 0
+ #endif
+ 
  #ifdef INSN_SCHEDULING
  /* Some accessor macros for h_i_d members only used within this file.  */
  #define INSN_REF_COUNT(INSN)	(h_i_d[INSN_UID (INSN)].ref_count)
*************** init_regions ()
*** 2969,2987 ****
  	}
      }
  
!   deaths_in_region = (int *) xmalloc (sizeof (int) * nr_regions);
  
    /* Remove all death notes from the subroutine.  */
    for (rgn = 0; rgn < nr_regions; rgn++)
      {
        int b;
  
-       sbitmap_zero (blocks);
        for (b = RGN_NR_BLOCKS (rgn) - 1; b >= 0; --b)
  	SET_BIT (blocks, rgn_bb_table[RGN_BLOCKS (rgn) + b]);
- 
-       deaths_in_region[rgn] = count_or_remove_death_notes (blocks, 1);
      }
  
    sbitmap_free (blocks);
  }
--- 2975,3005 ----
  	}
      }
  
!   if (CHECK_DEAD_NOTES)
!     {
!       deaths_in_region = (int *) xmalloc (sizeof (int) * nr_regions);
  
+       for (rgn = 0; rgn < nr_regions; rgn++)
+ 	{
+ 	  int b;
+ 
+ 	  sbitmap_zero (blocks);
+ 	  for (b = RGN_NR_BLOCKS (rgn) - 1; b >= 0; --b)
+ 	    SET_BIT (blocks, rgn_bb_table[RGN_BLOCKS (rgn) + b]);
+ 	  deaths_in_region[rgn] = count_or_remove_death_notes (blocks, 0);
+ 	}
+     }
+ 
+   sbitmap_zero (blocks);
    /* Remove all death notes from the subroutine.  */
    for (rgn = 0; rgn < nr_regions; rgn++)
      {
        int b;
  
        for (b = RGN_NR_BLOCKS (rgn) - 1; b >= 0; --b)
  	SET_BIT (blocks, rgn_bb_table[RGN_BLOCKS (rgn) + b]);
      }
+   count_or_remove_death_notes (blocks, 1);
  
    sbitmap_free (blocks);
  }
*************** void
*** 2993,3001 ****
  schedule_insns (dump_file)
       FILE *dump_file;
  {
!   sbitmap large_region_blocks, blocks;
    int rgn;
-   int any_large_regions;
  
    /* Taking care of this degenerate case makes the rest of
       this code simpler.  */
--- 3011,3018 ----
  schedule_insns (dump_file)
       FILE *dump_file;
  {
!   sbitmap blocks;
    int rgn;
  
    /* Taking care of this degenerate case makes the rest of
       this code simpler.  */
*************** schedule_insns (dump_file)
*** 3031,3058 ****
    allocate_reg_life_data ();
    compute_bb_for_insn (get_max_uid ());
  
-   any_large_regions = 0;
-   large_region_blocks = sbitmap_alloc (n_basic_blocks);
-   sbitmap_ones (large_region_blocks);
- 
    blocks = sbitmap_alloc (n_basic_blocks);
  
    for (rgn = 0; rgn < nr_regions; rgn++)
!     if (RGN_NR_BLOCKS (rgn) > 1)
!       any_large_regions = 1;
!     else
!       {
! 	sbitmap_zero (blocks);
! 	SET_BIT (blocks, rgn_bb_table[RGN_BLOCKS (rgn)]);
! 	RESET_BIT (large_region_blocks, rgn_bb_table[RGN_BLOCKS (rgn)]);
  
! 	/* Don't update reg info after reload, since that affects
! 	   regs_ever_live, which should not change after reload.  */
! 	update_life_info (blocks, UPDATE_LIFE_LOCAL,
! 			  (reload_completed ? PROP_DEATH_NOTES
! 			   : PROP_DEATH_NOTES | PROP_REG_INFO));
  
! #ifndef HAVE_conditional_execution
  	/* ??? REG_DEAD notes only exist for unconditional deaths.  We need
  	   a count of the conditional plus unconditional deaths for this to
  	   work out.  */
--- 3048,3077 ----
    allocate_reg_life_data ();
    compute_bb_for_insn (get_max_uid ());
  
    blocks = sbitmap_alloc (n_basic_blocks);
+   sbitmap_zero (blocks);
  
    for (rgn = 0; rgn < nr_regions; rgn++)
!     {
!       int b;
!       for (b = RGN_NR_BLOCKS (rgn) - 1; b >= 0; --b)
! 	SET_BIT (blocks, rgn_bb_table[RGN_BLOCKS (rgn) + b]);
!     }
! 
!   /* Don't update reg info after reload, since that affects
!      regs_ever_live, which should not change after reload.  */
!   update_life_info (blocks, UPDATE_LIFE_LOCAL,
! 		    (reload_completed ? PROP_DEATH_NOTES
! 		     : PROP_DEATH_NOTES | PROP_REG_INFO));
  
!   if (CHECK_DEAD_NOTES)
!     for (rgn = 0; rgn < nr_regions; rgn++)
!       {
! 	int b;
  
! 	sbitmap_zero (blocks);
! 	for (b = RGN_NR_BLOCKS (rgn) - 1; b >= 0; --b)
! 	  SET_BIT (blocks, rgn_bb_table[RGN_BLOCKS (rgn) + b]);
  	/* ??? REG_DEAD notes only exist for unconditional deaths.  We need
  	   a count of the conditional plus unconditional deaths for this to
  	   work out.  */
*************** schedule_insns (dump_file)
*** 3060,3074 ****
  	   not have changed during the schedule.  */
  	if (count_or_remove_death_notes (blocks, 0) != deaths_in_region[rgn])
  	  abort ();
- #endif
        }
  
-   if (any_large_regions)
-     {
-       update_life_info (large_region_blocks, UPDATE_LIFE_GLOBAL,
- 			PROP_DEATH_NOTES | PROP_REG_INFO);
-     }
- 
    /* Reposition the prologue and epilogue notes in case we moved the
       prologue/epilogue insns.  */
    if (reload_completed)
--- 3079,3086 ----
*************** schedule_insns (dump_file)
*** 3120,3127 ****
      }
  
    sbitmap_free (blocks);
-   sbitmap_free (large_region_blocks);
  
!   free (deaths_in_region);
  }
  #endif
--- 3132,3139 ----
      }
  
    sbitmap_free (blocks);
  
!   if (CHECK_DEAD_NOTES)
!     free (deaths_in_region);
  }
  #endif


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