From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 89697 invoked by alias); 13 Oct 2015 13:54:14 -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 89687 invoked by uid 89); 13 Oct 2015 13:54:13 -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-f178.google.com Received: from mail-yk0-f178.google.com (HELO mail-yk0-f178.google.com) (209.85.160.178) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Tue, 13 Oct 2015 13:54:12 +0000 Received: by ykey125 with SMTP id y125so16821044yke.3 for ; Tue, 13 Oct 2015 06:54:09 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.129.13.215 with SMTP id 206mr26525483ywn.280.1444744449826; Tue, 13 Oct 2015 06:54:09 -0700 (PDT) Received: by 10.37.93.136 with HTTP; Tue, 13 Oct 2015 06:54:09 -0700 (PDT) In-Reply-To: <20151008151140.GE63757@msticlxl57.ims.intel.com> References: <20151008151140.GE63757@msticlxl57.ims.intel.com> Date: Tue, 13 Oct 2015 13:54: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/msg01251.txt.bz2 On Thu, Oct 8, 2015 at 5:11 PM, Ilya Enkovich wrot= e: > Hi, > > This patch adds a special handling of boolean vector invariants. We need= additional code to determine type of generated invariant. For VEC_COND_EX= PR 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 suc= h 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_stm= t, gimple_stmt_iterator *gsi) > tree > vect_init_vector (gimple *stmt, tree val, tree type, gimple_stmt_iterato= r *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); 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 ... }; ? > + } > + 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 ty= pe, 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 vec= tor def > - needs to be introduced. */ > + needs to be introduced. VECTYPE may be used to specify a required ty= pe 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 *stm= t, 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_vectyp= e); > + 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 *stm= t, 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_vectyp= e); > + 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_stmt= _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? > if (reduc_index =3D=3D 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_c= ost *, 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 = =3D 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);