From patchwork Mon Jun 3 02:16:14 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kugan Vivekanandarajah X-Patchwork-Id: 17429 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qc0-f198.google.com (mail-qc0-f198.google.com [209.85.216.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 01BE625DF1 for ; Mon, 3 Jun 2013 02:16:21 +0000 (UTC) Received: by mail-qc0-f198.google.com with SMTP id k14sf4716478qcv.1 for ; Sun, 02 Jun 2013 19:16:21 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-beenthere:x-forwarded-to:x-forwarded-for:delivered-to:message-id :date:from:user-agent:mime-version:to:cc:subject:x-gm-message-state :x-original-sender:x-original-authentication-results:precedence :mailing-list:list-id:x-google-group-id:list-post:list-help :list-archive:list-unsubscribe:content-type; bh=QtgeejtIVt/5z/+i89IH6VHV3BnvkU5wybJQcxTApm8=; b=jLCg2y7Z+PpVnnSVcvqnw2UOCBsIhCQiUciv8pud+aXU1mviqXWq5L/gMPvBtNNPle Wi0HnMAnIhDePfu5E6+ejyAlunuTTZKDdIn5KQGvFOSUEUyeSVe1VADqEXtBIwXs5Sjg 6jKVhEkWisB9Ql4fzbv5V9sTABxTZZmfpSY5Z+aB+IAsWW/D00Id477L7zduzQ7yD8Zr Eg4Y/3vPbK3yCwlaiIznytvAprpdWzK1mk/CUsTqqweWJGQM6cgdZlJSUknCCuUe4qhC E3Bw1+Z8p9gZJCqedoIcYfdqu+vw2HM4E2br7EbsSq3M2qAaDg6Odj5WlvKgGGO69T6/ ZUlQ== X-Received: by 10.236.84.177 with SMTP id s37mr11105281yhe.37.1370225781722; Sun, 02 Jun 2013 19:16:21 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.3.105 with SMTP id b9ls1894699qeb.34.gmail; Sun, 02 Jun 2013 19:16:21 -0700 (PDT) X-Received: by 10.52.76.6 with SMTP id g6mr13701334vdw.13.1370225781574; Sun, 02 Jun 2013 19:16:21 -0700 (PDT) Received: from mail-ve0-x22e.google.com (mail-ve0-x22e.google.com [2607:f8b0:400c:c01::22e]) by mx.google.com with ESMTPS id qu17si15165478vec.6.2013.06.02.19.16.21 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 02 Jun 2013 19:16:21 -0700 (PDT) Received-SPF: neutral (google.com: 2607:f8b0:400c:c01::22e is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=2607:f8b0:400c:c01::22e; Received: by mail-ve0-f174.google.com with SMTP id oz10so2387196veb.19 for ; Sun, 02 Jun 2013 19:16:21 -0700 (PDT) X-Received: by 10.52.170.148 with SMTP id am20mr13696645vdc.75.1370225781257; Sun, 02 Jun 2013 19:16:21 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.221.10.206 with SMTP id pb14csp61404vcb; Sun, 2 Jun 2013 19:16:20 -0700 (PDT) X-Received: by 10.66.163.5 with SMTP id ye5mr22242432pab.60.1370225780172; Sun, 02 Jun 2013 19:16:20 -0700 (PDT) Received: from mail-pd0-f173.google.com (mail-pd0-f173.google.com [209.85.192.173]) by mx.google.com with ESMTPS id ad8si38670572pbd.156.2013.06.02.19.16.19 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 02 Jun 2013 19:16:20 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.192.173 is neither permitted nor denied by best guess record for domain of kugan.vivekanandarajah@linaro.org) client-ip=209.85.192.173; Received: by mail-pd0-f173.google.com with SMTP id v14so4944480pde.4 for ; Sun, 02 Jun 2013 19:16:19 -0700 (PDT) X-Received: by 10.68.178.33 with SMTP id cv1mr21586987pbc.209.1370225779640; Sun, 02 Jun 2013 19:16:19 -0700 (PDT) Received: from [192.168.1.4] (27-33-114-215.tpgi.com.au. [27.33.114.215]) by mx.google.com with ESMTPSA id uv1sm56829350pbc.16.2013.06.02.19.16.16 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 02 Jun 2013 19:16:19 -0700 (PDT) Message-ID: <51ABFC6E.30205@linaro.org> Date: Mon, 03 Jun 2013 11:46:14 +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" , patches@linaro.org CC: Richard Biener , rdsandiford@googlemail.com, Richard Earnshaw , ramana.radhakrishnan@arm.com Subject: [PATCH][2 of 2] RTL expansion for zero sign extension elimination with VRP X-Gm-Message-State: ALoCoQlTsCilEzItIsFLsRBY5ybO+h+yciHxMgA85L9xPE7CJNwwi3m/IreDtDmNEdPCwMfJy9vF X-Original-Sender: kugan.vivekanandarajah@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 2607:f8b0:400c:c01::22e is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , 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);