* config/i386/i386-protos.h (ix86_tls_address_pattern_p) New prototype.
authorUros Bizjak <uros@gcc.gnu.org>
Mon, 4 Sep 2017 15:11:42 +0000 (17:11 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Mon, 4 Sep 2017 15:11:42 +0000 (17:11 +0200)
(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.

From-SVN: r251662

gcc/ChangeLog
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/i386.md
gcc/config/i386/predicates.md

index 012c519d23eeb16c84516862c91fc6142e86e949..2ae4e776d90645ff9272cfab117da79eda7edf40 100644 (file)
@@ -1,3 +1,13 @@
+2017-09-04  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.
+
 2017-09-04  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/82084
        * tree-ssa-loop-manip.c (canonicalize_loop_ivs): Likewise.
 
 2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
-            Alan Hayward  <alan.hayward@arm.com>
-            David Sherwood  <david.sherwood@arm.com>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
 
        * machmode.h (opt_mode::else_blk): New function.
        (int_mode_for_mode): Declare.
        once.  Use get_narrowest_mode instead of GET_CLASS_NARROWEST_MODE.
 
 2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
-            Alan Hayward  <alan.hayward@arm.com>
-            David Sherwood  <david.sherwood@arm.com>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
 
        * machmode.h (mode_traits): New structure.
        (get_narrowest_mode): New function.
index 0ed22e6556d673b8b9575d96d4812783c4f6035f..4c57615093bf284c2efca2e4b0e5a2490ccff18d 100644 (file)
@@ -225,6 +225,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 6afd422d1a599c91d7699acc6a7a10d2f45d02bd..6fdc9fd54b1d6a9e77e1070887c0b2763acec1f5 100644 (file)
@@ -17649,6 +17649,89 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
   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 4cbd8cd551e7188c0f983f47cdafc4078a9fea9a..bf034795c8b1e71c7a1695a8c35afb6eae59c243 100644 (file)
   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 e7371a41b160f184ef202afcb2c9bcb8982060a2..f7854e942e551ea8957d55205528c74675b1fd6b 100644 (file)
   (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")