This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[dataflow] [patch RFA] A SH specific patch
- From: Kaz Kojima <kkojima at rr dot iij4u dot or dot jp>
- To: gcc-patches at gcc dot gnu dot org
- Cc: zadeck at naturalbridge dot com
- Date: Wed, 09 May 2007 22:44:12 +0900 (JST)
- Subject: [dataflow] [patch RFA] A SH specific patch
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