public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] AIX native TLS support
@ 2012-11-29  2:55 David Edelsohn
  2012-12-02 16:42 ` David Edelsohn
  0 siblings, 1 reply; 3+ messages in thread
From: David Edelsohn @ 2012-11-29  2:55 UTC (permalink / raw)
  To: GCC Patches

Below is a first attempt at native TLS support on AIX.  It produces
the correct syntax and works for small testcases.  All of GCC can
build with it enabled, but libstdc++ and libgomp do not run correctly,
so I am not enabling it by default.

The implementation treats local-dynamic as general-dynamic because AIX
local-dynamic is a mess to implement for not much gain.

Unlike PPC64 Linux, AIX requires TLS symbols to be placed in a special
CSECT mapping class and referenced with special TOC symbol
decorations, not assembler decorations left to the linker.  The patch
leaves PPC64 Linux behavior unchanged.

Thanks, David


	* xcoffout.c (xcoff_tls_data_section_name): Define.
	* xcoffout.h (xcoff_tls_data_section_name): Declare.
	* config/rs6000/rs6000.c (tls_data_section): Define.
	(TARGET_USE_BLOCKS_FOR_DECL_P): Define.
	(rs6000_legitimize_tls_address_aix): New function.
	(rs6000_legitimize_tls_address): Use new function for AIX.
	(rs6000_cannot_force_const_mem): No sum in TLS TOC symbols.
	Allow TLS symbol in constant pool other than ELF.
	(rs6000_legitimate_address_p): Allow TLS symbol other than ELF.
	(rs6000_assemble_visibility): Do not emit anything on AIX.
	(output_toc): Handle alias of TLS general-dynamic symbols.
	Emit TLS decorations on symbols.
	(rs6000_use_blocks_for_decl_p): New function.
	(rs6000_xcoff_output_tls_section_asm_op): New function.
	(rs6000_xcoff_asm_init_sections): Initialize tls_data_section.
	(rs6000_xcoff_select_section): Choose tls_data_section for
	thread-local storage.
	(rs6000_xcoff_file_start): Generate xcoff_tls_data_section_name.
	(rs6000_legitimate_constant_p): Allow TLS symbol other than ELF.
	* config/rs6000/rs6000.md (tls_tls_): Restrict to ELF.
	(tls_get_tpointer): New.
	(tle_get_tpointer_internal): New.
	(tls_get_addr<mode>): New.
	(tls_get_addr_internal<mode>): New.

Index: xcoffout.c
===================================================================
--- xcoffout.c	(revision 193917)
+++ xcoffout.c	(working copy)
@@ -66,6 +66,7 @@

 char *xcoff_bss_section_name;
 char *xcoff_private_data_section_name;
+char *xcoff_tls_data_section_name;
 char *xcoff_read_only_section_name;

 /* Last source file name mentioned in a NOTE insn.  */
Index: xcoffout.h
===================================================================
--- xcoffout.h	(revision 193917)
+++ xcoffout.h	(working copy)
@@ -126,6 +126,7 @@

 extern char *xcoff_bss_section_name;
 extern char *xcoff_private_data_section_name;
+extern char *xcoff_tls_data_section_name;
 extern char *xcoff_read_only_section_name;

 /* Last source file name mentioned in a NOTE insn.  */
Index: config/rs6000/rs6000.c
===================================================================
--- config/rs6000/rs6000.c	(revision 193917)
+++ config/rs6000/rs6000.c	(working copy)
@@ -208,6 +208,7 @@

 static GTY(()) section *read_only_data_section;
 static GTY(()) section *private_data_section;
+static GTY(()) section *tls_data_section;
 static GTY(()) section *read_only_private_data_section;
 static GTY(()) section *sdata2_section;
 static GTY(()) section *toc_section;
@@ -1405,6 +1406,8 @@
 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
+#undef TARGET_USE_BLOCKS_FOR_DECL_P
+#define TARGET_USE_BLOCKS_FOR_DECL_P rs6000_use_blocks_for_decl_p

 #undef TARGET_BUILTIN_RECIPROCAL
 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
@@ -5882,6 +5885,75 @@
   return rs6000_got_symbol;
 }

+/* AIX Thread-Local Address support.  */
+
+static rtx
+rs6000_legitimize_tls_address_aix (rtx addr, enum tls_model model)
+{
+  rtx sym, mem, tocref, tlsreg, tmpreg, dest;
+
+  /* Place addr into TOC constant pool.  */
+  sym = force_const_mem (GET_MODE (addr), addr);
+
+  /* Output the TOC entry and create the MEM referencing the value.  */
+  if (constant_pool_expr_p (XEXP (sym, 0))
+      && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (XEXP
(sym, 0)), Pmode))
+    {
+      tocref = create_TOC_reference (XEXP (sym, 0), NULL_RTX);
+      mem = gen_const_mem (Pmode, tocref);
+      set_mem_alias_set (mem, get_TOC_alias_set ());
+    }
+  else
+    return sym;
+
+  /* Use global-dynamic for local-dynamic.  */
+  if (model == TLS_MODEL_GLOBAL_DYNAMIC
+      || model == TLS_MODEL_LOCAL_DYNAMIC)
+    {
+      rtx module = gen_reg_rtx (Pmode);
+      /* Create new TOC reference for @m symbol.  */
+      const char *name = XSTR (XVECEXP (XEXP (mem, 0), 0, 0), 0);
+      char *name2 = XALLOCAVEC (char, strlen (name) + 1);
+      strcpy (name2, "*LCM");
+      strcat (name2, name + 3);
+      tocref = create_TOC_reference (gen_rtx_SYMBOL_REF (Pmode,
+							 ggc_alloc_string (name2,
+									   strlen (name2))),
+				     NULL_RTX);
+      rtx mem2 = gen_const_mem (Pmode, tocref);
+      set_mem_alias_set (mem2, get_TOC_alias_set ());
+
+      dest = gen_reg_rtx (Pmode);
+      tmpreg = gen_reg_rtx (Pmode);
+      emit_insn (gen_rtx_SET (VOIDmode, tmpreg, mem));
+      emit_insn (gen_rtx_SET (VOIDmode, module, mem2));
+      if (TARGET_32BIT)
+	emit_insn (gen_tls_get_addrsi (dest, module, tmpreg));
+      else
+	emit_insn (gen_tls_get_addrdi (dest, module, tmpreg));
+      return dest;
+    }
+  /* Obtain TLS pointer: 32 bit call or 64 bit GPR 13.  */
+  else if (TARGET_32BIT)
+    {
+      tlsreg = gen_reg_rtx (SImode);
+      emit_insn (gen_tls_get_tpointer (tlsreg));
+    }
+  else
+    tlsreg = gen_rtx_REG (DImode, 13);
+
+  /* Load the TOC value into temporary register.  */
+  tmpreg = gen_reg_rtx (Pmode);
+  emit_insn (gen_rtx_SET (VOIDmode, tmpreg, mem));
+  set_unique_reg_note (get_last_insn (), REG_EQUAL,
+		       gen_rtx_MINUS (Pmode, addr, tlsreg));
+
+  /* Add TOC symbol value to TLS pointer.  */
+  dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, tmpreg, tlsreg));
+
+  return dest;
+}
+
 /* ADDR contains a thread-local SYMBOL_REF.  Generate code to compute
    this (thread-local) address.  */

@@ -5890,6 +5962,9 @@
 {
   rtx dest, insn;

+  if (TARGET_XCOFF)
+    return rs6000_legitimize_tls_address_aix (addr, model);
+
   dest = gen_reg_rtx (Pmode);
   if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
     {
@@ -6085,7 +6160,15 @@
       && GET_CODE (XEXP (x, 0)) == UNSPEC)
     return true;

-  return rs6000_tls_referenced_p (x);
+  /* A TLS symbol in the TOC cannot contain a sum.  */
+  if (GET_CODE (x) == CONST
+      && GET_CODE (XEXP (x, 0)) == PLUS
+      && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
+      && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0)) != 0)
+    return true;
+
+  /* Do not place an ELF TLS symbol in the constant pool.  */
+  return TARGET_ELF && rs6000_tls_referenced_p (x);
 }

 /* Return 1 if *X is a thread-local symbol.  This is the same as
@@ -6380,7 +6463,7 @@
       && INTVAL (XEXP (x, 1)) == -16)
     x = XEXP (x, 0);

-  if (RS6000_SYMBOL_REF_TLS_P (x))
+  if (TARGET_ELF && RS6000_SYMBOL_REF_TLS_P (x))
     return 0;
   if (legitimate_indirect_address_p (x, reg_ok_strict))
     return 1;
@@ -15486,6 +15569,9 @@
 static void
 rs6000_assemble_visibility (tree decl, int vis)
 {
+  if (TARGET_XCOFF)
+    return;
+
   /* Functions need to have their entry point symbol visibility set as
      well as their descriptor symbol visibility.  */
   if (DEFAULT_ABI == ABI_AIX
@@ -21934,6 +22020,20 @@
 	  ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
 	  fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
 					      found)->labelno));
+
+#ifdef HAVE_AS_TLS
+	  if (TARGET_XCOFF && GET_CODE (x) == SYMBOL_REF
+	      && (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_GLOBAL_DYNAMIC
+		  || SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC))
+	    {
+	      fputs ("\t.set ", file);
+	      ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCM");
+	      fprintf (file, "%d,", labelno);
+	      ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCM");
+	      fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
+			       			      found)->labelno));
+	    }
+#endif
 	  return;
 	}
     }
@@ -22206,6 +22306,29 @@
     }
   else
     output_addr_const (file, x);
+
+#if HAVE_AS_TLS
+  if (TARGET_XCOFF && GET_CODE (base) == SYMBOL_REF)
+    {
+      if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_EXEC)
+	fputs ("[TL]@le", file);
+      else if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_INITIAL_EXEC)
+	fputs ("[TL]@ie", file);
+      /* Use global-dynamic for local-dynamic.  */
+      else if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_GLOBAL_DYNAMIC
+	       || SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_DYNAMIC)
+	{
+	  fputs ("[TL]\n", file);
+	  (*targetm.asm_out.internal_label) (file, "LCM", labelno);
+	  fputs ("\t.tc .", file);
+	  RS6000_OUTPUT_BASENAME (file, name);
+	  fputs ("[TC],", file);
+	  output_addr_const (file, x);
+	  fputs ("[TL]@m", file);
+	}
+    }
+#endif
+
   putc ('\n', file);
 }
 \f
@@ -24884,6 +25007,14 @@
 {
   return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
 }
+
+/* Do not place thread-local symbols refs in the object blocks.  */
+
+static bool
+rs6000_use_blocks_for_decl_p (const_tree decl)
+{
+  return !DECL_THREAD_LOCAL_P (decl);
+}
 \f
 /* Return a REG that occurs in ADDR with coefficient 1.
    ADDR can be effectively incremented by incrementing REG.
@@ -25516,6 +25647,14 @@
 	   XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
 }

+static void
+rs6000_xcoff_output_tls_section_asm_op (const void *directive)
+{
+  fprintf (asm_out_file, "\t.csect %s[TL],%s\n",
+	   *(const char *const *) directive,
+	   XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
+}
+
 /* A get_unnamed_section callback, used for switching to toc_section.  */

 static void
@@ -25553,6 +25692,11 @@
 			   rs6000_xcoff_output_readwrite_section_asm_op,
 			   &xcoff_private_data_section_name);

+  tls_data_section
+    = get_unnamed_section (SECTION_TLS,
+			   rs6000_xcoff_output_tls_section_asm_op,
+			   &xcoff_tls_data_section_name);
+
   read_only_private_data_section
     = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
 			   &xcoff_private_data_section_name);
@@ -25604,7 +25748,12 @@
     }
   else
     {
-      if (TREE_PUBLIC (decl))
+#if HAVE_AS_TLS
+      if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl))
+	return tls_data_section;
+      else
+#endif
+	if (TREE_PUBLIC (decl))
 	return data_section;
       else
 	return private_data_section;
@@ -25700,6 +25849,8 @@
 			   main_input_filename, ".bss_");
   rs6000_gen_section_name (&xcoff_private_data_section_name,
 			   main_input_filename, ".rw_");
+  rs6000_gen_section_name (&xcoff_tls_data_section_name,
+			   main_input_filename, ".tls_");
   rs6000_gen_section_name (&xcoff_read_only_section_name,
 			   main_input_filename, ".ro_");

@@ -28164,7 +28315,7 @@
 static bool
 rs6000_legitimate_constant_p (enum machine_mode mode, rtx x)
 {
-  if (rs6000_tls_referenced_p (x))
+  if (TARGET_ELF && rs6000_tls_referenced_p (x))
     return false;

   return ((GET_CODE (x) != CONST_DOUBLE && GET_CODE (x) != CONST_VECTOR)
Index: config/rs6000/rs6000.md
===================================================================
--- config/rs6000/rs6000.md	(revision 193917)
+++ config/rs6000/rs6000.md	(working copy)
@@ -9983,8 +9983,51 @@
 	(unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
 			 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
 			UNSPEC_TLSTLS))]
-  "HAVE_AS_TLS"
+  "TARGET_ELF && HAVE_AS_TLS"
   "add %0,%1,%2@tls")
+
+(define_expand "tls_get_tpointer"
+  [(set (match_operand:SI 0 "gpc_reg_operand" "")
+	(unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
+  "TARGET_XCOFF && HAVE_AS_TLS"
+  "
+{
+  emit_insn (gen_tls_get_tpointer_internal ());
+  emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
+  DONE;
+}")
+
+(define_insn "tls_get_tpointer_internal"
+  [(set (reg:SI 3)
+	(unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
+   (clobber (reg:SI LR_REGNO))]
+  "TARGET_XCOFF && HAVE_AS_TLS"
+  "bla __get_tpointer")
+
+(define_expand "tls_get_addr<mode>"
+  [(set (match_operand:P 0 "gpc_reg_operand" "")
+	(unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
+                   (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
+  "TARGET_XCOFF && HAVE_AS_TLS"
+  "
+{
+  emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
+  emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
+  emit_insn (gen_tls_get_addr_internal<mode> ());
+  emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
+  DONE;
+}")
+
+(define_insn "tls_get_addr_internal<mode>"
+  [(set (reg:P 3)
+	(unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
+   (clobber (reg:P 0))
+   (clobber (reg:P 5))
+   (clobber (reg:P 11))
+   (clobber (reg:CC CR0_REGNO))
+   (clobber (reg:P LR_REGNO))]
+  "TARGET_XCOFF && HAVE_AS_TLS"
+  "bla __tls_get_addr")
 \f
 ;; Next come insns related to the calling sequence.
 ;;

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] AIX native TLS support
  2012-11-29  2:55 [PATCH] AIX native TLS support David Edelsohn
@ 2012-12-02 16:42 ` David Edelsohn
  0 siblings, 0 replies; 3+ messages in thread
From: David Edelsohn @ 2012-12-02 16:42 UTC (permalink / raw)
  To: GCC Patches

I checked in the patch.

The problem, at least for libgomp testsuite, is GCC is not correctly
emitting the definitions of some variables specified with

#pragma omp threadprivate(XXX)

The symptoms are the variable is placed in a TLS section anchor block,
which never should happen, or the BSS variable is not visible.

- David

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH] AIX native TLS support
@ 2012-12-12 20:51 David Edelsohn
  0 siblings, 0 replies; 3+ messages in thread
From: David Edelsohn @ 2012-12-12 20:51 UTC (permalink / raw)
  To: GCC Patches

This is the next set of patches for native TLS support on AIX.  This
mainly adds support for BSS symbols. This should use local common and
I created a tbss section name, but I cannot figure out how to convince
the AIX assembler to match the TOC symbols reference to the lcomm
symbol.  Disassembly of XLC output shows that it uses COMMON symbols,
so I am punting to that as well.

This patch also removes the section anchor flag from native TLS
symbols if it was set.

This patch uses the logic from bss_initializer_p(). Should that
function in varasm.c be made non-static?

Bootstrapped on powerpc-ibm-aix7.1.0.0, although this still does not
pass libgomp testsuite.

Thanks, David

	* xcoffout.c (xcoff_tbss_section_name): Define.
	* xcoffout.h (xcoff_tbss_section_name): Declare.
	* config/rs6000/xcoff.h (TARGET_ENCODE_SECTION_INFO): Define.
	(ASM_OUTPUT_TLS_COMMON): Merge strings.
	* config/rs6000/rs6000.c (tls_private_dat_section): New.
	(output_toc): Only output CSECT decoration for TLS.
	Output appropriate CSECT for data or bss.
	(rs6000_xcoff_asm_init_sections) Define tls_private_data_section.
	(rs6000_xcoff_select_section): Handle TLS bss and private data.
	(rs6000_xcoff_file_start): Generate xcoff_tbss_section_name.
	(rs6000_xcoff_encode_section_info): Strip SYMBOL_FLAG_HAS_BLOCK_INFO
	from native TLS symbols.

Index: xcoffout.c
===================================================================
--- xcoffout.c	(revision 194435)
+++ xcoffout.c	(working copy)
@@ -67,6 +67,7 @@
 char *xcoff_bss_section_name;
 char *xcoff_private_data_section_name;
 char *xcoff_tls_data_section_name;
+char *xcoff_tbss_section_name;
 char *xcoff_read_only_section_name;

 /* Last source file name mentioned in a NOTE insn.  */
Index: xcoffout.h
===================================================================
--- xcoffout.h	(revision 194435)
+++ xcoffout.h	(working copy)
@@ -127,6 +127,7 @@
 extern char *xcoff_bss_section_name;
 extern char *xcoff_private_data_section_name;
 extern char *xcoff_tls_data_section_name;
+extern char *xcoff_tbss_section_name;
 extern char *xcoff_read_only_section_name;

 /* Last source file name mentioned in a NOTE insn.  */
Index: config/rs6000/xcoff.h
===================================================================
--- config/rs6000/xcoff.h	(revision 194435)
+++ config/rs6000/xcoff.h	(working copy)
@@ -98,6 +98,7 @@
 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
 #define TARGET_STRIP_NAME_ENCODING  rs6000_xcoff_strip_name_encoding
 #define TARGET_SECTION_TYPE_FLAGS  rs6000_xcoff_section_type_flags
+#define TARGET_ENCODE_SECTION_INFO rs6000_xcoff_encode_section_info

 /* FP save and restore routines.  */
 #define	SAVE_FP_PREFIX "._savef"
@@ -308,8 +309,8 @@
 #define ASM_OUTPUT_TLS_COMMON(FILE, DECL, NAME, SIZE)	\
   do { fputs(COMMON_ASM_OP, (FILE));			\
        RS6000_OUTPUT_BASENAME ((FILE), (NAME));		\
-       fputs("[UL]", (FILE));					\
-       fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE)); \
+       fprintf ((FILE), "[UL],"HOST_WIDE_INT_PRINT_UNSIGNED"\n", \
+       (SIZE));						\
   } while (0)
 #endif

Index: config/rs6000/rs6000.c
===================================================================
--- config/rs6000/rs6000.c	(revision 194435)
+++ config/rs6000/rs6000.c	(working copy)
@@ -209,6 +209,7 @@ static short cached_can_issue_more;
 static GTY(()) section *read_only_data_section;
 static GTY(()) section *private_data_section;
 static GTY(()) section *tls_data_section;
+static GTY(()) section *tls_private_data_section;
 static GTY(()) section *read_only_private_data_section;
 static GTY(()) section *sdata2_section;
 static GTY(()) section *toc_section;
@@ -22316,23 +22317,39 @@ output_toc (FILE *file, rtx x, int labelno, enum m
     output_addr_const (file, x);

 #if HAVE_AS_TLS
-  if (TARGET_XCOFF && GET_CODE (base) == SYMBOL_REF)
+  if (TARGET_XCOFF && GET_CODE (base) == SYMBOL_REF
+      && SYMBOL_REF_TLS_MODEL (base) != 0)
     {
+      tree decl = SYMBOL_REF_DECL (base);
+      if (DECL_INITIAL (decl) == NULL_TREE
+		   || DECL_INITIAL (decl) == error_mark_node
+		   || (flag_zero_initialized_in_bss
+		       /* Leave constant zeroes in .rodata so they
+			  can be shared.  */
+		       && !TREE_READONLY (decl)
+		       && initializer_zerop (DECL_INITIAL (decl))))
+	fputs ("[UL]", file);
+      else
+	fputs ("[TL]", file);
+
       if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_EXEC)
-	fputs ("[TL]@le", file);
+	fputs ("@le", file);
       else if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_INITIAL_EXEC)
-	fputs ("[TL]@ie", file);
+	fputs ("@ie", file);
       /* Use global-dynamic for local-dynamic.  */
       else if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_GLOBAL_DYNAMIC
 	       || SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_DYNAMIC)
 	{
-	  fputs ("[TL]\n", file);
+	  putc ('\n', file);
 	  (*targetm.asm_out.internal_label) (file, "LCM", labelno);
 	  fputs ("\t.tc .", file);
 	  RS6000_OUTPUT_BASENAME (file, name);
 	  fputs ("[TC],", file);
 	  output_addr_const (file, x);
-	  fputs ("[TL]@m", file);
+	  if (TREE_PUBLIC (SYMBOL_REF_DECL (base)))
+	    fputs ("[TL]@m", file);
+	  else
+	    fputs ("[UL]@m", file);
 	}
     }
 #endif
@@ -25705,6 +25722,11 @@ rs6000_xcoff_asm_init_sections (void)
 			   rs6000_xcoff_output_tls_section_asm_op,
 			   &xcoff_tls_data_section_name);

+  tls_private_data_section
+    = get_unnamed_section (SECTION_TLS,
+			   rs6000_xcoff_output_tls_section_asm_op,
+			   &xcoff_private_data_section_name);
+
   read_only_private_data_section
     = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
 			   &xcoff_private_data_section_name);
@@ -25758,7 +25780,24 @@ rs6000_xcoff_select_section (tree decl, int reloc,
     {
 #if HAVE_AS_TLS
       if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl))
-	return tls_data_section;
+	{
+	  if (TREE_PUBLIC (decl))
+	    return tls_data_section;
+	  else if (DECL_INITIAL (decl) == NULL_TREE
+		   || DECL_INITIAL (decl) == error_mark_node
+		   || (flag_zero_initialized_in_bss
+		       /* Leave constant zeroes in .rodata so they
+			  can be shared.  */
+		       && !TREE_READONLY (decl)
+		       && initializer_zerop (DECL_INITIAL (decl))))
+	    {
+	      /* Convert to COMMON to emit in BSS.  */
+	      DECL_COMMON (decl) = 1;
+	      return tls_comm_section;
+	    }
+	  else
+	    return tls_private_data_section;
+	}
       else
 #endif
 	if (TREE_PUBLIC (decl))
@@ -25857,10 +25896,12 @@ rs6000_xcoff_file_start (void)
 			   main_input_filename, ".bss_");
   rs6000_gen_section_name (&xcoff_private_data_section_name,
 			   main_input_filename, ".rw_");
+  rs6000_gen_section_name (&xcoff_read_only_section_name,
+			   main_input_filename, ".ro_");
   rs6000_gen_section_name (&xcoff_tls_data_section_name,
 			   main_input_filename, ".tls_");
-  rs6000_gen_section_name (&xcoff_read_only_section_name,
-			   main_input_filename, ".ro_");
+  rs6000_gen_section_name (&xcoff_tbss_section_name,
+			   main_input_filename, ".tbss_[UL]");

   fputs ("\t.file\t", asm_out_file);
   output_quoted_string (asm_out_file, main_input_filename);
@@ -25886,6 +25927,29 @@ rs6000_xcoff_file_end (void)
 	 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
 	 asm_out_file);
 }
+
+static void
+rs6000_xcoff_encode_section_info (tree decl, rtx rtl, int first)
+{
+  rtx symbol;
+  int flags;
+
+  default_encode_section_info (decl, rtl, first);
+
+  /* Careful not to prod global register variables.  */
+  if (!MEM_P (rtl))
+    return;
+  symbol = XEXP (rtl, 0);
+  if (GET_CODE (symbol) != SYMBOL_REF)
+    return;
+
+  flags = SYMBOL_REF_FLAGS (symbol);
+
+  if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl))
+    flags &= ~SYMBOL_FLAG_HAS_BLOCK_INFO;
+
+  SYMBOL_REF_FLAGS (symbol) = flags;
+}
 #endif /* TARGET_XCOFF */

 /* Compute a (partial) cost for rtx X.  Return true if the complete

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-12-12 20:51 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-29  2:55 [PATCH] AIX native TLS support David Edelsohn
2012-12-02 16:42 ` David Edelsohn
2012-12-12 20:51 David Edelsohn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).