Patchwork [RFC] Correct sparc's REGMODE_NATURAL_SIZE and MODES_TIEABLE_P wrt. vector modes.

login
register
mail settings
Submitter David Miller
Date Nov. 15, 2011, 9:22 p.m.
Message ID <20111115.162211.1736625982098083927.davem@davemloft.net>
Download mbox | patch
Permalink /patch/125872/
State New
Headers show

Comments

David Miller - Nov. 15, 2011, 9:22 p.m.
Eric, this is just something I noticed while trying to fix the
vec_init problems last week.

I'm confident that the issue is real, however I can't point to any
real bugs that are caused by this.

Therefore I'm reluctant to commit this change.

What do you think?

gcc/

	* config/sparc/sparc.c (sparc_regmode_natural_size): New function
	implementing REGMODE_NATURAL_SIZE taking into consideration vector
	modes.
	(sparc_modes_tieable_p): Similarly for MODES_TIEABLE_P.
	* config/sparc/sparc-protos.h (sparc_regmode_natural_size,
	sparc_modes_tieable_p): Declare.
	* gcc/config/sparc/sparc.h (REGMODE_NATURAL_SIZE,
	MODES_TIEABLE_P): Use new helper functions.
---
 gcc/ChangeLog                   |    9 +++++
 gcc/config/sparc/sparc-protos.h |    2 +
 gcc/config/sparc/sparc.c        |   65 +++++++++++++++++++++++++++++++++++++++
 gcc/config/sparc/sparc.h        |   18 +---------
 4 files changed, 78 insertions(+), 16 deletions(-)
Eric Botcazou - Nov. 17, 2011, 9:21 p.m.
> Eric, this is just something I noticed while trying to fix the
> vec_init problems last week.
>
> I'm confident that the issue is real, however I can't point to any
> real bugs that are caused by this.
>
> Therefore I'm reluctant to commit this change.
>
> What do you think?

I'd install it, this really appears to be a sensible change.
David Miller - Nov. 21, 2011, 9:51 p.m.
From: Eric Botcazou <ebotcazou@adacore.com>
Date: Thu, 17 Nov 2011 22:21:32 +0100

>> Eric, this is just something I noticed while trying to fix the
>> vec_init problems last week.
>>
>> I'm confident that the issue is real, however I can't point to any
>> real bugs that are caused by this.
>>
>> Therefore I'm reluctant to commit this change.
>>
>> What do you think?
> 
> I'd install it, this really appears to be a sensible change.

Ok, committed to trunk.

Thanks for reviewing.

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cf4e66b..3544d38 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,14 @@ 
 2011-11-11  David S. Miller  <davem@davemloft.net>
 
+	* config/sparc/sparc.c (sparc_regmode_natural_size): New function
+	implementing REGMODE_NATURAL_SIZE taking into consideration vector
+	modes.
+	(sparc_modes_tieable_p): Similarly for MODES_TIEABLE_P.
+	* config/sparc/sparc-protos.h (sparc_regmode_natural_size,
+	sparc_modes_tieable_p): Declare.
+	* gcc/config/sparc/sparc.h (REGMODE_NATURAL_SIZE,
+	MODES_TIEABLE_P): Use new helper functions.
+
 	Revert
 	2011-11-05  David S. Miller  <davem@davemloft.net>
 
diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h
index ccf20b1..10fa5ed 100644
--- a/gcc/config/sparc/sparc-protos.h
+++ b/gcc/config/sparc/sparc-protos.h
@@ -109,6 +109,8 @@  extern void sparc_expand_vector_init (rtx, rtx);
 extern void sparc_expand_vec_perm_bmask(enum machine_mode, rtx);
 extern bool sparc_expand_conditional_move (enum machine_mode, rtx *);
 extern void sparc_expand_vcond (enum machine_mode, rtx *, int, int);
+unsigned int sparc_regmode_natural_size (enum machine_mode);
+bool sparc_modes_tieable_p (enum machine_mode, enum machine_mode);
 #endif /* RTX_CODE */
 
 #endif /* __SPARC_PROTOS_H__ */
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 55759a0..b315698 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -11616,4 +11616,69 @@  sparc_expand_vcond (enum machine_mode mode, rtx *operands, int ccode, int fcode)
   emit_insn (gen_rtx_SET (VOIDmode, operands[0], bshuf));
 }
 
+/* On sparc, any mode which naturally allocates into the float
+   registers should return 4 here.  */
+
+unsigned int
+sparc_regmode_natural_size (enum machine_mode mode)
+{
+  int size = UNITS_PER_WORD;
+
+  if (TARGET_ARCH64)
+    {
+      enum mode_class mclass = GET_MODE_CLASS (mode);
+
+      if (mclass == MODE_FLOAT || mclass == MODE_VECTOR_INT)
+	size = 4;
+    }
+
+  return size;
+}
+
+/* Return TRUE if it is a good idea to tie two pseudo registers
+   when one has mode MODE1 and one has mode MODE2.
+   If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
+   for any hard reg, then this must be FALSE for correct output.
+
+   For V9 we have to deal with the fact that only the lower 32 floating
+   point registers are 32-bit addressable.  */
+
+bool
+sparc_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
+{
+  enum mode_class mclass1, mclass2;
+  unsigned short size1, size2;
+
+  if (mode1 == mode2)
+    return true;
+
+  mclass1 = GET_MODE_CLASS (mode1);
+  mclass2 = GET_MODE_CLASS (mode2);
+  if (mclass1 != mclass2)
+    return false;
+
+  if (! TARGET_V9)
+    return true;
+
+  /* Classes are the same and we are V9 so we have to deal with upper
+     vs. lower floating point registers.  If one of the modes is a
+     4-byte mode, and the other is not, we have to mark them as not
+     tieable because only the lower 32 floating point register are
+     addressable 32-bits at a time.
+
+     We can't just test explicitly for SFmode, otherwise we won't
+     cover the vector mode cases properly.  */
+
+  if (mclass1 != MODE_FLOAT && mclass1 != MODE_VECTOR_INT)
+    return true;
+
+  size1 = GET_MODE_SIZE (mode1);
+  size2 = GET_MODE_SIZE (mode2);
+  if ((size1 > 4 && size2 == 4)
+      || (size2 > 4 && size1 == 4))
+    return false;
+
+  return true;
+}
+
 #include "gt-sparc.h"
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index e8707f5..32f8c10 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -716,8 +716,7 @@  extern enum cmodel sparc_cmodel;
 
 /* Due to the ARCH64 discrepancy above we must override this next
    macro too.  */
-#define REGMODE_NATURAL_SIZE(MODE) \
-  ((TARGET_ARCH64 && FLOAT_MODE_P (MODE)) ? 4 : UNITS_PER_WORD)
+#define REGMODE_NATURAL_SIZE(MODE) sparc_regmode_natural_size (MODE)
 
 /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
    See sparc.c for how we initialize this.  */
@@ -735,20 +734,7 @@  extern int sparc_mode_class[];
    register window instruction in the prologue.  */
 #define HARD_REGNO_RENAME_OK(FROM, TO) ((FROM) != 1)
 
-/* Value is 1 if it is a good idea to tie two pseudo registers
-   when one has mode MODE1 and one has mode MODE2.
-   If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
-   for any hard reg, then this must be 0 for correct output.
-
-   For V9: SFmode can't be combined with other float modes, because they can't
-   be allocated to the %d registers.  Also, DFmode won't fit in odd %f
-   registers, but SFmode will.  */
-#define MODES_TIEABLE_P(MODE1, MODE2) \
-  ((MODE1) == (MODE2)						\
-   || (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2)		\
-       && (! TARGET_V9						\
-	   || (GET_MODE_CLASS (MODE1) != MODE_FLOAT		\
-	       || (MODE1 != SFmode && MODE2 != SFmode)))))
+#define MODES_TIEABLE_P(MODE1, MODE2) sparc_modes_tieable_p (MODE1, MODE2)
 
 /* Specify the registers used for certain standard purposes.
    The values of these macros are register numbers.  */