From patchwork Thu Dec 27 17:18:18 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Edelsohn X-Patchwork-Id: 208348 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id CDCDD2C00D2 for ; Fri, 28 Dec 2012 04:18:36 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1357233517; h=Comment: DomainKey-Signature:Received:Received:Received:Received: MIME-Version:Received:Received:Date:Message-ID:Subject:From:To: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=a0xU5iN 2Yicn1GashRkV+hj3nJw=; b=b7Q0OJF/hR2mnIyB5ztzctPaRxWgXAJ5ZkfQaVv N2maxY4zL95kKw87t8c/VlUohKf1Xs7yCB0o7mAO5HoMcCV4nS7bU7AEyBaNMzqI 099M735UqmBHsI0zSilWA+NzLoiqc5McNbyjafnCDaczqAkT/VZPLCLhQDCY+iRG hcHM= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:MIME-Version:Received:Received:Date:Message-ID:Subject:From:To:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=CccFhf11zB+9Q5aGSv+kYUYMmuvMzWmxto0SOZ1UgBuAKNMCQasaCcE+rhqN/P l85UkijdCmdhmsotj7xO7j6MZyNUpVZefFR3dr200m9nbCmbyo/O+ZrSbQJNilS1 EXCWGLo8WJ1J8wvzwVQquch44QUUUlsUWunIZtNZDN2pU=; Received: (qmail 18566 invoked by alias); 27 Dec 2012 17:18:28 -0000 Received: (qmail 18553 invoked by uid 22791); 27 Dec 2012 17:18:26 -0000 X-SWARE-Spam-Status: No, hits=-3.4 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, KAM_STOCKGEN, KHOP_RCVD_TRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE, TW_CP, TW_FW X-Spam-Check-By: sourceware.org Received: from mail-vc0-f174.google.com (HELO mail-vc0-f174.google.com) (209.85.220.174) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 27 Dec 2012 17:18:19 +0000 Received: by mail-vc0-f174.google.com with SMTP id d16so9913555vcd.5 for ; Thu, 27 Dec 2012 09:18:18 -0800 (PST) MIME-Version: 1.0 Received: by 10.52.155.229 with SMTP id vz5mr42779662vdb.17.1356628698792; Thu, 27 Dec 2012 09:18:18 -0800 (PST) Received: by 10.220.23.197 with HTTP; Thu, 27 Dec 2012 09:18:18 -0800 (PST) Date: Thu, 27 Dec 2012 12:18:18 -0500 Message-ID: Subject: [PATCH] AIX native TLS support [3/?] From: David Edelsohn To: GCC Patches Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org This patch gets GCC support for native TLS on AIX working and passing most tests. The patch shifts the creation of the qualified symbol name from output_toc() to rs6000_legitimize_tls_address_aix(). I was hoping that the separate SYMBOL_REF would prevent RTL fwprop from becoming confused about the symbols, but no such luck. The re-write still makes things a little cleaner. Also, private TLS data (static variables with non-zero initializers) are not decorated with the TLS CSECT qualifier so that the AIX assembler and linker resolve it correctly. To prevent fwprop from breaking things, I need to prevent rs6000_delegitimize_address from associating TLS TOC references with the original symbol. The rs6000 port uses the constant pool to manage the TOC. However, for TLS symbols, the value in the TOC is not equivalent to the symbol itself. The RTL fwprop pass thinks that it can associate the result of a TLS access, which materializes the symbol in a register, with the value in the constant pool and avoid re-loading the TOC value. This does not work and passes a garbage value to subsequent TLS calls, which produce garbage results. The two solutions are either "hide" the TLS constant pool values by not delegitmizing them or completely re-writing the TOC support to use a pool separate from the constant pool. I chose the former because TLS is a scarce resource and its usage should be minimal anyway. Bootstrapped on powerpc-ibm-aix7.1.0.0. Thanks, David * config/rs6000/rs6000.c (rs6000_deligitimze_address): Do not delegitimize TLS addresses on AIX. (rs6000_legitimize_tls_address_aix): Append TLS symbol qualifier. Set SYMBOL_FLAG_LOCAL on module symbol. (output_toc): Do not append TLS symbol qualifier here. * config/rs6000/rs6000.md (tls_get_addr_internal): Add GPR 4 to clobbers. Index: rs6000.c =================================================================== --- rs6000.c (revision 194725) +++ rs6000.c (working copy) @@ -5826,6 +5826,15 @@ rs6000_delegitimize_address (rtx orig_x) } #endif y = XVECEXP (y, 0, 0); + +#ifdef HAVE_AS_TLS + /* Do not associate thread-local symbols with the original + constant pool symbol. */ + if (TARGET_XCOFF + && SYMBOL_REF_TLS_MODEL (get_pool_constant (y)) >= TLS_MODEL_REAL) + return orig_x; +#endif + if (offset != NULL_RTX) y = gen_rtx_PLUS (Pmode, y, offset); if (!MEM_P (orig_x)) @@ -5899,10 +5908,29 @@ rs6000_got_sym (void) static rtx rs6000_legitimize_tls_address_aix (rtx addr, enum tls_model model) { - rtx sym, mem, tocref, tlsreg, tmpreg, dest; + rtx sym, mem, tocref, tlsreg, tmpreg, dest, tlsaddr; + const char *name; + char *tlsname; + name = XSTR (addr, 0); + /* Append TLS CSECT qualifier, unless the symbol already is qualified + or the symbol will be in TLS private data section. */ + if (name[strlen (name) - 1] != ']' + && (TREE_PUBLIC (SYMBOL_REF_DECL (addr)) + || bss_initializer_p (SYMBOL_REF_DECL (addr)))) + { + tlsname = XALLOCAVEC (char, strlen (name) + 4); + strcpy (tlsname, name); + strcat (tlsname, + bss_initializer_p (SYMBOL_REF_DECL (addr)) ? "[UL]" : "[TL]"); + tlsaddr = copy_rtx (addr); + XSTR (tlsaddr, 0) = ggc_strdup (tlsname); + } + else + tlsaddr = addr; + /* Place addr into TOC constant pool. */ - sym = force_const_mem (GET_MODE (addr), addr); + sym = force_const_mem (GET_MODE (tlsaddr), tlsaddr); /* Output the TOC entry and create the MEM referencing the value. */ if (constant_pool_expr_p (XEXP (sym, 0)) @@ -5919,27 +5947,28 @@ rs6000_legitimize_tls_address_aix (rtx addr, enum if (model == TLS_MODEL_GLOBAL_DYNAMIC || model == TLS_MODEL_LOCAL_DYNAMIC) { - rtx module = gen_reg_rtx (Pmode); /* Create new TOC reference for @m symbol. */ - const char *name = XSTR (XVECEXP (XEXP (mem, 0), 0, 0), 0); - char *name2 = XALLOCAVEC (char, strlen (name) + 1); - strcpy (name2, "*LCM"); - strcat (name2, name + 3); - tocref = create_TOC_reference (gen_rtx_SYMBOL_REF (Pmode, - ggc_alloc_string (name2, - strlen (name2))), - NULL_RTX); - rtx mem2 = gen_const_mem (Pmode, tocref); - set_mem_alias_set (mem2, get_TOC_alias_set ()); + name = XSTR (XVECEXP (XEXP (mem, 0), 0, 0), 0); + tlsname = XALLOCAVEC (char, strlen (name) + 1); + strcpy (tlsname, "*LCM"); + strcat (tlsname, name + 3); + rtx modaddr = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tlsname)); + SYMBOL_REF_FLAGS (modaddr) |= SYMBOL_FLAG_LOCAL; + tocref = create_TOC_reference (modaddr, NULL_RTX); + rtx modmem = gen_const_mem (Pmode, tocref); + set_mem_alias_set (modmem, get_TOC_alias_set ()); - dest = gen_reg_rtx (Pmode); + rtx modreg = gen_reg_rtx (Pmode); + emit_insn (gen_rtx_SET (VOIDmode, modreg, modmem)); + tmpreg = gen_reg_rtx (Pmode); emit_insn (gen_rtx_SET (VOIDmode, tmpreg, mem)); - emit_insn (gen_rtx_SET (VOIDmode, module, mem2)); + + dest = gen_reg_rtx (Pmode); if (TARGET_32BIT) - emit_insn (gen_tls_get_addrsi (dest, module, tmpreg)); + emit_insn (gen_tls_get_addrsi (dest, modreg, tmpreg)); else - emit_insn (gen_tls_get_addrdi (dest, module, tmpreg)); + emit_insn (gen_tls_get_addrdi (dest, modreg, tmpreg)); return dest; } /* Obtain TLS pointer: 32 bit call or 64 bit GPR 13. */ @@ -22320,12 +22349,6 @@ output_toc (FILE *file, rtx x, int labelno, enum m if (TARGET_XCOFF && GET_CODE (base) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (base) != 0) { - tree decl = SYMBOL_REF_DECL (base); - if (bss_initializer_p (decl)) - fputs ("[UL]", file); - else - fputs ("[TL]", file); - if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_EXEC) fputs ("@le", file); else if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_INITIAL_EXEC) @@ -22340,10 +22363,7 @@ output_toc (FILE *file, rtx x, int labelno, enum m RS6000_OUTPUT_BASENAME (file, name); fputs ("[TC],", file); output_addr_const (file, x); - if (TREE_PUBLIC (SYMBOL_REF_DECL (base))) - fputs ("[TL]@m", file); - else - fputs ("[UL]@m", file); + fputs ("@m", file); } } #endif Index: rs6000.md =================================================================== --- rs6000.md (revision 194725) +++ rs6000.md (working copy) @@ -10022,6 +10022,7 @@ [(set (reg:P 3) (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS)) (clobber (reg:P 0)) + (clobber (reg:P 4)) (clobber (reg:P 5)) (clobber (reg:P 11)) (clobber (reg:CC CR0_REGNO))