From patchwork Thu Oct 13 18:16:15 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Georg-Johann Lay X-Patchwork-Id: 119585 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 10DE1B71CE for ; Fri, 14 Oct 2011 05:16:53 +1100 (EST) Received: (qmail 31166 invoked by alias); 13 Oct 2011 18:16:49 -0000 Received: (qmail 31156 invoked by uid 22791); 13 Oct 2011 18:16:48 -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_LQ X-Spam-Check-By: sourceware.org Received: from mo-p00-ob.rzone.de (HELO mo-p00-ob.rzone.de) (81.169.146.160) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 13 Oct 2011 18:16:21 +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 mo25) (RZmta 26.10 AUTH) with ESMTPA id 2055b3n9DGREk6 ; Thu, 13 Oct 2011 20:16:15 +0200 (MEST) Message-ID: <4E972AEF.1020802@gjlay.de> Date: Thu, 13 Oct 2011 20:16:15 +0200 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] Print no-return functions as JMP 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 This patch saves some ticks and bytes on stack by JUMPing to no-return functions instead of CALLing them. Passes without regression. Ok for trunk? Johann * config/avr/avr-protos.h (avr_out_call): New prototype. * config/avr/avr.md (adjust_len): Add alternative "call". (call_insn, call_calue_insn): Use it. Use avr_out_call to print assembler. * config/avr/avr.c (avr_out_call): New function. (adjust_insn_length): Handle ADJUST_LEN_CALL. Index: config/avr/avr.md =================================================================== --- config/avr/avr.md (revision 179843) +++ config/avr/avr.md (working copy) @@ -133,11 +133,10 @@ (define_attr "length" "" ;; Following insn attribute tells if and how the adjustment has to be ;; done: ;; no No adjustment needed; attribute "length" is fine. -;; yes Analyse pattern in adjust_insn_length by hand. ;; Otherwise do special processing depending on the attribute. (define_attr "adjust_len" - "out_bitop, out_plus, addto_sp, tsthi, tstsi, compare, + "out_bitop, out_plus, addto_sp, tsthi, tstsi, compare, call, mov8, mov16, mov32, reload_in16, reload_in32, ashlqi, ashrqi, lshrqi, ashlhi, ashrhi, lshrhi, @@ -3634,21 +3633,12 @@ (define_insn "call_insn" ;; Operand 1 not used on the AVR. ;; Operand 2 is 1 for tail-call, 0 otherwise. "" - "@ - %!icall - %~call %x0 - %!ijmp - %~jmp %x0" + { + return avr_out_call (insn, operands[0], 0 != INTVAL (operands[2])); + } [(set_attr "cc" "clobber") - (set_attr_alternative "length" - [(const_int 1) - (if_then_else (eq_attr "mcu_mega" "yes") - (const_int 2) - (const_int 1)) - (const_int 1) - (if_then_else (eq_attr "mcu_mega" "yes") - (const_int 2) - (const_int 1))])]) + (set_attr "length" "1,*,1,*") + (set_attr "adjust_len" "*,call,*,call")]) (define_insn "call_value_insn" [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r") @@ -3658,21 +3648,12 @@ (define_insn "call_value_insn" ;; Operand 2 not used on the AVR. ;; Operand 3 is 1 for tail-call, 0 otherwise. "" - "@ - %!icall - %~call %x1 - %!ijmp - %~jmp %x1" + { + return avr_out_call (insn, operands[1], 0 != INTVAL (operands[3])); + } [(set_attr "cc" "clobber") - (set_attr_alternative "length" - [(const_int 1) - (if_then_else (eq_attr "mcu_mega" "yes") - (const_int 2) - (const_int 1)) - (const_int 1) - (if_then_else (eq_attr "mcu_mega" "yes") - (const_int 2) - (const_int 1))])]) + (set_attr "length" "1,*,1,*") + (set_attr "adjust_len" "*,call,*,call")]) (define_insn "nop" [(const_int 0)] Index: config/avr/avr-protos.h =================================================================== --- config/avr/avr-protos.h (revision 179842) +++ config/avr/avr-protos.h (working copy) @@ -84,6 +84,7 @@ extern const char *avr_out_sbxx_branch ( extern const char* avr_out_bitop (rtx, rtx*, int*); extern const char* avr_out_plus (rtx*, int*, int*); extern const char* avr_out_addto_sp (rtx*, int*); +extern const char* avr_out_call (rtx, rtx, bool); extern bool avr_popcount_each_byte (rtx, int, int); extern int extra_constraint_Q (rtx x); Index: config/avr/avr.c =================================================================== --- config/avr/avr.c (revision 179843) +++ config/avr/avr.c (working copy) @@ -4905,6 +4905,27 @@ avr_out_plus (rtx *xop, int *plen, int * } +/* Print call insn INSN to the assembler file and return "". + ADDRESS is the target address. + If SIBCALL_P then INSN is a tail-call. */ + +const char* +avr_out_call (rtx insn, rtx address, bool sibcall_p) +{ + /* No need to waste stack or time for no-return calls. */ + + if (optimize && find_reg_note (insn, REG_NORETURN, NULL)) + sibcall_p = true; + + if (REG_P (address)) + output_asm_insn (sibcall_p ? "%!ijmp" : "%!icall", &address); + else + output_asm_insn (sibcall_p ? "%~jmp %x0" : "%~call %x0", &address); + + return ""; +} + + /* Output bit operation (IOR, AND, XOR) with register XOP[0] and compile time constant XOP[2]: @@ -5311,6 +5332,8 @@ adjust_insn_length (rtx insn, int len) case ADJUST_LEN_ASHLQI: ashlqi3_out (insn, op, &len); break; case ADJUST_LEN_ASHLHI: ashlhi3_out (insn, op, &len); break; case ADJUST_LEN_ASHLSI: ashlsi3_out (insn, op, &len); break; + + case ADJUST_LEN_CALL: len = AVR_HAVE_JMP_CALL ? 2 : 1; break; default: gcc_unreachable();