(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
+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.
#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);
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. */
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
(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")