From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 56370 invoked by alias); 14 Oct 2015 08:49:41 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 56357 invoked by uid 89); 14 Oct 2015 08:49:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-yk0-f180.google.com Received: from mail-yk0-f180.google.com (HELO mail-yk0-f180.google.com) (209.85.160.180) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 14 Oct 2015 08:49:38 +0000 Received: by ykoo7 with SMTP id o7so41144654yko.0 for ; Wed, 14 Oct 2015 01:49:36 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.129.125.6 with SMTP id y6mr1236228ywc.5.1444812576354; Wed, 14 Oct 2015 01:49:36 -0700 (PDT) Received: by 10.37.117.136 with HTTP; Wed, 14 Oct 2015 01:49:36 -0700 (PDT) In-Reply-To: References: <20151008151140.GE63757@msticlxl57.ims.intel.com> Date: Wed, 14 Oct 2015 08:49:00 -0000 Message-ID: Subject: Re: [vec-cmp, patch 4/6] Support vector mask invariants From: Richard Biener To: Ilya Enkovich Cc: GCC Patches Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2015-10/txt/msg01325.txt.bz2 On Tue, Oct 13, 2015 at 4:52 PM, Ilya Enkovich wro= te: > 2015-10-13 16:54 GMT+03:00 Richard Biener : >> On Thu, Oct 8, 2015 at 5:11 PM, Ilya Enkovich w= rote: >>> Hi, >>> >>> This patch adds a special handling of boolean vector invariants. We ne= ed additional code to determine type of generated invariant. For VEC_COND_= EXPR case we even provide this type directly because statement vectype does= n't allow us to compute it. Separate code is used to generate and expand s= uch 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 invarian= ts >>> 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_exp= r, 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 =3D TYPE_MODE (TREE_TYPE (exp)); >>> + units =3D GET_MODE_NUNITS (mode); >>> + inner =3D GET_MODE_INNER (mode); >>> + >>> + v =3D rtvec_alloc (units); >>> + >>> + for (i =3D 0; i < VECTOR_CST_NELTS (exp); ++i) >>> + { >>> + elt =3D VECTOR_CST_ELT (exp, i); >>> + >>> + gcc_assert (TREE_CODE (elt) =3D=3D INTEGER_CST); >>> + if (integer_zerop (elt)) >>> + RTVEC_ELT (v, i) =3D CONST0_RTX (inner); >>> + else if (integer_onep (elt) >>> + || integer_minus_onep (elt)) >>> + RTVEC_ELT (v, i) =3D 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 =3D GET_MODE_NUNITS (mode); >>> inner =3D 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_s= tmt, gimple_stmt_iterator *gsi) >>> tree >>> vect_init_vector (gimple *stmt, tree val, tree type, gimple_stmt_itera= tor *gsi) >>> { >>> + tree val_type =3D TREE_TYPE (val); >>> + machine_mode mode =3D TYPE_MODE (type); >>> + machine_mode val_mode =3D TYPE_MODE(val_type); >>> tree new_var; >>> gimple *init_stmt; >>> tree vec_oprnd; >>> tree new_temp; >>> >>> if (TREE_CODE (type) =3D=3D VECTOR_TYPE >>> - && TREE_CODE (TREE_TYPE (val)) !=3D VECTOR_TYPE) >>> - { >>> - if (!types_compatible_p (TREE_TYPE (type), TREE_TYPE (val))) >>> + && TREE_CODE (val_type) !=3D 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 =3D (int)val >>> + vec_tmp =3D {tmp, ..., tmp} >>> + vec_cst =3D VIEW_CONVERT_EXPR(vec_tmp); */ >>> + if (TREE_CODE (val_type) =3D=3D BOOLEAN_TYPE >>> + && VECTOR_MODE_P (mode) >>> + && SCALAR_INT_MODE_P (GET_MODE_INNER (mode)) >>> + && GET_MODE_INNER (mode) !=3D val_mode) >>> { >>> - if (CONSTANT_CLASS_P (val)) >>> - val =3D fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (type), va= l); >>> - else >>> + unsigned size =3D GET_MODE_BITSIZE (GET_MODE_INNER (mode)); >>> + tree stype =3D build_nonstandard_integer_type (size, 1); >>> + tree vectype =3D get_vectype_for_scalar_type (stype); >>> + >>> + new_temp =3D make_ssa_name (stype); >>> + init_stmt =3D gimple_build_assign (new_temp, NOP_EXPR, val); >>> + vect_init_vector_1 (stmt, init_stmt, gsi); >>> + >>> + val =3D make_ssa_name (vectype); >>> + new_temp =3D build_vector_from_val (vectype, new_temp); >>> + init_stmt =3D gimple_build_assign (val, new_temp); >>> + vect_init_vector_1 (stmt, init_stmt, gsi); >>> + >>> + val =3D build1 (VIEW_CONVERT_EXPR, type, val); >>l >> So I don't quite understand - why don't we want to build >> >> tmp =3D (bool-element-type)val; >> vec_cst =3D {tmp, tmp, tmp ... }; >> >> ? > > This code was written at a time boolean vector elements always had > bitsize 1. I'll rework it in accordance with new boolean types. > >> >>> + } >>> + else >>> + { >>> + if (!types_compatible_p (TREE_TYPE (type), val_type)) >>> { >>> - new_temp =3D make_ssa_name (TREE_TYPE (type)); >>> - init_stmt =3D gimple_build_assign (new_temp, NOP_EXPR, va= l); >>> - vect_init_vector_1 (stmt, init_stmt, gsi); >>> - val =3D new_temp; >>> + if (CONSTANT_CLASS_P (val)) >>> + val =3D fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (type)= , val); >>> + else >>> + { >>> + new_temp =3D make_ssa_name (TREE_TYPE (type)); >>> + init_stmt =3D gimple_build_assign (new_temp, NOP_EXPR= , val); >>> + vect_init_vector_1 (stmt, init_stmt, gsi); >>> + val =3D new_temp; >>> + } >>> } >>> + val =3D build_vector_from_val (type, val); >>> } >>> - val =3D build_vector_from_val (type, val); >>> } >>> >>> new_var =3D 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 v= ector 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 =3D NULL; >>> stmt_vec_info stmt_vinfo =3D vinfo_for_stmt (stmt); >>> + tree stmt_vectype =3D STMT_VINFO_VECTYPE (stmt_vinfo); >>> unsigned int nunits; >>> loop_vec_info loop_vinfo =3D STMT_VINFO_LOOP_VINFO (stmt_vinfo); >>> tree def; >>> @@ -1403,7 +1440,14 @@ vect_get_vec_def_for_operand (tree op, gimple *s= tmt, tree *scalar_def) >>> /* Case 1: operand is a constant. */ >>> case vect_constant_def: >>> { >>> - vector_type =3D get_vectype_for_scalar_type (TREE_TYPE (op)); >>> + if (vectype) >>> + vector_type =3D vectype; >>> + else if (TREE_CODE (TREE_TYPE (op)) =3D=3D BOOLEAN_TYPE >>> + && VECTOR_BOOLEAN_TYPE_P (stmt_vectype)) >>> + vector_type =3D build_same_sized_truth_vector_type (stmt_vect= ype); >>> + else >>> + vector_type =3D get_vectype_for_scalar_type (TREE_TYPE (op)); >> >> Rather than this... >> >>> + >>> gcc_assert (vector_type); >>> nunits =3D TYPE_VECTOR_SUBPARTS (vector_type); >>> >>> @@ -1421,7 +1465,13 @@ vect_get_vec_def_for_operand (tree op, gimple *s= tmt, tree *scalar_def) >>> /* Case 2: operand is defined outside the loop - loop invariant. = */ >>> case vect_external_def: >>> { >>> - vector_type =3D get_vectype_for_scalar_type (TREE_TYPE (def)); >>> + if (vectype) >>> + vector_type =3D vectype; >>> + else if (TREE_CODE (TREE_TYPE (op)) =3D=3D BOOLEAN_TYPE >>> + && VECTOR_BOOLEAN_TYPE_P (stmt_vectype)) >>> + vector_type =3D build_same_sized_truth_vector_type (stmt_vect= ype); >>> + else >>> + vector_type =3D get_vectype_for_scalar_type (TREE_TYPE (def)); >>> gcc_assert (vector_type); >> >> and this ... >> >>> if (scalar_def) >>> @@ -7437,13 +7487,13 @@ vectorizable_condition (gimple *stmt, gimple_st= mt_iterator *gsi, >>> gimple *gtemp; >>> vec_cond_lhs =3D >>> 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 =3D >>> 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]); >> >> I'd simply open-code this here? > > I don't understand what you mean. vect_get_vec_def_for_operand has two > changes made. > 1. For boolean invariants use build_same_sized_truth_vector_type > instead of get_vectype_for_scalar_type in case statement produces a > boolean vector. This covers cases when we use invariants in > comparison, AND, IOR, XOR. Yes, I understand we need this special-casing to differentiate between the vector type used for boolean-typed loads/stores and the type for boolean typed constant= s. What happens if we mix them btw, like with _Bool b =3D bools[i]; _Bool c =3D b || d; ... ? > 2. COND_EXPR is an exception because it has built-in boolean vector > result not reflected in its vecinfo. Thus I added additional operand > for vect_get_vec_def_for_operand to directly specify vectype for > vector definition in case it is a loop invariant. > So what do you propose to do with these changes? This is the change I don't like and don't see why we need it. It works tod= ay and the comparison operands should be of appropriate type already? Richard. > Thanks, > Ilya