Patchwork [SPARC] Fix PR target/51920

login
register
mail settings
Submitter Eric Botcazou
Date Jan. 30, 2012, 12:41 p.m.
Message ID <201201301341.29055.ebotcazou@adacore.com>
Download mbox | patch
Permalink /patch/138567/
State New
Headers show

Comments

Eric Botcazou - Jan. 30, 2012, 12:41 p.m.
I think it's the long-standing issue with word-mode paradoxical subregs of FP
regs in 64-bit mode, which is present on both PA and SPARC.  We don't have any 
real solution as of this writing, only kludges, so the attached patch makes it 
so that vector_init_fpmerge doesn't create pseudos with long live ranges, to 
lower the pressure on the register allocator.

Tested on SPARC/Solaris, applied on the mainline.


2012-01-30  Eric Botcazou  <ebotcazou@adacore.com>

	PR target/51920
	* config/sparc/sparc.c (vector_init_fpmerge): Remove INNER_MODE
	parameter and use short-lived pseudos.
	(vector_init_faligndata): Remove INNER_MODE parameter and use loop.
	(sparc_expand_vector_init): Const-ify local variables and adjust
	calls to above functions.
David Miller - Jan. 30, 2012, 4:40 p.m.
From: Eric Botcazou <ebotcazou@adacore.com>
Date: Mon, 30 Jan 2012 13:41:28 +0100

> I think it's the long-standing issue with word-mode paradoxical subregs of FP
> regs in 64-bit mode, which is present on both PA and SPARC.  We don't have any 
> real solution as of this writing, only kludges, so the attached patch makes it 
> so that vector_init_fpmerge doesn't create pseudos with long live ranges, to 
> lower the pressure on the register allocator.
> 
> Tested on SPARC/Solaris, applied on the mainline.

Thanks for fixing this Eric.

Patch

Index: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c	(revision 183640)
+++ config/sparc/sparc.c	(working copy)
@@ -11485,49 +11485,47 @@  vector_init_bshuffle (rtx target, rtx el
   emit_insn (final_insn);
 }
 
+/* Subroutine of sparc_expand_vector_init.  Emit code to initialize
+   all fields of TARGET to ELT in V8QI by means of VIS FPMERGE insn.  */
+
 static void
-vector_init_fpmerge (rtx target, rtx elt, enum machine_mode inner_mode)
+vector_init_fpmerge (rtx target, rtx elt)
 {
-  rtx t1, t2, t3, t3_low;
+  rtx t1, t2, t2_low, t3, t3_low;
 
   t1 = gen_reg_rtx (V4QImode);
-  elt = convert_modes (SImode, inner_mode, elt, true);
+  elt = convert_modes (SImode, QImode, elt, true);
   emit_move_insn (gen_lowpart (SImode, t1), elt);
 
-  t2 = gen_reg_rtx (V4QImode);
-  emit_move_insn (t2, t1);
+  t2 = gen_reg_rtx (V8QImode);
+  t2_low = gen_lowpart (V4QImode, t2);
+  emit_insn (gen_fpmerge_vis (t2, t1, t1));
 
   t3 = gen_reg_rtx (V8QImode);
   t3_low = gen_lowpart (V4QImode, t3);
+  emit_insn (gen_fpmerge_vis (t3, t2_low, t2_low));
 
-  emit_insn (gen_fpmerge_vis (t3, t1, t2));
-  emit_move_insn (t1, t3_low);
-  emit_move_insn (t2, t3_low);
-
-  emit_insn (gen_fpmerge_vis (t3, t1, t2));
-  emit_move_insn (t1, t3_low);
-  emit_move_insn (t2, t3_low);
-
-  emit_insn (gen_fpmerge_vis (gen_lowpart (V8QImode, target), t1, t2));
+  emit_insn (gen_fpmerge_vis (target, t3_low, t3_low));
 }
 
+/* Subroutine of sparc_expand_vector_init.  Emit code to initialize
+   all fields of TARGET to ELT in V4HI by means of VIS FALIGNDATA insn.  */
+
 static void
-vector_init_faligndata (rtx target, rtx elt, enum machine_mode inner_mode)
+vector_init_faligndata (rtx target, rtx elt)
 {
   rtx t1 = gen_reg_rtx (V4HImode);
+  int i;
 
-  elt = convert_modes (SImode, inner_mode, elt, true);
-
+  elt = convert_modes (SImode, HImode, elt, true);
   emit_move_insn (gen_lowpart (SImode, t1), elt);
 
   emit_insn (gen_alignaddrsi_vis (gen_reg_rtx (SImode),
 				  force_reg (SImode, GEN_INT (6)),
-				  CONST0_RTX (SImode)));
+				  const0_rtx));
 
-  emit_insn (gen_faligndatav4hi_vis (target, t1, target));
-  emit_insn (gen_faligndatav4hi_vis (target, t1, target));
-  emit_insn (gen_faligndatav4hi_vis (target, t1, target));
-  emit_insn (gen_faligndatav4hi_vis (target, t1, target));
+  for (i = 0; i < 4; i++)
+    emit_insn (gen_faligndatav4hi_vis (target, t1, target));
 }
 
 /* Emit code to initialize TARGET to values for individual fields VALS.  */
@@ -11535,9 +11533,9 @@  vector_init_faligndata (rtx target, rtx
 void
 sparc_expand_vector_init (rtx target, rtx vals)
 {
-  enum machine_mode mode = GET_MODE (target);
-  enum machine_mode inner_mode = GET_MODE_INNER (mode);
-  int n_elts = GET_MODE_NUNITS (mode);
+  const enum machine_mode mode = GET_MODE (target);
+  const enum machine_mode inner_mode = GET_MODE_INNER (mode);
+  const int n_elts = GET_MODE_NUNITS (mode);
   int i, n_var = 0;
   bool all_same;
   rtx mem;
@@ -11593,12 +11591,12 @@  sparc_expand_vector_init (rtx target, rt
 	}
       if (mode == V8QImode)
 	{
-	  vector_init_fpmerge (target, XVECEXP (vals, 0, 0), inner_mode);
+	  vector_init_fpmerge (target, XVECEXP (vals, 0, 0));
 	  return;
 	}
       if (mode == V4HImode)
 	{
-	  vector_init_faligndata (target, XVECEXP (vals, 0, 0), inner_mode);
+	  vector_init_faligndata (target, XVECEXP (vals, 0, 0));
 	  return;
 	}
     }