From f3648f7d8d1486bb61c06ec48b01d7a38c1f59c8 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Mon, 4 Sep 2017 17:11:42 +0200 Subject: [PATCH] * 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. From-SVN: r251662 --- gcc/ChangeLog | 18 ++++++-- gcc/config/i386/i386-protos.h | 2 + gcc/config/i386/i386.c | 83 +++++++++++++++++++++++++++++++++++ gcc/config/i386/i386.md | 7 +++ gcc/config/i386/predicates.md | 4 ++ 5 files changed, 110 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 012c519d23e..2ae4e776d90 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2017-09-04 Uros Bizjak + + * 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 PR tree-optimization/82084 @@ -2237,8 +2247,8 @@ * tree-ssa-loop-manip.c (canonicalize_loop_ivs): Likewise. 2017-08-30 Richard Sandiford - Alan Hayward - David Sherwood + Alan Hayward + David Sherwood * machmode.h (opt_mode::else_blk): New function. (int_mode_for_mode): Declare. @@ -2539,8 +2549,8 @@ once. Use get_narrowest_mode instead of GET_CLASS_NARROWEST_MODE. 2017-08-30 Richard Sandiford - Alan Hayward - David Sherwood + Alan Hayward + David Sherwood * machmode.h (mode_traits): New structure. (get_narrowest_mode): New function. diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 0ed22e6556d..4c57615093b 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -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); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 6afd422d1a5..6fdc9fd54b1 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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. */ diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 4cbd8cd551e..bf034795c8b 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -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]);") + ;; These patterns match the binary 387 instructions for addM3, subM3, ;; mulM3 and divM3. There are three patterns for each of DFmode and diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index e7371a41b16..f7854e942e5 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -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") -- 2.30.2