From patchwork Mon Jun 17 01:31:37 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kugan Vivekanandarajah X-Patchwork-Id: 251758 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]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 102152C013D for ; Mon, 17 Jun 2013 11:31:51 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; q=dns; s=default; b=HJYBtEbUldRNGG5nL 34CnwaxEDZxbI0cFPHEwqiTpyggk26CpV2fKjC20tAj4QZHWALJilqYqdtvCFptY zlzSTg3HlCOESq7/tyT4L9oPdQvKoGawj3ua/fy763GWgunhiiyaK3OncHor/Hug +yvpRFl0iZmj9j7xSeKBorwtpQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; s=default; bh=aOvC3EldQFvBBubohP8mHGG yjoY=; b=aeoHstpV33XcrzJm/hR9JV9ULIiDyPvEHxGVJUsQSywHrlXJCd9imgz shIqwKkBZGXxRDagcXypMrlEN03YqnL1o6sSz84YZqqmJHwxCWWOihoKtoX9OU1Z OgVZ/qa27vRj0W+8knDOFgm+ejb9g63VtSoOfwfhZIBru0j6yY2c= Received: (qmail 13297 invoked by alias); 17 Jun 2013 01:31:45 -0000 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 Received: (qmail 13286 invoked by uid 89); 17 Jun 2013 01:31:45 -0000 X-Spam-SWARE-Status: No, score=-2.9 required=5.0 tests=AWL, BAYES_00, KHOP_THREADED, RCVD_IN_DNSWL_NONE, RCVD_IN_HOSTKARMA_YE, TW_TM autolearn=ham version=3.3.1 Received: from mail-pd0-f179.google.com (HELO mail-pd0-f179.google.com) (209.85.192.179) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Mon, 17 Jun 2013 01:31:43 +0000 Received: by mail-pd0-f179.google.com with SMTP id q10so2220495pdj.24 for ; Sun, 16 Jun 2013 18:31:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:x-gm-message-state; bh=Imwne405Q0OsfM7BtKJzQAmOAFSwrmLq8DEWx9iVeyY=; b=PHv1L5D3B+/VIVanwuYs5pDHHKm6SBIHkLlRt53gJwTBd3xC9rFYBHyal73BoYzZTG j0vPK8rboA+xVALn1B0WR4u8CG0a+sMX5WmmcLfGnfB6DkeooH/Z2FSs5AhLgotBR0m0 zontC4ZE2xi5o1C2KlyVK02IFR9aZl9gpS+ZhOP5IBbzljuXUuIxcH2zot7dnGL5fgPQ 8ywTVapA/gHMFnXJxP0rImvV7n38exAoeKAFQmBiBOEcjpoXfXaBKyxbCzwh12rx0oQY yxIhhmA2EWUIdMN4ZT06r7ArZR4C2F3U9rjyUMWUk2uAZ0c00hxU4G7b3PApWIhTC/en 64GQ== X-Received: by 10.68.1.226 with SMTP id 2mr11058229pbp.150.1371432702351; Sun, 16 Jun 2013 18:31:42 -0700 (PDT) Received: from [192.168.1.3] (27-33-114-215.tpgi.com.au. [27.33.114.215]) by mx.google.com with ESMTPSA id xl3sm10633555pbb.17.2013.06.16.18.31.39 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 16 Jun 2013 18:31:41 -0700 (PDT) Message-ID: <51BE66F9.20609@linaro.org> Date: Mon, 17 Jun 2013 11:01:37 +0930 From: Kugan User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130510 Thunderbird/17.0.6 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: Richard Biener , rdsandiford@googlemail.com, Richard Earnshaw , ramana.radhakrishnan@arm.com, ebotcazou@adacore.com Subject: [ping][PATCH][2 of 2] RTL expansion for zero sign extension elimination with VRP References: <51ABFC6E.30205@linaro.org> In-Reply-To: <51ABFC6E.30205@linaro.org> X-Gm-Message-State: ALoCoQmoFo1hpyPffgOKU8OlK1UnxNGhBEfZqw4JG/eu8wk8EuAxqCM0V3w7Ous80JRoAHozoIDr X-Virus-Found: No Can you please help to review this patch? Richard reviewed the original patch and asked it to be split into two parts. Also, he wanted a review from RTL maintainers for the RTL changes. Thanks, Kugan On 03/06/13 11:46, Kugan wrote: > Hi, > > This patch removes some of the redundant sign/zero extensions using > value range information during RTL expansion. > > When GIMPLE_ASSIGN stmts with LHS type smaller than word is expanded to > RTL, if we can prove that RHS expression value can always fit in LHS > type and there is no sign conversion, truncation and extension to fit > the type is redundant. For a SUBREG_PROMOTED_VAR_P, Subreg and Zero/sign > extensions are therefore redundant. > > For example, when an expression is evaluated and it's value is assigned > to variable of type short, the generated RTL would look something like > the following. > > (set (reg:SI 110) > (zero_extend:SI (subreg:HI (reg:SI 117) 0))) > > However, if during value range propagation, if we can say for certain > that the value of the expression which is present in register 117 is > within the limits of short and there is no sign conversion, we do not > need to perform the subreg and zero_extend; instead we can generate the > following RTl. > > (set (reg:SI 110) > (reg:SI 117))) > > Same could be done for other assign statements. > > This patch is based on the earlier attempt posted in > http://gcc.gnu.org/ml/gcc-patches/2013-05/msg00610.html and addresses > the review comments of Richard Biener. I am post-processing the > expand_expr_real_2 output in expand_gimple_stmt though. Reason for this > is that I would like to process all the possible assignment stmts, not > just CASE_CONVERT case and/or the REDUCE_BITFIELD. > > This change along with expansion improve the geomean of spec2k int > benchmark with ref by about ~3.5% on an arm chromebook. > > Tested on X86_64 and ARM. > > I would like review comments on this. > > Thanks, > Kugan > > > +2013-06-03 Kugan Vivekanandarajah > + > + * gcc/dojump.c (do_compare_and_jump): generates rtl without > + zero/sign extension if redundant. > + * gcc/cfgexpand.c (expand_gimple_stmt_1): Likewise. > + * gcc/gimple.c (gimple_assign_is_zero_sign_ext_redundant) : New > + function. > + * gcc/gimple.h (gimple_assign_is_zero_sign_ext_redundant) : New > + function definition. > + > > > > > > > diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index c187273..ce980bc 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -2311,6 +2311,17 @@ expand_gimple_stmt_1 (gimple stmt) if (temp == target) ; + /* If the value in SUBREG of temp fits that SUBREG (does not + overflow) and is assigned to target SUBREG of the same mode + without sign convertion, we can skip the SUBREG + and extension. */ + else if (promoted + && gimple_assign_is_zero_sign_ext_redundant (stmt) + && (GET_CODE (temp) == SUBREG) + && (GET_MODE (target) == GET_MODE (temp)) + && (GET_MODE (SUBREG_REG (target)) + == GET_MODE (SUBREG_REG (temp)))) + emit_move_insn (SUBREG_REG (target), SUBREG_REG (temp)); else if (promoted) { int unsignedp = SUBREG_PROMOTED_UNSIGNED_P (target); diff --git a/gcc/dojump.c b/gcc/dojump.c index 3f04eac..cb13f3a 100644 --- a/gcc/dojump.c +++ b/gcc/dojump.c @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see #include "ggc.h" #include "basic-block.h" #include "tm_p.h" +#include "gimple.h" static bool prefer_and_bit_test (enum machine_mode, int); static void do_jump_by_parts_greater (tree, tree, int, rtx, rtx, int); @@ -1108,6 +1109,60 @@ do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code, type = TREE_TYPE (treeop0); mode = TYPE_MODE (type); + + /* Is zero/sign extension redundant as per VRP. */ + bool op0_ext_redundant = false; + bool op1_ext_redundant = false; + + /* If promoted and the value in SUBREG of op0 fits (does not overflow), + it is a candidate for extension elimination. */ + if (GET_CODE (op0) == SUBREG && SUBREG_PROMOTED_VAR_P (op0)) + op0_ext_redundant = + gimple_assign_is_zero_sign_ext_redundant (SSA_NAME_DEF_STMT (treeop0)); + + /* If promoted and the value in SUBREG of op1 fits (does not overflow), + it is a candidate for extension elimination. */ + if (GET_CODE (op1) == SUBREG && SUBREG_PROMOTED_VAR_P (op1)) + op1_ext_redundant = + gimple_assign_is_zero_sign_ext_redundant (SSA_NAME_DEF_STMT (treeop1)); + + /* If zero/sign extension is redundant, generate RTL + for operands without zero/sign extension. */ + if ((op0_ext_redundant || TREE_CODE (treeop0) == INTEGER_CST) + && (op1_ext_redundant || TREE_CODE (treeop1) == INTEGER_CST)) + { + if (TREE_CODE (treeop1) == INTEGER_CST) + { + /* First operand is constant. */ + rtx new_op0 = gen_reg_rtx (GET_MODE (SUBREG_REG (op0))); + + emit_move_insn (new_op0, SUBREG_REG (op0)); + op0 = new_op0; + } + else if (TREE_CODE (treeop0) == INTEGER_CST) + { + /* Other operand is constant. */ + rtx new_op1 = gen_reg_rtx (GET_MODE (SUBREG_REG (op1))); + + emit_move_insn (new_op1, SUBREG_REG (op1)); + op1 = new_op1; + } + /* If both the comapre registers fits SUBREG and of the same mode. */ + else if ((TREE_CODE (treeop0) != INTEGER_CST) + && (TREE_CODE (treeop1) != INTEGER_CST) + && (GET_MODE (op0) == GET_MODE (op1)) + && (GET_MODE (SUBREG_REG (op0)) == GET_MODE (SUBREG_REG (op1)))) + { + rtx new_op0 = gen_reg_rtx (GET_MODE (SUBREG_REG (op0))); + rtx new_op1 = gen_reg_rtx (GET_MODE (SUBREG_REG (op1))); + + emit_move_insn (new_op0, SUBREG_REG (op0)); + emit_move_insn (new_op1, SUBREG_REG (op1)); + op0 = new_op0; + op1 = new_op1; + } + } + if (TREE_CODE (treeop0) == INTEGER_CST && (TREE_CODE (treeop1) != INTEGER_CST || (GET_MODE_BITSIZE (mode) diff --git a/gcc/gimple.c b/gcc/gimple.c index f507419..e9499b6 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -200,6 +200,75 @@ gimple_call_reset_alias_info (gimple s) pt_solution_reset (gimple_call_clobber_set (s)); } + +/* process gimple assign stmts and see if the sign/zero extensions are + redundant. i.e. if an assignment gimple statement has RHS expression + value that can fit in LHS type, truncation is redundant. Zero/sign + extensions in this case can be removed. */ + +bool +gimple_assign_is_zero_sign_ext_redundant (gimple stmt) +{ + double_int type_min, type_max; + tree int_val = NULL_TREE; + range_info_def *ri; + + /* skip if not assign stmt. */ + if (!is_gimple_assign (stmt)) + return false; + + tree lhs = gimple_assign_lhs (stmt); + + /* We can remove extension only for non-pointer and integral stmts. */ + if (!INTEGRAL_TYPE_P (TREE_TYPE (lhs)) + || POINTER_TYPE_P (TREE_TYPE (lhs))) + return false; + + type_max = tree_to_double_int (TYPE_MAX_VALUE (TREE_TYPE (lhs))); + type_min = tree_to_double_int (TYPE_MIN_VALUE (TREE_TYPE (lhs))); + + /* For binary expressions, if one of the argument is constant and is + larger than tne signed maximum, it can be intepreted as nagative + and sign extended. This could lead to problems so return false in + this case. */ + if (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_binary) + { + tree rhs1 = gimple_assign_rhs1 (stmt); + tree rhs2 = gimple_assign_rhs2 (stmt); + + if (TREE_CODE (rhs1) == INTEGER_CST) + int_val = rhs1; + else if (TREE_CODE (rhs2) == INTEGER_CST) + int_val = rhs2; + + if (int_val != NULL_TREE) + { + tree max = TYPE_MIN_VALUE (TREE_TYPE (lhs)); + + /* if type is unsigned, get the max for signed equivalent. */ + if (!INT_CST_LT (TYPE_MIN_VALUE (TREE_TYPE (lhs)), integer_zero_node)) + max = int_const_binop (RSHIFT_EXPR, + max, build_int_cst (TREE_TYPE (max), 1)); + if (!INT_CST_LT (int_val, max)) + return false; + } + } + + /* Get the value range. */ + ri = SSA_NAME_RANGE_INFO (lhs); + + /* Check if value range is valid. */ + if (!ri || !ri->valid || !ri->vr_range) + return false; + + /* Value range fits type. */ + if (ri->max.scmp (type_max) != 1 + && (type_min.scmp (ri->min) != 1)) + return true; + + return false; +} + /* Helper for gimple_build_call, gimple_build_call_valist, gimple_build_call_vec and gimple_build_call_from_tree. Build the basic components of a GIMPLE_CALL statement to function FN with NARGS diff --git a/gcc/gimple.h b/gcc/gimple.h index b4de403..e924c5b 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -829,6 +829,7 @@ int gimple_call_flags (const_gimple); int gimple_call_return_flags (const_gimple); int gimple_call_arg_flags (const_gimple, unsigned); void gimple_call_reset_alias_info (gimple); +bool gimple_assign_is_zero_sign_ext_redundant (gimple); bool gimple_assign_copy_p (gimple); bool gimple_assign_ssa_name_copy_p (gimple); bool gimple_assign_unary_nop_p (gimple);