From patchwork Wed Jul 14 11:14:14 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Schmidt X-Patchwork-Id: 58865 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 8E312B6EE9 for ; Wed, 14 Jul 2010 21:14:44 +1000 (EST) Received: (qmail 19332 invoked by alias); 14 Jul 2010 11:14:42 -0000 Received: (qmail 19298 invoked by uid 22791); 14 Jul 2010 11:14:41 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 14 Jul 2010 11:14:35 +0000 Received: (qmail 29275 invoked from network); 14 Jul 2010 11:14:33 -0000 Received: from unknown (HELO ?84.152.203.213?) (bernds@127.0.0.2) by mail.codesourcery.com with ESMTPA; 14 Jul 2010 11:14:33 -0000 Message-ID: <4C3D9C06.60901@codesourcery.com> Date: Wed, 14 Jul 2010 13:14:14 +0200 From: Bernd Schmidt User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.10) Gecko/20100625 Thunderbird/3.0.5 MIME-Version: 1.0 To: GCC Patches Subject: Emit more REG_EQUIV notes for function args (PR42235) 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 When moving arguments into pseudos, we are being very careful not to emit any instructions that could possibly clobber other argument registers. Currently, we generate unnecessarily complicated sequences of code for simple zero or sign extensions. With this patch, we check can_extend_p and the necessary predicates to see if an extend insn is available for the conversion we have to do. If so, we emit the insn directly, and create a REG_EQUIV note of the form (sign_extend (mem)). Reload can't really do anything with these yet, but there's an optimization in the register allocator to move argument loads directly before their use if there's only one use. On Thumb-2 this happens already, we seem to generate better code than before. Unfortunately Thumb-1, which the PR is about, has some other problems which I'll try to fix later. Bootstrapped and regression tested on i686-linux. Also regression tested on arm-linux, with my three usual sets of options. Ok? Bernd PR target/42235 * function.c (assign_parm_setup_reg): When an optab for extending exists, emit the insn directly and create a REG_EQUIV note. Index: function.c =================================================================== --- function.c (revision 162146) +++ function.c (working copy) @@ -2861,10 +2861,12 @@ static void assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, struct assign_parm_data_one *data) { - rtx parmreg; + rtx parmreg, validated_mem; + rtx equiv_stack_parm; enum machine_mode promoted_nominal_mode; int unsignedp = TYPE_UNSIGNED (TREE_TYPE (parm)); bool did_conversion = false; + bool need_conversion, moved; /* Store the parm in a pseudoregister during the function, but we may need to do it in a wider mode. Using 2 here makes the result @@ -2891,10 +2893,46 @@ assign_parm_setup_reg (struct assign_par assign_parm_remove_parallels (data); + equiv_stack_parm = data->stack_parm; + validated_mem = validize_mem (data->entry_parm); + + need_conversion = (data->nominal_mode != data->passed_mode + || promoted_nominal_mode != data->promoted_mode); + moved = false; + /* Copy the value into the register, thus bridging between assign_parm_find_data_types and expand_expr_real_1. */ - if (data->nominal_mode != data->passed_mode - || promoted_nominal_mode != data->promoted_mode) + if (need_conversion) + { + enum insn_code icode; + rtx op0, op1; + + icode = can_extend_p (promoted_nominal_mode, data->passed_mode, + unsignedp); + + op0 = parmreg; + op1 = validated_mem; + if (icode != CODE_FOR_nothing + && insn_data[icode].operand[0].predicate (op0, promoted_nominal_mode) + && insn_data[icode].operand[1].predicate (op1, data->passed_mode)) + { + enum rtx_code code = unsignedp ? ZERO_EXTEND : SIGN_EXTEND; + rtx insn; + + insn = gen_extend_insn (op0, op1, promoted_nominal_mode, + data->passed_mode, unsignedp); + emit_insn (insn); + + equiv_stack_parm = gen_rtx_fmt_e (code, GET_MODE (parmreg), + equiv_stack_parm); + moved = true; + } + } + + if (moved) + /* Nothing to do. */ + ; + else if (need_conversion) { int save_tree_used; @@ -2919,7 +2957,7 @@ assign_parm_setup_reg (struct assign_par rtx tempreg = gen_reg_rtx (GET_MODE (data->entry_parm)); - emit_move_insn (tempreg, validize_mem (data->entry_parm)); + emit_move_insn (tempreg, validated_mem); push_to_sequence2 (all->first_conversion_insn, all->last_conversion_insn); tempreg = convert_to_mode (data->nominal_mode, tempreg, unsignedp); @@ -2949,7 +2987,7 @@ assign_parm_setup_reg (struct assign_par did_conversion = true; } else - emit_move_insn (parmreg, validize_mem (data->entry_parm)); + emit_move_insn (parmreg, validated_mem); /* If we were passed a pointer but the actual value can safely live in a register, put it in one. */ @@ -3034,7 +3072,7 @@ assign_parm_setup_reg (struct assign_par } else if ((set = single_set (linsn)) != 0 && SET_DEST (set) == parmreg) - set_unique_reg_note (linsn, REG_EQUIV, data->stack_parm); + set_unique_reg_note (linsn, REG_EQUIV, equiv_stack_parm); } /* For pointer data type, suggest pointer register. */