From 294e72e9acbd0ff15ef5b18895de62cc173464ca Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Thu, 26 Nov 2020 16:38:35 +0100 Subject: [PATCH] Fix PR target/96607 After 15 years trying to find out what can go into the delay slot of the call to __tls_get_addr with the Solaris linker, it's now time to concede defeat and consider it as not to be filled. gcc/ChangeLog: PR target/96607 * config/sparc/sparc-protos.h (eligible_for_call_delay): Delete. * config/sparc/sparc.c (eligible_for_call_delay): Likewise. * config/sparc/sparc.md (in_call_delay): Likewise. (tls_delay_slot): New attribute. (define_delay [call]): Use in_branch_delay. (tgd_call): Set type to call_no_delay_slot when tls_delay_slot is false. (tldm_call): Likewise. --- gcc/config/sparc/sparc-protos.h | 1 - gcc/config/sparc/sparc.c | 35 ------------------------------- gcc/config/sparc/sparc.md | 37 +++++++++++++++++---------------- 3 files changed, 19 insertions(+), 54 deletions(-) diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index f525cd7a422..5f9999a669c 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -86,7 +86,6 @@ extern int mems_ok_for_ldd_peep (rtx, rtx, rtx); extern rtx widen_mem_for_ldd_peep (rtx, rtx, machine_mode); extern int empty_delay_slot (rtx_insn *); extern int emit_cbcond_nop (rtx_insn *); -extern int eligible_for_call_delay (rtx_insn *); extern int eligible_for_return_delay (rtx_insn *); extern int eligible_for_sibcall_delay (rtx_insn *); extern int emit_move_sequence (rtx, machine_mode); diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 2780b4243b5..02138c5d478 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -3949,41 +3949,6 @@ emit_cbcond_nop (rtx_insn *insn) return 1; } -/* Return nonzero if TRIAL can go into the call delay slot. */ - -int -eligible_for_call_delay (rtx_insn *trial) -{ - rtx pat; - - if (get_attr_in_branch_delay (trial) == IN_BRANCH_DELAY_FALSE) - return 0; - - /* The only problematic cases are TLS sequences with Sun as/ld. */ - if ((TARGET_GNU_TLS && HAVE_GNU_LD) || !TARGET_TLS) - return 1; - - pat = PATTERN (trial); - - /* We must reject tgd_add{32|64}, i.e. - (set (reg) (plus (reg) (unspec [(reg) (symbol_ref)] UNSPEC_TLSGD))) - and tldm_add{32|64}, i.e. - (set (reg) (plus (reg) (unspec [(reg) (symbol_ref)] UNSPEC_TLSLDM))) - for Sun as/ld. */ - if (GET_CODE (pat) == SET - && GET_CODE (SET_SRC (pat)) == PLUS) - { - rtx unspec = XEXP (SET_SRC (pat), 1); - - if (GET_CODE (unspec) == UNSPEC - && (XINT (unspec, 1) == UNSPEC_TLSGD - || XINT (unspec, 1) == UNSPEC_TLSLDM)) - return 0; - } - - return 1; -} - /* Return nonzero if TRIAL, an insn, can be combined with a 'restore' instruction. RETURN_P is true if the v9 variant 'return' is to be considered in the test too. diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 231c0d84778..edfb6353683 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -561,9 +561,9 @@ (set_attr "type" "multi")]) ;; Attributes for branch scheduling -(define_attr "in_call_delay" "false,true" - (symbol_ref "(eligible_for_call_delay (insn) - ? IN_CALL_DELAY_TRUE : IN_CALL_DELAY_FALSE)")) +(define_attr "tls_delay_slot" "false,true" + (symbol_ref "((TARGET_GNU_TLS && HAVE_GNU_LD) != 0 + ? TLS_DELAY_SLOT_TRUE : TLS_DELAY_SLOT_FALSE)")) (define_attr "in_sibcall_delay" "false,true" (symbol_ref "(eligible_for_sibcall_delay (insn) @@ -613,27 +613,24 @@ (const_string "true") ] (const_string "false"))) -(define_delay (eq_attr "type" "call") - [(eq_attr "in_call_delay" "true") (nil) (nil)]) - (define_delay (eq_attr "type" "sibcall") [(eq_attr "in_sibcall_delay" "true") (nil) (nil)]) (define_delay (eq_attr "type" "return") [(eq_attr "in_return_delay" "true") (nil) (nil)]) -(define_delay (and (eq_attr "type" "branch") - (not (eq_attr "branch_type" "icc"))) - [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay" "true")]) - -(define_delay (and (eq_attr "type" "branch") - (eq_attr "branch_type" "icc")) - [(eq_attr "in_branch_delay" "true") (nil) - (eq_attr "in_integer_branch_annul_delay" "true")]) - -(define_delay (eq_attr "type" "uncond_branch") +(define_delay (ior (eq_attr "type" "call") (eq_attr "type" "uncond_branch")) [(eq_attr "in_branch_delay" "true") (nil) (nil)]) +(define_delay (and (eq_attr "type" "branch") (not (eq_attr "branch_type" "icc"))) + [(eq_attr "in_branch_delay" "true") + (nil) + (eq_attr "in_branch_delay" "true")]) + +(define_delay (and (eq_attr "type" "branch") (eq_attr "branch_type" "icc")) + [(eq_attr "in_branch_delay" "true") + (nil) + (eq_attr "in_integer_branch_annul_delay" "true")]) ;; Include SPARC DFA schedulers @@ -7935,7 +7932,9 @@ visl") (clobber (reg:P O7_REG))] "TARGET_TLS" "call\t%a1, %%tgd_call(%a2)%#" - [(set_attr "type" "call")]) + [(set (attr "type") (if_then_else (eq_attr "tls_delay_slot" "true") + (const_string "call") + (const_string "call_no_delay_slot")))]) (define_insn "tldm_hi22" [(set (match_operand:P 0 "register_operand" "=r") @@ -7966,7 +7965,9 @@ visl") (clobber (reg:P O7_REG))] "TARGET_TLS" "call\t%a1, %%tldm_call(%&)%#" - [(set_attr "type" "call")]) + [(set (attr "type") (if_then_else (eq_attr "tls_delay_slot" "true") + (const_string "call") + (const_string "call_no_delay_slot")))]) (define_insn "tldo_hix22" [(set (match_operand:P 0 "register_operand" "=r") -- 2.30.2