This is the mail archive of the gcc@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: PR target/16482: first scheduling pass on SH4


[I'd like to cc this message to gcc-patches and SH port maintainers
because it includes a patch anyway.]

tm_gccmail@kloo.net wrote:
>> Does the first insn scheduling for SH-4 take account of such insn which
>> uses R0 implicitly?  Or is it a problem of the reload pass?
>
> The first instruction scheduling pass cannot extend the lifetime of
> pseudos which need r0 since there is only one r0 register.
>
> So yes, this sounds like an SH first instruction scheduling pass bug.

Thanks for your explanation.  I've attached the patch which I mentioned
in http://gcc.gnu.org/ml/gcc/2004-10/msg00176.html, though it could be
overkill.  It bootstraps on sh4-unknown-linux-gnu with no new regressions.

> Incidentally, I can reproduce the same problem with a small array index
> and -fPIC. Compile this with -O2 -mf -fPIC:
>
> int glob1;
>
> adrreg01limm1_set (float *p0)
> {
>         p0[10] = (float) glob1;
> }

Wow, too simple :-)  I've confirmed that the patch gets rid of the ICE
for it.

Regards,
	kaz
--
	* config/sh/sh.c (implicit_r0_use_block): New variable.
	(may_use_r0_in_reload, find_implicit_r0_use): New.
	(sh_md_init_global): Initialize and set implicit_r0_use_block.
	(sh_md_finish_global): Cleanup implicit_r0_use_block if needed.
	(implicit_r0_pressure): New.
	(sh_reorder): Use implicit_r0_pressure.
	(sh_reorder2): Likewise.

diff -uprN ORIG/gcc/gcc/config/sh/sh.c LOCAL/gcc/gcc/config/sh/sh.c
--- ORIG/gcc/gcc/config/sh/sh.c	2004-10-08 07:46:30.000000000 +0900
+++ LOCAL/gcc/gcc/config/sh/sh.c	2004-10-15 14:08:12.000000000 +0900
@@ -113,6 +113,10 @@ static short *regmode_weight[2];
 /* Total SFmode and SImode weights of scheduled insns.  */
 static int curr_regmode_pressure[2];
 
+/* Array indexed by basic block index whose element shows that an insn in
+   this basic block may use r0 in reload.  */
+static bool *implicit_r0_use_block;
+
 /* If true, skip cycles for Q -> R movement.  */
 static int skip_cycles = 0;
 
@@ -8744,6 +8748,73 @@ find_regmode_weight (int b, enum machine
     }
 }
 
+/* Return true if the pattern may use r0 in reload.  */
+static bool
+may_use_r0_in_reload (rtx x)
+{
+  /* The expression (mem (plus (reg) (reg))) may cause a reload with r0.  */
+  if (GET_CODE (x) == SET)
+    {
+      rtx m;
+
+      if (GET_CODE (SET_SRC (x)) == MEM)
+	m = SET_SRC (x);
+      else if (GET_CODE (SET_DEST (x)) == MEM)
+	m = SET_DEST (x);
+      else 
+	m = NULL_RTX;
+
+      if (m)
+	{
+	  if (GET_CODE (XEXP (m, 0)) == PLUS)
+	    {
+	      rtx base = XEXP (XEXP (m, 0), 0);
+	      rtx ofs = XEXP (XEXP (m, 0), 1);
+
+	      if ((GET_CODE (base) == REG || GET_CODE (base) == SUBREG)
+		  && (GET_CODE (ofs) == REG || GET_CODE (ofs) == SUBREG))
+		return true;
+	    }
+	}
+    }
+
+  if (GET_CODE (x) == PARALLEL)
+    {
+      int j;
+      for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
+	{
+	  rtx y = XVECEXP (x, 0, j);
+	  if (may_use_r0_in_reload (y))
+	    return true;
+	}
+    }
+
+  return false;
+}
+
+/* Set implicit_r0_use_block[B] if the basic block B includes an insn which
+   may use r0 in reload.  */
+static void
+find_implicit_r0_use (int b)
+{
+  rtx insn, next_tail, head, tail;
+
+  get_block_head_tail (b, &head, &tail);
+  next_tail = NEXT_INSN (tail);
+
+  for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
+    {
+      if (!INSN_P (insn))
+	continue;
+
+      if (may_use_r0_in_reload (PATTERN (insn)))
+	{
+	  implicit_r0_use_block[b] = true;
+	  break;
+	}
+    }
+}
+
 /* Comparison function for ready queue sorting.  */
 static int
 rank_for_reorder (const void *x, const void *y)
@@ -8801,14 +8872,18 @@ sh_md_init_global (FILE *dump ATTRIBUTE_
 		   int old_max_uid)
 {
   basic_block b;
+  int max_bb;
 
   regmode_weight[0] = (short *) xcalloc (old_max_uid, sizeof (short));
   regmode_weight[1] = (short *) xcalloc (old_max_uid, sizeof (short));
+  max_bb = VARRAY_SIZE (basic_block_info);
+  implicit_r0_use_block = (bool *) xcalloc (max_bb, sizeof (bool));
 
   FOR_EACH_BB_REVERSE (b)
   {
     find_regmode_weight (b->index, SImode);
     find_regmode_weight (b->index, SFmode);
+    find_implicit_r0_use (b->index);
   }
 
   CURR_REGMODE_PRESSURE (SImode) = 0;
@@ -8831,6 +8906,11 @@ sh_md_finish_global (FILE *dump ATTRIBUT
       free (regmode_weight[1]);
       regmode_weight[1] = NULL;
     }
+  if (implicit_r0_use_block)
+    {
+      free (implicit_r0_use_block);
+      implicit_r0_use_block = NULL;
+    }
 }
 
 /* Cache the can_issue_more so that we can return it from reorder2. Also,
@@ -8890,6 +8970,20 @@ high_pressure (enum machine_mode mode)
     return (CURR_REGMODE_PRESSURE (SImode) > SIMODE_MAX_WEIGHT);
 }
 
+/* Return true if there is an insn which may use r0 in ready queue
+   and there is an explicit r0 use.  */
+static bool
+implicit_r0_pressure (rtx *ready, int n ATTRIBUTE_UNUSED)
+{
+  return true;
+
+  if (REG_N_SETS (0) > 0
+      && implicit_r0_use_block[BLOCK_NUM (ready[0])])
+    return true;
+
+  return false;
+}
+
 /* Reorder ready queue if register pressure is high.  */
 static int
 sh_reorder (FILE *dump ATTRIBUTE_UNUSED,
@@ -8901,7 +8995,8 @@ sh_reorder (FILE *dump ATTRIBUTE_UNUSED,
   if (reload_completed)
     return sh_issue_rate ();
 
-  if (high_pressure (SFmode) || high_pressure (SImode))
+  if (high_pressure (SFmode) || high_pressure (SImode)
+      || implicit_r0_pressure (ready, *n_readyp))
     {
       ready_reorder (ready, *n_readyp);
     }
@@ -8920,7 +9015,8 @@ sh_reorder2 (FILE *dump ATTRIBUTE_UNUSED
   if (reload_completed)
     return cached_can_issue_more;
 
-  if (high_pressure(SFmode) || high_pressure (SImode))
+  if (high_pressure (SFmode) || high_pressure (SImode)
+      || implicit_r0_pressure (ready, *n_readyp)) 
     skip_cycles = 1;
 
   return cached_can_issue_more;


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