From patchwork Sun Jun 19 14:03:36 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 100967 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 86F33B7016 for ; Mon, 20 Jun 2011 00:04:05 +1000 (EST) Received: (qmail 24618 invoked by alias); 19 Jun 2011 14:04:01 -0000 Received: (qmail 24607 invoked by uid 22791); 19 Jun 2011 14:03:59 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, RFC_ABUSE_POST X-Spam-Check-By: sourceware.org Received: from mail-pz0-f47.google.com (HELO mail-pz0-f47.google.com) (209.85.210.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 19 Jun 2011 14:03:45 +0000 Received: by pzk36 with SMTP id 36so3110091pzk.20 for ; Sun, 19 Jun 2011 07:03:44 -0700 (PDT) Received: by 10.142.136.15 with SMTP id j15mr646922wfd.372.1308492222991; Sun, 19 Jun 2011 07:03:42 -0700 (PDT) Received: from bubble.grove.modra.org ([115.187.252.19]) by mx.google.com with ESMTPS id g10sm2632637pbi.73.2011.06.19.07.03.40 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 19 Jun 2011 07:03:42 -0700 (PDT) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id BE26F170C1B4; Sun, 19 Jun 2011 23:33:36 +0930 (CST) Date: Sun, 19 Jun 2011 23:33:36 +0930 From: Alan Modra To: gcc-patches@gcc.gnu.org, David Edelsohn Subject: powerpc64 large-toc vs. reload Message-ID: <20110619140336.GM21332@bubble.grove.modra.org> Mail-Followup-To: gcc-patches@gcc.gnu.org, David Edelsohn MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) X-IsSubscribed: yes 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 I was alerted to a problem with large toc (-mcmodel=medium/large) code a few days ago by warnings emitted during a binutils build. dwarf.c: In function 'display_debug_lines_raw': dwarf.c:2409:1: note: non-delegitimized UNSPEC UNSPEC_TOCREL (44) found in variable location dwarf.c:2409:1: note: non-delegitimized UNSPEC UNSPEC_TOCREL (44) found in variable location On investigating why this was happening, I found that these UNSPECs were from the high part calculation of a toc-relative address that didn't get a register. reload allocated the pseudo to a stack slot.. The stack slot didn't match the tight pattern in delegitimize_address which is why we have an UNSPEC left in the debug info. The real problem of course is that reload should never allocate a stack slot for a simple address calculation that can be rematerialised anywhere in the function with just one instruction. So after quite a bit of digging around in reload, I finally figured out that the problem has a really easy solution. Simply tell reload that those high part address calculations are constants. Which is true. That's what the create_TOC_reference change, and the rs6000.md changes below do. (I also fix large-toc tls patterns.) The rest of the patch just adjusts for the changed RTL. Bootstrap and regression tests powerpc64-linux in progress. OK to apply mainline and 4.6 assuming no regressions? * config/rs6000/rs6000.c (create_TOC_reference): Wrap high part of toc-relative address in CONST. (rs6000_delegitimize_address): Recognize changed address. (rs6000_legitimize_reload_address): Likewise. (rs6000_emit_move): Don't force these constants to memory. * config/rs6000/rs6000.md (tls_gd, tls_gd_high): Wrap high part of toc-relative address in CONST. (tls_ld, tls_ld_high, tls_got_dtprel, tls_got_dtprel_high): Likewise. (tls_got_tprel, tls_got_tprel_high, largetoc_high): Likewise. Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 175175) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -5803,12 +5803,13 @@ rs6000_delegitimize_address (rtx orig_x) || TARGET_MINIMAL_TOC || TARGET_CMODEL != CMODEL_SMALL)) || (TARGET_CMODEL != CMODEL_SMALL - && GET_CODE (XEXP (x, 0)) == PLUS - && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG - && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER - && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH + && GET_CODE (XEXP (x, 0)) == CONST + && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS + && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == REG + && REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0)) == TOC_REGISTER + && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == HIGH && rtx_equal_p (XEXP (x, 1), - XEXP (XEXP (XEXP (x, 0), 1), 0))))) + XEXP (XEXP (XEXP (XEXP (x, 0), 0), 1), 0))))) { y = XVECEXP (y, 0, 0); if (offset != NULL_RTX) @@ -6147,11 +6148,12 @@ rs6000_legitimize_reload_address (rtx x, && GET_CODE (XEXP (x, 0)) == PLUS && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER - && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST + && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == HIGH && GET_CODE (XEXP (x, 1)) == CONST && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL - && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1))) + && rtx_equal_p (XEXP (XEXP (XEXP (XEXP (x, 0), 1), 0), 0), XEXP (x, 1))) { push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, @@ -7197,6 +7196,11 @@ rs6000_emit_move (rtx dest, rtx source, } else if (mode == Pmode && CONSTANT_P (operands[1]) + && GET_CODE (operands[1]) != HIGH + && !(TARGET_CMODEL != CMODEL_SMALL + && GET_CODE (operands[1]) == CONST + && GET_CODE (XEXP (operands[1], 0)) == PLUS + && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == HIGH) && ((GET_CODE (operands[1]) != CONST_INT && ! easy_fp_constant (operands[1], mode)) || (GET_CODE (operands[1]) == CONST_INT @@ -7204,7 +7208,6 @@ rs6000_emit_move (rtx dest, rtx source, > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2))) || (GET_CODE (operands[0]) == REG && FP_REGNO_P (REGNO (operands[0])))) - && GET_CODE (operands[1]) != HIGH && ! legitimate_constant_pool_address_p (operands[1], mode, false) && ! toc_relative_expr_p (operands[1]) @@ -19063,7 +19078,9 @@ create_TOC_reference (rtx symbol, rtx la tocreg = gen_rtx_REG (Pmode, TOC_REGISTER); if (TARGET_CMODEL != CMODEL_SMALL) { - rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel)); + rtx hi = gen_rtx_CONST (Pmode, + gen_rtx_PLUS (Pmode, tocreg, + gen_rtx_HIGH (Pmode, tocrel))); if (largetoc_reg != NULL) { emit_move_insn (largetoc_reg, hi); Index: gcc/config/rs6000/rs6000.md =================================================================== --- gcc/config/rs6000/rs6000.md (revision 175175) +++ gcc/config/rs6000/rs6000.md (working copy) @@ -11523,9 +11523,10 @@ (define_insn_and_split "*tls_gd" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (high:TLSmode - (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGD))))] + (const:TLSmode + (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (high:TLSmode + (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGD)))))] "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%1,%2@got@tlsgd@ha" [(set_attr "length" "4")]) @@ -11658,9 +11660,10 @@ (define_insn_and_split "*tls_ld" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (high:TLSmode - (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD))))] + (const:TLSmode + (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (high:TLSmode + (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))))] "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%1,%&@got@tlsld@ha" [(set_attr "length" "4")]) @@ -11753,9 +11757,10 @@ (define_insn_and_split "tls_got_dtprel_< "l %0,%2@got@dtprel(%1)" "&& TARGET_CMODEL != CMODEL_SMALL" [(set (match_dup 3) - (plus:TLSmode (match_dup 1) - (high:TLSmode - (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTDTPREL)))) + (const:TLSmode + (plus:TLSmode (match_dup 1) + (high:TLSmode + (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTDTPREL))))) (set (match_dup 0) (lo_sum:TLSmode (match_dup 3) (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTDTPREL)))] @@ -11770,10 +11775,11 @@ (define_insn_and_split "tls_got_dtprel_< (define_insn "*tls_got_dtprel_high" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (high:TLSmode - (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGOTDTPREL))))] + (const:TLSmode + (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (high:TLSmode + (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGOTDTPREL)))))] "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%1,%2@got@dtprel@ha" [(set_attr "length" "4")]) @@ -11823,9 +11829,10 @@ (define_insn_and_split "tls_got_tprel_ %0,%2@got@tprel(%1)" "&& TARGET_CMODEL != CMODEL_SMALL" [(set (match_dup 3) - (plus:TLSmode (match_dup 1) - (high:TLSmode - (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTTPREL)))) + (const:TLSmode + (plus:TLSmode (match_dup 1) + (high:TLSmode + (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTTPREL))))) (set (match_dup 0) (lo_sum:TLSmode (match_dup 3) (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTTPREL)))] @@ -11840,10 +11847,11 @@ (define_insn_and_split "tls_got_tprel_" [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") - (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") - (high:TLSmode - (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] - UNSPEC_TLSGOTTPREL))))] + (const:TLSmode + (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") + (high:TLSmode + (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGOTTPREL)))))] "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" "addis %0,%1,%2@got@tprel@ha" [(set_attr "length" "4")]) @@ -12157,8 +12165,9 @@ (define_insn "elf_low" ;; Largetoc support (define_insn "largetoc_high" [(set (match_operand:DI 0 "gpc_reg_operand" "=b") - (plus:DI (match_operand:DI 1 "gpc_reg_operand" "b") - (high:DI (match_operand:DI 2 "" ""))))] + (const:DI + (plus:DI (match_operand:DI 1 "gpc_reg_operand" "b") + (high:DI (match_operand:DI 2 "" "")))))] "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" "{cau|addis} %0,%1,%2@ha")