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>
* gcc/config/aarch64/aarch64-simd.md
......
......@@ -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
......@@ -10523,7 +10523,6 @@
[(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))
(use (reg:SI LR_REGNO))
(simple_return)])]
""
"
......@@ -10550,7 +10549,6 @@
(call (mem:SI (match_operand 1 "address_operand" ""))
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))
(use (reg:SI LR_REGNO))
(simple_return)])]
""
"
......@@ -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"
[(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"
"*
......@@ -10600,7 +10593,6 @@
[(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"
"*
......@@ -10621,7 +10613,6 @@
(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"
"*
......@@ -10642,7 +10633,6 @@
(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"
"*
......@@ -10662,7 +10652,6 @@
[(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)
......@@ -10693,7 +10682,6 @@
(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)
......@@ -12612,13 +12600,6 @@
(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...
......
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