diff mbox

PowerPC shrink-wrap support 3 of 3

Message ID 20110917071914.GW10321@bubble.grove.modra.org
State New
Headers show

Commit Message

Alan Modra Sept. 17, 2011, 7:19 a.m. UTC
Finally, the powerpc backend changes.  These are mostly just
mechanical.  I'll note that we need both "simple_return" and "return"
variants of the conditional returns because they can only be used when
no epilogue is required.  The "return" variant must use
direct_return() as a predicate to check this requirement.  The
"simple_return" variant is used by the shrink_wrap optimization to
enable a conditional return before the function prologue, and should
*not* use direct_return() because the optimization is valid for
functions that do require an epilogue.  All other instructions in the
rs6000 backend that currently use "return" are generated from the
epilogue or are sibling calls, so "simple_return" is appropriate as
per md.texi.

	* config/rs6000/rs6000.c (rs6000_make_savres_rtx): Delete unneeded
	declaration.
	(rs6000_make_savres_rtx): Rename to rs6000_emit_savres_rtx.  Use
	simple_return in pattern, emit instruction, and set jump_label.
	(rs6000_emit_prologue): Update for rs6000_emit_savres_rtx.  Use
	simple_return rather than return.
	(rs6000_output_mi_thunk): Use simple_return rather than return.
	* config/rs6000/altivec.md (restore_world): Likewise.
	* config/rs6000/spe.md (return_and_restore_gpregs_spe): Likewise.
	* config/rs6000/rs6000.md (sibcall*, sibcall_value*): Likewise.
	(return_internal*, return_and_restore*): Likewise.
	(any_return, return_pred, return_str): New iterators.
	(return, conditional return insns): Provide both return and
	simple_return variants.
diff mbox

Patch

diff -urp -x.svn -x'*~' -x'*.orig' gcc-bernd/gcc/config/rs6000/rs6000.c gcc-current/gcc/config/rs6000/rs6000.c
--- gcc-bernd/gcc/config/rs6000/rs6000.c	2011-09-16 11:52:15.000000000 +0930
+++ gcc-current/gcc/config/rs6000/rs6000.c	2011-09-15 22:25:50.000000000 +0930
@@ -899,8 +900,6 @@  static const char *rs6000_mangle_type (c
 static void rs6000_set_default_type_attributes (tree);
 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
-static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
-				   enum machine_mode, bool, bool, bool);
 static bool rs6000_reg_live_or_pic_offset_p (int);
 static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
@@ -19729,10 +19764,11 @@  rs6000_emit_stack_reset (rs6000_stack_t 
 }
 
 /* Construct a parallel rtx describing the effect of a call to an
-   out-of-line register save/restore routine.  */
+   out-of-line register save/restore routine, and emit the insn
+   or jump_insn as appropriate.  */
 
 static rtx
-rs6000_make_savres_rtx (rs6000_stack_t *info,
+rs6000_emit_savres_rtx (rs6000_stack_t *info,
 			rtx frame_reg_rtx, int save_area_offset,
 			enum machine_mode reg_mode,
 			bool savep, bool gpr, bool lr)
@@ -19742,6 +19778,7 @@  rs6000_make_savres_rtx (rs6000_stack_t *
   int reg_size = GET_MODE_SIZE (reg_mode);
   rtx sym;
   rtvec p;
+  rtx par, insn;
 
   offset = 0;
   start_reg = (gpr
@@ -19752,7 +19789,7 @@  rs6000_make_savres_rtx (rs6000_stack_t *
   p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
 
   if (!savep && lr)
-    RTVEC_ELT (p, offset++) = ret_rtx;
+    RTVEC_ELT (p, offset++) = simple_return_rtx;
 
   RTVEC_ELT (p, offset++)
     = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
@@ -19788,7 +19825,16 @@  rs6000_make_savres_rtx (rs6000_stack_t *
       RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
     }
 
-  return gen_rtx_PARALLEL (VOIDmode, p);
+  par = gen_rtx_PARALLEL (VOIDmode, p);
+
+  if (!savep && lr)
+    {
+      insn = emit_jump_insn (par);
+      JUMP_LABEL (insn) = simple_return_rtx;
+    }
+  else
+    insn = emit_insn (par);
+  return insn;
 }
 
 /* Determine whether the gp REG is really used.  */
@@ -20087,16 +20133,13 @@  rs6000_emit_prologue (void)
     }
   else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
     {
-      rtx par;
-
-      par = rs6000_make_savres_rtx (info, frame_reg_rtx,
-				    info->fp_save_offset + sp_offset,
-				    DFmode,
-				    /*savep=*/true, /*gpr=*/false,
-				    /*lr=*/(strategy
-					    & SAVE_NOINLINE_FPRS_SAVES_LR)
-					   != 0);
-      insn = emit_insn (par);
+      insn = rs6000_emit_savres_rtx (info, frame_reg_rtx,
+				     info->fp_save_offset + sp_offset,
+				     DFmode,
+				     /*savep=*/true, /*gpr=*/false,
+				     /*lr=*/((strategy
+					      & SAVE_NOINLINE_FPRS_SAVES_LR)
+					     != 0));
       rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
 			    NULL_RTX, NULL_RTX);
     }
@@ -20186,13 +20229,10 @@  rs6000_emit_prologue (void)
 	}
       else
 	{
-	  rtx par;
-
-	  par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
-					0, reg_mode,
-					/*savep=*/true, /*gpr=*/true,
-					/*lr=*/false);
-	  insn = emit_insn (par);
+	  insn = rs6000_emit_savres_rtx (info, gen_rtx_REG (Pmode, 11),
+					 0, reg_mode,
+					 /*savep=*/true, /*gpr=*/true,
+					 /*lr=*/false);
 	  rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
 				NULL_RTX, NULL_RTX);
 	}
@@ -20204,8 +20244,6 @@  rs6000_emit_prologue (void)
     }
   else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
     {
-      rtx par;
-
       /* Need to adjust r11 (r12) if we saved any FPRs.  */
       if (info->first_fp_reg_save != 64)
         {
@@ -20216,14 +20254,13 @@  rs6000_emit_prologue (void)
 	  emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
         }
 
-      par = rs6000_make_savres_rtx (info, frame_reg_rtx,
-				    info->gp_save_offset + sp_offset,
-				    reg_mode,
-				    /*savep=*/true, /*gpr=*/true,
-				    /*lr=*/(strategy
-					    & SAVE_NOINLINE_GPRS_SAVES_LR)
-					   != 0);
-      insn = emit_insn (par);
+      insn = rs6000_emit_savres_rtx (info, frame_reg_rtx,
+				     info->gp_save_offset + sp_offset,
+				     reg_mode,
+				     /*savep=*/true, /*gpr=*/true,
+				     /*lr=*/((strategy
+					      & SAVE_NOINLINE_GPRS_SAVES_LR)
+					     != 0));
       rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
 			    NULL_RTX, NULL_RTX);
     }
@@ -20750,7 +20805,7 @@  rs6000_emit_epilogue (int sibcall)
       alloc_rname = ggc_strdup (rname);
 
       j = 0;
-      RTVEC_ELT (p, j++) = ret_rtx;
+      RTVEC_ELT (p, j++) = simple_return_rtx;
       RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
 					gen_rtx_REG (Pmode,
 						     LR_REGNO));
@@ -21165,13 +21214,11 @@  rs6000_emit_epilogue (int sibcall)
 	}
       else
 	{
-	  rtx par;
+	  rs6000_emit_savres_rtx (info, gen_rtx_REG (Pmode, 11),
+				  0, reg_mode,
+				  /*savep=*/false, /*gpr=*/true,
+				  /*lr=*/true);
 
-	  par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
-					0, reg_mode,
-					/*savep=*/false, /*gpr=*/true,
-					/*lr=*/true);
-	  emit_jump_insn (par);
 	  /* We don't want anybody else emitting things after we jumped
 	     back.  */
 	  return;
@@ -21181,12 +21228,22 @@  rs6000_emit_epilogue (int sibcall)
     {
       /* We are jumping to an out-of-line function.  */
       bool can_use_exit = info->first_fp_reg_save == 64;
-      rtx par;
 
       /* Emit stack reset code if we need it.  */
       if (can_use_exit)
-	rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
-				 sp_offset, can_use_exit);
+	{
+	  rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
+				   sp_offset, can_use_exit);
+	  if (info->cr_save_p)
+	    {
+	      rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
+	      if (DEFAULT_ABI == ABI_V4)
+		cfa_restores
+		  = alloc_reg_note (REG_CFA_RESTORE,
+				    gen_rtx_REG (SImode, CR2_REGNO),
+				    cfa_restores);
+	    }
+	}
       else
 	{
 	  emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
@@ -21197,31 +21254,18 @@  rs6000_emit_epilogue (int sibcall)
 	    sp_offset += info->fp_size;
 	}
 
-      par = rs6000_make_savres_rtx (info, frame_reg_rtx,
-				    info->gp_save_offset, reg_mode,
-				    /*savep=*/false, /*gpr=*/true,
-				    /*lr=*/can_use_exit);
+      insn = rs6000_emit_savres_rtx (info, frame_reg_rtx,
+				     info->gp_save_offset, reg_mode,
+				     /*savep=*/false, /*gpr=*/true,
+				     /*lr=*/can_use_exit);
 
       if (can_use_exit)
 	{
-	  if (info->cr_save_p)
-	    {
-	      rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
-	      if (DEFAULT_ABI == ABI_V4)
-		cfa_restores
-		  = alloc_reg_note (REG_CFA_RESTORE,
-				    gen_rtx_REG (SImode, CR2_REGNO),
-				    cfa_restores);
-	    }
-
-	  emit_jump_insn (par);
-
 	  /* We don't want anybody else emitting things after we jumped
 	     back.  */
 	  return;
 	}
 
-      insn = emit_insn (par);
       if (DEFAULT_ABI == ABI_V4)
 	{
 	  if (frame_pointer_needed)
@@ -21366,7 +21410,7 @@  rs6000_emit_epilogue (int sibcall)
       else
 	p = rtvec_alloc (2);
 
-      RTVEC_ELT (p, 0) = ret_rtx;
+      RTVEC_ELT (p, 0) = simple_return_rtx;
       RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
 			  ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
 			  : gen_rtx_CLOBBER (VOIDmode,
@@ -21768,7 +21812,7 @@  rs6000_output_mi_thunk (FILE *file, tree
 			gen_rtx_USE (VOIDmode,
 				     gen_rtx_REG (SImode,
 						  LR_REGNO)),
-			ret_rtx)));
+			simple_return_rtx)));
   SIBLING_CALL_P (insn) = 1;
   emit_barrier ();
 
diff -urp -x.svn -x'*~' -x'*.orig' gcc-bernd/gcc/config/rs6000/altivec.md gcc-current/gcc/config/rs6000/altivec.md
--- gcc-bernd/gcc/config/rs6000/altivec.md	2011-09-16 11:52:15.000000000 +0930
+++ gcc-current/gcc/config/rs6000/altivec.md	2011-09-15 18:28:43.000000000 +0930
@@ -306,7 +306,7 @@ 
 
 (define_insn "*restore_world"
  [(match_parallel 0 "restore_world_operation"
-                  [(return)
+                  [(simple_return)
 		   (use (reg:SI 65))
                    (use (match_operand:SI 1 "call_operand" "s"))
                    (clobber (match_operand:SI 2 "gpc_reg_operand" "=r"))])]
diff -urp -x.svn -x'*~' -x'*.orig' gcc-bernd/gcc/config/rs6000/rs6000.md gcc-current/gcc/config/rs6000/rs6000.md
--- gcc-bernd/gcc/config/rs6000/rs6000.md	2011-09-16 11:52:15.000000000 +0930
+++ gcc-current/gcc/config/rs6000/rs6000.md	2011-09-16 11:32:31.000000000 +0930
@@ -264,6 +265,12 @@ 
 ; Iterator for just SF/DF
 (define_mode_iterator SFDF [SF DF])
 
+; Conditional returns.
+(define_code_iterator any_return [return simple_return])
+(define_code_attr return_pred [(return "direct_return ()")
+			       (simple_return "")])
+(define_code_attr return_str [(return "") (simple_return "simple_")])
+
 ; Various instructions that come in SI and DI forms.
 ; A generic w/d attribute, for things like cmpw/cmpd.
 (define_mode_attr wd [(QI "b") (HI "h") (SI "w") (DI "d")])
@@ -12814,7 +12831,7 @@ 
 		    (match_operand 1 "" ""))
 	      (use (match_operand 2 "" ""))
 	      (use (reg:SI LR_REGNO))
-	      (return)])]
+	      (simple_return)])]
   ""
   "
 {
@@ -12838,7 +12855,7 @@ 
 	 (match_operand 1 "" "g,g"))
    (use (match_operand:SI 2 "immediate_operand" "O,n"))
    (use (reg:SI LR_REGNO))
-   (return)]
+   (simple_return)]
   "(INTVAL (operands[2]) & CALL_LONG) == 0"
   "*
 {
@@ -12858,7 +12875,7 @@ 
 	 (match_operand 1 "" "g,g"))
    (use (match_operand:SI 2 "immediate_operand" "O,n"))
    (use (reg:SI LR_REGNO))
-   (return)]
+   (simple_return)]
   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
   "*
 {
@@ -12879,7 +12896,7 @@ 
 	      (match_operand 2 "" "g,g")))
    (use (match_operand:SI 3 "immediate_operand" "O,n"))
    (use (reg:SI LR_REGNO))
-   (return)]
+   (simple_return)]
   "(INTVAL (operands[3]) & CALL_LONG) == 0"
   "*
 {
@@ -12901,7 +12918,7 @@ 
 	      (match_operand 2 "" "g,g")))
    (use (match_operand:SI 3 "immediate_operand" "O,n"))
    (use (reg:SI LR_REGNO))
-   (return)]
+   (simple_return)]
   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
   "*
 {
@@ -12921,7 +12938,7 @@ 
 	 (match_operand 1 "" "g,g"))
    (use (match_operand:SI 2 "immediate_operand" "O,O"))
    (use (reg:SI LR_REGNO))
-   (return)]
+   (simple_return)]
   "DEFAULT_ABI == ABI_AIX
    && (INTVAL (operands[2]) & CALL_LONG) == 0"
   "@
@@ -12936,7 +12953,7 @@ 
 	      (match_operand 2 "" "g,g")))
    (use (match_operand:SI 3 "immediate_operand" "O,O"))
    (use (reg:SI LR_REGNO))
-   (return)]
+   (simple_return)]
   "DEFAULT_ABI == ABI_AIX
    && (INTVAL (operands[3]) & CALL_LONG) == 0"
   "@
@@ -12950,7 +12967,7 @@ 
 	 (match_operand 1 "" ""))
    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
    (use (reg:SI LR_REGNO))
-   (return)]
+   (simple_return)]
   "(DEFAULT_ABI == ABI_DARWIN
     || DEFAULT_ABI == ABI_V4)
    && (INTVAL (operands[2]) & CALL_LONG) == 0"
@@ -12981,7 +12998,7 @@ 
 		      (match_operand 2 "" "")))
 	      (use (match_operand 3 "" ""))
 	      (use (reg:SI LR_REGNO))
-	      (return)])]
+	      (simple_return)])]
   ""
   "
 {
@@ -13002,7 +13019,7 @@ 
 	      (match_operand 2 "" "")))
    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
    (use (reg:SI LR_REGNO))
-   (return)]
+   (simple_return)]
   "(DEFAULT_ABI == ABI_DARWIN
     || DEFAULT_ABI == ABI_V4)
    && (INTVAL (operands[3]) & CALL_LONG) == 0"
@@ -15328,9 +15345,9 @@ 
 				      [(match_operand 1
 						      "cc_reg_operand" "y")
 				       (const_int 0)])
-		      (return)
+		      (any_return)
 		      (pc)))]
-  "direct_return ()"
+  "<return_pred>"
   "*
 {
   return output_cbranch (operands[0], NULL, 0, insn);
@@ -15360,8 +15377,8 @@ 
 						      "cc_reg_operand" "y")
 				       (const_int 0)])
 		      (pc)
-		      (return)))]
-  "direct_return ()"
+		      (any_return)))]
+  "<return_pred>"
   "*
 {
   return output_cbranch (operands[0], NULL, 1, insn);
@@ -15491,9 +15508,9 @@ 
   "b %l0"
   [(set_attr "type" "branch")])
 
-(define_insn "return"
-  [(return)]
-  "direct_return ()"
+(define_insn "<return_str>return"
+  [(any_return)]
+  "<return_pred>"
   "{br|blr}"
   [(set_attr "type" "jmpreg")])
 
@@ -16015,7 +16032,7 @@ 
    (set_attr "cell_micro" "always")])
 
 (define_insn "*return_internal_<mode>"
-  [(return)
+  [(simple_return)
    (use (match_operand:P 0 "register_operand" "lc"))]
   ""
   "b%T0"
@@ -16077,7 +16094,7 @@ 
 
 (define_insn "*return_and_restore_gpregs_<mode>_r11"
  [(match_parallel 0 "any_parallel_operand"
-                  [(return)
+                  [(simple_return)
 		   (clobber (match_operand:P 1 "register_operand" "=l"))
 		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
                    (use (reg:P 11))
@@ -16090,7 +16107,7 @@ 
 
 (define_insn "*return_and_restore_gpregs_<mode>_r12"
  [(match_parallel 0 "any_parallel_operand"
-                  [(return)
+                  [(simple_return)
 		   (clobber (match_operand:P 1 "register_operand" "=l"))
 		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
                    (use (reg:P 12))
@@ -16103,7 +16120,7 @@ 
 
 (define_insn "*return_and_restore_gpregs_<mode>_r1"
  [(match_parallel 0 "any_parallel_operand"
-                  [(return)
+                  [(simple_return)
 		   (clobber (match_operand:P 1 "register_operand" "=l"))
 		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
                    (use (reg:P 1))
@@ -16116,7 +16133,7 @@ 
 
 (define_insn "*return_and_restore_fpregs_<mode>_r11"
  [(match_parallel 0 "any_parallel_operand"
-                  [(return)
+                  [(simple_return)
 		   (clobber (match_operand:P 1 "register_operand" "=l"))
 		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
                    (use (reg:P 11))
@@ -16129,7 +16146,7 @@ 
 
 (define_insn "*return_and_restore_fpregs_<mode>_r12"
  [(match_parallel 0 "any_parallel_operand"
-                  [(return)
+                  [(simple_return)
 		   (clobber (match_operand:P 1 "register_operand" "=l"))
 		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
                    (use (reg:P 12))
@@ -16142,7 +16159,7 @@ 
 
 (define_insn "*return_and_restore_fpregs_<mode>_r1"
  [(match_parallel 0 "any_parallel_operand"
-                  [(return)
+                  [(simple_return)
 		   (clobber (match_operand:P 1 "register_operand" "=l"))
 		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
                    (use (reg:P 1))
@@ -16155,7 +16172,7 @@ 
 
 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
  [(match_parallel 0 "any_parallel_operand"
-		  [(return)
+		  [(simple_return)
 		   (use (match_operand:P 1 "register_operand" "l"))
 		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
 		   (use (reg:P 11))
@@ -16168,7 +16185,7 @@ 
 
 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
  [(match_parallel 0 "any_parallel_operand"
-		  [(return)
+		  [(simple_return)
 		   (use (match_operand:P 1 "register_operand" "l"))
 		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
 		   (use (reg:P 1))
diff -urp -x.svn -x'*~' -x'*.orig' gcc-bernd/gcc/config/rs6000/spe.md gcc-current/gcc/config/rs6000/spe.md
--- gcc-bernd/gcc/config/rs6000/spe.md	2011-09-16 11:52:15.000000000 +0930
+++ gcc-current/gcc/config/rs6000/spe.md	2011-09-15 18:28:43.000000000 +0930
@@ -3178,7 +3178,7 @@ 
 
 (define_insn "*return_and_restore_gpregs_spe"
  [(match_parallel 0 "any_parallel_operand"
-		  [(return)
+		  [(simple_return)
 		   (clobber (reg:P 65))
 		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
 		   (use (reg:P 11))