From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 47549 invoked by alias); 13 Oct 2015 14:52:42 -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 47533 invoked by uid 89); 13 Oct 2015 14:52:41 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-io0-f170.google.com Received: from mail-io0-f170.google.com (HELO mail-io0-f170.google.com) (209.85.223.170) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Tue, 13 Oct 2015 14:52:35 +0000 Received: by iow1 with SMTP id 1so23682289iow.1 for ; Tue, 13 Oct 2015 07:52:33 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.107.160.196 with SMTP id j187mr36374540ioe.91.1444747953669; Tue, 13 Oct 2015 07:52:33 -0700 (PDT) Received: by 10.36.122.14 with HTTP; Tue, 13 Oct 2015 07:52:33 -0700 (PDT) In-Reply-To: References: <20151008151140.GE63757@msticlxl57.ims.intel.com> Date: Tue, 13 Oct 2015 14:52:00 -0000 Message-ID: Subject: Re: [vec-cmp, patch 4/6] Support vector mask invariants From: Ilya Enkovich To: Richard Biener Cc: GCC Patches Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2015-10/txt/msg01258.txt.bz2 2015-10-13 16:54 GMT+03:00 Richard Biener : > On Thu, Oct 8, 2015 at 5:11 PM, Ilya Enkovich wr= ote: >> Hi, >> >> This patch adds a special handling of boolean vector invariants. We nee= d additional code to determine type of generated invariant. For VEC_COND_E= XPR 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 su= ch 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 =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_st= mt, gimple_stmt_iterator *gsi) >> tree >> vect_init_vector (gimple *stmt, tree val, tree type, gimple_stmt_iterat= or *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), val= ); >> - 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, val= ); >> - 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 t= ype, 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 ve= ctor def >> - needs to be introduced. */ >> + needs to be introduced. VECTYPE may be used to specify a required t= ype 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 *st= mt, 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_vecty= pe); >> + 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 *st= mt, 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_vecty= pe); >> + 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_stm= t_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. 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? Thanks, Ilya