+2015-08-06 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+ Jiong Wang <jiong.wang@arm.com>
+
+ * config/aarch64/aarch64.d (tlsdesc_small_pseudo_<mode>): New pattern.
+ * config/aarch64/aarch64.h (reg_class): New enumeration FIXED_REG0.
+ (REG_CLASS_NAMES): Likewise.
+ (REG_CLASS_CONTENTS): Likewise.
+ * config/aarch64/aarch64.c (aarch64_class_max_nregs): Likewise.
+ (aarch64_register_move_cost): Likewise.
+ (aarch64_load_symref_appropriately): Invoke the new added pattern if
+ possible.
+ * config/aarch64/constraints.md (Uc0): New constraint.
+
2015-08-06 Jiong Wang <jiong.wang@arm.com>
* config/aarch64/constraints.md (Usf): Add the test of
gcc_assert (mode == Pmode || mode == ptr_mode);
- /* In ILP32, the got entry is always of SImode size. Unlike
- small GOT, the dest is fixed at reg 0. */
- if (TARGET_ILP32)
- emit_insn (gen_tlsdesc_small_si (imm));
+ if (can_create_pseudo_p ())
+ {
+ rtx reg = gen_reg_rtx (mode);
+
+ if (TARGET_ILP32)
+ emit_insn (gen_tlsdesc_small_pseudo_si (imm, reg));
+ else
+ emit_insn (gen_tlsdesc_small_pseudo_di (imm, reg));
+
+ emit_use (reg);
+ }
else
- emit_insn (gen_tlsdesc_small_di (imm));
+ {
+ /* In ILP32, the got entry is always of SImode size. Unlike
+ small GOT, the dest is fixed at reg 0. */
+ if (TARGET_ILP32)
+ emit_insn (gen_tlsdesc_small_si (imm));
+ else
+ emit_insn (gen_tlsdesc_small_di (imm));
+ }
tp = aarch64_load_tp (NULL);
if (mode != Pmode)
[(set_attr "type" "call")
(set_attr "length" "16")])
+;; The same as tlsdesc_small_<mode> except that we don't expose hard register X0
+;; as the destination of set as it will cause trouble for RTL loop iv.
+;; RTL loop iv will abort ongoing optimization once it finds there is hard reg
+;; as destination of set. This pattern thus could help these tlsdesc
+;; instruction sequences hoisted out of loop.
+(define_insn "tlsdesc_small_pseudo_<mode>"
+ [(set (match_operand:PTR 1 "register_operand" "=r")
+ (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
+ UNSPEC_TLSDESC))
+ (clobber (reg:DI R0_REGNUM))
+ (clobber (reg:DI LR_REGNUM))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_TLS_DESC"
+ "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
+ [(set_attr "type" "call")
+ (set_attr "length" "16")])
+
(define_insn "stack_tie"
[(set (mem:BLK (scratch))
(unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
+2015-08-06 Jiong Wang <jiong.wang@arm.com>
+
+ * gcc.target/aarch64/tlsdesc_hoist.c: New testcase.
+
2015-08-06 Jiong Wang <jiong.wang@arm.com>
* gcc.target/aarch64/noplt_3.c: New testcase.
--- /dev/null
+/* { dg-do compile } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-options "-O2 -fpic -fdump-rtl-loop2_invariant" } */
+/* { dg-skip-if "-mcmodel=large, no support for -fpic" { aarch64-*-* } { "-mcmodel=large" } { "" } } */
+
+int cal (int, int);
+__thread int tls_data;
+
+int
+foo (int bound)
+{
+ int i = 0;
+ int sum = 0;
+
+ for (i; i < bound; i++)
+ sum = cal (sum, tls_data);
+
+ return sum;
+}
+
+/* Insn sequences for TLS descriptor should be hoisted out of the loop. */
+/* { dg-final { scan-rtl-dump "Decided" "loop2_invariant" } } */