Fix PR target/96607
authorEric Botcazou <ebotcazou@adacore.com>
Thu, 26 Nov 2020 15:38:35 +0000 (16:38 +0100)
committerEric Botcazou <ebotcazou@adacore.com>
Thu, 26 Nov 2020 15:42:31 +0000 (16:42 +0100)
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<P:mode>): Set type to call_no_delay_slot when
tls_delay_slot is false.
(tldm_call<P:mode>): Likewise.

gcc/config/sparc/sparc-protos.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.md

index f525cd7a422abf63253d6bb00c2b40ff64e4c423..5f9999a669ce53b85f81c7c6b6d711458a842dab 100644 (file)
@@ -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);
index 2780b4243b51514c71f813b8835892407c7301dd..02138c5d4788cf891ac3d2973dc852b206614e99 100644 (file)
@@ -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.
index 231c0d84778a7c6e16c37730bd5504460b837c64..edfb6353683d1f7f525d309f3666ede387255e1b 100644 (file)
    (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)
           (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<P:mode>"
   [(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<P:mode>"
   [(set (match_operand:P 0 "register_operand" "=r")