From 8c0f8755b2a2cf60cafad74e7ffbe32a653ebc4c Mon Sep 17 00:00:00 2001 From: Bill Schmidt Date: Wed, 16 Sep 2020 16:12:35 -0500 Subject: [PATCH] rs6000: Add rs6000_cfun_pcrel_p Most uses of rs6000_pcrel_p are called for the current function. A specialized version for cfun is more efficient for these uses. 2020-09-16 Bill Schmidt gcc/ * config/rs6000/predicates.md (current_file_function_operand): Remove argument from rs6000_pcrel_p call. * config/rs6000/rs6000-logue.c (rs6000_decl_ok_for_sibcall): Likewise. (rs6000_global_entry_point_prologue_needed_p): Likewise. (rs6000_output_function_prologue): Likewise. * config/rs6000/rs6000-protos.h (rs6000_function_pcrel_p): New prototype. (rs6000_pcrel_p): Remove argument. * config/rs6000/rs6000.c (rs6000_legitimize_tls_address): Remove argument from rs6000_pcrel_p call. (rs6000_call_template_1): Likewise. (rs6000_indirect_call_template_1): Likewise. (rs6000_longcall_ref): Likewise. (rs6000_call_aix): Likewise. (rs6000_sibcall_aix): Likewise. (rs6000_function_pcrel_p): Rename from rs6000_pcrel_p. (rs6000_pcrel_p): Rewrite. * config/rs6000/rs6000.md (*pltseq_plt_pcrel): Remove argument from rs6000_pcrel_p call. (*call_local): Likewise. (*call_value_local): Likewise. (*call_nonlocal_aix): Likewise. (*call_value_nonlocal_aix): Likewise. (*call_indirect_pcrel): Likewise. (*call_value_indirect_pcrel): Likewise. --- gcc/config/rs6000/predicates.md | 2 +- gcc/config/rs6000/rs6000-logue.c | 6 +++--- gcc/config/rs6000/rs6000-protos.h | 3 ++- gcc/config/rs6000/rs6000.c | 34 ++++++++++++++++++++----------- gcc/config/rs6000/rs6000.md | 14 ++++++------- 5 files changed, 35 insertions(+), 24 deletions(-) diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 2709e46f7e5..4c2fe7fa312 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -1056,7 +1056,7 @@ && SYMBOL_REF_DECL (op) != NULL && TREE_CODE (SYMBOL_REF_DECL (op)) == FUNCTION_DECL && (rs6000_fndecl_pcrel_p (SYMBOL_REF_DECL (op)) - != rs6000_pcrel_p (cfun)))"))) + != rs6000_pcrel_p ()))"))) ;; Return 1 if this operand is a valid input for a move insn. (define_predicate "input_operand" diff --git a/gcc/config/rs6000/rs6000-logue.c b/gcc/config/rs6000/rs6000-logue.c index 5a2cb7fdf2c..0f88ec19929 100644 --- a/gcc/config/rs6000/rs6000-logue.c +++ b/gcc/config/rs6000/rs6000-logue.c @@ -1085,7 +1085,7 @@ rs6000_decl_ok_for_sibcall (tree decl) r2 for its caller's TOC. Such a function may make sibcalls to any function, whether local or external, without restriction based on TOC-save/restore rules. */ - if (rs6000_pcrel_p (cfun)) + if (rs6000_pcrel_p ()) return true; /* Otherwise, under the AIX or ELFv2 ABIs we can't allow sibcalls @@ -2562,7 +2562,7 @@ rs6000_global_entry_point_prologue_needed_p (void) return false; /* PC-relative functions never generate a global entry point prologue. */ - if (rs6000_pcrel_p (cfun)) + if (rs6000_pcrel_p ()) return false; /* Ensure we have a global entry point for thunks. ??? We could @@ -3978,7 +3978,7 @@ rs6000_output_function_prologue (FILE *file) fputs ("\n", file); } - else if (rs6000_pcrel_p (cfun)) + else if (rs6000_pcrel_p ()) { const char *name = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); /* All functions compiled to use PC-relative addressing will diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 02e4d71922f..25fa5dd57cd 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -152,7 +152,8 @@ extern rtx rs6000_machopic_legitimize_pic_address (rtx, machine_mode, extern rtx rs6000_allocate_stack_temp (machine_mode, bool, bool); extern align_flags rs6000_loop_align (rtx); extern void rs6000_split_logical (rtx [], enum rtx_code, bool, bool, bool); -extern bool rs6000_pcrel_p (struct function *); +extern bool rs6000_function_pcrel_p (struct function *); +extern bool rs6000_pcrel_p (void); extern bool rs6000_fndecl_pcrel_p (const_tree); /* Different PowerPC instruction formats that are used by GCC. There are diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 6d0c5509b0e..640fc405dd4 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -8780,7 +8780,7 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model model) dest = gen_reg_rtx (Pmode); if (model == TLS_MODEL_LOCAL_EXEC - && (rs6000_tls_size == 16 || rs6000_pcrel_p (cfun))) + && (rs6000_tls_size == 16 || rs6000_pcrel_p ())) { rtx tlsreg; @@ -8827,7 +8827,7 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model model) them in the .got section. So use a pointer to the .got section, not one to secondary TOC sections used by 64-bit -mminimal-toc, or to secondary GOT sections used by 32-bit -fPIC. */ - if (rs6000_pcrel_p (cfun)) + if (rs6000_pcrel_p ()) got = const0_rtx; else if (TARGET_64BIT) got = gen_rtx_REG (Pmode, 2); @@ -8892,7 +8892,7 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model model) rtx uns = gen_rtx_UNSPEC (Pmode, vec, UNSPEC_TLS_GET_ADDR); set_unique_reg_note (get_last_insn (), REG_EQUAL, uns); - if (rs6000_tls_size == 16 || rs6000_pcrel_p (cfun)) + if (rs6000_tls_size == 16 || rs6000_pcrel_p ()) { if (TARGET_64BIT) insn = gen_tls_dtprel_64 (dest, tmp1, addr); @@ -8933,7 +8933,7 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model model) else insn = gen_tls_got_tprel_32 (tmp2, got, addr); emit_insn (insn); - if (rs6000_pcrel_p (cfun)) + if (rs6000_pcrel_p ()) { if (TARGET_64BIT) insn = gen_tls_tls_pcrel_64 (dest, tmp2, addr); @@ -13740,7 +13740,7 @@ rs6000_call_template_1 (rtx *operands, unsigned int funop, bool sibcall) ? "+32768" : "")); static char str[32]; /* 1 spare */ - if (rs6000_pcrel_p (cfun)) + if (rs6000_pcrel_p ()) sprintf (str, "b%s %s@notoc%s", sibcall ? "" : "l", z, arg); else if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) sprintf (str, "b%s %s%s%s", sibcall ? "" : "l", z, arg, @@ -13880,7 +13880,7 @@ rs6000_indirect_call_template_1 (rtx *operands, unsigned int funop, rel64); } - const char *notoc = rs6000_pcrel_p (cfun) ? "_NOTOC" : ""; + const char *notoc = rs6000_pcrel_p () ? "_NOTOC" : ""; const char *addend = (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic == 2 ? "+32768" : ""); if (!speculate) @@ -13897,7 +13897,7 @@ rs6000_indirect_call_template_1 (rtx *operands, unsigned int funop, else if (!speculate) s += sprintf (s, "crset 2\n\t"); - if (rs6000_pcrel_p (cfun)) + if (rs6000_pcrel_p ()) { if (speculate) sprintf (s, "b%%T%ul", funop); @@ -19668,7 +19668,7 @@ rs6000_longcall_ref (rtx call_ref, rtx arg) { rtx base = const0_rtx; int regno = 12; - if (rs6000_pcrel_p (cfun)) + if (rs6000_pcrel_p ()) { rtx reg = gen_rtx_REG (Pmode, regno); rtx u = gen_rtx_UNSPEC_VOLATILE (Pmode, @@ -24729,7 +24729,7 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) if (!SYMBOL_REF_P (func) || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (func))) { - if (!rs6000_pcrel_p (cfun)) + if (!rs6000_pcrel_p ()) { /* Save the TOC into its reserved slot before the call, and prepare to restore it after the call. */ @@ -24835,7 +24835,7 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) else { /* No TOC register needed for calls from PC-relative callers. */ - if (!rs6000_pcrel_p (cfun)) + if (!rs6000_pcrel_p ()) /* Direct calls use the TOC: for local calls, the callee will assume the TOC register is set; for non-local calls, the PLT stub needs the TOC register. */ @@ -24902,7 +24902,7 @@ rs6000_sibcall_aix (rtx value, rtx func_desc, rtx tlsarg, rtx cookie) insn = emit_call_insn (insn); /* Note use of the TOC register. */ - if (!rs6000_pcrel_p (cfun)) + if (!rs6000_pcrel_p ()) use_reg (&CALL_INSN_FUNCTION_USAGE (insn), gen_rtx_REG (Pmode, TOC_REGNUM)); @@ -25189,7 +25189,7 @@ rs6000_fndecl_pcrel_p (const_tree fndecl) /* Return whether we should generate PC-relative code for *FN. */ bool -rs6000_pcrel_p (struct function *fn) +rs6000_function_pcrel_p (struct function *fn) { if (DEFAULT_ABI != ABI_ELFv2) return false; @@ -25202,6 +25202,16 @@ rs6000_pcrel_p (struct function *fn) return rs6000_fndecl_pcrel_p (fn->decl); } +/* Return whether we should generate PC-relative code for the current + function. */ +bool +rs6000_pcrel_p () +{ + return (DEFAULT_ABI == ABI_ELFv2 + && (rs6000_isa_flags & OPTION_MASK_PCREL) != 0 + && TARGET_CMODEL == CMODEL_MEDIUM); +} + /* Given an address (ADDR), a mode (MODE), and what the format of the non-prefixed address (NON_PREFIXED_FORMAT) is, return the instruction format diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 9c5a22823c0..694ff70635e 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -10553,7 +10553,7 @@ (match_operand:P 3 "" "")] UNSPECV_PLT_PCREL))] "HAVE_AS_PLTSEQ && TARGET_ELF - && rs6000_pcrel_p (cfun)" + && rs6000_pcrel_p ()" { return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34); } @@ -10638,7 +10638,7 @@ else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn ("creqv 6,6,6", operands); - if (rs6000_pcrel_p (cfun)) + if (rs6000_pcrel_p ()) return "bl %z0@notoc"; return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0"; } @@ -10659,7 +10659,7 @@ else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) output_asm_insn ("creqv 6,6,6", operands); - if (rs6000_pcrel_p (cfun)) + if (rs6000_pcrel_p ()) return "bl %z1@notoc"; return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1"; } @@ -10834,7 +10834,7 @@ } [(set_attr "type" "branch") (set (attr "length") - (if_then_else (match_test "rs6000_pcrel_p (cfun)") + (if_then_else (match_test "rs6000_pcrel_p ()") (const_int 4) (const_int 8)))]) @@ -10851,7 +10851,7 @@ } [(set_attr "type" "branch") (set (attr "length") - (if_then_else (match_test "rs6000_pcrel_p (cfun)") + (if_then_else (match_test "rs6000_pcrel_p ()") (const_int 4) (const_int 8)))]) @@ -10925,7 +10925,7 @@ (match_operand 1)) (use (match_operand:SI 2 "immediate_operand" "n,n,n")) (clobber (reg:P LR_REGNO))] - "rs6000_pcrel_p (cfun)" + "rs6000_pcrel_p ()" { return rs6000_indirect_call_template (operands, 0); } @@ -10962,7 +10962,7 @@ (match_operand:P 2 "unspec_tls" ""))) (use (match_operand:SI 3 "immediate_operand" "n,n,n")) (clobber (reg:P LR_REGNO))] - "rs6000_pcrel_p (cfun)" + "rs6000_pcrel_p ()" { return rs6000_indirect_call_template (operands, 1); } -- 2.30.2