public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFC PATCH, i386]: Convert TLS location to DEFAULT_TLS_SEG_REG address space
@ 2017-08-31 22:19 Uros Bizjak
  2017-09-04 15:42 ` Uros Bizjak
  0 siblings, 1 reply; 2+ messages in thread
From: Uros Bizjak @ 2017-08-31 22:19 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2404 bytes --]

Hello!

Using following testcase:

--cut here--
__thread int a;

int foo (void)
{
  return a;
}
--cut here--

Attached patch converts TLS location in the form of:

        (mem/c:SI (plus:DI (unspec:DI [
                        (const_int 0 [0])
                    ] UNSPEC_TP)
                (const:DI (unspec:DI [
                            (symbol_ref:DI ("a") [flags 0x2a]
<var_decl 0x7f8c3acd5e10 a>)
                        ] UNSPEC_NTPOFF))) [1 a+0 S4 A32]))
"thread.c":5 82 {*movsi_internal}
to:

        (mem/c:SI (const:DI (unspec:DI [
                        (symbol_ref:DI ("a") [flags 0x2a]  <var_decl
0x7f8c3acd5e10 a>)
                    ] UNSPEC_NTPOFF)) [1 a+0 S4 A32 AS1])) "thread.c":5 -1

avoiding the UNSPEC_TP tag and instead mark the location with AS.

This way, address space becomes the property of the memory location,
not of the address itself, so we don't need ugly hacks when the
address is moved to a register (LEA ignores segment overrides, c.f.
split_long_move function in i386.c).

Please note that some instructions (e.g. prefetchX) operate on
prefixed *address*, so we can't just rip out non-AS code from
print_operand. The above amended example:

--cut here--
__thread int a;

int foo (void)
{
  __builtin_prefetch (&a, 0);
  return a;
}
--cut here--

compiles to:

        prefetcht0      %fs:a@tpoff
        movl    %fs:a@tpoff, %eax

where prefetch operand remains:

(insn 7 6 16 2 (prefetch (plus:DI (unspec:DI [
                    (const_int 0 [0])
                ] UNSPEC_TP)
            (const:DI (unspec:DI [
                        (symbol_ref:DI ("a") [flags 0x2a]  <var_decl
0x7fe994a14e10 a>)
                    ] UNSPEC_NTPOFF)))
        (const_int 0 [0])
        (const_int 3 [0x3])) "thread.c":5 1010 {*prefetch_sse}
     (nil))

2017-08-31  Uros Bizjak  <ubizjak@gmail.com>

    * config/i386/i386-protos.h (ix86_tls_address_pattern_p) New prototype.
    (ix86_rewrite_tls_address): Ditto.
    * config/i386/i386.c (ix86_tls_address_pattern_p) New function.
    (ix86_rewrite_tls_address_1): Ditto.
    (ix86_rewrite_tls_address): Ditto.
    * config/i386/predicates.md (tls_address_pattern): New predicate.
    * config/i386/i386.md (TLS address splitter): New splitter.

Patch was bootstrapped and regression tested on x86_64-linux-gnu
{,-m32}, all default languages plus go.

I plan to commit the patch to the mainline early next week.

Uros

[-- Attachment #2: p.diff.txt --]
[-- Type: text/plain, Size: 4042 bytes --]

Index: config/i386/i386-protos.h
===================================================================
--- config/i386/i386-protos.h	(revision 251566)
+++ config/i386/i386-protos.h	(working copy)
@@ -227,6 +227,8 @@ extern unsigned int ix86_get_callcvt (const_tree);
 #endif
 
 extern rtx ix86_tls_module_base (void);
+extern bool ix86_tls_address_pattern_p (rtx);
+extern rtx ix86_rewrite_tls_address (rtx);
 
 extern void ix86_expand_vector_init (bool, rtx, rtx);
 extern void ix86_expand_vector_set (bool, rtx, rtx, int);
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 251566)
+++ config/i386/i386.c	(working copy)
@@ -17631,6 +17631,89 @@ legitimize_tls_address (rtx x, enum tls_model mode
   return dest;
 }
 
+/* Return true if OP refers to a TLS address.  */
+bool
+ix86_tls_address_pattern_p (rtx op)
+{
+  subrtx_var_iterator::array_type array;
+  FOR_EACH_SUBRTX_VAR (iter, array, op, ALL)
+    {
+      rtx op = *iter;
+      if (MEM_P (op))
+	{
+	  rtx *x = &XEXP (op, 0);
+	  while (GET_CODE (*x) == PLUS)
+	    {
+	      int i;
+	      for (i = 0; i < 2; i++)
+		{
+		  rtx u = XEXP (*x, i);
+		  if (GET_CODE (u) == ZERO_EXTEND)
+		    u = XEXP (u, 0);
+		  if (GET_CODE (u) == UNSPEC
+		      && XINT (u, 1) == UNSPEC_TP)
+		    return true;
+		}
+	      x = &XEXP (*x, 0);
+	    }
+
+	  iter.skip_subrtxes ();
+	}
+    }
+
+  return false;
+}
+
+/* Rewrite *LOC so that it refers to a default TLS address space.  */
+void
+ix86_rewrite_tls_address_1 (rtx *loc)
+{
+  subrtx_ptr_iterator::array_type array;
+  FOR_EACH_SUBRTX_PTR (iter, array, loc, ALL)
+    {
+      rtx *loc = *iter;
+      if (MEM_P (*loc))
+	{
+	  rtx addr = XEXP (*loc, 0);
+	  rtx *x = &addr;
+	  while (GET_CODE (*x) == PLUS)
+	    {
+	      int i;
+	      for (i = 0; i < 2; i++)
+		{
+		  rtx u = XEXP (*x, i);
+		  if (GET_CODE (u) == ZERO_EXTEND)
+		    u = XEXP (u, 0);
+		  if (GET_CODE (u) == UNSPEC
+		      && XINT (u, 1) == UNSPEC_TP)
+		    {
+		      addr_space_t as = DEFAULT_TLS_SEG_REG;
+
+		      *x = XEXP (*x, 1 - i);
+
+		      *loc = replace_equiv_address_nv (*loc, addr, true);
+		      set_mem_addr_space (*loc, as);
+		      return;
+		    }
+		}
+	      x = &XEXP (*x, 0);
+	    }
+
+	  iter.skip_subrtxes ();
+	}
+    }
+}
+
+/* Rewrite instruction pattern involvning TLS address
+   so that it refers to a default TLS address space.  */
+rtx
+ix86_rewrite_tls_address (rtx pattern)
+{
+  pattern = copy_insn (pattern);
+  ix86_rewrite_tls_address_1 (&pattern);
+  return pattern;
+}
+
 /* Create or return the unique __imp_DECL dllimport symbol corresponding
    to symbol DECL if BEIMPORT is true.  Otherwise create or return the
    unique refptr-DECL symbol corresponding to symbol DECL.  */
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 251566)
+++ config/i386/i386.md	(working copy)
@@ -14143,6 +14143,13 @@
   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
 })
+
+(define_split
+  [(match_operand 0 "tls_address_pattern")]
+  "TARGET_TLS_DIRECT_SEG_REFS"
+  [(match_dup 0)]
+  "operands[0] = ix86_rewrite_tls_address (operands[0]);")
+
 \f
 ;; These patterns match the binary 387 instructions for addM3, subM3,
 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
Index: config/i386/predicates.md
===================================================================
--- config/i386/predicates.md	(revision 251566)
+++ config/i386/predicates.md	(working copy)
@@ -567,6 +567,10 @@
   (and (match_code "symbol_ref")
        (match_test "op == ix86_tls_module_base ()")))
 
+(define_predicate "tls_address_pattern"
+  (and (match_code "set,parallel,unspec,unspec_volatile")
+       (match_test "ix86_tls_address_pattern_p (op)")))
+
 ;; Test for a pc-relative call operand
 (define_predicate "constant_call_address_operand"
   (match_code "symbol_ref")

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

* Re: [RFC PATCH, i386]: Convert TLS location to DEFAULT_TLS_SEG_REG address space
  2017-08-31 22:19 [RFC PATCH, i386]: Convert TLS location to DEFAULT_TLS_SEG_REG address space Uros Bizjak
@ 2017-09-04 15:42 ` Uros Bizjak
  0 siblings, 0 replies; 2+ messages in thread
From: Uros Bizjak @ 2017-09-04 15:42 UTC (permalink / raw)
  To: gcc-patches

On Thu, Aug 31, 2017 at 9:32 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
> Hello!
>
> Using following testcase:
>
> --cut here--
> __thread int a;
>
> int foo (void)
> {
>   return a;
> }
> --cut here--
>
> Attached patch converts TLS location in the form of:
>
>         (mem/c:SI (plus:DI (unspec:DI [
>                         (const_int 0 [0])
>                     ] UNSPEC_TP)
>                 (const:DI (unspec:DI [
>                             (symbol_ref:DI ("a") [flags 0x2a]
> <var_decl 0x7f8c3acd5e10 a>)
>                         ] UNSPEC_NTPOFF))) [1 a+0 S4 A32]))
> "thread.c":5 82 {*movsi_internal}
> to:
>
>         (mem/c:SI (const:DI (unspec:DI [
>                         (symbol_ref:DI ("a") [flags 0x2a]  <var_decl
> 0x7f8c3acd5e10 a>)
>                     ] UNSPEC_NTPOFF)) [1 a+0 S4 A32 AS1])) "thread.c":5 -1
>
> avoiding the UNSPEC_TP tag and instead mark the location with AS.
>
> This way, address space becomes the property of the memory location,
> not of the address itself, so we don't need ugly hacks when the
> address is moved to a register (LEA ignores segment overrides, c.f.
> split_long_move function in i386.c).
>
> Please note that some instructions (e.g. prefetchX) operate on
> prefixed *address*, so we can't just rip out non-AS code from
> print_operand. The above amended example:
>
> --cut here--
> __thread int a;
>
> int foo (void)
> {
>   __builtin_prefetch (&a, 0);
>   return a;
> }
> --cut here--
>
> compiles to:
>
>         prefetcht0      %fs:a@tpoff
>         movl    %fs:a@tpoff, %eax
>
> where prefetch operand remains:
>
> (insn 7 6 16 2 (prefetch (plus:DI (unspec:DI [
>                     (const_int 0 [0])
>                 ] UNSPEC_TP)
>             (const:DI (unspec:DI [
>                         (symbol_ref:DI ("a") [flags 0x2a]  <var_decl
> 0x7fe994a14e10 a>)
>                     ] UNSPEC_NTPOFF)))
>         (const_int 0 [0])
>         (const_int 3 [0x3])) "thread.c":5 1010 {*prefetch_sse}
>      (nil))
>
> 2017-08-31  Uros Bizjak  <ubizjak@gmail.com>
>
>     * config/i386/i386-protos.h (ix86_tls_address_pattern_p) New prototype.
>     (ix86_rewrite_tls_address): Ditto.
>     * config/i386/i386.c (ix86_tls_address_pattern_p) New function.
>     (ix86_rewrite_tls_address_1): Ditto.
>     (ix86_rewrite_tls_address): Ditto.
>     * config/i386/predicates.md (tls_address_pattern): New predicate.
>     * config/i386/i386.md (TLS address splitter): New splitter.
>
> Patch was bootstrapped and regression tested on x86_64-linux-gnu
> {,-m32}, all default languages plus go.
>
> I plan to commit the patch to the mainline early next week.

Committed to mainline SVN.

Uros

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

end of thread, other threads:[~2017-09-04 15:42 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-31 22:19 [RFC PATCH, i386]: Convert TLS location to DEFAULT_TLS_SEG_REG address space Uros Bizjak
2017-09-04 15:42 ` Uros Bizjak

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).