From patchwork Fri May 4 07:30:44 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Pinski X-Patchwork-Id: 156806 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 C4026B6FBD for ; Fri, 4 May 2012 17:31:24 +1000 (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=1336721485; h=Comment: DomainKey-Signature:Received:Received:Received:Received: MIME-Version:Received:Received:In-Reply-To:References:Date: Message-ID:Subject:From:To:Cc:Content-Type:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=s4CJXNTfk86dDaGC2ClYR6er6rY=; b=XjVbz9S6PJSh/qAbiCJcbWIEhmcuIMLDOxZWoJU0pLibpZnGCjOCHx4e20aKzs qvxO6vghWmKcUQTqzl26JHa/OH+IRILh+IgVOTYvK8mVtW/FE7Oj5v3yXRF7zDuH BfGlkgJBckBt0SRSFeEzdntXSo0Cjj/4hS2HyZD/0o6C4= 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:In-Reply-To:References:Date:Message-ID:Subject:From:To:Cc:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=jq3/N1XfJGqgS34mp+7KLkW/ttm5mpUuWxQH8onoeCthgWm+NbLiQFQ5B/S9/v IkSG0+l/Jh0icFyLJXX46AKveMtB0U34XpY7IpCI90u1mUs5RhlpdmWBASZFKAQJ cDYUk6MWbEo8TL/b1TVVJngIEuK5rDCNHjoxYCt8OsfBk=; Received: (qmail 20532 invoked by alias); 4 May 2012 07:31:11 -0000 Received: (qmail 20500 invoked by uid 22791); 4 May 2012 07:31:08 -0000 X-SWARE-Spam-Status: No, hits=-5.0 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, FREEMAIL_FROM, KHOP_RCVD_TRUST, KHOP_THREADED, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE, TW_TM X-Spam-Check-By: sourceware.org Received: from mail-wi0-f173.google.com (HELO mail-wi0-f173.google.com) (209.85.212.173) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 04 May 2012 07:30:45 +0000 Received: by wibhr7 with SMTP id hr7so670878wib.8 for ; Fri, 04 May 2012 00:30:44 -0700 (PDT) MIME-Version: 1.0 Received: by 10.180.104.137 with SMTP id ge9mr10103610wib.20.1336116644184; Fri, 04 May 2012 00:30:44 -0700 (PDT) Received: by 10.216.100.197 with HTTP; Fri, 4 May 2012 00:30:44 -0700 (PDT) In-Reply-To: References: <4FA01329.5040004@redhat.com> Date: Fri, 4 May 2012 00:30:44 -0700 Message-ID: Subject: Re: [PATCH] Improve COND_EXPR expansion From: Andrew Pinski To: Richard Henderson Cc: GCC Patches 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 On Fri, May 4, 2012 at 12:29 AM, Andrew Pinski wrote: > On Tue, May 1, 2012 at 9:45 AM, Richard Henderson wrote: >> On 04/30/2012 08:22 PM, Andrew Pinski wrote: >>> >>> * expr.c (convert_tree_comp_to_rtx): New function. >>> (expand_expr_real_2): Try using conditional moves for COND_EXPRs if they >>> exist. >>> * config/i386/i386.c (ix86_expand_int_movcc): Disallow comparison >>> modes of DImode for 32bits and TImode. >> >> >> Looks ok, modulo some unwrapped long lines. >> Those lines might not be so long if this were split out as a subroutine... >> >> I'll not quibble about that though... > > Here is a new patch which splits this out into a subroutine which > reduces the long lines.  I added some extra comments that might make > some stuff like the extra can_conditionally_move_p check. > > OK?  Bootstrapped and tested on x86_64-linux-gnu. This time with the patch. -- Andrew > > Thanks, > Andrew Pinski > > ChangeLog: > * expr.c (get_def_for_expr_class): New function. > (convert_tree_comp_to_rtx): New function. > (expand_cond_expr_using_cmove): New function. > (expand_expr_real_2 ): Call > expand_cond_expr_using_cmove first and return if it succeeds. > Remove the check for HAVE_conditional_move since we should have > already converted it to a conditional move. > > * config/i386/i386.c (ix86_expand_int_movcc): Disallow comparison > modes of DImode for 32bits and TImode. Index: gcc/expr.c =================================================================== --- gcc/expr.c (revision 187138) +++ gcc/expr.c (working copy) @@ -2346,6 +2346,26 @@ get_def_for_expr (tree name, enum tree_c return def_stmt; } + +/* Return the defining gimple statement for SSA_NAME NAME if it is an + assigment and the class of the expresion on the RHS is CLASS. Return + NULL otherwise. */ + +static gimple +get_def_for_expr_class (tree name, enum tree_code_class tclass) +{ + gimple def_stmt; + + if (TREE_CODE (name) != SSA_NAME) + return NULL; + + def_stmt = get_gimple_for_ssa_name (name); + if (!def_stmt + || TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) != tclass) + return NULL; + + return def_stmt; +} /* Determine whether the LEN bytes generated by CONSTFUN can be @@ -7344,6 +7364,64 @@ highest_pow2_factor_for_target (const_tr return MAX (factor, talign); } +/* Convert the tree comparision code TCODE to the rtl one where the + signedness is UNSIGNEDP. */ + +static enum rtx_code +convert_tree_comp_to_rtx (enum tree_code tcode, int unsignedp) +{ + enum rtx_code code; + switch (tcode) + { + case EQ_EXPR: + code = EQ; + break; + case NE_EXPR: + code = NE; + break; + case LT_EXPR: + code = unsignedp ? LTU : LT; + break; + case LE_EXPR: + code = unsignedp ? LEU : LE; + break; + case GT_EXPR: + code = unsignedp ? GTU : GT; + break; + case GE_EXPR: + code = unsignedp ? GEU : GE; + break; + case UNORDERED_EXPR: + code = UNORDERED; + break; + case ORDERED_EXPR: + code = ORDERED; + break; + case UNLT_EXPR: + code = UNLT; + break; + case UNLE_EXPR: + code = UNLE; + break; + case UNGT_EXPR: + code = UNGT; + break; + case UNGE_EXPR: + code = UNGE; + break; + case UNEQ_EXPR: + code = UNEQ; + break; + case LTGT_EXPR: + code = LTGT; + break; + + default: + gcc_unreachable (); + } + return code; +} + /* Subroutine of expand_expr. Expand the two operands of a binary expression EXP0 and EXP1 placing the results in OP0 and OP1. The value may be stored in TARGET if TARGET is nonzero. The @@ -7782,6 +7860,96 @@ expand_expr_real (tree exp, rtx target, return ret; } +/* Try to expand the conditional expression which is represented by + TREEOP0 ? TREEOP1 : TREEOP2 using conditonal moves. If succeseds + return the rtl reg which repsents the result. Otherwise return NULL_RTL. */ + +static rtx +expand_cond_expr_using_cmove (tree treeop0, tree treeop1, tree treeop2) +{ +#ifdef HAVE_conditional_move + rtx insn; + rtx op00, op01, op1, op2; + enum rtx_code comparison_code; + enum machine_mode comparison_mode; + gimple srcstmt; + rtx temp; + tree type = TREE_TYPE (treeop1); + int unsignedp = TYPE_UNSIGNED (type); + enum machine_mode mode = TYPE_MODE (type); + + temp = assign_temp (type, 0, 0, 1); + + /* If we cannot do a conditional move on the mode, try doing it + with the promoted mode. */ + if (!can_conditionally_move_p (mode)) + mode = promote_mode (type, mode, &unsignedp); + + if (!can_conditionally_move_p (mode)) + return NULL_RTX; + + start_sequence (); + expand_operands (treeop1, treeop2, + temp, &op1, &op2, EXPAND_NORMAL); + + if (TREE_CODE (treeop0) == SSA_NAME + && (srcstmt = get_def_for_expr_class (treeop0, tcc_comparison))) + { + tree type = TREE_TYPE (gimple_assign_rhs1 (srcstmt)); + enum tree_code cmpcode = gimple_assign_rhs_code (srcstmt); + op00 = expand_normal (gimple_assign_rhs1 (srcstmt)); + op01 = expand_normal (gimple_assign_rhs2 (srcstmt)); + comparison_mode = TYPE_MODE (type); + unsignedp = TYPE_UNSIGNED (type); + comparison_code = convert_tree_comp_to_rtx (cmpcode, unsignedp); + } + else if (TREE_CODE_CLASS (TREE_CODE (treeop0)) == tcc_comparison) + { + tree type = TREE_TYPE (TREE_OPERAND (treeop0, 0)); + enum tree_code cmpcode = TREE_CODE (treeop0); + op00 = expand_normal (TREE_OPERAND (treeop0, 0)); + op01 = expand_normal (TREE_OPERAND (treeop0, 1)); + unsignedp = TYPE_UNSIGNED (type); + comparison_mode = TYPE_MODE (type); + comparison_code = convert_tree_comp_to_rtx (cmpcode, unsignedp); + } + else + { + op00 = expand_normal (treeop0); + op01 = const0_rtx; + comparison_code = NE; + comparison_mode = TYPE_MODE (TREE_TYPE (treeop0)); + } + + if (GET_MODE (op1) != mode) + op1 = gen_lowpart (mode, op1); + + if (GET_MODE (op2) != mode) + op2 = gen_lowpart (mode, op2); + + /* Try to emit the conditional move. */ + insn = emit_conditional_move (temp, comparison_code, + op00, op01, comparison_mode, + op1, op2, mode, + unsignedp); + + /* If we could do the conditional move, emit the sequence, + and return. */ + if (insn) + { + rtx seq = get_insns (); + end_sequence (); + emit_insn (seq); + return temp; + } + + /* Otherwise discard the sequence and fall back to code with + branches. */ + end_sequence (); +#endif + return NULL_RTX; +} + rtx expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, enum expand_modifier modifier) @@ -8841,6 +9009,10 @@ expand_expr_real_2 (sepops ops, rtx targ && TREE_TYPE (treeop1) != void_type_node && TREE_TYPE (treeop2) != void_type_node); + temp = expand_cond_expr_using_cmove (treeop0, treeop1, treeop2); + if (temp) + return temp; + /* If we are not to produce a result, we have no target. Otherwise, if a target was specified use it; it will not be used as an intermediate target unless it is safe. If no target, use a @@ -8850,10 +9022,6 @@ expand_expr_real_2 (sepops ops, rtx targ && original_target && safe_from_p (original_target, treeop0, 1) && GET_MODE (original_target) == mode -#ifdef HAVE_conditional_move - && (! can_conditionally_move_p (mode) - || REG_P (original_target)) -#endif && !MEM_P (original_target)) temp = original_target; else Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c (revision 187138) +++ gcc/config/i386/i386.c (working copy) @@ -18832,6 +18832,11 @@ ix86_expand_int_movcc (rtx operands[]) rtx op0 = XEXP (operands[1], 0); rtx op1 = XEXP (operands[1], 1); + if (GET_MODE (op0) == TImode + || (GET_MODE (op0) == DImode + && !TARGET_64BIT)) + return false; + start_sequence (); compare_op = ix86_expand_compare (code, op0, op1); compare_seq = get_insns ();