This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [dataflow] [patch RFA] A SH specific patch
- From: Kenneth Zadeck <zadeck at naturalbridge dot com>
- To: Kaz Kojima <kkojima at rr dot iij4u dot or dot jp>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 09 May 2007 10:07:55 -0400
- Subject: Re: [dataflow] [patch RFA] A SH specific patch
- References: <20070509.224412.59655741.kkojima@rr.iij4u.or.jp>
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