rs6000: Don't emit a use of LR in returns and sibcalls
authorSegher Boessenkool <segher@kernel.crashing.org>
Tue, 30 Aug 2016 16:30:01 +0000 (18:30 +0200)
committerSegher Boessenkool <segher@gcc.gnu.org>
Tue, 30 Aug 2016 16:30:01 +0000 (18:30 +0200)
The exit block (to which every return artificially jumps) already has
a use of LR.  The LR use in all returns and sibcalls is an anachronism,
probably made unnecessary by the dataflow merge.  The simple_returns
that shrink-wrapping generates also do not have such a use.  Newer
backends do not do this either it seems.

With this use removed, a normal return is no longer a parallel but just
a return insn, and cfgcleanup then can transform conditional jumps to
those into conditional returns.

This splits the return emission code with restoring_FPRs_inline from
that without it; this is simpler code, fewer lines, and less indentation.

The return_internal_<mode> pattern can now be deleted since nothing uses
it anymore.

* config/rs6000/rs6000.c (rs6000_emit_epilogue): Do not emit
USEs of LR_REGNO in returns and sibcalls.
(rs6000_output_mi_thunk): Similar.
(rs6000_sibcall_aix): Similar.
* config/rs6000/rs6000.md (sibcall, sibcall_value, sibcall_local32,
sibcall_local64, sibcall_value_local32, sibcall_value_local64,
sibcall_nonlocal_sysv<mode>, sibcall_value_nonlocal_sysv<mode>):
Remove the USE of LR_REGNO from the patterns as well.  Delete an
obsolete comment.
(return_internal_<mode>): Delete.

From-SVN: r239866

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md

index c6bda6055fd394f5f83dce25f391339d68e8088a..d43d00e164b2ec89bc8e74dd4e74d8c86013c0f6 100644 (file)
@@ -1,3 +1,16 @@
+2016-08-30  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       * config/rs6000/rs6000.c (rs6000_emit_epilogue): Do not emit
+       USEs of LR_REGNO in returns and sibcalls.
+       (rs6000_output_mi_thunk): Similar.
+       (rs6000_sibcall_aix): Similar.
+       * config/rs6000/rs6000.md (sibcall, sibcall_value, sibcall_local32,
+       sibcall_local64, sibcall_value_local32, sibcall_value_local64,
+       sibcall_nonlocal_sysv<mode>, sibcall_value_nonlocal_sysv<mode>):
+       Remove the USE of LR_REGNO from the patterns as well.  Delete an
+       obsolete comment.
+       (return_internal_<mode>): Delete.
+
 2016-08-30  Tamar Christina  <tamar.christina@arm.com>
 
        * gcc/config/aarch64/aarch64-simd.md
index 4de70ea86efd09d3df0d8d39091cce8d6b4c4743..2f15a053075d67532f9b1e6259d64e9b474be37f 100644 (file)
@@ -28277,7 +28277,6 @@ rs6000_emit_epilogue (int sibcall)
         longer necessary.  */
 
       p = rtvec_alloc (9
-                      + 1
                       + 32 - info->first_gp_reg_save
                       + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
                       + 63 + 1 - info->first_fp_reg_save);
@@ -28288,9 +28287,6 @@ rs6000_emit_epilogue (int sibcall)
 
       j = 0;
       RTVEC_ELT (p, j++) = ret_rtx;
-      RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
-                                       gen_rtx_REG (Pmode,
-                                                    LR_REGNO));
       RTVEC_ELT (p, j++)
        = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
       /* The instruction pattern requires a clobber here;
@@ -29013,73 +29009,63 @@ rs6000_emit_epilogue (int sibcall)
       emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
     }
 
-  if (!sibcall)
+  if (!sibcall && restoring_FPRs_inline)
     {
-      rtvec p;
-      bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
-      if (! restoring_FPRs_inline)
-       {
-         p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
-         RTVEC_ELT (p, 0) = ret_rtx;
-       }
-      else
+      if (cfa_restores)
        {
-         if (cfa_restores)
-           {
-             /* We can't hang the cfa_restores off a simple return,
-                since the shrink-wrap code sometimes uses an existing
-                return.  This means there might be a path from
-                pre-prologue code to this return, and dwarf2cfi code
-                wants the eh_frame unwinder state to be the same on
-                all paths to any point.  So we need to emit the
-                cfa_restores before the return.  For -m64 we really
-                don't need epilogue cfa_restores at all, except for
-                this irritating dwarf2cfi with shrink-wrap
-                requirement;  The stack red-zone means eh_frame info
-                from the prologue telling the unwinder to restore
-                from the stack is perfectly good right to the end of
-                the function.  */
-             emit_insn (gen_blockage ());
-             emit_cfa_restores (cfa_restores);
-             cfa_restores = NULL_RTX;
-           }
-         p = rtvec_alloc (2);
-         RTVEC_ELT (p, 0) = simple_return_rtx;
+         /* We can't hang the cfa_restores off a simple return,
+            since the shrink-wrap code sometimes uses an existing
+            return.  This means there might be a path from
+            pre-prologue code to this return, and dwarf2cfi code
+            wants the eh_frame unwinder state to be the same on
+            all paths to any point.  So we need to emit the
+            cfa_restores before the return.  For -m64 we really
+            don't need epilogue cfa_restores at all, except for
+            this irritating dwarf2cfi with shrink-wrap
+            requirement;  The stack red-zone means eh_frame info
+            from the prologue telling the unwinder to restore
+            from the stack is perfectly good right to the end of
+            the function.  */
+         emit_insn (gen_blockage ());
+         emit_cfa_restores (cfa_restores);
+         cfa_restores = NULL_RTX;
        }
 
-      RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
-                         ? gen_rtx_USE (VOIDmode,
-                                        gen_rtx_REG (Pmode, LR_REGNO))
-                         : gen_rtx_CLOBBER (VOIDmode,
-                                            gen_rtx_REG (Pmode, LR_REGNO)));
+      emit_jump_insn (targetm.gen_simple_return ());
+    }
 
-      /* If we have to restore more than two FP registers, branch to the
+  if (!sibcall && !restoring_FPRs_inline)
+    {
+      bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
+      rtvec p = rtvec_alloc (3 + !!lr + 64 - info->first_fp_reg_save);
+      int elt = 0;
+      RTVEC_ELT (p, elt++) = ret_rtx;
+      if (lr)
+       RTVEC_ELT (p, elt++)
+         = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNO));
+
+      /* We have to restore more than two FP registers, so branch to the
         restore function.  It will return to our caller.  */
-      if (! restoring_FPRs_inline)
-       {
-         int i;
-         int reg;
-         rtx sym;
+      int i;
+      int reg;
+      rtx sym;
 
-         if (flag_shrink_wrap)
-           cfa_restores = add_crlr_cfa_restore (info, cfa_restores);
+      if (flag_shrink_wrap)
+       cfa_restores = add_crlr_cfa_restore (info, cfa_restores);
 
-         sym = rs6000_savres_routine_sym (info,
-                                          SAVRES_FPR | (lr ? SAVRES_LR : 0));
-         RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
-         reg = (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)? 1 : 11;
-         RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, reg));
+      sym = rs6000_savres_routine_sym (info, SAVRES_FPR | (lr ? SAVRES_LR : 0));
+      RTVEC_ELT (p, elt++) = gen_rtx_USE (VOIDmode, sym);
+      reg = (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)? 1 : 11;
+      RTVEC_ELT (p, elt++) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, reg));
 
-         for (i = 0; i < 64 - info->first_fp_reg_save; i++)
-           {
-             rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
+      for (i = 0; i < 64 - info->first_fp_reg_save; i++)
+       {
+         rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
 
-             RTVEC_ELT (p, i + 4)
-               = gen_frame_load (reg, sp_reg_rtx, info->fp_save_offset + 8 * i);
-             if (flag_shrink_wrap)
-               cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
-                                              cfa_restores);
-           }
+         RTVEC_ELT (p, elt++)
+           = gen_frame_load (reg, sp_reg_rtx, info->fp_save_offset + 8 * i);
+         if (flag_shrink_wrap)
+           cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
        }
 
       emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
@@ -29667,13 +29653,10 @@ rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
      generate sibcall RTL explicitly.  */
   insn = emit_call_insn (
           gen_rtx_PARALLEL (VOIDmode,
-            gen_rtvec (4,
+            gen_rtvec (3,
                        gen_rtx_CALL (VOIDmode,
                                      funexp, const0_rtx),
                        gen_rtx_USE (VOIDmode, const0_rtx),
-                       gen_rtx_USE (VOIDmode,
-                                    gen_rtx_REG (SImode,
-                                                 LR_REGNO)),
                        simple_return_rtx)));
   SIBLING_CALL_P (insn) = 1;
   emit_barrier ();
@@ -37578,9 +37561,6 @@ rs6000_sibcall_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
 
   /* Note use of the TOC register.  */
   use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG (Pmode, TOC_REGNUM));
-  /* We need to also mark a use of the link register since the function we
-     sibling-call to will use it to return to our caller.  */
-  use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG (Pmode, LR_REGNO));
 }
 
 /* Return whether we need to always update the saved TOC pointer when we update
index df75dc26807939331b126ffaf07ce7a70e055e54..560cf1fd7404956221111f220ddc95abe7db99a9 100644 (file)
   [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
                    (match_operand 1 "" ""))
              (use (match_operand 2 "" ""))
-             (use (reg:SI LR_REGNO))
              (simple_return)])]
   ""
   "
                (call (mem:SI (match_operand 1 "address_operand" ""))
                      (match_operand 2 "" "")))
              (use (match_operand 3 "" ""))
-             (use (reg:SI LR_REGNO))
              (simple_return)])]
   ""
   "
     }
 }")
 
-;; this and similar patterns must be marked as using LR, otherwise
-;; dataflow will try to delete the store into it.  This is true
-;; even when the actual reg to jump to is in CTR, when LR was
-;; saved and restored around the PIC-setting BCL.
 (define_insn "*sibcall_local32"
   [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
         (match_operand 1 "" "g,g"))
    (use (match_operand:SI 2 "immediate_operand" "O,n"))
-   (use (reg:SI LR_REGNO))
    (simple_return)]
   "(INTVAL (operands[2]) & CALL_LONG) == 0"
   "*
   [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
         (match_operand 1 "" "g,g"))
    (use (match_operand:SI 2 "immediate_operand" "O,n"))
-   (use (reg:SI LR_REGNO))
    (simple_return)]
   "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
   "*
        (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
              (match_operand 2 "" "g,g")))
    (use (match_operand:SI 3 "immediate_operand" "O,n"))
-   (use (reg:SI LR_REGNO))
    (simple_return)]
   "(INTVAL (operands[3]) & CALL_LONG) == 0"
   "*
        (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
              (match_operand 2 "" "g,g")))
    (use (match_operand:SI 3 "immediate_operand" "O,n"))
-   (use (reg:SI LR_REGNO))
    (simple_return)]
   "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
   "*
   [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
         (match_operand 1 "" ""))
    (use (match_operand 2 "immediate_operand" "O,n,O,n"))
-   (use (reg:SI LR_REGNO))
    (simple_return)]
   "(DEFAULT_ABI == ABI_DARWIN
     || DEFAULT_ABI == ABI_V4)
        (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
              (match_operand 2 "" "")))
    (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
-   (use (reg:SI LR_REGNO))
    (simple_return)]
   "(DEFAULT_ABI == ABI_DARWIN
     || DEFAULT_ABI == ABI_V4)
    (set_attr "indexed" "yes")
    (set_attr "cell_micro" "always")])
 
-(define_insn "*return_internal_<mode>"
-  [(simple_return)
-   (use (match_operand:P 0 "register_operand" "lc"))]
-  ""
-  "b%T0"
-  [(set_attr "type" "jmpreg")])
-
 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
 ; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...