diff mbox series

[rs6000] Stop non-volatile CR usage from killing shrink-wrap

Message ID d6adf5bf-1dea-b7ac-0021-00f4857bc264@linux.vnet.ibm.com
State New
Headers show
Series [rs6000] Stop non-volatile CR usage from killing shrink-wrap | expand

Commit Message

Pat Haugen Aug. 28, 2017, 9:34 p.m. UTC
The following patch allows shrink-wrapping to succeed in the presence of
non-volatile CR save/restore. The movesi_from_cr define_insn used to
list all CRs as used, even though it's only the non-volatile values that
we are interested in saving/restoring. This prevented the prolog from
being moved past the early exit test because that compare was defining a
register used in the prolog (a volatile CR). The patch removes the
mentions of the volatile CRs and renames the functions involved so that
it's hopefully clear they are for prolog generation only.

Bootstrap/regtest on powerpc64le-linux with no new regressions. Ok for
trunk?

-Pat



2017-08-28  Pat Haugen  <pthaugen@us.ibm.com>

	* config/rs6000/rs6000.c (rs6000_emit_prolog_move_from_cr): Rename from
	rs6000_emit_move_from_cr and call renamed function.
	(rs6000_emit_prologue): Call renamed functions.
	* config/rs6000/rs6000.md (prolog_movesi_from_cr): Rename from
	prolog_movesi_from_cr, remove volatile CRs.


testsuite/ChangeLog:
2017-08-28  Pat Haugen  <pthaugen@us.ibm.com>

	* gcc.target/powerpc/cr_shrink-wrap.c: New.

Comments

Segher Boessenkool Aug. 29, 2017, 12:58 p.m. UTC | #1
Hi Pat,

On Mon, Aug 28, 2017 at 04:34:16PM -0500, Pat Haugen wrote:
> The following patch allows shrink-wrapping to succeed in the presence of
> non-volatile CR save/restore. The movesi_from_cr define_insn used to
> list all CRs as used, even though it's only the non-volatile values that
> we are interested in saving/restoring. This prevented the prolog from
> being moved past the early exit test because that compare was defining a
> register used in the prolog (a volatile CR). The patch removes the
> mentions of the volatile CRs and renames the functions involved so that
> it's hopefully clear they are for prolog generation only.

It is spelled "prologue" (prolog is a computer language).

> --- gcc/config/rs6000/rs6000.c	(revision 251389)
> +++ gcc/config/rs6000/rs6000.c	(working copy)
> @@ -26083,10 +26083,14 @@ rs6000_emit_savres_rtx (rs6000_stack_t *
>    return insn;
>  }
>  
> -/* Emit code to store CR fields that need to be saved into REG.  */
> +/* Emit prolog code to store CR fields that need to be saved into REG. This

Super nit: two spaces after a full stop.

Okay for trunk with those fixed.  Thanks!


Segher
diff mbox series

Patch

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 251389)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -26083,10 +26083,14 @@  rs6000_emit_savres_rtx (rs6000_stack_t *
   return insn;
 }
 
-/* Emit code to store CR fields that need to be saved into REG.  */
+/* Emit prolog code to store CR fields that need to be saved into REG. This
+   function should only be called when moving the non-volatile CRs to REG, it
+   is not a general purpose routine to move the entire set of CRs to REG.
+   Specifically, gen_prolog_movesi_from_cr() does not contain uses of the
+   volatile CRs.  */
 
 static void
-rs6000_emit_move_from_cr (rtx reg)
+rs6000_emit_prolog_move_from_cr (rtx reg)
 {
   /* Only the ELFv2 ABI allows storing only selected fields.  */
   if (DEFAULT_ABI == ABI_ELFv2 && TARGET_MFCRF)
@@ -26117,7 +26121,7 @@  rs6000_emit_move_from_cr (rtx reg)
 	 as well, using logical operations to combine the values.  */
     }
 
-  emit_insn (gen_movesi_from_cr (reg));
+  emit_insn (gen_prolog_movesi_from_cr (reg));
 }
 
 /* Return whether the split-stack arg pointer (r12) is used.  */
@@ -26857,7 +26861,7 @@  rs6000_emit_prologue (void)
     {
       cr_save_rtx = gen_rtx_REG (SImode, cr_save_regno);
       START_USE (cr_save_regno);
-      rs6000_emit_move_from_cr (cr_save_rtx);
+      rs6000_emit_prolog_move_from_cr (cr_save_rtx);
     }
 
   /* Do any required saving of fpr's.  If only one or two to save, do
@@ -27095,7 +27099,7 @@  rs6000_emit_prologue (void)
 	{
 	  START_USE (0);
 	  cr_save_rtx = gen_rtx_REG (SImode, 0);
-	  rs6000_emit_move_from_cr (cr_save_rtx);
+	  rs6000_emit_prolog_move_from_cr (cr_save_rtx);
 	}
 
       /* Saving CR requires a two-instruction sequence: one instruction
@@ -27182,7 +27186,7 @@  rs6000_emit_prologue (void)
       /* ??? We might get better performance by using multiple mfocrf
 	 instructions.  */
       crsave = gen_rtx_REG (SImode, 0);
-      emit_insn (gen_movesi_from_cr (crsave));
+      emit_insn (gen_prolog_movesi_from_cr (crsave));
 
       for (i = 0; i < 8; i++)
 	if (!call_used_regs[CR0_REGNO + i])
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 251389)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -13032,12 +13032,14 @@  (define_insn "*movesi_from_cr_one"
 }"
   [(set_attr "type" "mfcrf")])
 
-(define_insn "movesi_from_cr"
+;; Don't include the volatile CRs since their values are not used wrt CR save
+;; in the prolog and doing so prevents shrink-wrapping because we can't move the
+;; prolog past an insn (early exit test) that defines a register used in the
+;; prolog.
+(define_insn "prolog_movesi_from_cr"
   [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-        (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO)
-		    (reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
-		    (reg:CC CR4_REGNO) (reg:CC CR5_REGNO)
-		    (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)]
+        (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
+		    (reg:CC CR4_REGNO)]
 		   UNSPEC_MOVESI_FROM_CR))]
   ""
   "mfcr %0"
Index: gcc/testsuite/gcc.target/powerpc/cr_shrink-wrap.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/cr_shrink-wrap.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/cr_shrink-wrap.c	(working copy)
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-rtl-pro_and_epilogue" } */
+
+void foo(int i)
+{
+  if (i > 0)
+    /* Non-volatile CR kill on true path should not prevent shrink-wrap.  */
+    asm ("" : : : "cr2", "cr3");
+}
+
+/* { dg-final { scan-rtl-dump-times "Performing shrink-wrapping" 1 "pro_and_epilogue" } } */