Commit dd9fe1b9 by Segher Boessenkool Committed by Segher Boessenkool

rs6000: Don't emit a use of LR in returns and sibcalls

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
parent ac45b2ba
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> 2016-08-30 Tamar Christina <tamar.christina@arm.com>
* gcc/config/aarch64/aarch64-simd.md * gcc/config/aarch64/aarch64-simd.md
......
...@@ -28277,7 +28277,6 @@ rs6000_emit_epilogue (int sibcall) ...@@ -28277,7 +28277,6 @@ rs6000_emit_epilogue (int sibcall)
longer necessary. */ longer necessary. */
p = rtvec_alloc (9 p = rtvec_alloc (9
+ 1
+ 32 - info->first_gp_reg_save + 32 - info->first_gp_reg_save
+ LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
+ 63 + 1 - info->first_fp_reg_save); + 63 + 1 - info->first_fp_reg_save);
...@@ -28288,9 +28287,6 @@ rs6000_emit_epilogue (int sibcall) ...@@ -28288,9 +28287,6 @@ rs6000_emit_epilogue (int sibcall)
j = 0; j = 0;
RTVEC_ELT (p, j++) = ret_rtx; RTVEC_ELT (p, j++) = ret_rtx;
RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
gen_rtx_REG (Pmode,
LR_REGNO));
RTVEC_ELT (p, j++) RTVEC_ELT (p, j++)
= gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname)); = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
/* The instruction pattern requires a clobber here; /* The instruction pattern requires a clobber here;
...@@ -29013,73 +29009,63 @@ rs6000_emit_epilogue (int sibcall) ...@@ -29013,73 +29009,63 @@ rs6000_emit_epilogue (int sibcall)
emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa)); emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
} }
if (!sibcall) if (!sibcall && restoring_FPRs_inline)
{ {
rtvec p; if (cfa_restores)
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) /* We can't hang the cfa_restores off a simple return,
{ since the shrink-wrap code sometimes uses an existing
/* We can't hang the cfa_restores off a simple return, return. This means there might be a path from
since the shrink-wrap code sometimes uses an existing pre-prologue code to this return, and dwarf2cfi code
return. This means there might be a path from wants the eh_frame unwinder state to be the same on
pre-prologue code to this return, and dwarf2cfi code all paths to any point. So we need to emit the
wants the eh_frame unwinder state to be the same on cfa_restores before the return. For -m64 we really
all paths to any point. So we need to emit the don't need epilogue cfa_restores at all, except for
cfa_restores before the return. For -m64 we really this irritating dwarf2cfi with shrink-wrap
don't need epilogue cfa_restores at all, except for requirement; The stack red-zone means eh_frame info
this irritating dwarf2cfi with shrink-wrap from the prologue telling the unwinder to restore
requirement; The stack red-zone means eh_frame info from the stack is perfectly good right to the end of
from the prologue telling the unwinder to restore the function. */
from the stack is perfectly good right to the end of emit_insn (gen_blockage ());
the function. */ emit_cfa_restores (cfa_restores);
emit_insn (gen_blockage ()); cfa_restores = NULL_RTX;
emit_cfa_restores (cfa_restores);
cfa_restores = NULL_RTX;
}
p = rtvec_alloc (2);
RTVEC_ELT (p, 0) = simple_return_rtx;
} }
RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr) emit_jump_insn (targetm.gen_simple_return ());
? gen_rtx_USE (VOIDmode, }
gen_rtx_REG (Pmode, LR_REGNO))
: gen_rtx_CLOBBER (VOIDmode,
gen_rtx_REG (Pmode, LR_REGNO)));
/* 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. */ restore function. It will return to our caller. */
if (! restoring_FPRs_inline) int i;
{ int reg;
int i; rtx sym;
int reg;
rtx sym;
if (flag_shrink_wrap) if (flag_shrink_wrap)
cfa_restores = add_crlr_cfa_restore (info, cfa_restores); cfa_restores = add_crlr_cfa_restore (info, cfa_restores);
sym = rs6000_savres_routine_sym (info, sym = rs6000_savres_routine_sym (info, SAVRES_FPR | (lr ? SAVRES_LR : 0));
SAVRES_FPR | (lr ? SAVRES_LR : 0)); RTVEC_ELT (p, elt++) = gen_rtx_USE (VOIDmode, sym);
RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym); reg = (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)? 1 : 11;
reg = (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)? 1 : 11; RTVEC_ELT (p, elt++) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, reg));
RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, reg));
for (i = 0; i < 64 - 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); rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
RTVEC_ELT (p, i + 4) RTVEC_ELT (p, elt++)
= gen_frame_load (reg, sp_reg_rtx, info->fp_save_offset + 8 * i); = gen_frame_load (reg, sp_reg_rtx, info->fp_save_offset + 8 * i);
if (flag_shrink_wrap) if (flag_shrink_wrap)
cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
cfa_restores);
}
} }
emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p)); emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
...@@ -29667,13 +29653,10 @@ rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, ...@@ -29667,13 +29653,10 @@ rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
generate sibcall RTL explicitly. */ generate sibcall RTL explicitly. */
insn = emit_call_insn ( insn = emit_call_insn (
gen_rtx_PARALLEL (VOIDmode, gen_rtx_PARALLEL (VOIDmode,
gen_rtvec (4, gen_rtvec (3,
gen_rtx_CALL (VOIDmode, gen_rtx_CALL (VOIDmode,
funexp, const0_rtx), funexp, const0_rtx),
gen_rtx_USE (VOIDmode, const0_rtx), gen_rtx_USE (VOIDmode, const0_rtx),
gen_rtx_USE (VOIDmode,
gen_rtx_REG (SImode,
LR_REGNO)),
simple_return_rtx))); simple_return_rtx)));
SIBLING_CALL_P (insn) = 1; SIBLING_CALL_P (insn) = 1;
emit_barrier (); emit_barrier ();
...@@ -37578,9 +37561,6 @@ rs6000_sibcall_aix (rtx value, rtx func_desc, rtx flag, rtx cookie) ...@@ -37578,9 +37561,6 @@ rs6000_sibcall_aix (rtx value, rtx func_desc, rtx flag, rtx cookie)
/* Note use of the TOC register. */ /* Note use of the TOC register. */
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG (Pmode, TOC_REGNUM)); 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 /* Return whether we need to always update the saved TOC pointer when we update
...@@ -10523,7 +10523,6 @@ ...@@ -10523,7 +10523,6 @@
[(parallel [(call (mem:SI (match_operand 0 "address_operand" "")) [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
(match_operand 1 "" "")) (match_operand 1 "" ""))
(use (match_operand 2 "" "")) (use (match_operand 2 "" ""))
(use (reg:SI LR_REGNO))
(simple_return)])] (simple_return)])]
"" ""
" "
...@@ -10550,7 +10549,6 @@ ...@@ -10550,7 +10549,6 @@
(call (mem:SI (match_operand 1 "address_operand" "")) (call (mem:SI (match_operand 1 "address_operand" ""))
(match_operand 2 "" ""))) (match_operand 2 "" "")))
(use (match_operand 3 "" "")) (use (match_operand 3 "" ""))
(use (reg:SI LR_REGNO))
(simple_return)])] (simple_return)])]
"" ""
" "
...@@ -10572,15 +10570,10 @@ ...@@ -10572,15 +10570,10 @@
} }
}") }")
;; 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" (define_insn "*sibcall_local32"
[(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s")) [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
(match_operand 1 "" "g,g")) (match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n")) (use (match_operand:SI 2 "immediate_operand" "O,n"))
(use (reg:SI LR_REGNO))
(simple_return)] (simple_return)]
"(INTVAL (operands[2]) & CALL_LONG) == 0" "(INTVAL (operands[2]) & CALL_LONG) == 0"
"* "*
...@@ -10600,7 +10593,6 @@ ...@@ -10600,7 +10593,6 @@
[(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s")) [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
(match_operand 1 "" "g,g")) (match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n")) (use (match_operand:SI 2 "immediate_operand" "O,n"))
(use (reg:SI LR_REGNO))
(simple_return)] (simple_return)]
"TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
"* "*
...@@ -10621,7 +10613,6 @@ ...@@ -10621,7 +10613,6 @@
(call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s")) (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
(match_operand 2 "" "g,g"))) (match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n")) (use (match_operand:SI 3 "immediate_operand" "O,n"))
(use (reg:SI LR_REGNO))
(simple_return)] (simple_return)]
"(INTVAL (operands[3]) & CALL_LONG) == 0" "(INTVAL (operands[3]) & CALL_LONG) == 0"
"* "*
...@@ -10642,7 +10633,6 @@ ...@@ -10642,7 +10633,6 @@
(call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
(match_operand 2 "" "g,g"))) (match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n")) (use (match_operand:SI 3 "immediate_operand" "O,n"))
(use (reg:SI LR_REGNO))
(simple_return)] (simple_return)]
"TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
"* "*
...@@ -10662,7 +10652,6 @@ ...@@ -10662,7 +10652,6 @@
[(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c")) [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
(match_operand 1 "" "")) (match_operand 1 "" ""))
(use (match_operand 2 "immediate_operand" "O,n,O,n")) (use (match_operand 2 "immediate_operand" "O,n,O,n"))
(use (reg:SI LR_REGNO))
(simple_return)] (simple_return)]
"(DEFAULT_ABI == ABI_DARWIN "(DEFAULT_ABI == ABI_DARWIN
|| DEFAULT_ABI == ABI_V4) || DEFAULT_ABI == ABI_V4)
...@@ -10693,7 +10682,6 @@ ...@@ -10693,7 +10682,6 @@
(call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c")) (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
(match_operand 2 "" ""))) (match_operand 2 "" "")))
(use (match_operand:SI 3 "immediate_operand" "O,n,O,n")) (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
(use (reg:SI LR_REGNO))
(simple_return)] (simple_return)]
"(DEFAULT_ABI == ABI_DARWIN "(DEFAULT_ABI == ABI_DARWIN
|| DEFAULT_ABI == ABI_V4) || DEFAULT_ABI == ABI_V4)
...@@ -12612,13 +12600,6 @@ ...@@ -12612,13 +12600,6 @@
(set_attr "indexed" "yes") (set_attr "indexed" "yes")
(set_attr "cell_micro" "always")]) (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 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible... ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment