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 take 2


Hi,
here is updated patch.  It passes both enable/disable checking i386 bootstrap
and seems to pass the sparc bootstrap too (it is about to finish).

I've changed way the life information is rebuilt - I now understand the purpose
of large regions - if I do interblock scheduling, I need to do global life
update.  Now one BB regions are updated locally and multiple BB ones globally.

I've verified that the patch avoids the 15% of time on disable-checking 
20001226-1.c testcase I was shooting for.  It still save some time on
enable-checking compilation due to easier life updating.

Honza

Sat Oct 27 17:28:31 CEST 2001  Jan Hubicka  <jh@suse.cz>

	* sched-rgn.c (CHECK_DEAD_NOTES): New constant.
	(init_regions, schedule_insns): Conditionalize the checking
	code by CHECK_DEAD_NOTES; avoid multiple calls to update_life_info.

*** sched-rgn.c.old	Sat Oct 27 16:40:38 2001
--- sched-rgn.c	Sat Oct 27 17:14:04 2001
*************** Software Foundation, 59 Temple Place - S
*** 62,67 ****
--- 62,78 ----
  #include "recog.h"
  #include "sched-int.h"
  
+ /* Define when we want to do count REG_DEAD notes before and after scheduling
+    for sanity checking.  We can't do that when conditional execution is used,
+    as REG_DEAD exist only for unconditional deaths.  */
+ 
+ #if !defined (HAVE_conditional_execution) && defined (ENABLE_CHECKING)
+ #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 ()
*** 2790,2797 ****
    block_to_bb = (int *) xmalloc ((n_basic_blocks) * sizeof (int));
    containing_rgn = (int *) xmalloc ((n_basic_blocks) * sizeof (int));
  
-   blocks = sbitmap_alloc (n_basic_blocks);
- 
    /* Compute regions for scheduling.  */
    if (reload_completed
        || n_basic_blocks == 1
--- 2801,2806 ----
*************** init_regions ()
*** 2849,2869 ****
  	}
      }
  
-   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);
  }
  
  /* The one entry point in this file.  DUMP_FILE is the dump file for
--- 2858,2883 ----
  	}
      }
  
  
!   if (CHECK_DEAD_NOTES)
      {
!       blocks = sbitmap_alloc (n_basic_blocks);
!       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);
      }
!   else
!     deaths_in_region[rgn] = count_or_remove_death_notes (NULL, 1);
  }
  
  /* The one entry point in this file.  DUMP_FILE is the dump file for
*************** schedule_insns (dump_file)
*** 2916,2954 ****
    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.  */
- 	/* In the single block case, the count of registers that died should
- 	   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)
--- 2930,2978 ----
    sbitmap_ones (large_region_blocks);
  
    blocks = sbitmap_alloc (n_basic_blocks);
+   sbitmap_zero (blocks);
  
+   /* Update life information.  For regions consisting of multiple blocks
+      we've possibly done interblock scheduling that affects global liveness.
+      For regions consisting of single blocks we need to do only local
+      liveness.  */
    for (rgn = 0; rgn < nr_regions; rgn++)
      if (RGN_NR_BLOCKS (rgn) > 1)
        any_large_regions = 1;
      else
        {
  	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));
    if (any_large_regions)
      {
        update_life_info (large_region_blocks, UPDATE_LIFE_GLOBAL,
  			PROP_DEATH_NOTES | PROP_REG_INFO);
      }
  
+   if (CHECK_DEAD_NOTES)
+     {
+       /* 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]);
+ 
+ 	  if (deaths_in_region[rgn] != count_or_remove_death_notes (blocks, 0))
+ 	    abort ();
+ 	}
+       free (deaths_in_region);
+     }
+ 
    /* Reposition the prologue and epilogue notes in case we moved the
       prologue/epilogue insns.  */
    if (reload_completed)
*************** schedule_insns (dump_file)
*** 3001,3007 ****
  
    sbitmap_free (blocks);
    sbitmap_free (large_region_blocks);
- 
-   free (deaths_in_region);
  }
  #endif
--- 3025,3029 ----


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