From patchwork Fri Mar 9 18:46:22 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Georg-Johann Lay X-Patchwork-Id: 145749 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 8057AB6EEC for ; Sat, 10 Mar 2012 05:47:08 +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=1331923629; h=Comment: DomainKey-Signature:Received:Received:Received:Received: Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=u0bLGTW YALUta1Damxkg9MZTST0=; b=xYBW8oCfig4kz9bbSyei/G8igUGo1gXjH0H414H fSrjHCneSvrUL/u3nl3geBwToLhEJmS3Gu77b0ifLGB9fTu5LQ/nNj3aO73NftiL jXJduB496H+31rLRD7SNZV3jHF73drdQQk/cw1fki1xPqzqlfASMdC11OpwfAtqV 1KHs= 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:X-RZG-AUTH:X-RZG-CLASS-ID:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=NPXLBQ2MVpr1sAV7X7nMPhkfNcujBbo1P4rFyn9RxmkL+n7Lp1tpx/9h+baxEq YDpXdCAdowAkEjbueN044ndgAMwFN1SSwiPcp6KsDoBw/k7I5UGnVyyVFzder7UM 0pWGgnsC8eJZkx/TayMkOG7xB/9IGG9OXS+3G9U7deGG0=; Received: (qmail 16182 invoked by alias); 9 Mar 2012 18:47:01 -0000 Received: (qmail 16165 invoked by uid 22791); 9 Mar 2012 18:46:57 -0000 X-SWARE-Spam-Status: No, hits=-1.5 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE, TW_EG, TW_OV X-Spam-Check-By: sourceware.org Received: from mo-p00-ob.rzone.de (HELO mo-p00-ob.rzone.de) (81.169.146.161) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 09 Mar 2012 18:46:35 +0000 X-RZG-AUTH: :LXoWVUeid/7A29J/hMvvT2k715jHQaJercGObUOFkj18odoYNahU4Q== X-RZG-CLASS-ID: mo00 Received: from [192.168.0.22] (business-188-111-022-002.static.arcor-ip.net [188.111.22.2]) by smtp.strato.de (jimi mo37) (RZmta 27.7 AUTH) with ESMTPA id 401cbao29IiK9R ; Fri, 9 Mar 2012 19:46:25 +0100 (MET) Message-ID: <4F5A4FFE.9000203@gjlay.de> Date: Fri, 09 Mar 2012 19:46:22 +0100 From: Georg-Johann Lay User-Agent: Thunderbird 2.0.0.24 (X11/20100302) MIME-Version: 1.0 To: gcc-patches@gcc.gnu.org CC: Denis Chertykov , Eric Weddington Subject: [Patch,AVR]: Hack around PR rtl-optimization/52543 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 The problem with the PR is that lower-subreg.c happily splits multi-byte moves from address spaces without knowing anything about the additional costs this is causing. The TARGET_MODE_DEPENDENT_ADDRESS_P hook cannot be used for 16-bit addresses because that hook is not sensitive to address spaces, but is is used for the 24-bit address space to avoid subreg lowering for PSImode. For the 16-bit address spaces the mov expander now assigns the address register by hand as post-increment. Luckily, post-increment is the only addressing mode that makes sense with the non-generic address spaces and there is no choice for the address register resp. addressing mode, anyway... This patch does not fix the PR issue, of course, it just avoids subreg lowering by using/pretending mode-dependent addresses. Ok for trunk? Johann PR rtl-optimization/52543 * config/avr/avr.c (avr_mode_dependent_address_p): New function. (TARGET_MODE_DEPENDENT_ADDRESS_P): New define. * config/avr/avr.md (unspec): Add UNSPEC_LPM. (load__libgcc): Use UNSPEC_LPM instead of MEM. (mov): For multi-byte move from non-generic 16-bit address spaces: Expand to use Z++ as address for inline code and use UNSPEC_LPM (Z) for code from libgcc. (load_libgcc): Remove expander. (split-lpmx): Remove split. Index: config/avr/avr.md =================================================================== --- config/avr/avr.md (revision 185105) +++ config/avr/avr.md (working copy) @@ -63,6 +63,7 @@ (define_c_enum "unspec" [UNSPEC_STRLEN UNSPEC_MOVMEM UNSPEC_INDEX_JMP + UNSPEC_LPM UNSPEC_FMUL UNSPEC_FMULS UNSPEC_FMULSU @@ -364,43 +365,24 @@ (define_split ;;======================================================================== ;; Move stuff around -;; "loadqi_libgcc" -;; "loadhi_libgcc" -;; "loadpsi_libgcc" -;; "loadsi_libgcc" -;; "loadsf_libgcc" -(define_expand "load_libgcc" - [(set (match_dup 3) - (match_dup 2)) - (set (reg:MOVMODE 22) - (match_operand:MOVMODE 1 "memory_operand" "")) - (set (match_operand:MOVMODE 0 "register_operand" "") - (reg:MOVMODE 22))] - "avr_load_libgcc_p (operands[1])" - { - operands[3] = gen_rtx_REG (HImode, REG_Z); - operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX); - operands[1] = replace_equiv_address (operands[1], operands[3]); - set_mem_addr_space (operands[1], ADDR_SPACE_FLASH); - }) +;; Represent a load from __flash that needs libgcc support as UNSPEC. +;; This is legal because we read from non-changing memory. +;; For rationale see the FIXME below. -;; "load_qi_libgcc" -;; "load_hi_libgcc" ;; "load_psi_libgcc" ;; "load_si_libgcc" ;; "load_sf_libgcc" (define_insn "load__libgcc" [(set (reg:MOVMODE 22) - (match_operand:MOVMODE 0 "memory_operand" "m,m"))] - "avr_load_libgcc_p (operands[0]) - && REG_P (XEXP (operands[0], 0)) - && REG_Z == REGNO (XEXP (operands[0], 0))" + (unspec:MOVMODE [(reg:HI REG_Z)] + UNSPEC_LPM))] + "" { - operands[0] = GEN_INT (GET_MODE_SIZE (mode)); - return "%~call __load_%0"; + rtx n_bytes = GEN_INT (GET_MODE_SIZE (mode)); + output_asm_insn ("%~call __load_%0", &n_bytes); + return ""; } - [(set_attr "length" "1,2") - (set_attr "isa" "rjmp,jmp") + [(set_attr "type" "xcall") (set_attr "cc" "clobber")]) @@ -549,10 +531,53 @@ (define_expand "mov" DONE; } - if (avr_load_libgcc_p (src)) + /* ; FIXME: Load from non-generic 16-bit address spaces by means of + ; POST_INC or a call to a support routine from libgcc. Reason is the + ; extreme code bloat caused by subreg lowering which splits multi-byte + ; moves without knowing anything about the additional costs caused by + ; these splits, see PR rtl-optimization/52543. + ; We assign the address to Z already at expand-time because there is + ; no choice for the address register, anyway, and pre-post-increment + ; optimization is virtually non-existent. */ + + if (avr_load_libgcc_p (src) + || (GET_MODE_SIZE (mode) > 1 + && avr_mem_flash_p (src) + && can_create_pseudo_p() + && (GET_CODE (XEXP (src, 0)) != POST_INC + || (GET_CODE (XEXP (src, 0)) == POST_INC + && REGNO (XEXP (XEXP (src, 0), 0)) != REG_Z)))) { - /* For the small devices, do loads per libgcc call. */ - emit_insn (gen_load_libgcc (dest, src)); + rtx addr = XEXP (src, 0); + rtx regz = gen_rtx_REG (Pmode, REG_Z); + + if (GET_CODE (addr) == POST_INC) + emit_move_insn (regz, XEXP (addr, 0)); + else + emit_move_insn (regz, force_reg (Pmode, addr)); + + if (avr_load_libgcc_p (src)) + { + /* For old devices without LPMX, prefer loads per libcall. */ + + emit_insn (gen_load__libgcc ()); + emit_move_insn (operands[0], gen_rtx_REG (mode, 22)); + if (GET_CODE (addr) == POST_INC) + emit_move_insn (XEXP (addr, 0), + plus_constant (XEXP (addr, 0), + GET_MODE_SIZE (mode))); + } + else + { + /* For remaining multi-byte cases hard-code the address as Z++. */ + + emit_move_insn (operands[0], + replace_equiv_address (operands[1], + gen_rtx_POST_INC (Pmode, regz))); + if (GET_CODE (addr) == POST_INC) + emit_move_insn (XEXP (addr, 0), regz); + } + DONE; } }) @@ -694,40 +719,6 @@ (define_peephole2 ; movw_r operands[5] = gen_rtx_REG (HImode, REGNO (operands[3])); }) -;; For LPM loads from AS1 we split -;; R = *Z -;; to -;; R = *Z++ -;; Z = Z - sizeof (R) -;; -;; so that the second instruction can be optimized out. - -(define_split ; "split-lpmx" - [(set (match_operand:HISI 0 "register_operand" "") - (match_operand:HISI 1 "memory_operand" ""))] - "reload_completed - && AVR_HAVE_LPMX" - [(set (match_dup 0) - (match_dup 2)) - (set (match_dup 3) - (plus:HI (match_dup 3) - (match_dup 4)))] - { - rtx addr = XEXP (operands[1], 0); - - if (!avr_mem_flash_p (operands[1]) - || !REG_P (addr) - || reg_overlap_mentioned_p (addr, operands[0])) - { - FAIL; - } - - operands[2] = replace_equiv_address (operands[1], - gen_rtx_POST_INC (Pmode, addr)); - operands[3] = addr; - operands[4] = gen_int_mode (-GET_MODE_SIZE (mode), HImode); - }) - ;;========================================================================== ;; xpointer move (24 bit) Index: config/avr/avr.c =================================================================== --- config/avr/avr.c (revision 185100) +++ config/avr/avr.c (working copy) @@ -1423,6 +1423,22 @@ avr_cannot_modify_jumps_p (void) } +/* Implement `TARGET_MODE_DEPENDENT_ADDRESS_P'. */ + +/* FIXME: PSImode addresses are not mode-dependent in themselves. + This hook just serves to hack around PR rtl-optimization/52543 by + claiming that PSImode addresses (which are used for the 24-bit + address space __memx) were mode-dependent so that lower-subreg.s + will skip these addresses. See also the similar FIXME comment along + with mov expanders in avr.md. */ + +static bool +avr_mode_dependent_address_p (const_rtx addr) +{ + return GET_MODE (addr) != Pmode; +} + + /* Helper function for `avr_legitimate_address_p'. */ static inline bool @@ -11027,6 +11043,9 @@ avr_fold_builtin (tree fndecl, int n_arg #undef TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS #define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS avr_addr_space_legitimize_address +#undef TARGET_MODE_DEPENDENT_ADDRESS_P +#define TARGET_MODE_DEPENDENT_ADDRESS_P avr_mode_dependent_address_p + #undef TARGET_PRINT_OPERAND #define TARGET_PRINT_OPERAND avr_print_operand #undef TARGET_PRINT_OPERAND_ADDRESS