[SPARC] Fix PR target/51920

Submitted by Eric Botcazou on Jan. 30, 2012, 12:41 p.m.

Details

Message ID 201201301341.29055.ebotcazou@adacore.com
State New
Headers show

Commit Message

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.

Comments

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 hide | download patch | download mbox

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;
 	}
     }