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]
Other format: [Raw text]

Re: [dataflow] [patch RFA] A SH specific patch


Kaz Kojima wrote:
> Hi,
>
> This is a follow up patch for Kenny's patch:
>
> Change the way register information is computed
> http://gcc.gnu.org/ml/gcc-patches/2007-05/msg00547.html
>
> to avoid unexpected spill failures when the first scheduling
> is enabled for SH.  It's tested on sh4-unknown-linux-gnu.
> I need a one liner for df-core.c:df_get_bb_dirty
>
>  bool
>  df_get_bb_dirty (basic_block bb)
>  {
> -  if (df)
> +  if (df && df_live)
>      return bitmap_bit_p (df_live->out_of_date_transfer_functions, bb->index);
>    else
>      return false;
>
> for the build and test on this target, though it isn't
> related to the patch.
>
> OK to commit this patch against sh.c?
>
> Regards,
> 	kaz
> --
> 2007-05-08  Kaz Kojima  <kkojima@gcc.gnu.org>
>
> 	* config/sh/sh.c (r0_life_regions): New variable.
> 	(find_r0_life_regions): New static function.
> 	(sh_md_init_global): Call find_r0_life_regions when
> 	reload_completed isn't set.
> 	(R0_MAX_LIVE_LENGTH): Remove.
> 	(high__pressure): Return 1 if r0_life_regions is over
> 	the given threshold.
>
> --- ORIG/dataflow/gcc/config/sh/sh.c	2007-05-09 06:38:14.000000000 +0900
> +++ LOCAL/dataflow/gcc/config/sh/sh.c	2007-05-09 13:18:29.000000000 +0900
> @@ -88,6 +88,9 @@ static short *regmode_weight[2];
>  /* Total SFmode and SImode weights of scheduled insns.  */
>  static int curr_regmode_pressure[2];
>  
> +/* Number of r0 life regions.  */
> +static int r0_life_regions;
> +
>  /* If true, skip cycles for Q -> R movement.  */
>  static int skip_cycles = 0;
>  
> @@ -210,6 +213,7 @@ static int sh_dfa_new_cycle (FILE *, int
>  static short find_set_regmode_weight (rtx, enum machine_mode);
>  static short find_insn_regmode_weight (rtx, enum machine_mode);
>  static void find_regmode_weight (basic_block, enum machine_mode);
> +static int find_r0_life_regions (basic_block);
>  static void  sh_md_init_global (FILE *, int, int);
>  static void  sh_md_finish_global (FILE *, int);
>  static int rank_for_reorder (const void *, const void *);
> @@ -9209,6 +9213,56 @@ ready_reorder (rtx *ready, int nready)
>    SCHED_REORDER (ready, nready);
>  }
>  
> +/* Count life regions of r0 for a block.  */
> +static int
> +find_r0_life_regions (basic_block b)
> +{
> +  rtx end, insn;
> +  rtx pset;
> +  rtx r0_reg;
> +  int live;
> +  int set;
> +  int death = 0;
> +
> +  if (REGNO_REG_SET_P (DF_LIVE_IN (b), R0_REG))
> +    {
> +      set = 1;
> +      live = 1;
> +    }
> +  else
> +    {
> +      set = 0;
> +      live = 0;
> +    }
> +
> +  insn = BB_HEAD (b);
> +  end = BB_END (b);
> +  r0_reg = gen_rtx_REG (SImode, R0_REG);
> +  while (1)
> +    {
> +      if (INSN_P (insn))
> +	{
> +	  if (find_regno_note (insn, REG_DEAD, R0_REG))
> +	    {
> +	      death++;
> +	      live = 0;
> +	    }
> +	  if (!live
> +	      && (pset = single_set (insn))
> +	      && reg_overlap_mentioned_p (r0_reg, SET_DEST (pset))
> +	      && !find_regno_note (insn, REG_UNUSED, R0_REG))
> +	    {
> +	      set++;
> +	      live = 1;
> +	    }
> +	}
> +      if (insn == end)
> +	break;
> +      insn = NEXT_INSN (insn);
> +    }
> +  return set - death;
> +}
> +
>  /* Calculate regmode weights for all insns of all basic block.  */
>  static void
>  sh_md_init_global (FILE *dump ATTRIBUTE_UNUSED,
> @@ -9219,11 +9273,14 @@ sh_md_init_global (FILE *dump ATTRIBUTE_
>  
>    regmode_weight[0] = (short *) xcalloc (old_max_uid, sizeof (short));
>    regmode_weight[1] = (short *) xcalloc (old_max_uid, sizeof (short));
> +  r0_life_regions = 0;
>  
>    FOR_EACH_BB_REVERSE (b)
>    {
>      find_regmode_weight (b, SImode);
>      find_regmode_weight (b, SFmode);
> +    if (!reload_completed)
> +      r0_life_regions += find_r0_life_regions (b);
>    }
>  
>    CURR_REGMODE_PRESSURE (SImode) = 0;
> @@ -9284,7 +9341,6 @@ sh_md_init (FILE *dump ATTRIBUTE_UNUSED,
>  /* Pressure on register r0 can lead to spill failures. so avoid sched1 for
>     functions that already have high pressure on r0. */
>  #define R0_MAX_LIFE_REGIONS 2
> -#define R0_MAX_LIVE_LENGTH 12
>  /* Register Pressure thresholds for SImode and SFmode registers.  */
>  #define SIMODE_MAX_WEIGHT 5
>  #define SFMODE_MAX_WEIGHT 10
> @@ -9293,6 +9349,11 @@ sh_md_init (FILE *dump ATTRIBUTE_UNUSED,
>  static short
>  high_pressure (enum machine_mode mode)
>  {
> +  /* Pressure on register r0 can lead to spill failures. so avoid sched1 for
> +     functions that already have high pressure on r0. */
> +   if (r0_life_regions >= R0_MAX_LIFE_REGIONS)
> +     return 1;
> +
>    if (mode == SFmode)
>      return (CURR_REGMODE_PRESSURE (SFmode) > SFMODE_MAX_WEIGHT);
>    else
>   
ok to check in both patches on the dataflow branch, thanks.

kenny


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