This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PowerPC TLS scheduling


This patch allows gcc to split __tls_get_addr sequences now that the
hole in the PowerPC TLS ABIs has been fixed by
http://sourceware.org/ml/binutils/2009-02/msg00274.html

Bootstrapped and regression tested powerpc and powerpc64-linux.
OK for mainline?

	* configure.ac (HAVE_AS_TLS_MARKERS): New gas feature check.
	* configure: Regenerate.
	* config.in: Regenerate.
	* config/rs6000/rs6000.opt (mtls-markers): Add.
	* config/rs6000/rs6000.h (TARGET_TLS_MARKERS): Define.
	* config/rs6000/rs6000.md (tls_gd_aix, tls_gd_sysv): Add splitter.
	(tls_ld_aix, tls_ld_sysv): Likewise.
	(tls_gd, tls_gd_call_aix, tls_gd_call_sysv): New insns.
	(tls_ld, tls_ld_call_aix, tls_ld_call_sysv): Likewise.

Index: gcc/configure.ac
===================================================================
--- gcc/configure.ac	(revision 145289)
+++ gcc/configure.ac	(working copy)
@@ -3128,6 +3128,12 @@ LCF0:
       [.gnu_attribute 4,1],,
       [AC_DEFINE(HAVE_AS_GNU_ATTRIBUTE, 1,
 	  [Define if your assembler supports .gnu_attribute.])])
+
+    gcc_GAS_CHECK_FEATURE([tls marker support],
+      gcc_cv_as_powerpc_tls_markers, [2,20,0],,
+      [ bl __tls_get_addr(x@tlsgd)],,
+      [AC_DEFINE(HAVE_AS_TLS_MARKERS, 1,
+	  [Define if your assembler supports arg info for __tls_get_addr.])])
     ;;
 
   mips*-*-*)
Index: gcc/config/rs6000/rs6000.opt
===================================================================
--- gcc/config/rs6000/rs6000.opt	(revision 145289)
+++ gcc/config/rs6000/rs6000.opt	(working copy)
@@ -131,6 +131,10 @@ mfused-madd
 Target Report RejectNegative InverseMask(NO_FUSED_MADD, FUSED_MADD)
 Generate fused multiply/add instructions
 
+mtls-markers
+Target Report Var(tls_markers) Init(1)
+Mark __tls_get_addr calls with argument info
+
 msched-prolog
 Target Report Var(TARGET_SCHED_PROLOG) Init(1)
 Schedule the start and end of the procedure
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(revision 145289)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -240,6 +240,15 @@ extern const char *host_detect_local_cpu
 #define TARGET_DFP 0
 #endif
 
+/* Define TARGET_TLS_MARKERS if the target assembler does not support
+   arg markers for __tls_get_addr calls.  */
+#ifndef HAVE_AS_TLS_MARKERS
+#undef  TARGET_TLS_MARKERS
+#define TARGET_TLS_MARKERS 0
+#else
+#define TARGET_TLS_MARKERS tls_markers
+#endif
+
 #ifndef TARGET_SECURE_PLT
 #define TARGET_SECURE_PLT 0
 #endif
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 145289)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -10412,7 +10412,7 @@ (define_mode_attr tls_abi_suffix [(SI "3
 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
 
-(define_insn "tls_gd_aix<TLSmode:tls_abi_suffix>"
+(define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
 	      (match_operand 4 "" "g")))
@@ -10422,10 +10422,21 @@ (define_insn "tls_gd_aix<TLSmode:tls_abi
    (clobber (reg:SI LR_REGNO))]
   "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX"
   "addi %0,%1,%2@got@tlsgd\;bl %z3\;%."
+  "&& TARGET_TLS_MARKERS"
+  [(set (match_dup 0)
+	(unspec:TLSmode [(match_dup 1)
+			 (match_dup 2)]
+			UNSPEC_TLSGD))
+   (parallel [(set (match_dup 0)
+   	     	   (call (mem:TLSmode (match_dup 3))
+		   	 (match_dup 4)))
+	      (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
+	      (clobber (reg:SI LR_REGNO))])]
+  ""
   [(set_attr "type" "two")
    (set_attr "length" "12")])
 
-(define_insn "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
+(define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
         (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
 	      (match_operand 4 "" "g")))
@@ -10445,10 +10456,62 @@ (define_insn "tls_gd_sysv<TLSmode:tls_sy
   else
     return "addi %0,%1,%2@got@tlsgd\;bl %z3";
 }
+  "&& TARGET_TLS_MARKERS"
+  [(set (match_dup 0)
+	(unspec:TLSmode [(match_dup 1)
+			 (match_dup 2)]
+			UNSPEC_TLSGD))
+   (parallel [(set (match_dup 0)
+   	     	   (call (mem:TLSmode (match_dup 3))
+		   	 (match_dup 4)))
+	      (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
+	      (clobber (reg:SI LR_REGNO))])]
+  ""
   [(set_attr "type" "two")
    (set_attr "length" "8")])
 
-(define_insn "tls_ld_aix<TLSmode:tls_abi_suffix>"
+(define_insn "*tls_gd<TLSmode:tls_abi_suffix>"
+  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
+	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
+			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
+			UNSPEC_TLSGD))]
+  "HAVE_AS_TLS && TARGET_TLS_MARKERS"
+  "addi %0,%1,%2@got@tlsgd"
+  [(set_attr "length" "4")])
+
+(define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
+  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
+        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
+	      (match_operand 2 "" "g")))
+   (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
+		   UNSPEC_TLSGD)
+   (clobber (reg:SI LR_REGNO))]
+  "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX && TARGET_TLS_MARKERS"
+  "bl %z1(%3@tlsgd)\;%."
+  [(set_attr "type" "branch")
+   (set_attr "length" "8")])
+
+(define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
+  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
+        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
+	      (match_operand 2 "" "g")))
+   (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
+		   UNSPEC_TLSGD)
+   (clobber (reg:SI LR_REGNO))]
+  "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
+{
+  if (flag_pic)
+    {
+      if (TARGET_SECURE_PLT && flag_pic == 2)
+	return "bl %z1+32768(%3@tlsgd)@plt";
+      return "bl %z1(%3@tlsgd)@plt";
+    }
+  return "bl %z1(%3@tlsgd)";
+}
+  [(set_attr "type" "branch")
+   (set_attr "length" "4")])
+
+(define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
 	      (match_operand 3 "" "g")))
@@ -10457,9 +10520,19 @@ (define_insn "tls_ld_aix<TLSmode:tls_abi
    (clobber (reg:SI LR_REGNO))]
   "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX"
   "addi %0,%1,%&@got@tlsld\;bl %z2\;%."
+  "&& TARGET_TLS_MARKERS"
+  [(set (match_dup 0)
+	(unspec:TLSmode [(match_dup 1)]
+			UNSPEC_TLSLD))
+   (parallel [(set (match_dup 0)
+   	     	   (call (mem:TLSmode (match_dup 2))
+		   	 (match_dup 3)))
+	      (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
+	      (clobber (reg:SI LR_REGNO))])]
+  ""
   [(set_attr "length" "12")])
 
-(define_insn "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
+(define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
         (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
 	      (match_operand 3 "" "g")))
@@ -10478,8 +10551,56 @@ (define_insn "tls_ld_sysv<TLSmode:tls_sy
   else
     return "addi %0,%1,%&@got@tlsld\;bl %z2";
 }
+  "&& TARGET_TLS_MARKERS"
+  [(set (match_dup 0)
+	(unspec:TLSmode [(match_dup 1)]
+			UNSPEC_TLSLD))
+   (parallel [(set (match_dup 0)
+   	     	   (call (mem:TLSmode (match_dup 2))
+		   	 (match_dup 3)))
+	      (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
+	      (clobber (reg:SI LR_REGNO))])]
+  ""
   [(set_attr "length" "8")])
 
+(define_insn "*tls_ld<TLSmode:tls_abi_suffix>"
+  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
+	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
+			UNSPEC_TLSLD))]
+  "HAVE_AS_TLS && TARGET_TLS_MARKERS"
+  "addi %0,%1,%&@got@tlsld"
+  [(set_attr "length" "4")])
+
+(define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
+  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
+        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
+	      (match_operand 2 "" "g")))
+   (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
+   (clobber (reg:SI LR_REGNO))]
+  "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX && TARGET_TLS_MARKERS"
+  "bl %z1(%&@tlsld)\;%."
+  [(set_attr "type" "branch")
+   (set_attr "length" "8")])
+
+(define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
+  [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
+        (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
+	      (match_operand 2 "" "g")))
+   (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
+   (clobber (reg:SI LR_REGNO))]
+  "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
+{
+  if (flag_pic)
+    {
+      if (TARGET_SECURE_PLT && flag_pic == 2)
+	return "bl %z1+32768(%&@tlsld)@plt";
+      return "bl %z1(%&@tlsld)@plt";
+    }
+  return "bl %z1(%&@tlsld)";
+}
+  [(set_attr "type" "branch")
+   (set_attr "length" "4")])
+
 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
   [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
 	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]