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]

[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


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