From dd9fe1b95bd57d1f69816b546cfea2b507b15a72 Mon Sep 17 00:00:00 2001 From: Segher Boessenkool Date: Tue, 30 Aug 2016 18:30:01 +0200 Subject: [PATCH] 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_ 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, sibcall_value_nonlocal_sysv): Remove the USE of LR_REGNO from the patterns as well. Delete an obsolete comment. (return_internal_): Delete. From-SVN: r239866 --- gcc/ChangeLog | 13 ++++ gcc/config/rs6000/rs6000.c | 116 +++++++++++++++--------------------- gcc/config/rs6000/rs6000.md | 19 ------ 3 files changed, 61 insertions(+), 87 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c6bda6055fd..d43d00e164b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2016-08-30 Segher Boessenkool + + * 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, sibcall_value_nonlocal_sysv): + Remove the USE of LR_REGNO from the patterns as well. Delete an + obsolete comment. + (return_internal_): Delete. + 2016-08-30 Tamar Christina * gcc/config/aarch64/aarch64-simd.md diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 4de70ea86ef..2f15a053075 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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 diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index df75dc26807..560cf1fd740 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -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_" - [(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... -- 2.30.2