aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2016-08-30 18:30:01 +0200
committerSegher Boessenkool <segher@gcc.gnu.org>2016-08-30 18:30:01 +0200
commitdd9fe1b95bd57d1f69816b546cfea2b507b15a72 (patch)
tree1ac5bdadede8518c52f7f5869ecbb43eaa1564ac /gcc
parentac45b2ba8c75573b9630656ccf3a20e6da333913 (diff)
downloadgcc-dd9fe1b95bd57d1f69816b546cfea2b507b15a72.zip
gcc-dd9fe1b95bd57d1f69816b546cfea2b507b15a72.tar.gz
gcc-dd9fe1b95bd57d1f69816b546cfea2b507b15a72.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/rs6000/rs6000.c116
-rw-r--r--gcc/config/rs6000/rs6000.md19
3 files changed, 61 insertions, 87 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c6bda60..d43d00e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 4de70ea..2f15a05 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 df75dc2..560cf1f 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_<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...