From patchwork Thu Oct 8 15:11:40 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Enkovich X-Patchwork-Id: 527772 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.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 30377140E53 for ; Fri, 9 Oct 2015 02:12:24 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=dKPGt8kl; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=ShiGBtRgiZb81vqfUpkotyoAZh52UkVNhpNMJP1vMQzuo7yFM0gdr zThWKuI4uapkXWDy5ALis2VPon4z+dZhZgooXRERv6f1j7RKwu9gFc+RdbDLKMJJ TeQK4mx1ld7TixEzzplgZ0BtlCLYtn57eciVDmU8A8NQYsaPet1LKU= 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:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=xbBh6xGj7ZwKQSbnIe8clkqEuCs=; b=dKPGt8kl7UCObIVor9wV CwO6ksFeESTsti5CzR9oBy18ADiul+lhfmPM2cm0nfdUiZT9qRKcD7dmTeYW5Wjx cwGB+ZWUqi5ocnVRGSLxVG+/dCNdqoCaE20eba0NL9g8hJCyLVudFX5nMD3HNP0R W5+0vkIViwes2wB5h0ASyUw= Received: (qmail 25260 invoked by alias); 8 Oct 2015 15:12:15 -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 25247 invoked by uid 89); 8 Oct 2015 15:12:15 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-wi0-f172.google.com Received: from mail-wi0-f172.google.com (HELO mail-wi0-f172.google.com) (209.85.212.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 08 Oct 2015 15:12:08 +0000 Received: by wiclk2 with SMTP id lk2so33200827wic.0 for ; Thu, 08 Oct 2015 08:12:05 -0700 (PDT) X-Received: by 10.180.182.83 with SMTP id ec19mr2716503wic.35.1444317125699; Thu, 08 Oct 2015 08:12:05 -0700 (PDT) Received: from msticlxl57.ims.intel.com (jfdmzpr02-ext.jf.intel.com. [134.134.137.71]) by smtp.gmail.com with ESMTPSA id eo5sm7635198wib.17.2015.10.08.08.12.03 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Oct 2015 08:12:05 -0700 (PDT) Date: Thu, 8 Oct 2015 18:11:40 +0300 From: Ilya Enkovich To: gcc-patches@gcc.gnu.org Subject: [vec-cmp, patch 4/6] Support vector mask invariants Message-ID: <20151008151140.GE63757@msticlxl57.ims.intel.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes Hi, This patch adds a special handling of boolean vector invariants. We need additional code to determine type of generated invariant. For VEC_COND_EXPR case we even provide this type directly because statement vectype doesn't allow us to compute it. Separate code is used to generate and expand such vectors. Thanks, Ilya --- gcc/ 2015-10-08 Ilya Enkovich * expr.c (const_vector_mask_from_tree): New. (const_vector_from_tree): Use const_vector_mask_from_tree for boolean vectors. * tree-vect-stmts.c (vect_init_vector): Support boolean vector invariants. (vect_get_vec_def_for_operand): Add VECTYPE arg. (vectorizable_condition): Directly provide vectype for invariants used in comparison. * tree-vectorizer.h (vect_get_vec_def_for_operand): Add VECTYPE arg. diff --git a/gcc/expr.c b/gcc/expr.c index 88da8cb..a624a34 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -11320,6 +11320,40 @@ try_tablejump (tree index_type, tree index_expr, tree minval, tree range, return 1; } +/* Return a CONST_VECTOR rtx representing vector mask for + a VECTOR_CST of booleans. */ +static rtx +const_vector_mask_from_tree (tree exp) +{ + rtvec v; + unsigned i; + int units; + tree elt; + machine_mode inner, mode; + + mode = TYPE_MODE (TREE_TYPE (exp)); + units = GET_MODE_NUNITS (mode); + inner = GET_MODE_INNER (mode); + + v = rtvec_alloc (units); + + for (i = 0; i < VECTOR_CST_NELTS (exp); ++i) + { + elt = VECTOR_CST_ELT (exp, i); + + gcc_assert (TREE_CODE (elt) == INTEGER_CST); + if (integer_zerop (elt)) + RTVEC_ELT (v, i) = CONST0_RTX (inner); + else if (integer_onep (elt) + || integer_minus_onep (elt)) + RTVEC_ELT (v, i) = CONSTM1_RTX (inner); + else + gcc_unreachable (); + } + + return gen_rtx_CONST_VECTOR (mode, v); +} + /* Return a CONST_VECTOR rtx for a VECTOR_CST tree. */ static rtx const_vector_from_tree (tree exp) @@ -11335,6 +11369,9 @@ const_vector_from_tree (tree exp) if (initializer_zerop (exp)) return CONST0_RTX (mode); + if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp))) + return const_vector_mask_from_tree (exp); + units = GET_MODE_NUNITS (mode); inner = GET_MODE_INNER (mode); diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 6949c71..337ea7b 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -1308,27 +1308,61 @@ vect_init_vector_1 (gimple *stmt, gimple *new_stmt, gimple_stmt_iterator *gsi) tree vect_init_vector (gimple *stmt, tree val, tree type, gimple_stmt_iterator *gsi) { + tree val_type = TREE_TYPE (val); + machine_mode mode = TYPE_MODE (type); + machine_mode val_mode = TYPE_MODE(val_type); tree new_var; gimple *init_stmt; tree vec_oprnd; tree new_temp; if (TREE_CODE (type) == VECTOR_TYPE - && TREE_CODE (TREE_TYPE (val)) != VECTOR_TYPE) - { - if (!types_compatible_p (TREE_TYPE (type), TREE_TYPE (val))) + && TREE_CODE (val_type) != VECTOR_TYPE) + { + /* Handle vector of bool represented as a vector of + integers here rather than on expand because it is + a default mask type for targets. Vector mask is + built in a following way: + + tmp = (int)val + vec_tmp = {tmp, ..., tmp} + vec_cst = VIEW_CONVERT_EXPR(vec_tmp); */ + if (TREE_CODE (val_type) == BOOLEAN_TYPE + && VECTOR_MODE_P (mode) + && SCALAR_INT_MODE_P (GET_MODE_INNER (mode)) + && GET_MODE_INNER (mode) != val_mode) { - if (CONSTANT_CLASS_P (val)) - val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (type), val); - else + unsigned size = GET_MODE_BITSIZE (GET_MODE_INNER (mode)); + tree stype = build_nonstandard_integer_type (size, 1); + tree vectype = get_vectype_for_scalar_type (stype); + + new_temp = make_ssa_name (stype); + init_stmt = gimple_build_assign (new_temp, NOP_EXPR, val); + vect_init_vector_1 (stmt, init_stmt, gsi); + + val = make_ssa_name (vectype); + new_temp = build_vector_from_val (vectype, new_temp); + init_stmt = gimple_build_assign (val, new_temp); + vect_init_vector_1 (stmt, init_stmt, gsi); + + val = build1 (VIEW_CONVERT_EXPR, type, val); + } + else + { + if (!types_compatible_p (TREE_TYPE (type), val_type)) { - new_temp = make_ssa_name (TREE_TYPE (type)); - init_stmt = gimple_build_assign (new_temp, NOP_EXPR, val); - vect_init_vector_1 (stmt, init_stmt, gsi); - val = new_temp; + if (CONSTANT_CLASS_P (val)) + val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (type), val); + else + { + new_temp = make_ssa_name (TREE_TYPE (type)); + init_stmt = gimple_build_assign (new_temp, NOP_EXPR, val); + vect_init_vector_1 (stmt, init_stmt, gsi); + val = new_temp; + } } + val = build_vector_from_val (type, val); } - val = build_vector_from_val (type, val); } new_var = vect_get_new_vect_var (type, vect_simple_var, "cst_"); @@ -1350,16 +1384,19 @@ vect_init_vector (gimple *stmt, tree val, tree type, gimple_stmt_iterator *gsi) STMT_VINFO_VEC_STMT of the defining stmt holds the relevant def. In case OP is an invariant or constant, a new stmt that creates a vector def - needs to be introduced. */ + needs to be introduced. VECTYPE may be used to specify a required type for + vector invariant. */ tree -vect_get_vec_def_for_operand (tree op, gimple *stmt, tree *scalar_def) +vect_get_vec_def_for_operand (tree op, gimple *stmt, tree *scalar_def, + tree vectype) { tree vec_oprnd; gimple *vec_stmt; gimple *def_stmt; stmt_vec_info def_stmt_info = NULL; stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt); + tree stmt_vectype = STMT_VINFO_VECTYPE (stmt_vinfo); unsigned int nunits; loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo); tree def; @@ -1403,7 +1440,14 @@ vect_get_vec_def_for_operand (tree op, gimple *stmt, tree *scalar_def) /* Case 1: operand is a constant. */ case vect_constant_def: { - vector_type = get_vectype_for_scalar_type (TREE_TYPE (op)); + if (vectype) + vector_type = vectype; + else if (TREE_CODE (TREE_TYPE (op)) == BOOLEAN_TYPE + && VECTOR_BOOLEAN_TYPE_P (stmt_vectype)) + vector_type = build_same_sized_truth_vector_type (stmt_vectype); + else + vector_type = get_vectype_for_scalar_type (TREE_TYPE (op)); + gcc_assert (vector_type); nunits = TYPE_VECTOR_SUBPARTS (vector_type); @@ -1421,7 +1465,13 @@ vect_get_vec_def_for_operand (tree op, gimple *stmt, tree *scalar_def) /* Case 2: operand is defined outside the loop - loop invariant. */ case vect_external_def: { - vector_type = get_vectype_for_scalar_type (TREE_TYPE (def)); + if (vectype) + vector_type = vectype; + else if (TREE_CODE (TREE_TYPE (op)) == BOOLEAN_TYPE + && VECTOR_BOOLEAN_TYPE_P (stmt_vectype)) + vector_type = build_same_sized_truth_vector_type (stmt_vectype); + else + vector_type = get_vectype_for_scalar_type (TREE_TYPE (def)); gcc_assert (vector_type); if (scalar_def) @@ -7437,13 +7487,13 @@ vectorizable_condition (gimple *stmt, gimple_stmt_iterator *gsi, gimple *gtemp; vec_cond_lhs = vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0), - stmt, NULL); + stmt, NULL, comp_vectype); vect_is_simple_use (TREE_OPERAND (cond_expr, 0), stmt, loop_vinfo, NULL, >emp, &def, &dts[0]); vec_cond_rhs = vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1), - stmt, NULL); + stmt, NULL, comp_vectype); vect_is_simple_use (TREE_OPERAND (cond_expr, 1), stmt, loop_vinfo, NULL, >emp, &def, &dts[1]); if (reduc_index == 1) diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 23a82ee..1a1e509 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -1032,7 +1032,7 @@ extern unsigned record_stmt_cost (stmt_vector_for_cost *, int, extern void vect_finish_stmt_generation (gimple *, gimple *, gimple_stmt_iterator *); extern bool vect_mark_stmts_to_be_vectorized (loop_vec_info); -extern tree vect_get_vec_def_for_operand (tree, gimple *, tree *); +extern tree vect_get_vec_def_for_operand (tree, gimple *, tree *, tree = NULL); extern tree vect_init_vector (gimple *, tree, tree, gimple_stmt_iterator *); extern tree vect_get_vec_def_for_stmt_copy (enum vect_def_type, tree);