Patchwork [003/236] config/mn10300: Fix missing PATTERN in PARALLEL handling

login
register
mail settings
Submitter David Malcolm
Date Aug. 27, 2014, 4:32 p.m.
Message ID <1409157135.24896.77.camel@surprise>
Download mbox | patch
Permalink /patch/383490/
State New
Headers show

Comments

David Malcolm - Aug. 27, 2014, 4:32 p.m.
On Wed, 2014-08-27 at 09:11 -0700, Richard Henderson wrote:
> On 08/27/2014 08:48 AM, David Malcolm wrote:
> > Alternatively, should this simply use "single_set"?
> 
> Yes.
> 
> > (though I think that's a more invasive change, especially since some of
> > the logic is for non-SETs).
> 
> I don't think that's the case.  Take the tests in order:
> 
>   if (mn10300_tune_cpu == PROCESSOR_AM34
>       && is_load_insn (dep)
>       && is_store_insn (insn))
>     cost += 1;
> 
> Requires sets for both.
> 
>   else if (mn10300_tune_cpu == PROCESSOR_AM34
>       && ! is_store_insn (insn)
>       && ! JUMP_P (insn)
>       && GET_CODE (PATTERN (dep)) == SET
>       && GET_CODE (PATTERN (insn)) == SET
> 
> Duh.
> 
>   if (GET_CODE (PATTERN (dep)) != SET)
>     return cost;
> 
> Filtering out non-sets from dep.
> 
>   /* Now check to see if the previous instruction is a load or store.  */
>   if (! is_load_insn (insn) && ! is_store_insn (insn))
>     return cost;
> 
> Filtering out non-sets from insn.
> 
> Thus in no case do we return anything but the original "cost" when either the
> dep or insn pattern is not a set.
> 
> Oh, and while you're massaging this function...
> 
> mn10300_adjust_sched_cost (rtx insn, rtx link, rtx dep, int cost)
> {
>   int timings = get_attr_timings (insn);
> ...
>   /* Extract the latency value from the timings attribute.  */
>   return timings < 100 ? (timings % 10) : (timings % 100);
> }
> 
> 
> Will you please move the (expensive) get_attr_timings call to the end, after
> we've discarded all of the cases in which it isn't used?

Fair enough.

Update version of patch attached; again, only lightly tested so far.

	* gcc/config/mn10300/mn10300.c (is_load_insn): Rename to...
	(set_is_load_p): ...this, updating to work on a SET pattern rather
	than an insn.
	(is_store_insn): Rename to...
	(set_is_store_p): ...this, updating to work on a SET pattern
	rather than an insn.
	(mn10300_adjust_sched_cost): Move call to get_attr_timings from
	top of function to where it is needed.  Rewrite the bogus
	condition that checks for "insn" and "dep" being PARALLEL to
	instead use single_set, introducing locals "insn_set" and
	"dep_set".  Given that we only ever returned "cost" for a non-pair
	of SETs, bail out early if we don't have a pair of SET.
	Rewrite all uses of PATTERN (dep) and PATTERN (insn) to instead
	use the new locals "insn_set" and "dep_set", and update calls to
	is_load_insn and is_store_insn to be calls to set_is_load_p and
	set_is_store_p.
Richard Henderson - Aug. 27, 2014, 4:42 p.m.
On 08/27/2014 09:32 AM, David Malcolm wrote:
> 	* gcc/config/mn10300/mn10300.c (is_load_insn): Rename to...
> 	(set_is_load_p): ...this, updating to work on a SET pattern rather
> 	than an insn.
> 	(is_store_insn): Rename to...
> 	(set_is_store_p): ...this, updating to work on a SET pattern
> 	rather than an insn.
> 	(mn10300_adjust_sched_cost): Move call to get_attr_timings from
> 	top of function to where it is needed.  Rewrite the bogus
> 	condition that checks for "insn" and "dep" being PARALLEL to
> 	instead use single_set, introducing locals "insn_set" and
> 	"dep_set".  Given that we only ever returned "cost" for a non-pair
> 	of SETs, bail out early if we don't have a pair of SET.
> 	Rewrite all uses of PATTERN (dep) and PATTERN (insn) to instead
> 	use the new locals "insn_set" and "dep_set", and update calls to
> 	is_load_insn and is_store_insn to be calls to set_is_load_p and
> 	set_is_store_p.

Ok, if it passes your smoke tests.

> +  /* We are only interested in pairs of SET. */
> +  insn_set = single_set (insn);
> +  if (!insn_set)
> +    return cost;
>  
> +  dep_set = single_set (dep);
> +  if (!dep_set)
> +    return cost;
>  
> +  gcc_assert (GET_CODE (insn_set) == SET);
> +  gcc_assert (GET_CODE (dep_set) == SET);

I don't think you need the asserts; we should be able to trust single_set.


r~

Patch

Index: gcc/config/mn10300/mn10300.c
===================================================================
--- gcc/config/mn10300/mn10300.c	(revision 214575)
+++ gcc/config/mn10300/mn10300.c	(working copy)
@@ -2742,21 +2742,15 @@ 
 }
 
 static inline bool
-is_load_insn (rtx insn)
+set_is_load_p (rtx set)
 {
-  if (GET_CODE (PATTERN (insn)) != SET)
-    return false;
-
-  return MEM_P (SET_SRC (PATTERN (insn)));
+  return MEM_P (SET_SRC (set));
 }
 
 static inline bool
-is_store_insn (rtx insn)
+set_is_store_p (rtx set)
 {
-  if (GET_CODE (PATTERN (insn)) != SET)
-    return false;
-
-  return MEM_P (SET_DEST (PATTERN (insn)));
+  return MEM_P (SET_DEST (set));
 }
 
 /* Update scheduling costs for situations that cannot be
@@ -2768,33 +2762,39 @@ 
 static int
 mn10300_adjust_sched_cost (rtx insn, rtx link, rtx dep, int cost)
 {
-  int timings = get_attr_timings (insn);
+  rtx insn_set;
+  rtx dep_set;
+  int timings;
 
   if (!TARGET_AM33)
     return 1;
 
-  if (GET_CODE (insn) == PARALLEL)
-    insn = XVECEXP (insn, 0, 0);
+  /* We are only interested in pairs of SET. */
+  insn_set = single_set (insn);
+  if (!insn_set)
+    return cost;
 
-  if (GET_CODE (dep) == PARALLEL)
-    dep = XVECEXP (dep, 0, 0);
+  dep_set = single_set (dep);
+  if (!dep_set)
+    return cost;
 
+  gcc_assert (GET_CODE (insn_set) == SET);
+  gcc_assert (GET_CODE (dep_set) == SET);
+
   /* For the AM34 a load instruction that follows a
      store instruction incurs an extra cycle of delay.  */
   if (mn10300_tune_cpu == PROCESSOR_AM34
-      && is_load_insn (dep)
-      && is_store_insn (insn))
+      && set_is_load_p (dep_set)
+      && set_is_store_p (insn_set))
     cost += 1;
 
   /* For the AM34 a non-store, non-branch FPU insn that follows
      another FPU insn incurs a one cycle throughput increase.  */
   else if (mn10300_tune_cpu == PROCESSOR_AM34
-      && ! is_store_insn (insn)
+      && ! set_is_store_p (insn_set)
       && ! JUMP_P (insn)
-      && GET_CODE (PATTERN (dep)) == SET
-      && GET_CODE (PATTERN (insn)) == SET
-      && GET_MODE_CLASS (GET_MODE (SET_SRC (PATTERN (dep)))) == MODE_FLOAT
-      && GET_MODE_CLASS (GET_MODE (SET_SRC (PATTERN (insn)))) == MODE_FLOAT)
+      && GET_MODE_CLASS (GET_MODE (SET_SRC (dep_set))) == MODE_FLOAT
+      && GET_MODE_CLASS (GET_MODE (SET_SRC (insn_set))) == MODE_FLOAT)
     cost += 1;
 
   /*  Resolve the conflict described in section 1-7-4 of
@@ -2816,23 +2816,21 @@ 
     return cost;
 
   /* Check that the instruction about to scheduled is an FPU instruction.  */
-  if (GET_CODE (PATTERN (dep)) != SET)
+  if (GET_MODE_CLASS (GET_MODE (SET_SRC (dep_set))) != MODE_FLOAT)
     return cost;
 
-  if (GET_MODE_CLASS (GET_MODE (SET_SRC (PATTERN (dep)))) != MODE_FLOAT)
-    return cost;
-
   /* Now check to see if the previous instruction is a load or store.  */
-  if (! is_load_insn (insn) && ! is_store_insn (insn))
+  if (! set_is_load_p (insn_set) && ! set_is_store_p (insn_set))
     return cost;
 
   /* XXX: Verify: The text of 1-7-4 implies that the restriction
      only applies when an INTEGER load/store precedes an FPU
      instruction, but is this true ?  For now we assume that it is.  */
-  if (GET_MODE_CLASS (GET_MODE (SET_SRC (PATTERN (insn)))) != MODE_INT)
+  if (GET_MODE_CLASS (GET_MODE (SET_SRC (insn_set))) != MODE_INT)
     return cost;
 
   /* Extract the latency value from the timings attribute.  */
+  timings = get_attr_timings (insn);
   return timings < 100 ? (timings % 10) : (timings % 100);
 }