From patchwork Sun Nov 8 09:43:06 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kugan Vivekanandarajah X-Patchwork-Id: 56153 Delivered-To: patch@linaro.org Received: by 10.112.61.134 with SMTP id p6csp590161lbr; Sun, 8 Nov 2015 01:43:50 -0800 (PST) X-Received: by 10.68.104.2 with SMTP id ga2mr31063793pbb.56.1446975830363; Sun, 08 Nov 2015 01:43:50 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id ah10si9233858pad.118.2015.11.08.01.43.49 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 08 Nov 2015 01:43:50 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-413121-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; spf=pass (google.com: domain of gcc-patches-return-413121-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-413121-patch=linaro.org@gcc.gnu.org; dkim=pass header.i=@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; q=dns; s=default; b=kwVf6tLuFNonc1HtP rMcFfLcVph89QE3uYKhgMXYaob7++K6gTNODwDvSOhnRGk3u/L6p71cDFg6kLMQX mRQa0/QQQC8oO3753z2s+6KN7yo+ixpKXnob5VjU17aRKwDrD9s9EvYUK7IUv7O2 P17J/QPaV3BqCXVjl2hcbQpf7I= 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 :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; s=default; bh=w/aOSxvUrydxPdAzKUjvNUv 2FSI=; b=EXrPpqiTHnoIyOv+rMKLOIYgsCzl7jBUQMqIjB6AND5y534zrcnwdp1 mbB78z4WcFuy3CmrtZqWxTu7AQcnr8SmZ7eng7UNzYKU+RkTpzJuOsZ5AQ3wsvSk JGDuQXdCVfPZ6GXU7bfgRQvfbfoqo83JC8KkdcH6X+K0dTA6IRWk= Received: (qmail 125726 invoked by alias); 8 Nov 2015 09:43:33 -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 125589 invoked by uid 89); 8 Nov 2015 09:43:29 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.0 required=5.0 tests=AWL, BAYES_50, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f44.google.com Received: from mail-pa0-f44.google.com (HELO mail-pa0-f44.google.com) (209.85.220.44) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Sun, 08 Nov 2015 09:43:23 +0000 Received: by pasz6 with SMTP id z6so172104503pas.2 for ; Sun, 08 Nov 2015 01:43:21 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to:content-type; bh=K/Z9DFQ5ckl8PNYPUUSdtHzXkKMzL/xTl1k6Qwr88LI=; b=HTM1SvKaQfAY3xRTviszDQlx7x6OBzHdE8X3HYlvxN8rnbTJ6NIFk9dJEB17T8Zkd2 4yUmm2ziNZsjxpBYyk2hQnJbo8EG3Rb7HX10xVCab9fGqu8YLu3bTZI20TkFkZprgS2N esf7Ick7S+59riHYvgt0moAWYydmrfgalktgvhsVTpdzCp1szpJleJ1VAV66JecaEZDU iCtfMRonGCGyr1kpA5zRwetkYfo3HRdlEKWVGOnBpjoyn09wXwjp3+e7qtU2pVQWki6G 2zWAVdDhoqK81BO2CJnpzb1C10/Wd4rP19IBqTTRF0hbLwWqr+zHcxEYpEbKwPhbwqDd 1LSg== X-Gm-Message-State: ALoCoQmJia+KLqTSqM5OyemBWYQQWK2mliaAPvqdOlgjSYA8Sy5kO0B0S6SiWPiu5in2rFZlASYS X-Received: by 10.66.192.193 with SMTP id hi1mr101621pac.110.1446975801384; Sun, 08 Nov 2015 01:43:21 -0800 (PST) Received: from [10.1.1.9] (58-6-183-210.dyn.iinet.net.au. [58.6.183.210]) by smtp.googlemail.com with ESMTPSA id v17sm6964714pbs.69.2015.11.08.01.43.18 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 08 Nov 2015 01:43:20 -0800 (PST) Subject: Re: [0/7] Type promotion pass and elimination of zext/sext To: Richard Biener References: <55ECFC2A.7050908@linaro.org> <56269E01.5010408@linaro.org> <5628BF86.6070503@linaro.org> <562ECA5D.2040008@linaro.org> <56372A31.3080607@linaro.org> Cc: "gcc-patches@gcc.gnu.org" From: Kugan Message-ID: <563F192A.7020004@linaro.org> Date: Sun, 8 Nov 2015 20:43:06 +1100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: X-IsSubscribed: yes Thanks Richard for the comments. Please find the attached patches which now passes bootstrap with x86_64-none-linux-gnu, aarch64-linux-gnu and ppc64-linux-gnu. Regression testing is ongoing. Please find the comments for your questions/suggestions below. > > I notice > > diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c > index 82fd4a1..80fcf70 100644 > --- a/gcc/tree-ssanames.c > +++ b/gcc/tree-ssanames.c > @@ -207,7 +207,8 @@ set_range_info (tree name, enum value_range_type range_type, > unsigned int precision = TYPE_PRECISION (TREE_TYPE (name)); > > /* Allocate if not available. */ > - if (ri == NULL) > + if (ri == NULL > + || (precision != ri->get_min ().get_precision ())) > > and I think you need to clear range info on promoted SSA vars in the > promotion pass. Done. > > The basic "structure" thing still remains. You walk over all uses and > defs in all stmts > in promote_all_stmts which ends up calling promote_ssa_if_not_promoted on all > uses and defs which in turn promotes (the "def") and then fixes up all > uses in all stmts. Done. > > Instead of this you should, in promote_all_stmts, walk over all uses doing what > fixup_uses does and then walk over all defs, doing what promote_ssa does. > > + case GIMPLE_NOP: > + { > + if (SSA_NAME_VAR (def) == NULL) > + { > + /* Promote def by fixing its type for anonymous def. */ > + TREE_TYPE (def) = promoted_type; > + } > + else > + { > + /* Create a promoted copy of parameters. */ > + bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)); > > I think the uninitialized vars are somewhat tricky and it would be best > to create a new uninit anonymous SSA name for them. You can > have SSA_NAME_VAR != NULL and def _not_ being a parameter > btw. Done. I also had to do some changes to in couple of other places to reflect this. They are: { Does this look OK? > > +/* Return true if it is safe to promote the defined SSA_NAME in the STMT > + itself. */ > +static bool > +safe_to_promote_def_p (gimple *stmt) > +{ > + enum tree_code code = gimple_assign_rhs_code (stmt); > + if (gimple_vuse (stmt) != NULL_TREE > + || gimple_vdef (stmt) != NULL_TREE > + || code == ARRAY_REF > + || code == LROTATE_EXPR > + || code == RROTATE_EXPR > + || code == VIEW_CONVERT_EXPR > + || code == BIT_FIELD_REF > + || code == REALPART_EXPR > + || code == IMAGPART_EXPR > + || code == REDUC_MAX_EXPR > + || code == REDUC_PLUS_EXPR > + || code == REDUC_MIN_EXPR) > + return false; > + return true; > > huh, I think this function has an odd name, maybe > can_promote_operation ()? Please > use TREE_CODE_CLASS (code) == tcc_reference for all _REF trees. Done. > > Note that as followup things like the rotates should be "expanded" like > we'd do on RTL (open-coding the thing). And we'd need a way to > specify zero-/sign-extended loads. > > +/* Return true if it is safe to promote the use in the STMT. */ > +static bool > +safe_to_promote_use_p (gimple *stmt) > +{ > + enum tree_code code = gimple_assign_rhs_code (stmt); > + tree lhs = gimple_assign_lhs (stmt); > + > + if (gimple_vuse (stmt) != NULL_TREE > + || gimple_vdef (stmt) != NULL_TREE > > I think the vuse/vdef check is bogus, you can have a use of 'i_3' in say > _2 = a[i_3]; > When I remove this, I see errors in stmts like: unsigned char unsigned int # .MEM_197 = VDEF <.MEM_187> fs_9(D)->fde_encoding = _154; > + || code == VIEW_CONVERT_EXPR > + || code == LROTATE_EXPR > + || code == RROTATE_EXPR > + || code == CONSTRUCTOR > + || code == BIT_FIELD_REF > + || code == COMPLEX_EXPR > + || code == ASM_EXPR > + || VECTOR_TYPE_P (TREE_TYPE (lhs))) > + return false; > + return true; > > ASM_EXPR can never appear here. I think PROMOTE_MODE never > promotes vector types - what cases did you need to add VECTOR_TYPE_P for? Done > > +/* Return true if the SSA_NAME has to be truncated to preserve the > + semantics. */ > +static bool > +truncate_use_p (gimple *stmt) > +{ > + enum tree_code code = gimple_assign_rhs_code (stmt); > > I think the description can be improved. This is about stray bits set > beyond the original type, correct? > > Please use NOP_EXPR wherever you use CONVERT_EXPR right how. > > + if (TREE_CODE_CLASS (code) > + == tcc_comparison) > + promote_cst_in_stmt (stmt, promoted_type, true); > > don't you always need to promote constant operands? I am promoting all the constants. Here, I am promoting the the constants that are part of the conditions. Thanks, Kugan >From c0ce364e3a422912a08189645efde46c36583753 Mon Sep 17 00:00:00 2001 From: Kugan Vivekanandarajah Date: Thu, 22 Oct 2015 10:51:42 +1100 Subject: [PATCH 1/4] Add new SEXT_EXPR tree code --- gcc/cfgexpand.c | 12 ++++++++++++ gcc/expr.c | 20 ++++++++++++++++++++ gcc/fold-const.c | 4 ++++ gcc/tree-cfg.c | 12 ++++++++++++ gcc/tree-inline.c | 1 + gcc/tree-pretty-print.c | 11 +++++++++++ gcc/tree.def | 5 +++++ 7 files changed, 65 insertions(+) diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index eaad859..aeb64bb 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -5054,6 +5054,18 @@ expand_debug_expr (tree exp) case FMA_EXPR: return simplify_gen_ternary (FMA, mode, inner_mode, op0, op1, op2); + case SEXT_EXPR: + gcc_assert (CONST_INT_P (op1)); + inner_mode = mode_for_size (INTVAL (op1), MODE_INT, 0); + gcc_assert (GET_MODE_BITSIZE (inner_mode) == INTVAL (op1)); + + if (mode != inner_mode) + op0 = simplify_gen_unary (SIGN_EXTEND, + mode, + gen_lowpart_SUBREG (inner_mode, op0), + inner_mode); + return op0; + default: flag_unsupported: #ifdef ENABLE_CHECKING diff --git a/gcc/expr.c b/gcc/expr.c index da68870..c2f535f 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -9318,6 +9318,26 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, target = expand_vec_cond_expr (type, treeop0, treeop1, treeop2, target); return target; + case SEXT_EXPR: + { + machine_mode inner_mode = mode_for_size (tree_to_uhwi (treeop1), + MODE_INT, 0); + rtx temp, result; + rtx op0 = expand_normal (treeop0); + op0 = force_reg (mode, op0); + if (mode != inner_mode) + { + result = gen_reg_rtx (mode); + temp = simplify_gen_unary (SIGN_EXTEND, mode, + gen_lowpart_SUBREG (inner_mode, op0), + inner_mode); + convert_move (result, temp, 0); + } + else + result = op0; + return result; + } + default: gcc_unreachable (); } diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 602ea24..a149bad 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -987,6 +987,10 @@ int_const_binop_1 (enum tree_code code, const_tree arg1, const_tree parg2, res = wi::bit_and (arg1, arg2); break; + case SEXT_EXPR: + res = wi::sext (arg1, arg2.to_uhwi ()); + break; + case RSHIFT_EXPR: case LSHIFT_EXPR: if (wi::neg_p (arg2)) diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 8e3e810..d18b3f7 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -3752,6 +3752,18 @@ verify_gimple_assign_binary (gassign *stmt) return false; } + case SEXT_EXPR: + { + if (!INTEGRAL_TYPE_P (lhs_type) + || !useless_type_conversion_p (lhs_type, rhs1_type) + || !tree_fits_uhwi_p (rhs2)) + { + error ("invalid operands in sext expr"); + return true; + } + return false; + } + case VEC_WIDEN_LSHIFT_HI_EXPR: case VEC_WIDEN_LSHIFT_LO_EXPR: { diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index b8269ef..e61c200 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -3893,6 +3893,7 @@ estimate_operator_cost (enum tree_code code, eni_weights *weights, case BIT_XOR_EXPR: case BIT_AND_EXPR: case BIT_NOT_EXPR: + case SEXT_EXPR: case TRUTH_ANDIF_EXPR: case TRUTH_ORIF_EXPR: diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index 11f90051..bec9082 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -1923,6 +1923,14 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, int flags, } break; + case SEXT_EXPR: + pp_string (pp, "SEXT_EXPR <"); + dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); + pp_string (pp, ", "); + dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); + pp_greater (pp); + break; + case MODIFY_EXPR: case INIT_EXPR: dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, @@ -3561,6 +3569,9 @@ op_symbol_code (enum tree_code code) case MIN_EXPR: return "min"; + case SEXT_EXPR: + return "sext"; + default: return "<<< ??? >>>"; } diff --git a/gcc/tree.def b/gcc/tree.def index d0a3bd6..789cfdd 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -760,6 +760,11 @@ DEFTREECODE (BIT_XOR_EXPR, "bit_xor_expr", tcc_binary, 2) DEFTREECODE (BIT_AND_EXPR, "bit_and_expr", tcc_binary, 2) DEFTREECODE (BIT_NOT_EXPR, "bit_not_expr", tcc_unary, 1) +/* Sign-extend operation. It will sign extend first operand from + the sign bit specified by the second operand. The type of the + result is that of the first operand. */ +DEFTREECODE (SEXT_EXPR, "sext_expr", tcc_binary, 2) + /* ANDIF and ORIF allow the second operand not to be computed if the value of the expression is determined from the first operand. AND, OR, and XOR always compute the second operand whether its value is -- 1.9.1